OGS
CreatePhaseFieldProcess.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
10#include "ParameterLib/Utils.h"
11#include "PhaseFieldProcess.h"
16
17namespace ProcessLib
18{
19namespace PhaseField
20{
21template <int DisplacementDim>
22std::unique_ptr<Process> createPhaseFieldProcess(
23 std::string const& name,
24 MeshLib::Mesh& mesh,
25 std::unique_ptr<ProcessLib::AbstractJacobianAssembler>&& jacobian_assembler,
26 std::vector<ProcessVariable> const& variables,
27 std::vector<std::unique_ptr<ParameterLib::ParameterBase>> const& parameters,
28 std::optional<ParameterLib::CoordinateSystem> const&
29 local_coordinate_system,
30 unsigned const integration_order,
31 BaseLib::ConfigTree const& config)
32{
34 config.checkConfigParameter("type", "PHASE_FIELD");
35 DBUG("Create PhaseFieldProcess.");
36
37 auto const coupling_scheme =
39 config.getConfigParameterOptional<std::string>("coupling_scheme");
40 const bool use_monolithic_scheme =
41 !(coupling_scheme && (*coupling_scheme == "staggered"));
42
44
46 auto const pv_config = config.getConfigSubtree("process_variables");
47
48 ProcessVariable* variable_ph;
49 ProcessVariable* variable_u;
50 std::vector<std::vector<std::reference_wrapper<ProcessVariable>>>
51 process_variables;
52 if (use_monolithic_scheme) // monolithic scheme.
53 {
54 OGS_FATAL("Monolithic implementation is not available.");
55 }
56 else // staggered scheme.
57 {
58 using namespace std::string_literals;
59 for (
62 auto const& variable_name :
63 {
64 "displacement"s,
66 "phasefield"s})
67 {
68 auto per_process_variables =
69 findProcessVariables(variables, pv_config, {variable_name});
70 process_variables.push_back(std::move(per_process_variables));
71 }
72 variable_u = &process_variables[0][0].get();
73 variable_ph = &process_variables[1][0].get();
74 }
75
76 DBUG("Associate displacement with process variable '{:s}'.",
77 variable_u->getName());
78
79 if (variable_u->getNumberOfGlobalComponents() != DisplacementDim)
80 {
82 "Number of components of the process variable '{:s}' is different "
83 "from the displacement dimension: got {:d}, expected {:d}",
84 variable_u->getName(),
85 variable_u->getNumberOfGlobalComponents(),
86 DisplacementDim);
87 }
88
89 DBUG("Associate phase field with process variable '{:s}'.",
90 variable_ph->getName());
91 if (variable_ph->getNumberOfGlobalComponents() != 1)
92 {
94 "Phasefield process variable '{:s}' is not a scalar variable but "
95 "has {:d} components.",
96 variable_ph->getName(),
97 variable_ph->getNumberOfGlobalComponents());
98 }
100 auto solid_constitutive_relations =
102 parameters, local_coordinate_system, materialIDs(mesh), config);
103
104 auto const phasefield_parameters_config =
106 config.getConfigSubtree("phasefield_parameters");
107
108 // Residual stiffness
109 auto const& residual_stiffness = ParameterLib::findParameter<double>(
110 phasefield_parameters_config,
112 "residual_stiffness", parameters, 1);
113 DBUG("Use '{:s}' as residual stiffness.", residual_stiffness.name);
114
115 // Crack resistance
116 auto const& crack_resistance = ParameterLib::findParameter<double>(
117 phasefield_parameters_config,
119 "crack_resistance", parameters, 1);
120 DBUG("Use '{:s}' as crack resistance.", crack_resistance.name);
121
122 // Crack length scale
123 auto const& crack_length_scale = ParameterLib::findParameter<double>(
124 phasefield_parameters_config,
126 "crack_length_scale", parameters, 1);
127 DBUG("Use '{:s}' as crack length scale.", crack_length_scale.name);
128
129 // Characteristic_length
130 auto const characteristic_length =
132 config.getConfigParameter<double>("characteristic_length", 1.0);
133
134 // Solid density
135 auto const& solid_density = ParameterLib::findParameter<double>(
136 config,
138 "solid_density", parameters, 1);
139 DBUG("Use '{:s}' as solid density parameter.", solid_density.name);
140
141 // Specific body force
142 Eigen::Matrix<double, DisplacementDim, 1> specific_body_force;
143 {
144 std::vector<double> const b =
146 config.getConfigParameter<std::vector<double>>(
147 "specific_body_force");
148 if (b.size() != DisplacementDim)
149 {
150 OGS_FATAL(
151 "The size of the specific body force vector does not match the "
152 "displacement dimension. Vector size is {:d}, displacement "
153 "dimension is {:d}",
154 b.size(), DisplacementDim);
155 }
156
157 std::copy_n(b.data(), b.size(), specific_body_force.data());
158 }
159
160 auto const crack_scheme =
162 config.getConfigParameterOptional<std::string>(
163 "pressurized_crack_scheme");
164 if (crack_scheme &&
165 ((*crack_scheme != "propagating") && (*crack_scheme != "static")))
166 {
167 OGS_FATAL(
168 "crack_scheme must be 'propagating' or 'static' but '{:s}' "
169 "was given",
170 crack_scheme->c_str());
171 }
172
173 const bool pressurized_crack = crack_scheme.has_value();
174 const bool propagating_pressurized_crack =
175 (crack_scheme && (*crack_scheme == "propagating"));
176 const bool static_pressurized_crack =
177 (crack_scheme && (*crack_scheme == "static"));
178
179 auto const irreversible_threshold =
181 config.getConfigParameter<double>("irreversible_threshold", 0.05);
182
183 auto const phasefield_model_string =
185 config.getConfigParameter<std::string>("phasefield_model");
186 auto const phasefield_model =
188 DisplacementDim>(phasefield_model_string);
189
190 // Initial stress conditions
192 config, parameters, mesh);
193
194 auto const softening_curve_string =
196 config.getConfigParameterOptional<std::string>("softening_curve");
197 auto const softening_curve =
199 DisplacementDim>(softening_curve_string);
200
201 auto const energy_split_model_string =
203 config.getConfigParameter<std::string>("energy_split_model");
204 auto const energy_split_model =
206 DisplacementDim>(energy_split_model_string);
207
208 auto degradation_derivative = creatDegradationDerivative<DisplacementDim>(
209 phasefield_model, characteristic_length, softening_curve);
210
212 materialIDs(mesh),
213 std::move(solid_constitutive_relations),
214 residual_stiffness,
215 crack_resistance,
216 crack_length_scale,
217 solid_density,
218 initial_stress,
219 specific_body_force,
220 pressurized_crack,
221 propagating_pressurized_crack,
222 static_pressurized_crack,
223 irreversible_threshold,
224 phasefield_model,
225 energy_split_model,
226 softening_curve,
227 characteristic_length,
228 std::move(degradation_derivative)};
229
230 SecondaryVariableCollection secondary_variables;
231
232 ProcessLib::createSecondaryVariables(config, secondary_variables);
233
234 return std::make_unique<PhaseFieldProcess<DisplacementDim>>(
235 std::move(name), mesh, std::move(jacobian_assembler), parameters,
236 integration_order, std::move(process_variables),
237 std::move(process_data), std::move(secondary_variables),
238 use_monolithic_scheme);
239}
240
241template std::unique_ptr<Process> createPhaseFieldProcess<2>(
242 std::string const& name,
243 MeshLib::Mesh& mesh,
244 std::unique_ptr<ProcessLib::AbstractJacobianAssembler>&& jacobian_assembler,
245 std::vector<ProcessVariable> const& variables,
246 std::vector<std::unique_ptr<ParameterLib::ParameterBase>> const& parameters,
247 std::optional<ParameterLib::CoordinateSystem> const&
248 local_coordinate_system,
249 unsigned const integration_order,
250 BaseLib::ConfigTree const& config);
251
252template std::unique_ptr<Process> createPhaseFieldProcess<3>(
253 std::string const& name,
254 MeshLib::Mesh& mesh,
255 std::unique_ptr<ProcessLib::AbstractJacobianAssembler>&& jacobian_assembler,
256 std::vector<ProcessVariable> const& variables,
257 std::vector<std::unique_ptr<ParameterLib::ParameterBase>> const& parameters,
258 std::optional<ParameterLib::CoordinateSystem> const&
259 local_coordinate_system,
260 unsigned const integration_order,
261 BaseLib::ConfigTree const& config);
262
263} // namespace PhaseField
264} // 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)
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)
std::unique_ptr< Process > createPhaseFieldProcess(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)
template std::unique_ptr< Process > createPhaseFieldProcess< 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)
template std::unique_ptr< Process > createPhaseFieldProcess< 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::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)