/** * \file * \author Norbert Grunwald * \date Sep 7, 2017 * * \copyright * Copyright (c) 2012-2019, OpenGeoSys Community (http://www.opengeosys.org) * Distributed under a Modified BSD License. * See accompanying file LICENSE.txt or * http://www.opengeosys.org/project/license * */ #include "CreateProperty.h" #include <string> #include <vector> #include "BaseLib/ConfigTree.h" #include "Properties/Properties.h" #include "Component.h" #include "Medium.h" #include "Phase.h" namespace { std::unique_ptr<MaterialPropertyLib::Property> createProperty( BaseLib::ConfigTree const& config) { using namespace MaterialPropertyLib; // Parsing the property type: //! \ogs_file_param{properties__property__type} auto const property_type = config.getConfigParameter<std::string>("type"); // If (and only if) the given property type is 'constant', a corresponding // value is needed. if (property_type == "Constant") { std::vector<double> const values = //! \ogs_file_param{properties__property__Constant__value} config.getConfigParameter<std::vector<double>>("value"); switch (values.size()) { case 1: { // scalar PropertyDataType property_value = values[0]; return std::make_unique<Constant>(property_value); } case 2: { // Pair PropertyDataType property_value = Pair{values[0], values[1]}; return std::make_unique<Constant>(property_value); } case 3: { // Vector PropertyDataType property_value = Vector{values[0], values[1], values[2]}; return std::make_unique<Constant>(property_value); } case 6: { // Symmetric Tensor - xx, yy, zz, xy, xz, yz PropertyDataType property_value = SymmTensor{values[0], values[1], values[2], values[3], values[4], values[5]}; return std::make_unique<Constant>(property_value); } case 9: { // Tensor PropertyDataType property_value = Tensor{ values[0], values[1], values[2], values[3], values[4], values[5], values[6], values[7], values[8]}; return std::make_unique<Constant>(property_value); } default: { OGS_FATAL( "Creation of a constant property with %i components is not " "implemented.", values.size()); } } PropertyDataType property_value; return std::make_unique<Constant>(property_value); } // Properties can be medium, phase, or component properties. // Some of them require information about the respective material. // Thus, we pass a pointer to the material that requests the property. // In this method, this pointer is realized via typename MaterialType, which // replaces either Medium*, Phase*, or Component*. // Note that most property constructors (only those that request material // pointers) must be overloaded for any type of material. if (property_type == "Linear") { double const reference_value = //! \ogs_file_param{properties__property__LinearProperty__reference_value} config.getConfigParameter<double>("reference_value"); auto const& independent_variable_config = //! \ogs_file_param{properties__property__LinearProperty__independent_variable} config.getConfigSubtree("independent_variable"); auto const& variable_name = //! \ogs_file_param{properties__property__LinearProperty__independent_variable__variable_name} independent_variable_config.getConfigParameter<std::string>( "variable_name"); double const reference_condition = //! \ogs_file_param{properties__property__LinearProperty__independent_variable__reference_condition} independent_variable_config.getConfigParameter<double>( "reference_condition"); double const slope = //! \ogs_file_param{properties__property__LinearProperty__independent_variable__slope} independent_variable_config.getConfigParameter<double>("slope"); MaterialPropertyLib::Variable ivt = MaterialPropertyLib::convertStringToVariable(variable_name); MaterialPropertyLib::IndependentVariable const iv{ ivt, reference_condition, slope}; MaterialPropertyLib::LinearProperty linear_property{reference_value, iv}; return std::make_unique<MaterialPropertyLib::LinearProperty>( reference_value, iv); } /* TODO Additional properties go here, for example: if (boost::iequals(property_type, "BilinearTemperaturePressure")) { return createBilinearTemperaturePressure(config, material_type); } */ // If none of the above property types are found, OGS throws an error. OGS_FATAL("The specified component property type '%s' was not recognized", property_type.c_str()); } } // namespace namespace MaterialPropertyLib { std::unique_ptr<PropertyArray> createProperties( boost::optional<BaseLib::ConfigTree> const& config) { if (!config) { return nullptr; } //! \ogs_file_param{properties__property} auto const& property_configs = config->getConfigSubtreeList("property"); if (property_configs.empty()) { return nullptr; } auto properties = std::make_unique<PropertyArray>(); for (auto property_config : property_configs) { // Parsing the property name: auto const property_name = //! \ogs_file_param{properties__property__name} property_config.getConfigParameter<std::string>("name"); // Create a new property based on the configuration subtree: auto property = createProperty(property_config); // Insert the new property at the right position into the components // private PropertyArray: (*properties)[convertStringToProperty(property_name)] = std::move(property); } return properties; } } // namespace MaterialPropertyLib