39{
41 config.checkConfigParameter("type", "PHASE_FIELD");
42 DBUG(
"Create PhaseFieldProcess.");
43
44 auto const coupling_scheme =
46 config.getConfigParameterOptional<std::string>("coupling_scheme");
47 const bool use_monolithic_scheme =
48 !(coupling_scheme && (*coupling_scheme == "staggered"));
49
51
53 auto const pv_config = config.getConfigSubtree("process_variables");
54
57 std::vector<std::vector<std::reference_wrapper<ProcessVariable>>>
58 process_variables;
59 if (use_monolithic_scheme)
60 {
61 OGS_FATAL(
"Monolithic implementation is not available.");
62 }
63 else
64 {
65 using namespace std::string_literals;
66 for (
69 auto const& variable_name :
70 {
71 "displacement"s,
73 "phasefield"s})
74 {
75 auto per_process_variables =
76 findProcessVariables(variables, pv_config, {variable_name});
77 process_variables.push_back(std::move(per_process_variables));
78 }
79 variable_u = &process_variables[0][0].get();
80 variable_ph = &process_variables[1][0].get();
81 }
82
83 DBUG(
"Associate displacement with process variable '{:s}'.",
85
87 {
89 "Number of components of the process variable '{:s}' is different "
90 "from the displacement dimension: got {:d}, expected {:d}",
93 DisplacementDim);
94 }
95
96 DBUG(
"Associate phase field with process variable '{:s}'.",
99 {
101 "Phasefield process variable '{:s}' is not a scalar variable but "
102 "has {:d} components.",
105 }
107 auto solid_constitutive_relations =
109 parameters, local_coordinate_system,
materialIDs(mesh), config);
110
111 auto const phasefield_parameters_config =
113 config.getConfigSubtree("phasefield_parameters");
114
115
117 phasefield_parameters_config,
119 "residual_stiffness", parameters, 1);
120 DBUG(
"Use '{:s}' as residual stiffness.", residual_stiffness.name);
121
122
124 phasefield_parameters_config,
126 "crack_resistance", parameters, 1);
127 DBUG(
"Use '{:s}' as crack resistance.", crack_resistance.name);
128
129
131 phasefield_parameters_config,
133 "crack_length_scale", parameters, 1);
134 DBUG(
"Use '{:s}' as crack length scale.", crack_length_scale.name);
135
136
137 auto const characteristic_length =
139 config.getConfigParameter<double>("characteristic_length", 1.0);
140
141
143 config,
145 "solid_density", parameters, 1);
146 DBUG(
"Use '{:s}' as solid density parameter.", solid_density.name);
147
148
149 Eigen::Matrix<double, DisplacementDim, 1> specific_body_force;
150 {
151 std::vector<double> const b =
153 config.getConfigParameter<std::vector<double>>(
154 "specific_body_force");
155 if (b.size() != DisplacementDim)
156 {
158 "The size of the specific body force vector does not match the "
159 "displacement dimension. Vector size is {:d}, displacement "
160 "dimension is {:d}",
161 b.size(), DisplacementDim);
162 }
163
164 std::copy_n(b.data(), b.size(), specific_body_force.data());
165 }
166
167 auto const crack_scheme =
169 config.getConfigParameterOptional<std::string>(
170 "pressurized_crack_scheme");
171 if (crack_scheme &&
172 ((*crack_scheme != "propagating") && (*crack_scheme != "static")))
173 {
175 "crack_scheme must be 'propagating' or 'static' but '{:s}' "
176 "was given",
177 crack_scheme->c_str());
178 }
179
180 const bool pressurized_crack = crack_scheme.has_value();
181 const bool propagating_pressurized_crack =
182 (crack_scheme && (*crack_scheme == "propagating"));
183 const bool static_pressurized_crack =
184 (crack_scheme && (*crack_scheme == "static"));
185
186 auto const irreversible_threshold =
188 config.getConfigParameter<double>("irreversible_threshold", 0.05);
189
190 auto const phasefield_model = [&]
191 {
192 auto const phasefield_model_string =
194 config.getConfigParameter<std::string>("phasefield_model");
195
196 if (phasefield_model_string == "AT1")
197 {
198 return PhaseFieldModel::AT1;
199 }
200 if (phasefield_model_string == "AT2")
201 {
202 return PhaseFieldModel::AT2;
203 }
204 if (phasefield_model_string == "COHESIVE")
205 {
206 return PhaseFieldModel::COHESIVE;
207 }
209 "phasefield_model must be 'AT1', 'AT2' or 'COHESIVE' but '{:s}' "
210 "was given",
211 phasefield_model_string.c_str());
212 }();
213
214
216 config, parameters, mesh);
217
218 auto const softening_curve = [&]
219 {
220 auto const softening_curve_string =
222 config.getConfigParameterOptional<std::string>("softening_curve");
223 if (softening_curve_string)
224 {
225 if (*softening_curve_string == "Linear")
226 {
227 return SofteningCurve::Linear;
228 }
229 if (*softening_curve_string == "Exponential")
230 {
231 return SofteningCurve::Exponential;
232 }
234 "softening_curve must be 'Linear' or 'Exponential' but '{:s}' "
235 "was given",
236 softening_curve_string->c_str());
237 }
238 return SofteningCurve::Linear;
239 }();
240
241 auto const energy_split_model = [&]
242 {
243 auto const energy_split_model_string =
245 config.getConfigParameter<std::string>("energy_split_model");
246
247 if (energy_split_model_string == "Isotropic")
248 {
249 return EnergySplitModel::Isotropic;
250 }
251 if (energy_split_model_string == "VolumetricDeviatoric")
252 {
253 return EnergySplitModel::VolDev;
254 }
255 if (energy_split_model_string == "EffectiveStress")
256 {
257 return EnergySplitModel::EffectiveStress;
258 }
259 if (energy_split_model_string == "OrthoVolDev")
260 {
261 return EnergySplitModel::OrthoVolDev;
262 }
263 if (energy_split_model_string == "OrthoMasonry")
264 {
265 return EnergySplitModel::OrthoMasonry;
266 }
268 "energy_split_model must be 'Isotropic' or 'VolumetricDeviatoric' "
269 "but '{:s}' was given",
270 energy_split_model_string);
271 }();
272
273 std::unique_ptr<DegradationDerivative> degradation_derivative;
274 if (phasefield_model == PhaseFieldModel::COHESIVE)
275 {
276 degradation_derivative =
277 std::make_unique<COHESIVE_DegradationDerivative>(
278 characteristic_length, softening_curve);
279 }
280 else
281 {
282 degradation_derivative = std::make_unique<AT_DegradationDerivative>();
283 }
284
285 PhaseFieldProcessData<DisplacementDim> process_data{
287 std::move(solid_constitutive_relations),
288 residual_stiffness,
289 crack_resistance,
290 crack_length_scale,
291 solid_density,
292 initial_stress,
293 specific_body_force,
294 pressurized_crack,
295 propagating_pressurized_crack,
296 static_pressurized_crack,
297 irreversible_threshold,
298 phasefield_model,
299 energy_split_model,
300 softening_curve,
301 characteristic_length,
302 std::move(degradation_derivative)};
303
304 SecondaryVariableCollection secondary_variables;
305
307
308 return std::make_unique<PhaseFieldProcess<DisplacementDim>>(
309 std::move(name), mesh, std::move(jacobian_assembler), parameters,
310 integration_order, std::move(process_variables),
311 std::move(process_data), std::move(secondary_variables),
312 use_monolithic_scheme);
313}
void DBUG(fmt::format_string< Args... > fmt, Args &&... args)
std::string const & getName() const
int getNumberOfGlobalComponents() const
Returns the number of components of the process variable.
std::map< int, std::shared_ptr< MaterialLib::Solids::MechanicsBase< DisplacementDim > > > createConstitutiveRelations(std::vector< std::unique_ptr< ParameterLib::ParameterBase > > const ¶meters, std::optional< ParameterLib::CoordinateSystem > const &local_coordinate_system, MeshLib::PropertyVector< int > const *const material_ids, BaseLib::ConfigTree const &config)
PropertyVector< int > const * materialIDs(Mesh const &mesh)
OGS_NO_DANGLING Parameter< ParameterDataType > & findParameter(std::string const ¶meter_name, std::vector< std::unique_ptr< ParameterBase > > const ¶meters, int const num_components, MeshLib::Mesh const *const mesh=nullptr)
InitialStress createInitialStress(BaseLib::ConfigTree const &config, std::vector< std::unique_ptr< ParameterLib::ParameterBase > > const ¶meters, MeshLib::Mesh const &mesh, bool const mandatory_stress_type)
void createSecondaryVariables(BaseLib::ConfigTree const &config, SecondaryVariableCollection &secondary_variables)