OGS
CreateHMPhaseFieldProcess.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
15#include "ParameterLib/Utils.h"
18
19namespace ProcessLib
20{
21namespace HMPhaseField
22{
24 std::map<int, std::shared_ptr<MaterialPropertyLib::Medium>> const& media)
25{
26 std::array const requiredMediumProperties = {
29 std::array const requiredFluidProperties = {MaterialPropertyLib::viscosity,
31 std::array const requiredSolidProperties = {
33
34 for (auto const& m : media)
35 {
36 checkRequiredProperties(*m.second, requiredMediumProperties);
37 checkRequiredProperties(
39 requiredFluidProperties);
40 checkRequiredProperties(
42 requiredSolidProperties);
43 }
44}
45
46template <int DisplacementDim>
47std::unique_ptr<Process> createHMPhaseFieldProcess(
48 std::string name, MeshLib::Mesh& mesh,
49 std::unique_ptr<ProcessLib::AbstractJacobianAssembler>&& jacobian_assembler,
50 std::vector<ProcessVariable> const& variables,
51 std::vector<std::unique_ptr<ParameterLib::ParameterBase>> const& parameters,
52 std::optional<ParameterLib::CoordinateSystem> const&
53 local_coordinate_system,
54 unsigned const integration_order, BaseLib::ConfigTree const& config,
55 std::map<int, std::shared_ptr<MaterialPropertyLib::Medium>> const& media)
56{
58 config.checkConfigParameter("type", "HM_PHASE_FIELD");
59 DBUG("Create HMPhaseFieldProcess.");
60
61 auto const coupling_scheme =
63 config.getConfigParameter<std::string>("coupling_scheme", "staggered");
64 const bool use_monolithic_scheme = (coupling_scheme != "staggered");
65
67 auto const pv_config = config.getConfigSubtree("process_variables");
68
69 ProcessVariable* variable_ph;
70 ProcessVariable* variable_p;
71 ProcessVariable* variable_u;
72 std::vector<std::vector<std::reference_wrapper<ProcessVariable>>>
73 process_variables;
74 if (use_monolithic_scheme) // monolithic scheme.
75 {
76 OGS_FATAL("Monolithic implementation is not available.");
77 }
78 else // staggered scheme.
79 {
80 using namespace std::string_literals;
81 for (
84 auto const& variable_name :
85 {
86 "phasefield"s,
88 "pressure"s,
90 "displacement"s})
91 {
92 auto per_process_variables =
93 findProcessVariables(variables, pv_config, {variable_name});
94 process_variables.push_back(std::move(per_process_variables));
95 }
96 variable_ph = &process_variables[0][0].get();
97 variable_p = &process_variables[1][0].get();
98 variable_u = &process_variables[2][0].get();
99 }
100
101 DBUG("Associate phase field with process variable '{}'.",
102 variable_ph->getName());
103 if (variable_ph->getNumberOfGlobalComponents() != 1)
104 {
105 OGS_FATAL(
106 "HMPhasefield process variable '{}' is not a scalar variable but "
107 "has {:d} components.",
108 variable_ph->getName(),
109 variable_ph->getNumberOfGlobalComponents());
110 }
111
112 DBUG("Associate pressure with process variable '{}'.",
113 variable_p->getName());
114 if (variable_p->getNumberOfGlobalComponents() != 1)
115 {
116 OGS_FATAL(
117 "HMPhasefield process variable '{}' is not a scalar variable but "
118 "has {:d} components.",
119 variable_p->getName(),
120 variable_p->getNumberOfGlobalComponents());
121 }
122
123 DBUG("Associate displacement with process variable '{}'.",
124 variable_u->getName());
125
126 if (variable_u->getNumberOfGlobalComponents() != DisplacementDim)
127 {
128 OGS_FATAL(
129 "The component number of the process variable '{}' is different "
130 "from the displacement dimension: got {:d}, expected {:d}",
131 variable_u->getName(),
132 variable_u->getNumberOfGlobalComponents(),
133 DisplacementDim);
134 }
135
137 auto solid_constitutive_relations =
139 parameters, local_coordinate_system, materialIDs(mesh), config);
140
141 auto const phasefield_parameters_config =
143 config.getConfigSubtree("phasefield_parameters");
144
145 // Residual stiffness
146 auto const& residual_stiffness = ParameterLib::findParameter<double>(
147 phasefield_parameters_config,
149 "residual_stiffness", parameters, 1);
150 DBUG("Use '{}' as residual stiffness.", residual_stiffness.name);
151
152 // Crack resistance
153 auto const& crack_resistance = ParameterLib::findParameter<double>(
154 phasefield_parameters_config,
156 "crack_resistance", parameters, 1);
157 DBUG("Use '{}' as crack resistance.", crack_resistance.name);
158
159 // Crack length scale
160 auto const& crack_length_scale = ParameterLib::findParameter<double>(
161 phasefield_parameters_config,
163 "crack_length_scale", parameters, 1);
164 DBUG("Use '{}' as crack length scale.", crack_length_scale.name);
165
166 // Characteristic_length
167 auto const characteristic_length =
169 config.getConfigParameter<double>("characteristic_length", 1.0);
170
171 // Fluid compression modulus. Default value is 0.0.
172 auto const fluid_compressibility =
174 config.getConfigParameter<double>("fluid_compressibility", 0.0);
175
176 // Specific body force
177 Eigen::Matrix<double, DisplacementDim, 1> specific_body_force;
178 {
179 std::vector<double> const b =
181 config.getConfigParameter<std::vector<double>>(
182 "specific_body_force");
183 if (b.size() != DisplacementDim)
184 {
185 OGS_FATAL(
186 "The size of the specific body force vector does not match the "
187 "displacement dimension. Vector size is {:d}, displacement "
188 "dimension is {:d}",
189 b.size(), DisplacementDim);
190 }
191
192 std::copy_n(b.data(), b.size(), specific_body_force.data());
193 }
194
195 // Specific fracture direction
196 Eigen::Vector<double, DisplacementDim> specific_fracture_direction;
197 {
198 std::vector<double> const fracture_normal =
200 config.getConfigParameter<std::vector<double>>(
201 "specific_fracture_direction");
202 if (fracture_normal.size() != DisplacementDim)
203 {
204 OGS_FATAL(
205 "The size of the specific fracture direction vector does not "
206 "match the displacement dimension. Vector size is {:d}, "
207 "displacement dimension is {:d}",
208 fracture_normal.size(), DisplacementDim);
209 }
210
211 std::copy_n(fracture_normal.data(), fracture_normal.size(),
212 specific_fracture_direction.data());
213 }
214
215 auto const irreversible_threshold =
217 config.getConfigParameter<double>("irreversible_threshold", 0.05);
218
219 auto const phasefield_model_string =
221 config.getConfigParameter<std::string>("phasefield_model");
222 auto const phasefield_model =
224 DisplacementDim>(phasefield_model_string);
225
226 auto const softening_curve_string =
228 config.getConfigParameterOptional<std::string>("softening_curve");
229 auto const softening_curve =
231 DisplacementDim>(softening_curve_string);
232
233 auto const energy_split_model_string =
235 config.getConfigParameter<std::string>("energy_split_model");
236 auto const energy_split_model =
238 DisplacementDim>(energy_split_model_string);
239
240 auto degradation_derivative = creatDegradationDerivative<DisplacementDim>(
241 phasefield_model, characteristic_length, softening_curve);
242
243 auto const diffused_range_parameter =
245 config.getConfigParameter<double>("diffused_range_parameter", 2.0);
246
247 auto const fracture_threshold =
249 config.getConfigParameter<double>("fracture_threshold", 1.0);
250
251 auto const fracture_permeability_parameter =
253 config.getConfigParameter<double>("fracture_permeability_parameter",
254 0.0);
255
256 // Default value is 0.5, which is recommended by [Mikelic & Wheeler].
257 double const fixed_stress_stabilization_parameter =
259 config.getConfigParameter<double>(
260 "fixed_stress_stabilization_parameter", 0.5);
261
262 DBUG("Using value {:g} for coupling parameter of staggered scheme.",
263 fixed_stress_stabilization_parameter);
264
265 auto spatial_stabilization_parameter_optional =
267 config.getConfigParameterOptional<double>(
268 "spatial_stabilization_parameter");
269 double const spatial_stabilization_parameter =
270 spatial_stabilization_parameter_optional
271 ? spatial_stabilization_parameter_optional.value()
272 : 0.0;
273 DBUG("Using value {} for spatial stabilization coupling parameter.",
274 spatial_stabilization_parameter);
275
276 // Initial width
277 auto const& width_init = ParameterLib::findParameter<double>(
278 config,
280 "width_init", parameters, 0.0);
281 DBUG("Use '{}' as initial width.", width_init.name);
282
283 auto media_map =
285 DBUG("Check the media properties of HMPhaseField process ...");
286 checkMPLProperties(media);
287 DBUG("Media properties verified.");
288
290 materialIDs(mesh),
291 std::move(media_map),
292 std::move(solid_constitutive_relations),
293 residual_stiffness,
294 crack_resistance,
295 crack_length_scale,
296 specific_body_force,
297 specific_fracture_direction,
298 irreversible_threshold,
299 phasefield_model,
300 energy_split_model,
301 softening_curve,
302 characteristic_length,
303 std::move(degradation_derivative),
304 diffused_range_parameter,
305 fluid_compressibility,
306 fracture_threshold,
307 fracture_permeability_parameter,
308 fixed_stress_stabilization_parameter,
309 spatial_stabilization_parameter,
310 width_init};
311
312 SecondaryVariableCollection secondary_variables;
313
314 ProcessLib::createSecondaryVariables(config, secondary_variables);
315
316 return std::make_unique<HMPhaseFieldProcess<DisplacementDim>>(
317 std::move(name), mesh, std::move(jacobian_assembler), parameters,
318 integration_order, std::move(process_variables),
319 std::move(process_data), std::move(secondary_variables),
320 use_monolithic_scheme);
321}
322
323template std::unique_ptr<Process> createHMPhaseFieldProcess<2>(
324 std::string name, MeshLib::Mesh& mesh,
325 std::unique_ptr<ProcessLib::AbstractJacobianAssembler>&& jacobian_assembler,
326 std::vector<ProcessVariable> const& variables,
327 std::vector<std::unique_ptr<ParameterLib::ParameterBase>> const& parameters,
328 std::optional<ParameterLib::CoordinateSystem> const&
329 local_coordinate_system,
330 unsigned const integration_order, BaseLib::ConfigTree const& config,
331 std::map<int, std::shared_ptr<MaterialPropertyLib::Medium>> const& media);
332
333template std::unique_ptr<Process> createHMPhaseFieldProcess<3>(
334 std::string name, MeshLib::Mesh& mesh,
335 std::unique_ptr<ProcessLib::AbstractJacobianAssembler>&& jacobian_assembler,
336 std::vector<ProcessVariable> const& variables,
337 std::vector<std::unique_ptr<ParameterLib::ParameterBase>> const& parameters,
338 std::optional<ParameterLib::CoordinateSystem> const&
339 local_coordinate_system,
340 unsigned const integration_order, BaseLib::ConfigTree const& config,
341 std::map<int, std::shared_ptr<MaterialPropertyLib::Medium>> const& media);
342
343} // namespace HMPhaseField
344} // namespace ProcessLib
#define OGS_FATAL(...)
Definition Error.h:19
void DBUG(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:22
std::optional< T > getConfigParameterOptional(std::string const &param) 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
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.
PhaseFieldModel convertStringToPhaseFieldModel(std::string const &phasefield_model)
SofteningCurve convertStringToSofteningCurve(std::optional< std::string > const &softening_curve)
EnergySplitModel convertStringToEnergySplitModel(std::string const &energy_split_model)
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)
MaterialSpatialDistributionMap createMaterialSpatialDistributionMap(std::map< int, std::shared_ptr< Medium > > const &media, MeshLib::Mesh const &mesh)
OGS_NO_DANGLING Parameter< ParameterDataType > & findParameter(std::string const &parameter_name, std::vector< std::unique_ptr< ParameterBase > > const &parameters, int const num_components, MeshLib::Mesh const *const mesh=nullptr)
template std::unique_ptr< Process > createHMPhaseFieldProcess< 3 >(std::string 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)
void checkMPLProperties(std::map< int, std::shared_ptr< MaterialPropertyLib::Medium > > const &media)
template std::unique_ptr< Process > createHMPhaseFieldProcess< 2 >(std::string 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::unique_ptr< Process > createHMPhaseFieldProcess(std::string 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)