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