/** * \copyright * Copyright (c) 2012-2018, 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 <cassert> #include "MaterialLib/SolidModels/MechanicsBase.h" #include "MaterialLib/SolidModels/CreateConstitutiveRelation.h" #include "ProcessLib/Output/CreateSecondaryVariables.h" #include "ProcessLib/Utils/ProcessUtils.h" #include "ThermoMechanicsProcess.h" #include "ThermoMechanicsProcessData.h" namespace ProcessLib { namespace ThermoMechanics { template <int DisplacementDim> std::unique_ptr<Process> createThermoMechanicsProcess( MeshLib::Mesh& mesh, std::unique_ptr<ProcessLib::AbstractJacobianAssembler>&& jacobian_assembler, std::vector<ProcessVariable> const& variables, std::vector<std::unique_ptr<ParameterBase>> const& parameters, unsigned const integration_order, BaseLib::ConfigTree const& config) { //! \ogs_file_param{prj__processes__process__type} config.checkConfigParameter("type", "THERMO_MECHANICS"); DBUG("Create ThermoMechanicsProcess."); auto const staggered_scheme = //! \ogs_file_param{prj__processes__process__THERMO_MECHANICS__coupling_scheme} config.getConfigParameterOptional<std::string>("coupling_scheme"); const bool use_monolithic_scheme = !(staggered_scheme && (*staggered_scheme == "staggered")); // Process variable. //! \ogs_file_param{prj__processes__process__THERMO_MECHANICS__process_variables} auto const pv_config = config.getConfigSubtree("process_variables"); ProcessVariable* variable_T; ProcessVariable* variable_u; std::vector<std::vector<std::reference_wrapper<ProcessVariable>>> 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(); } DBUG("Associate displacement with process variable \'%s\'.", variable_u->getName().c_str()); if (variable_u->getNumberOfComponents() != DisplacementDim) { OGS_FATAL( "Number of components of the process variable '%s' is different " "from the displacement dimension: got %d, expected %d", variable_u->getName().c_str(), variable_u->getNumberOfComponents(), DisplacementDim); } DBUG("Associate temperature with process variable \'%s\'.", variable_T->getName().c_str()); if (variable_T->getNumberOfComponents() != 1) { OGS_FATAL( "Pressure process variable '%s' is not a scalar variable but has " "%d components.", variable_T->getName().c_str(), variable_T->getNumberOfComponents()); } // Constitutive relation. auto material = MaterialLib::Solids::createConstitutiveRelation<DisplacementDim>( parameters, config); // Reference solid density auto& reference_solid_density = findParameter<double>( config, //! \ogs_file_param_special{prj__processes__process__THERMO_MECHANICS__reference_solid_density} "reference_solid_density", parameters, 1); DBUG("Use \'%s\' as solid density parameter.", reference_solid_density.name.c_str()); // Linear thermal expansion coefficient auto& linear_thermal_expansion_coefficient = findParameter<double>( config, //! \ogs_file_param_special{prj__processes__process__THERMO_MECHANICS__linear_thermal_expansion_coefficient} "linear_thermal_expansion_coefficient", parameters, 1); DBUG("Use \'%s\' as linear thermal expansion coefficient.", linear_thermal_expansion_coefficient.name.c_str()); // Specific heat capacity auto& specific_heat_capacity = findParameter<double>( config, //! \ogs_file_param_special{prj__processes__process__THERMO_MECHANICS__specific_heat_capacity} "specific_heat_capacity", parameters, 1); DBUG("Use \'%s\' as specific heat capacity parameter.", specific_heat_capacity.name.c_str()); // Thermal conductivity // TODO To be changed as tensor input. auto& thermal_conductivity = findParameter<double>( config, //! \ogs_file_param_special{prj__processes__process__THERMO_MECHANICS__thermal_conductivity} "thermal_conductivity", parameters, 1); DBUG("Use \'%s\' as thermal conductivity parameter.", thermal_conductivity.name.c_str()); // Specific body force Eigen::Matrix<double, DisplacementDim, 1> specific_body_force; { std::vector<double> const b = //! \ogs_file_param{prj__processes__process__THERMO_MECHANICS__specific_body_force} config.getConfigParameter<std::vector<double>>( "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()); } ThermoMechanicsProcessData<DisplacementDim> process_data{ std::move(material), reference_solid_density, linear_thermal_expansion_coefficient, specific_heat_capacity, thermal_conductivity, specific_body_force}; SecondaryVariableCollection secondary_variables; NumLib::NamedFunctionCaller named_function_caller( {"ThermoMechanics_temperature_displacement"}); ProcessLib::createSecondaryVariables(config, secondary_variables, named_function_caller); return std::make_unique<ThermoMechanicsProcess<DisplacementDim>>( mesh, std::move(jacobian_assembler), parameters, integration_order, std::move(process_variables), std::move(process_data), std::move(secondary_variables), std::move(named_function_caller), use_monolithic_scheme); } template std::unique_ptr<Process> createThermoMechanicsProcess<2>( MeshLib::Mesh& mesh, std::unique_ptr<ProcessLib::AbstractJacobianAssembler>&& jacobian_assembler, std::vector<ProcessVariable> const& variables, std::vector<std::unique_ptr<ParameterBase>> const& parameters, unsigned const integration_order, BaseLib::ConfigTree const& config); template std::unique_ptr<Process> createThermoMechanicsProcess<3>( MeshLib::Mesh& mesh, std::unique_ptr<ProcessLib::AbstractJacobianAssembler>&& jacobian_assembler, std::vector<ProcessVariable> const& variables, std::vector<std::unique_ptr<ParameterBase>> const& parameters, unsigned const integration_order, BaseLib::ConfigTree const& config); } // namespace ThermoMechanics } // namespace ProcessLib