OGS
HydroMechanics/CreateHydroMechanicsProcess.cpp
Go to the documentation of this file.
1// SPDX-FileCopyrightText: Copyright (c) OpenGeoSys Community (opengeosys.org)
2// SPDX-License-Identifier: BSD-3-Clause
3
5
6#include <cassert>
7#include <range/v3/range.hpp>
8#include <string>
9
19#include "ParameterLib/Utils.h"
23
24namespace ProcessLib
25{
27{
28
30 std::optional<BaseLib::ConfigTree> const& config)
31{
32 if (!config)
33 {
34 return Monolithic{};
35 }
36
37 auto const coupling_scheme_type =
39 config->getConfigParameter<std::string>("type");
40
41 if (coupling_scheme_type == "monolithic")
42 {
43 return Monolithic{};
44 }
45
46 // Default value is 0.5, which is recommended by [Mikelic & Wheeler].
47 double const fixed_stress_stabilization_parameter =
49 config->getConfigParameter<double>(
50 "fixed_stress_stabilization_parameter", 0.5);
51
52 DBUG("Using value {:g} for coupling parameter of staggered scheme.",
53 fixed_stress_stabilization_parameter);
54
55 { // Check parameter value. Optimum is not a-priori known, but within
56 // certain interval [Storvik & Nordbotten]
57 double const csp_min = 1.0 / 6.0;
58 double const csp_max = 1.0;
59 if (fixed_stress_stabilization_parameter < csp_min ||
60 fixed_stress_stabilization_parameter > csp_max)
61 {
62 WARN(
63 "Value of coupling scheme parameter = {:g} is out of "
64 "reasonable range ({:g}, {:g}).",
65 fixed_stress_stabilization_parameter, csp_min, csp_max);
66 }
67 }
68
69 bool const fixed_stress_over_time_step =
71 config->getConfigParameter<std::string>("fixed_stress_over_time_step",
72 "false") == "true";
73
74 return Staggered{fixed_stress_stabilization_parameter,
75 fixed_stress_over_time_step};
76}
77
78template <int DisplacementDim>
79std::unique_ptr<Process> createHydroMechanicsProcess(
80 std::string const& name, MeshLib::Mesh& mesh,
81 std::unique_ptr<ProcessLib::AbstractJacobianAssembler>&& jacobian_assembler,
82 std::vector<ProcessVariable> const& variables,
83 std::vector<std::unique_ptr<ParameterLib::ParameterBase>> const& parameters,
84 std::optional<ParameterLib::CoordinateSystem> const&
85 local_coordinate_system,
86 unsigned const integration_order, BaseLib::ConfigTree const& config,
87 std::map<int, std::shared_ptr<MaterialPropertyLib::Medium>> const& media)
88{
90 config.checkConfigParameter("type", "HYDRO_MECHANICS");
91 DBUG("Create HydroMechanicsProcess.");
92
93 if (DisplacementDim == 2)
94 {
95 if (mesh.isAxiallySymmetric() &&
97 {
99 "Mesh {:s} is on a plane rotated around the vertical axis. The "
100 "axisymmetric problem can not use such mesh.",
101 mesh.getName());
102 }
103 }
104
105 auto const coupling_scheme = parseCouplingScheme(
107 config.getConfigSubtreeOptional("coupling_scheme"));
108
110
112 auto const pv_config = config.getConfigSubtree("process_variables");
113
114 ProcessVariable* variable_p = nullptr;
115 ProcessVariable* variable_u = nullptr;
116 std::vector<std::vector<std::reference_wrapper<ProcessVariable>>>
117 process_variables;
118
119 int const hydraulic_process_id = 0;
120 int mechanics_related_process_id = 0;
121
122 if (std::holds_alternative<Monolithic>(coupling_scheme))
123 {
126 auto per_process_variables = findProcessVariables(
127 variables, pv_config,
128 {
129 "pressure",
131 "displacement"});
132 variable_p = &per_process_variables[0].get();
133 variable_u = &per_process_variables[1].get();
134 process_variables.push_back(std::move(per_process_variables));
135 }
136
137 if (std::holds_alternative<Staggered>(coupling_scheme))
138 {
139 using namespace std::string_literals;
140 for (auto const& variable_name : {"pressure"s, "displacement"s})
141 {
142 auto per_process_variables =
143 findProcessVariables(variables, pv_config, {variable_name});
144 process_variables.push_back(std::move(per_process_variables));
145 }
146 mechanics_related_process_id = 1;
147 variable_p = &process_variables[hydraulic_process_id][0].get();
148 variable_u = &process_variables[mechanics_related_process_id][0].get();
149 }
150
151 DBUG("Associate displacement with process variable '{:s}'.",
152 variable_u->getName());
153
154 if (variable_u->getNumberOfGlobalComponents() != DisplacementDim)
155 {
156 OGS_FATAL(
157 "Number of components of the process variable '{:s}' is different "
158 "from the displacement dimension: got {:d}, expected {:d}",
159 variable_u->getName(),
160 variable_u->getNumberOfGlobalComponents(),
161 DisplacementDim);
162 }
163
164 DBUG("Associate pressure with process variable '{:s}'.",
165 variable_p->getName());
166 if (variable_p->getNumberOfGlobalComponents() != 1)
167 {
168 OGS_FATAL(
169 "Pressure process variable '{:s}' is not a scalar variable but has "
170 "{:d} components.",
171 variable_p->getName(),
172 variable_p->getNumberOfGlobalComponents());
173 }
174
175 auto solid_constitutive_relations =
177 parameters, local_coordinate_system, materialIDs(mesh), config);
178
180 // Specific body force
181 Eigen::Matrix<double, DisplacementDim, 1> specific_body_force;
182 {
183 std::vector<double> const b =
185 config.getConfigParameter<std::vector<double>>(
186 "specific_body_force");
187 if (b.size() != DisplacementDim)
188 {
189 OGS_FATAL(
190 "The size of the specific body force vector does not match the "
191 "displacement dimension. Vector size is {:d}, displacement "
192 "dimension is {:d}",
193 b.size(), DisplacementDim);
194 }
195
196 std::copy_n(b.data(), b.size(), specific_body_force.data());
197 }
198
200 auto mass_lumping = config.getConfigParameter<bool>("mass_lumping", false);
201
202 auto const is_linear =
204 config.getConfigParameter("linear", false);
205
206 auto media_map =
208
209 std::array const requiredMediumProperties = {
213 std::array const requiredFluidProperties = {MaterialPropertyLib::viscosity,
215 std::array const requiredSolidProperties = {MaterialPropertyLib::density};
216
218
219 // The uniqueness of phase has already been checked in
220 // `checkMPLPhasesForSinglePhaseFlow`.
221 MaterialPropertyLib::Variable const phase_variable =
222 (*ranges::begin(media_map.media()))->hasPhase("Gas")
225 for (auto const& medium : media_map.media())
226 {
227 checkRequiredProperties(*medium, requiredMediumProperties);
228 checkRequiredProperties(fluidPhase(*medium), requiredFluidProperties);
229 checkRequiredProperties(medium->phase("Solid"),
230 requiredSolidProperties);
231 }
232 DBUG("Media properties verified.");
233
234 // Initial stress conditions
236 config, parameters, mesh);
237
238 const bool use_taylor_hood_elements = variable_p->getShapeFunctionOrder() !=
239 variable_u->getShapeFunctionOrder();
240
242 materialIDs(mesh),
243 std::move(media_map),
244 std::move(solid_constitutive_relations),
245 initial_stress,
246 specific_body_force,
247 mass_lumping,
248 coupling_scheme,
249 hydraulic_process_id,
250 mechanics_related_process_id,
251 use_taylor_hood_elements,
252 phase_variable};
253
254 SecondaryVariableCollection secondary_variables;
255
256 ProcessLib::createSecondaryVariables(config, secondary_variables);
257
258 return std::make_unique<HydroMechanicsProcess<DisplacementDim>>(
259 std::move(name), mesh, std::move(jacobian_assembler), parameters,
260 integration_order, std::move(process_variables),
261 std::move(process_data), std::move(secondary_variables),
262 std::holds_alternative<Monolithic>(coupling_scheme), is_linear);
263}
264
265template std::unique_ptr<Process> createHydroMechanicsProcess<2>(
266 std::string const& name,
267 MeshLib::Mesh& mesh,
268 std::unique_ptr<ProcessLib::AbstractJacobianAssembler>&& jacobian_assembler,
269 std::vector<ProcessVariable> const& variables,
270 std::vector<std::unique_ptr<ParameterLib::ParameterBase>> const& parameters,
271 std::optional<ParameterLib::CoordinateSystem> const&
272 local_coordinate_system,
273 unsigned const integration_order,
274 BaseLib::ConfigTree const& config,
275 std::map<int, std::shared_ptr<MaterialPropertyLib::Medium>> const& media);
276
277template std::unique_ptr<Process> createHydroMechanicsProcess<3>(
278 std::string const& name,
279 MeshLib::Mesh& mesh,
280 std::unique_ptr<ProcessLib::AbstractJacobianAssembler>&& jacobian_assembler,
281 std::vector<ProcessVariable> const& variables,
282 std::vector<std::unique_ptr<ParameterLib::ParameterBase>> const& parameters,
283 std::optional<ParameterLib::CoordinateSystem> const&
284 local_coordinate_system,
285 unsigned const integration_order,
286 BaseLib::ConfigTree const& config,
287 std::map<int, std::shared_ptr<MaterialPropertyLib::Medium>> const& media);
288
289} // namespace HydroMechanics
290} // namespace ProcessLib
#define OGS_FATAL(...)
Definition Error.h:19
void DBUG(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:22
void WARN(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:34
std::optional< ConfigTree > getConfigSubtreeOptional(std::string const &root) const
T getConfigParameter(std::string const &param) const
ConfigTree getConfigSubtree(std::string const &root) const
void checkConfigParameter(std::string const &param, std::string_view const value) const
bool isAxiallySymmetric() const
Definition Mesh.h:128
const std::string getName() const
Get name of the mesh.
Definition Mesh.h:94
unsigned getShapeFunctionOrder() const
std::string const & getName() const
int getNumberOfGlobalComponents() const
Returns the number of components of the process variable.
Handles configuration of several secondary variables from the project file.
std::map< int, std::shared_ptr< MaterialLib::Solids::MechanicsBase< DisplacementDim > > > createConstitutiveRelations(std::vector< std::unique_ptr< ParameterLib::ParameterBase > > const &parameters, std::optional< ParameterLib::CoordinateSystem > const &local_coordinate_system, MeshLib::PropertyVector< int > const *const material_ids, BaseLib::ConfigTree const &config)
void checkMPLPhasesForSinglePhaseFlow(MeshLib::Mesh const &mesh, MaterialPropertyLib::MaterialSpatialDistributionMap const &media_map)
MaterialSpatialDistributionMap createMaterialSpatialDistributionMap(std::map< int, std::shared_ptr< Medium > > const &media, MeshLib::Mesh const &mesh)
bool is2DMeshOnRotatedVerticalPlane(Mesh const &mesh)
std::unique_ptr< Process > createHydroMechanicsProcess(std::string const &name, MeshLib::Mesh &mesh, std::unique_ptr< ProcessLib::AbstractJacobianAssembler > &&jacobian_assembler, std::vector< ProcessVariable > const &variables, std::vector< std::unique_ptr< ParameterLib::ParameterBase > > const &parameters, std::optional< ParameterLib::CoordinateSystem > const &local_coordinate_system, unsigned const integration_order, BaseLib::ConfigTree const &config, std::map< int, std::shared_ptr< MaterialPropertyLib::Medium > > const &media)
CouplingScheme parseCouplingScheme(std::optional< BaseLib::ConfigTree > const &config)
std::variant< Monolithic, Staggered > CouplingScheme
template std::unique_ptr< Process > createHydroMechanicsProcess< 2 >(std::string const &name, MeshLib::Mesh &mesh, std::unique_ptr< ProcessLib::AbstractJacobianAssembler > &&jacobian_assembler, std::vector< ProcessVariable > const &variables, std::vector< std::unique_ptr< ParameterLib::ParameterBase > > const &parameters, std::optional< ParameterLib::CoordinateSystem > const &local_coordinate_system, unsigned const integration_order, BaseLib::ConfigTree const &config, std::map< int, std::shared_ptr< MaterialPropertyLib::Medium > > const &media)
template std::unique_ptr< Process > createHydroMechanicsProcess< 3 >(std::string const &name, MeshLib::Mesh &mesh, std::unique_ptr< ProcessLib::AbstractJacobianAssembler > &&jacobian_assembler, std::vector< ProcessVariable > const &variables, std::vector< std::unique_ptr< ParameterLib::ParameterBase > > const &parameters, std::optional< ParameterLib::CoordinateSystem > const &local_coordinate_system, unsigned const integration_order, BaseLib::ConfigTree const &config, std::map< int, std::shared_ptr< MaterialPropertyLib::Medium > > const &media)
std::vector< std::reference_wrapper< ProcessVariable > > findProcessVariables(std::vector< ProcessVariable > const &variables, BaseLib::ConfigTree const &pv_config, std::initializer_list< std::string > tags)
InitialStress createInitialStress(BaseLib::ConfigTree const &config, std::vector< std::unique_ptr< ParameterLib::ParameterBase > > const &parameters, MeshLib::Mesh const &mesh, bool const mandatory_stress_type)
void createSecondaryVariables(BaseLib::ConfigTree const &config, SecondaryVariableCollection &secondary_variables)