/** * \file * \copyright * Copyright (c) 2012-2021, 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 "CreateThermoMechanicsProcess.h" #include #include "MaterialLib/MPL/CreateMaterialSpatialDistributionMap.h" #include "MaterialLib/MPL/MaterialSpatialDistributionMap.h" #include "MaterialLib/MPL/Medium.h" #include "MaterialLib/SolidModels/CreateConstitutiveRelation.h" #include "MaterialLib/SolidModels/MechanicsBase.h" #include "ParameterLib/Utils.h" #include "ProcessLib/Output/CreateSecondaryVariables.h" #include "ProcessLib/Utils/ProcessUtils.h" #include "ThermoMechanicsProcess.h" #include "ThermoMechanicsProcessData.h" namespace ProcessLib { namespace ThermoMechanics { void checkMPLProperties( std::map> const& media) { std::array const required_solid_properties = { MaterialPropertyLib::density, MaterialPropertyLib::thermal_expansivity, MaterialPropertyLib::thermal_conductivity, MaterialPropertyLib::specific_heat_capacity}; for (auto const& m : media) { checkRequiredProperties(m.second->phase("Solid"), required_solid_properties); } } template std::unique_ptr createThermoMechanicsProcess( std::string name, MeshLib::Mesh& mesh, std::unique_ptr&& jacobian_assembler, std::vector const& variables, std::vector> const& parameters, std::optional const& local_coordinate_system, unsigned const integration_order, BaseLib::ConfigTree const& config, std::map> const& media) { //! \ogs_file_param{prj__processes__process__type} config.checkConfigParameter("type", "THERMO_MECHANICS"); DBUG("Create ThermoMechanicsProcess."); auto const coupling_scheme = //! \ogs_file_param{prj__processes__process__THERMO_MECHANICS__coupling_scheme} config.getConfigParameterOptional("coupling_scheme"); const bool use_monolithic_scheme = !(coupling_scheme && (*coupling_scheme == "staggered")); // Process variable. //! \ogs_file_param{prj__processes__process__THERMO_MECHANICS__process_variables} auto const pv_config = config.getConfigSubtree("process_variables"); // Process IDs, which are set according to the appearance order of the int heat_conduction_process_id = 0; int mechanics_process_id = 0; ProcessVariable* variable_T; ProcessVariable* variable_u; std::vector>> process_variables; if (use_monolithic_scheme) // monolithic scheme. { auto per_process_variables = findProcessVariables( variables, pv_config, {//! \ogs_file_param_special{prj__processes__process__THERMO_MECHANICS__process_variables__temperature} "temperature", //! \ogs_file_param_special{prj__processes__process__THERMO_MECHANICS__process_variables__displacement} "displacement"}); variable_T = &per_process_variables[0].get(); variable_u = &per_process_variables[1].get(); process_variables.push_back(std::move(per_process_variables)); } else // staggered scheme. { using namespace std::string_literals; for (auto const& variable_name : {"temperature"s, "displacement"s}) { auto per_process_variables = findProcessVariables(variables, pv_config, {variable_name}); process_variables.push_back(std::move(per_process_variables)); } variable_T = &process_variables[0][0].get(); variable_u = &process_variables[1][0].get(); // process variables. Up to now, the ordering is fixed as: heat_conduction_process_id = 0; mechanics_process_id = 1; } DBUG("Associate displacement with process variable '{:s}'.", variable_u->getName()); if (variable_u->getNumberOfGlobalComponents() != DisplacementDim) { OGS_FATAL( "Number of components of the process variable '{:s}' is different " "from the displacement dimension: got {:d}, expected {:d}", variable_u->getName(), variable_u->getNumberOfGlobalComponents(), DisplacementDim); } DBUG("Associate temperature with process variable '{:s}'.", variable_T->getName()); if (variable_T->getNumberOfGlobalComponents() != 1) { OGS_FATAL( "Pressure process variable '{:s}' is not a scalar variable but has " "{:d} components.", variable_T->getName(), variable_T->getNumberOfGlobalComponents()); } //! \ogs_file_param{prj__processes__process__THERMO_MECHANICS__constitutive_relation} config.peekConfigParameter("constitutive_relation"); auto solid_constitutive_relations = MaterialLib::Solids::createConstitutiveRelations( parameters, local_coordinate_system, config); // Specific body force Eigen::Matrix specific_body_force; { std::vector const b = //! \ogs_file_param{prj__processes__process__THERMO_MECHANICS__specific_body_force} config.getConfigParameter>( "specific_body_force"); if (b.size() != DisplacementDim) { OGS_FATAL( "The size of the specific body force vector does not match the " "displacement dimension. Vector size is {:d}, displacement " "dimension is {:d}", b.size(), DisplacementDim); } std::copy_n(b.data(), b.size(), specific_body_force.data()); } // Initial stress conditions auto const initial_stress = ParameterLib::findOptionalTagParameter( //! \ogs_file_param_special{prj__processes__process__THERMO_MECHANICS__initial_stress} config, "initial_stress", parameters, // Symmetric tensor size, 4 or 6, not a Kelvin vector. MathLib::KelvinVector::kelvin_vector_dimensions(DisplacementDim), &mesh); auto media_map = MaterialPropertyLib::createMaterialSpatialDistributionMap(media, mesh); DBUG("Check the solid properties of ThermoMechanics process ..."); checkMPLProperties(media); DBUG("Solid properties verified."); ThermoMechanicsProcessData process_data{ materialIDs(mesh), std::move(media_map), std::move(solid_constitutive_relations), initial_stress, specific_body_force, mechanics_process_id, heat_conduction_process_id}; SecondaryVariableCollection secondary_variables; ProcessLib::createSecondaryVariables(config, secondary_variables); return std::make_unique>( std::move(name), mesh, std::move(jacobian_assembler), parameters, integration_order, std::move(process_variables), std::move(process_data), std::move(secondary_variables), use_monolithic_scheme); } template std::unique_ptr createThermoMechanicsProcess<2>( std::string name, MeshLib::Mesh& mesh, std::unique_ptr&& jacobian_assembler, std::vector const& variables, std::vector> const& parameters, std::optional const& local_coordinate_system, unsigned const integration_order, BaseLib::ConfigTree const& config, std::map> const& media); template std::unique_ptr createThermoMechanicsProcess<3>( std::string name, MeshLib::Mesh& mesh, std::unique_ptr&& jacobian_assembler, std::vector const& variables, std::vector> const& parameters, std::optional const& local_coordinate_system, unsigned const integration_order, BaseLib::ConfigTree const& config, std::map> const& media); } // namespace ThermoMechanics } // namespace ProcessLib