https://mooseframework.inl.gov
Loading...
Searching...
No Matches
DomainIntegralAction.C
Go to the documentation of this file.
1//* This file is part of the MOOSE framework
2//* https://mooseframework.inl.gov
3//*
4//* All rights reserved, see COPYRIGHT for full restrictions
5//* https://github.com/idaholab/moose/blob/master/COPYRIGHT
6//*
7//* Licensed under LGPL 2.1, please see LICENSE for details
8//* https://www.gnu.org/licenses/lgpl-2.1.html
9
10// MOOSE includes
12#include "ExecFlagRegistry.h"
13#include "Factory.h"
14#include "FEProblem.h"
15#include "Moose.h"
16#include "Parser.h"
18#include "MooseMesh.h"
19#include "Conversion.h"
20
21#include "libmesh/string_to_enum.h"
22
23registerMooseAction("SolidMechanicsApp", DomainIntegralAction, "add_user_object");
24
25registerMooseAction("SolidMechanicsApp", DomainIntegralAction, "add_aux_variable");
26
27registerMooseAction("SolidMechanicsApp", DomainIntegralAction, "add_aux_kernel");
28
29registerMooseAction("SolidMechanicsApp", DomainIntegralAction, "add_postprocessor");
30
31registerMooseAction("SolidMechanicsApp", DomainIntegralAction, "add_material");
32
35{
38 MultiMooseEnum integral_vec(
39 "JIntegral CIntegral KFromJIntegral InteractionIntegralKI InteractionIntegralKII "
40 "InteractionIntegralKIII InteractionIntegralT");
42 "Creates the MOOSE objects needed to compute fraction domain integrals");
43 params.addRequiredParam<MultiMooseEnum>("integrals",
44 integral_vec,
45 "Domain integrals to calculate. Choices are: " +
46 integral_vec.getRawNames());
47 params.addParam<std::vector<BoundaryName>>(
48 "boundary", {}, "Boundary containing the crack front points");
49 params.addParam<std::vector<Point>>("crack_front_points", "Set of points to define crack front");
50 params.addParam<std::string>(
51 "order", "FIRST", "Specifies the order of the FE shape function to use for q AuxVariables");
52 params.addParam<std::string>(
53 "family", "LAGRANGE", "Specifies the family of FE shape functions to use for q AuxVariables");
54 params.addParam<std::vector<Real>>("radius_inner", "Inner radius for volume integral domain");
55 params.addParam<std::vector<Real>>("radius_outer", "Outer radius for volume integral domain");
56 params.addParam<unsigned int>("ring_first",
57 "The first ring of elements for volume integral domain");
58 params.addParam<unsigned int>("ring_last",
59 "The last ring of elements for volume integral domain");
60 params.addParam<std::vector<VariableName>>(
61 "output_variable", "Variable values to be reported along the crack front");
62 params.addParam<Real>("poissons_ratio", "Poisson's ratio");
63 params.addParam<Real>("youngs_modulus", "Young's modulus");
64 params.addParam<std::vector<SubdomainName>>(
65 "block", {}, "The block ids where integrals are defined");
66 params.addParam<std::vector<VariableName>>(
67 "displacements",
68 {},
69 "The displacements appropriate for the simulation geometry and coordinate system");
70 params.addParam<VariableName>("temperature", "", "The temperature");
71 params.addParam<MaterialPropertyName>(
72 "functionally_graded_youngs_modulus_crack_dir_gradient",
73 "Gradient of the spatially varying Young's modulus provided in "
74 "'functionally_graded_youngs_modulus' in the direction of crack extension.");
75 params.addParam<MaterialPropertyName>(
76 "functionally_graded_youngs_modulus",
77 "Spatially varying elasticity modulus variable. This input is required when "
78 "using the functionally graded material capability.");
79 params.addCoupledVar("additional_eigenstrain_00",
80 "Optional additional eigenstrain variable that will be accounted for in the "
81 "interaction integral (component 00 or XX).");
82 params.addCoupledVar("additional_eigenstrain_01",
83 "Optional additional eigenstrain variable that will be accounted for in the "
84 "interaction integral (component 01 or XY).");
85 params.addCoupledVar("additional_eigenstrain_11",
86 "Optional additional eigenstrain variable that will be accounted for in the "
87 "interaction integral (component 11 or YY).");
88 params.addCoupledVar("additional_eigenstrain_22",
89 "Optional additional eigenstrain variable that will be accounted for in the "
90 "interaction integral (component 22 or ZZ).");
91 params.addCoupledVar("additional_eigenstrain_02",
92 "Optional additional eigenstrain variable that will be accounted for in the "
93 "interaction integral (component 02 or XZ).");
94 params.addCoupledVar("additional_eigenstrain_12",
95 "Optional additional eigenstrain variable that will be accounted for in the "
96 "interaction integral (component 12 or XZ).");
98 "additional_eigenstrain_00 additional_eigenstrain_01 additional_eigenstrain_11 "
99 "additional_eigenstrain_22 additional_eigenstrain_02 additional_eigenstrain_12",
100 "Generic eigenstrains for the computation of the interaction integral.");
101 MooseEnum position_type("Angle Distance", "Distance");
102 params.addParam<MooseEnum>(
103 "position_type",
104 position_type,
105 "The method used to calculate position along crack front. Options are: " +
106 position_type.getRawNames());
107 MooseEnum q_function_type("Geometry Topology", "Geometry");
108 params.addParam<MooseEnum>("q_function_type",
109 q_function_type,
110 "The method used to define the integration domain. Options are: " +
111 q_function_type.getRawNames());
112 params.addParam<bool>(
113 "equivalent_k",
114 false,
115 "Calculate an equivalent K from KI, KII and KIII, assuming self-similar crack growth.");
116 params.addParam<bool>("output_q", false, "Output q");
117 params.addRequiredParam<bool>(
118 "incremental", "Flag to indicate whether an incremental or total model is being used.");
119 params.addParam<std::vector<MaterialPropertyName>>(
120 "eigenstrain_names", "List of eigenstrains applied in the strain calculation");
121 params.addDeprecatedParam<bool>("convert_J_to_K",
122 false,
123 "Convert J-integral to stress intensity factor K.",
124 "This input parameter is deprecated and will be removed soon. "
125 "Use 'integrals = KFromJIntegral' to request output of the "
126 "conversion from the J-integral to stress intensity factors");
127 params.addParam<std::vector<MaterialName>>(
128 "inelastic_models",
129 "The material objects to use to calculate the strain energy rate density.");
130 params.addParam<MaterialPropertyName>("eigenstrain_gradient",
131 "Material defining gradient of eigenstrain tensor");
132 params.addParam<MaterialPropertyName>("body_force", "Material defining body force");
133 params.addParam<bool>("use_automatic_differentiation",
134 false,
135 "Flag to use automatic differentiation (AD) objects when possible");
136 params.addParam<bool>("output_vpp",
137 true,
138 "Flag to control the vector postprocessor outputs. Select false to "
139 "suppress the redundant csv files for each time step and ring");
140 return params;
141}
142
144 : Action(params),
145 _boundary_names(getParam<std::vector<BoundaryName>>("boundary")),
146 _closed_loop(getParam<bool>("closed_loop")),
147 _use_crack_front_points_provider(false),
148 _order(getParam<std::string>("order")),
149 _family(getParam<std::string>("family")),
150 _direction_method_moose_enum(getParam<MooseEnum>("crack_direction_method")),
151 _end_direction_method_moose_enum(getParam<MooseEnum>("crack_end_direction_method")),
152 _have_crack_direction_vector(isParamValid("crack_direction_vector")),
153 _crack_direction_vector(
154 _have_crack_direction_vector ? getParam<RealVectorValue>("crack_direction_vector") : 0.0),
155 _have_crack_direction_vector_end_1(isParamValid("crack_direction_vector_end_1")),
156 _crack_direction_vector_end_1(_have_crack_direction_vector_end_1
157 ? getParam<RealVectorValue>("crack_direction_vector_end_1")
158 : 0.0),
159 _have_crack_direction_vector_end_2(isParamValid("crack_direction_vector_end_2")),
160 _crack_direction_vector_end_2(_have_crack_direction_vector_end_2
161 ? getParam<RealVectorValue>("crack_direction_vector_end_2")
162 : 0.0),
163 _treat_as_2d(getParam<bool>("2d")),
164 _axis_2d(getParam<unsigned int>("axis_2d")),
165 _has_symmetry_plane(isParamValid("symmetry_plane")),
166 _symmetry_plane(_has_symmetry_plane ? getParam<unsigned int>("symmetry_plane")
167 : std::numeric_limits<unsigned int>::max()),
168 _position_type(getParam<MooseEnum>("position_type")),
169 _q_function_type(getParam<MooseEnum>("q_function_type")),
170 _get_equivalent_k(getParam<bool>("equivalent_k")),
171 _use_displaced_mesh(false),
172 _output_q(getParam<bool>("output_q")),
173 _incremental(getParam<bool>("incremental")),
174 _convert_J_to_K(isParamValid("convert_J_to_K") ? getParam<bool>("convert_J_to_K") : false),
175 _fgm_crack(false),
176 _use_ad(getParam<bool>("use_automatic_differentiation"))
177{
178
179 if (isParamValid("functionally_graded_youngs_modulus_crack_dir_gradient") !=
180 isParamValid("functionally_graded_youngs_modulus"))
181 paramError("functionally_graded_youngs_modulus_crack_dir_gradient",
182 "You have selected to compute the interaction integral for a crack in FGM. That "
183 "selection requires the user to provide a spatially varying elasticity modulus that "
184 "defines the transition of material properties (i.e. "
185 "'functionally_graded_youngs_modulus') and its "
186 "spatial derivative in the crack direction (i.e. "
187 "'functionally_graded_youngs_modulus_crack_dir_gradient').");
188
189 if (isParamValid("functionally_graded_youngs_modulus_crack_dir_gradient") &&
190 isParamValid("functionally_graded_youngs_modulus"))
191 {
192 _fgm_crack = true;
194 getParam<MaterialPropertyName>("functionally_graded_youngs_modulus_crack_dir_gradient");
196 getParam<MaterialPropertyName>("functionally_graded_youngs_modulus");
197 }
198
200 {
201 if (isParamValid("radius_inner") && isParamValid("radius_outer"))
202 {
203 _radius_inner = getParam<std::vector<Real>>("radius_inner");
204 _radius_outer = getParam<std::vector<Real>>("radius_outer");
205 }
206 else
207 mooseError("DomainIntegral error: must set radius_inner and radius_outer.");
208 for (unsigned int i = 0; i < _radius_inner.size(); ++i)
209 _ring_vec.push_back(i + 1);
210 }
211 else if (_q_function_type == TOPOLOGY)
212 {
213 if (isParamValid("ring_first") && isParamValid("ring_last"))
214 {
215 _ring_first = getParam<unsigned int>("ring_first");
216 _ring_last = getParam<unsigned int>("ring_last");
217 }
218 else
220 "DomainIntegral error: must set ring_first and ring_last if q_function_type = Topology.");
221 for (unsigned int i = _ring_first; i <= _ring_last; ++i)
222 _ring_vec.push_back(i);
223 }
224 else
225 paramError("q_function_type", "DomainIntegral error: invalid q_function_type.");
226
227 if (isParamValid("crack_front_points"))
228 _crack_front_points = getParam<std::vector<Point>>("crack_front_points");
229
230 if (isParamValid("crack_front_points_provider"))
231 {
233 _crack_front_points_provider = getParam<UserObjectName>("crack_front_points_provider");
234 }
235 else if (isParamValid("number_points_from_provider"))
236 paramError("crack_front_points_provider",
237 "DomainIntegral error: number_points_from_provider is provided but "
238 "crack_front_points_provider cannot be found.");
239 if (isParamValid("crack_mouth_boundary"))
240 _crack_mouth_boundary_names = getParam<std::vector<BoundaryName>>("crack_mouth_boundary");
241 if (isParamValid("intersecting_boundary"))
242 _intersecting_boundary_names = getParam<std::vector<BoundaryName>>("intersecting_boundary");
243 if (_radius_inner.size() != _radius_outer.size())
244 mooseError("Number of entries in 'radius_inner' and 'radius_outer' must match.");
245
246 bool youngs_modulus_set(false);
247 bool poissons_ratio_set(false);
248
249 // All domain integral types block restrict the objects created by this action.
250 _blocks = getParam<std::vector<SubdomainName>>("block");
251
252 MultiMooseEnum integral_moose_enums = getParam<MultiMooseEnum>("integrals");
253 for (unsigned int i = 0; i < integral_moose_enums.size(); ++i)
254 {
255 _displacements = getParam<std::vector<VariableName>>("displacements");
256
257 if (_displacements.size() < 2)
259 "displacements",
260 "DomainIntegral error: The size of the displacements vector should at least be 2.");
261
262 if (integral_moose_enums[i] != "JIntegral" && integral_moose_enums[i] != "CIntegral" &&
263 integral_moose_enums[i] != "KFromJIntegral")
264 {
265 // Check that parameters required for interaction integrals are defined
266 if (!(isParamValid("poissons_ratio")) || !(isParamValid("youngs_modulus")))
268 "DomainIntegral error: must set Poisson's ratio and Young's modulus for integral: ",
269 integral_moose_enums[i]);
270
271 _poissons_ratio = getParam<Real>("poissons_ratio");
272 poissons_ratio_set = true;
273 _youngs_modulus = getParam<Real>("youngs_modulus");
274 youngs_modulus_set = true;
275 }
276
277 _integrals.insert(INTEGRAL(int(integral_moose_enums.get(i))));
278 }
279
280 if ((_integrals.count(J_INTEGRAL) != 0 && _integrals.count(C_INTEGRAL) != 0) ||
281 (_integrals.count(J_INTEGRAL) != 0 && _integrals.count(K_FROM_J_INTEGRAL) != 0) ||
282 (_integrals.count(C_INTEGRAL) != 0 && _integrals.count(K_FROM_J_INTEGRAL) != 0))
283 paramError("integrals",
284 "JIntegral, CIntegral, and KFromJIntegral options are mutually exclusive");
285
286 // Acommodate deprecated parameter convert_J_to_K
288 {
290 _integrals.erase(J_INTEGRAL);
291 }
292
293 if (isParamValid("temperature"))
294 _temp = getParam<VariableName>("temperature");
295
296 if (_temp != "" && !isParamValid("eigenstrain_names"))
298 "eigenstrain_names",
299 "DomainIntegral error: must provide `eigenstrain_names` when temperature is coupled.");
300
304 paramError("integrals",
305 "DomainIntegral error: must calculate KI, KII and KIII to get equivalent K.");
306
307 if (isParamValid("output_variable"))
308 {
309 _output_variables = getParam<std::vector<VariableName>>("output_variable");
310 if (_crack_front_points.size() > 0)
311 paramError("output_variables",
312 "'output_variables' not yet supported with 'crack_front_points'");
313 }
314
315 if (_integrals.count(K_FROM_J_INTEGRAL) != 0)
316 {
317 if (!isParamValid("youngs_modulus") || !isParamValid("poissons_ratio"))
318 mooseError("DomainIntegral error: must set Young's modulus and Poisson's ratio "
319 "if K_FROM_J_INTEGRAL is selected.");
320 if (!youngs_modulus_set)
321 _youngs_modulus = getParam<Real>("youngs_modulus");
322 if (!poissons_ratio_set)
323 _poissons_ratio = getParam<Real>("poissons_ratio");
324 }
325
326 if (_integrals.count(J_INTEGRAL) != 0 || _integrals.count(C_INTEGRAL) != 0 ||
327 _integrals.count(K_FROM_J_INTEGRAL) != 0)
328 {
329 if (isParamValid("eigenstrain_gradient"))
330 paramError("eigenstrain_gradient",
331 "'eigenstrain_gradient' cannot be specified when the computed integrals include "
332 "JIntegral, CIntegral, or KFromJIntegral");
333 if (isParamValid("body_force"))
334 paramError("body_force",
335 "'body_force' cannot be specified when the computed integrals include JIntegral, "
336 "CIntegral, or KFromJIntegral");
337 }
338 if (isParamValid("eigenstrain_gradient") && (_temp != "" || isParamValid("eigenstrain_names")))
339 paramError("eigenstrain_gradient",
340 "'eigenstrain_gradient' cannot be specified together with 'temperature' or "
341 "'eigenstrain_names'. These are for separate, mutually exclusive systems for "
342 "including the effect of eigenstrains");
343}
344
346
347void
349{
350 const std::string uo_name("crackFrontDefinition");
351 const std::string ak_base_name("q");
352 const std::string av_base_name("q");
353 const unsigned int num_crack_front_points = calcNumCrackFrontPoints();
354 const std::string aux_stress_base_name("aux_stress");
355 const std::string aux_grad_disp_base_name("aux_grad_disp");
356
357 // checking if built with xfem and setting flags for vpps used by xfem
358 std::vector<std::string> xfem_exec_flags = {EXEC_XFEM_MARK, EXEC_TIMESTEP_END};
359
360 std::string ad_prepend = "";
361 if (_use_ad)
362 ad_prepend = "AD";
363
364 if (_current_task == "add_user_object")
365 {
366 const std::string uo_type_name("CrackFrontDefinition");
367
368 InputParameters params = _factory.getValidParams(uo_type_name);
369 // The CrackFrontDefinition updates the vpps and MUST execute before them
370 params.set<int>("execution_order_group") = -1;
372 params.set<ExecFlagEnum>("execute_on") = xfem_exec_flags;
373 else
374 params.set<ExecFlagEnum>("execute_on") = {EXEC_INITIAL, EXEC_TIMESTEP_END};
375
376 params.set<MooseEnum>("crack_direction_method") = _direction_method_moose_enum;
377 params.set<MooseEnum>("crack_end_direction_method") = _end_direction_method_moose_enum;
379 params.set<RealVectorValue>("crack_direction_vector") = _crack_direction_vector;
381 params.set<RealVectorValue>("crack_direction_vector_end_1") = _crack_direction_vector_end_1;
383 params.set<RealVectorValue>("crack_direction_vector_end_2") = _crack_direction_vector_end_2;
384 if (_crack_mouth_boundary_names.size() != 0)
385 params.set<std::vector<BoundaryName>>("crack_mouth_boundary") = _crack_mouth_boundary_names;
386 if (_intersecting_boundary_names.size() != 0)
387 params.set<std::vector<BoundaryName>>("intersecting_boundary") = _intersecting_boundary_names;
388 params.set<bool>("2d") = _treat_as_2d;
389 params.set<unsigned int>("axis_2d") = _axis_2d;
391 params.set<unsigned int>("symmetry_plane") = _symmetry_plane;
392 if (_boundary_names.size() != 0)
393 params.set<std::vector<BoundaryName>>("boundary") = _boundary_names;
394 if (_crack_front_points.size() != 0)
395 params.set<std::vector<Point>>("crack_front_points") = _crack_front_points;
397 {
398 params.set<UserObjectName>("crack_front_points_provider") = _crack_front_points_provider;
399 if (isParamValid("number_points_from_provider"))
400 params.set<unsigned int>("number_points_from_provider") =
401 getParam<unsigned int>("number_points_from_provider");
402 }
403 if (_closed_loop)
404 params.set<bool>("closed_loop") = _closed_loop;
405 params.set<bool>("use_displaced_mesh") = _use_displaced_mesh;
406 if (_integrals.count(INTERACTION_INTEGRAL_T) != 0)
407 {
408 params.set<VariableName>("disp_x") = _displacements[0];
409 params.set<VariableName>("disp_y") = _displacements[1];
410 if (_displacements.size() == 3)
411 params.set<VariableName>("disp_z") = _displacements[2];
412 params.set<bool>("t_stress") = true;
413 }
414
415 unsigned int nrings = 0;
417 {
418 params.set<bool>("q_function_rings") = true;
419 params.set<unsigned int>("last_ring") = _ring_last;
420 params.set<unsigned int>("first_ring") = _ring_first;
421 nrings = _ring_last - _ring_first + 1;
422 }
423 else if (_q_function_type == GEOMETRY)
424 {
425 params.set<std::vector<Real>>("j_integral_radius_inner") = _radius_inner;
426 params.set<std::vector<Real>>("j_integral_radius_outer") = _radius_outer;
427 nrings = _ring_vec.size();
428 }
429
430 params.set<unsigned int>("nrings") = nrings;
431 params.set<MooseEnum>("q_function_type") = _q_function_type;
432
433 _problem->addUserObject(uo_type_name, uo_name, params);
434 }
435 else if (_current_task == "add_aux_variable" && _output_q)
436 {
437 if (isParamValid("number_points_from_provider") && num_crack_front_points == 0)
438 {
439 paramError("output_q",
440 "Requesting AuxVariable output of q functions but the number of crack fronts for "
441 "output is zero. AuxVariable output for XFEM cutter objects requires "
442 "number_points_from_provider to be set.");
443 }
444
445 for (unsigned int ring_index = 0; ring_index < _ring_vec.size(); ++ring_index)
446 {
447 std::string aux_var_type;
448 if (_family == "LAGRANGE")
449 aux_var_type = "MooseVariable";
450 else if (_family == "MONOMIAL")
451 aux_var_type = "MooseVariableConstMonomial";
452 else if (_family == "SCALAR")
453 aux_var_type = "MooseVariableScalar";
454 else
455 mooseError("Unsupported finite element family in, " + name() +
456 ". Please use LAGRANGE, MONOMIAL, or SCALAR");
457
458 auto params = _factory.getValidParams(aux_var_type);
459 params.set<MooseEnum>("order") = _order;
460 params.set<MooseEnum>("family") = _family;
461
463 {
464 std::ostringstream av_name_stream;
465 av_name_stream << av_base_name << "_" << _ring_vec[ring_index];
466 _problem->addAuxVariable(aux_var_type, av_name_stream.str(), params);
467 }
468 else
469 {
470 for (unsigned int cfp_index = 0; cfp_index < num_crack_front_points; ++cfp_index)
471 {
472 std::ostringstream av_name_stream;
473 av_name_stream << av_base_name << "_" << cfp_index + 1 << "_" << _ring_vec[ring_index];
474 _problem->addAuxVariable(aux_var_type, av_name_stream.str(), params);
475 }
476 }
477 }
478 }
479
480 else if (_current_task == "add_aux_kernel" && _output_q)
481 {
482 std::string ak_type_name;
483 unsigned int nrings = 0;
485 {
486 ak_type_name = "DomainIntegralQFunction";
487 nrings = _ring_vec.size();
488 }
489 else if (_q_function_type == TOPOLOGY)
490 {
491 ak_type_name = "DomainIntegralTopologicalQFunction";
492 nrings = _ring_last - _ring_first + 1;
493 }
494
495 InputParameters params = _factory.getValidParams(ak_type_name);
496 params.set<ExecFlagEnum>("execute_on") = {EXEC_INITIAL, EXEC_TIMESTEP_END};
497 params.set<UserObjectName>("crack_front_definition") = uo_name;
498 params.set<bool>("use_displaced_mesh") = _use_displaced_mesh;
499
500 for (unsigned int ring_index = 0; ring_index < nrings; ++ring_index)
501 {
503 {
504 params.set<Real>("j_integral_radius_inner") = _radius_inner[ring_index];
505 params.set<Real>("j_integral_radius_outer") = _radius_outer[ring_index];
506 }
507 else if (_q_function_type == TOPOLOGY)
508 {
509 params.set<unsigned int>("ring_index") = _ring_first + ring_index;
510 }
511
513 {
514 std::ostringstream ak_name_stream;
515 ak_name_stream << ak_base_name << "_" << _ring_vec[ring_index];
516 std::ostringstream av_name_stream;
517 av_name_stream << av_base_name << "_" << _ring_vec[ring_index];
518 params.set<AuxVariableName>("variable") = av_name_stream.str();
519 _problem->addAuxKernel(ak_type_name, ak_name_stream.str(), params);
520 }
521 else
522 {
523 for (unsigned int cfp_index = 0; cfp_index < num_crack_front_points; ++cfp_index)
524 {
525 std::ostringstream ak_name_stream;
526 ak_name_stream << ak_base_name << "_" << cfp_index + 1 << "_" << _ring_vec[ring_index];
527 std::ostringstream av_name_stream;
528 av_name_stream << av_base_name << "_" << cfp_index + 1 << "_" << _ring_vec[ring_index];
529 params.set<AuxVariableName>("variable") = av_name_stream.str();
530 params.set<unsigned int>("crack_front_point_index") = cfp_index;
531 _problem->addAuxKernel(ak_type_name, ak_name_stream.str(), params);
532 }
533 }
534 }
535 }
536
537 else if (_current_task == "add_postprocessor")
538 {
539 // Check that the number specified by the XFEM cutter object matches the number of points
540 // specified in the DomainIntegralAction block. This is being done in teh add_postprocessor
541 // block because it must be done after all userObjects have been created.
542 if (_use_crack_front_points_provider && isParamValid("number_points_from_provider"))
543 {
544 auto crack_front_points_provider = &_problem->getUserObject<CrackFrontPointsProvider>(
545 getParam<UserObjectName>("crack_front_points_provider"));
546 if (crack_front_points_provider->usesMesh())
547 {
548 auto xfem_cutter_points = crack_front_points_provider->getNumberOfCrackFrontPoints();
549 if (xfem_cutter_points != num_crack_front_points)
550 paramError("number_points_from_provider",
551 "This must match the number of points provided by the XFEM mesh cutter "
552 "object."
553 "\n number_points_from_provider:",
554 num_crack_front_points,
555 "\n XFEM Crack Front Points: ",
556 xfem_cutter_points);
557 }
558 }
559 for (std::set<INTEGRAL>::iterator sit = _integrals.begin(); sit != _integrals.end(); ++sit)
560 {
561 std::string pp_base_name;
562 switch (*sit)
563 {
564 case J_INTEGRAL:
565 pp_base_name = "J";
566 break;
567
568 case C_INTEGRAL:
569 pp_base_name = "C";
570 break;
571
573 pp_base_name = "K";
574 break;
575
577 pp_base_name = "II_KI";
578 break;
579
581 pp_base_name = "II_KII";
582 break;
583
585 pp_base_name = "II_KIII";
586 break;
587
589 pp_base_name = "II_T";
590 break;
591 }
592 const std::string pp_type_name("VectorPostprocessorComponent");
593 InputParameters params = _factory.getValidParams(pp_type_name);
594 for (unsigned int ring_index = 0; ring_index < _ring_vec.size(); ++ring_index)
595 {
597 {
598 params.set<VectorPostprocessorName>("vectorpostprocessor") =
599 pp_base_name + "_2DVPP_" + Moose::stringify(_ring_vec[ring_index]);
600 std::string pp_name = pp_base_name + +"_" + Moose::stringify(_ring_vec[ring_index]);
601 params.set<unsigned int>("index") = 0;
602 params.set<std::string>("vector_name") =
603 pp_base_name + "_" + Moose::stringify(_ring_vec[ring_index]);
604 _problem->addPostprocessor(pp_type_name, pp_name, params);
605 }
606 else
607 {
608 for (unsigned int cfp_index = 0; cfp_index < num_crack_front_points; ++cfp_index)
609 {
610 params.set<VectorPostprocessorName>("vectorpostprocessor") =
611 pp_base_name + "_" + Moose::stringify(_ring_vec[ring_index]);
612 std::string pp_name = pp_base_name + "_" + Moose::stringify(cfp_index + 1) + "_" +
613 Moose::stringify(_ring_vec[ring_index]);
614 params.set<unsigned int>("index") = cfp_index;
615 params.set<std::string>("vector_name") =
616 pp_base_name + "_" + Moose::stringify(_ring_vec[ring_index]);
617 _problem->addPostprocessor(pp_type_name, pp_name, params);
618 }
619 }
620 }
621 }
622
624 {
625 std::string pp_base_name("Keq");
626 const std::string pp_type_name("VectorPostprocessorComponent");
627 InputParameters params = _factory.getValidParams(pp_type_name);
628 for (unsigned int ring_index = 0; ring_index < _ring_vec.size(); ++ring_index)
629 {
631 {
632 params.set<VectorPostprocessorName>("vectorpostprocessor") =
633 pp_base_name + "_2DVPP_" + Moose::stringify(_ring_vec[ring_index]);
634 std::string pp_name = pp_base_name + +"_" + Moose::stringify(_ring_vec[ring_index]);
635 params.set<unsigned int>("index") = 0;
636 params.set<std::string>("vector_name") =
637 pp_base_name + "_" + Moose::stringify(_ring_vec[ring_index]);
638 _problem->addPostprocessor(pp_type_name, pp_name, params);
639 }
640 else
641 {
642 for (unsigned int cfp_index = 0; cfp_index < num_crack_front_points; ++cfp_index)
643 {
644 params.set<VectorPostprocessorName>("vectorpostprocessor") =
645 pp_base_name + "_" + Moose::stringify(_ring_vec[ring_index]);
646 std::string pp_name = pp_base_name + "_" + Moose::stringify(cfp_index + 1) + "_" +
647 Moose::stringify(_ring_vec[ring_index]);
648 params.set<unsigned int>("index") = cfp_index;
649 params.set<std::string>("vector_name") =
650 pp_base_name + "_" + Moose::stringify(_ring_vec[ring_index]);
651 _problem->addPostprocessor(pp_type_name, pp_name, params);
652 }
653 }
654 }
655 }
656
657 for (unsigned int i = 0; i < _output_variables.size(); ++i)
658 {
659 const std::string ov_base_name(_output_variables[i]);
660 const std::string pp_type_name("CrackFrontData");
661 InputParameters params = _factory.getValidParams(pp_type_name);
662 params.set<ExecFlagEnum>("execute_on") = EXEC_TIMESTEP_END;
663 params.set<UserObjectName>("crack_front_definition") = uo_name;
665 {
666 std::ostringstream pp_name_stream;
667 pp_name_stream << ov_base_name << "_crack";
668 params.set<VariableName>("variable") = _output_variables[i];
669 _problem->addPostprocessor(pp_type_name, pp_name_stream.str(), params);
670 }
671 else
672 {
673 for (unsigned int cfp_index = 0; cfp_index < num_crack_front_points; ++cfp_index)
674 {
675 std::ostringstream pp_name_stream;
676 pp_name_stream << ov_base_name << "_crack_" << cfp_index + 1;
677 params.set<VariableName>("variable") = _output_variables[i];
678 params.set<unsigned int>("crack_front_point_index") = cfp_index;
679 _problem->addPostprocessor(pp_type_name, pp_name_stream.str(), params);
680 }
681 }
682 }
683 }
684
685 else if (_current_task == "add_vector_postprocessor")
686 {
687 if (_integrals.count(J_INTEGRAL) != 0 || _integrals.count(C_INTEGRAL) != 0 ||
688 _integrals.count(K_FROM_J_INTEGRAL) != 0)
689 {
690 std::string vpp_base_name;
691 std::string jintegral_selection = "JIntegral";
692
693 if (_integrals.count(J_INTEGRAL) != 0)
694 {
695 vpp_base_name = "J";
696 jintegral_selection = "JIntegral";
697 }
698 else if (_integrals.count(K_FROM_J_INTEGRAL) != 0)
699 {
700 vpp_base_name = "K";
701 jintegral_selection = "KFromJIntegral";
702 }
703 else if (_integrals.count(C_INTEGRAL) != 0)
704 {
705 vpp_base_name = "C";
706 jintegral_selection = "CIntegral";
707 }
708
710 vpp_base_name += "_2DVPP";
711
712 const std::string vpp_type_name("JIntegral");
713 InputParameters params = _factory.getValidParams(vpp_type_name);
714 if (!getParam<bool>("output_vpp"))
715 params.set<std::vector<OutputName>>("outputs") = {"none"};
716
717 params.set<ExecFlagEnum>("execute_on") = EXEC_TIMESTEP_END;
718 params.set<UserObjectName>("crack_front_definition") = uo_name;
719 params.set<std::vector<SubdomainName>>("block") = {_blocks};
720 params.set<MooseEnum>("position_type") = _position_type;
721
722 if (_integrals.count(K_FROM_J_INTEGRAL) != 0)
723 {
724 params.set<Real>("youngs_modulus") = _youngs_modulus;
725 params.set<Real>("poissons_ratio") = _poissons_ratio;
726 }
727
729 params.set<unsigned int>("symmetry_plane") = _symmetry_plane;
730
731 // Select the integral type to be computed in JIntegral vector postprocessor
732 params.set<MooseEnum>("integral") = jintegral_selection;
733
734 params.set<std::vector<VariableName>>("displacements") = _displacements;
735 params.set<bool>("use_displaced_mesh") = _use_displaced_mesh;
736 for (unsigned int ring_index = 0; ring_index < _ring_vec.size(); ++ring_index)
737 {
738 params.set<unsigned int>("ring_index") = _ring_vec[ring_index];
739 params.set<MooseEnum>("q_function_type") = _q_function_type;
740
741 std::string vpp_name = vpp_base_name + "_" + Moose::stringify(_ring_vec[ring_index]);
742 _problem->addVectorPostprocessor(vpp_type_name, vpp_name, params);
743 }
744 }
745
746 if (_integrals.count(INTERACTION_INTEGRAL_KI) != 0 ||
750 {
753 paramError("symmetry_plane",
754 "In DomainIntegral, symmetry_plane option cannot be used with mode-II or "
755 "mode-III interaction integral");
756
757 std::string vpp_base_name;
758 std::string vpp_type_name(ad_prepend + "InteractionIntegral");
759
760 InputParameters params = _factory.getValidParams(vpp_type_name);
761 if (!getParam<bool>("output_vpp"))
762 params.set<std::vector<OutputName>>("outputs") = {"none"};
763
765 params.set<ExecFlagEnum>("execute_on") = xfem_exec_flags;
766 else
767 params.set<ExecFlagEnum>("execute_on") = {EXEC_TIMESTEP_END};
768
769 if (isParamValid("additional_eigenstrain_00") && isParamValid("additional_eigenstrain_01") &&
770 isParamValid("additional_eigenstrain_11") && isParamValid("additional_eigenstrain_22"))
771 {
772 params.set<CoupledName>("additional_eigenstrain_00") =
773 getParam<CoupledName>("additional_eigenstrain_00");
774 params.set<CoupledName>("additional_eigenstrain_01") =
775 getParam<CoupledName>("additional_eigenstrain_01");
776 params.set<CoupledName>("additional_eigenstrain_11") =
777 getParam<CoupledName>("additional_eigenstrain_11");
778 params.set<CoupledName>("additional_eigenstrain_22") =
779 getParam<CoupledName>("additional_eigenstrain_22");
780 }
781
782 params.set<UserObjectName>("crack_front_definition") = uo_name;
783 params.set<bool>("use_displaced_mesh") = _use_displaced_mesh;
784 params.set<std::vector<SubdomainName>>("block") = {_blocks};
785
787 params.set<unsigned int>("symmetry_plane") = _symmetry_plane;
788
789 if (_fgm_crack)
790 {
791 params.set<MaterialPropertyName>(
792 "functionally_graded_youngs_modulus_crack_dir_gradient") = {
794 params.set<MaterialPropertyName>("functionally_graded_youngs_modulus") = {
796 }
797
798 params.set<Real>("poissons_ratio") = _poissons_ratio;
799 params.set<Real>("youngs_modulus") = _youngs_modulus;
800 params.set<std::vector<VariableName>>("displacements") = _displacements;
801 if (_temp != "")
802 params.set<std::vector<VariableName>>("temperature") = {_temp};
803
804 if (parameters().isParamValid("eigenstrain_gradient"))
805 params.set<MaterialPropertyName>("eigenstrain_gradient") =
806 parameters().get<MaterialPropertyName>("eigenstrain_gradient");
807 if (parameters().isParamValid("body_force"))
808 params.set<MaterialPropertyName>("body_force") =
809 parameters().get<MaterialPropertyName>("body_force");
810
811 for (std::set<INTEGRAL>::iterator sit = _integrals.begin(); sit != _integrals.end(); ++sit)
812 {
813 switch (*sit)
814 {
815 case J_INTEGRAL:
816 continue;
817
818 case C_INTEGRAL:
819 continue;
820
822 continue;
823
825 vpp_base_name = "II_KI";
826 params.set<Real>("K_factor") =
827 0.5 * _youngs_modulus / (1.0 - std::pow(_poissons_ratio, 2.0));
828 params.set<MooseEnum>("sif_mode") = "KI";
829 break;
830
832 vpp_base_name = "II_KII";
833 params.set<Real>("K_factor") =
834 0.5 * _youngs_modulus / (1.0 - std::pow(_poissons_ratio, 2.0));
835 params.set<MooseEnum>("sif_mode") = "KII";
836 break;
837
839 vpp_base_name = "II_KIII";
840 params.set<Real>("K_factor") = 0.5 * _youngs_modulus / (1.0 + _poissons_ratio);
841 params.set<MooseEnum>("sif_mode") = "KIII";
842 break;
843
845 vpp_base_name = "II_T";
846 params.set<Real>("K_factor") = _youngs_modulus / (1 - std::pow(_poissons_ratio, 2));
847 params.set<MooseEnum>("sif_mode") = "T";
848 break;
849 }
851 vpp_base_name += "_2DVPP";
852 for (unsigned int ring_index = 0; ring_index < _ring_vec.size(); ++ring_index)
853 {
854 params.set<unsigned int>("ring_index") = _ring_vec[ring_index];
855 params.set<MooseEnum>("q_function_type") = _q_function_type;
856
857 std::string vpp_name = vpp_base_name + "_" + Moose::stringify(_ring_vec[ring_index]);
858 _problem->addVectorPostprocessor(vpp_type_name, vpp_name, params);
859 }
860 }
861 }
862
864 {
865 std::string vpp_base_name("Keq");
867 vpp_base_name += "_2DVPP";
868 const std::string vpp_type_name("MixedModeEquivalentK");
869 InputParameters params = _factory.getValidParams(vpp_type_name);
870 params.set<ExecFlagEnum>("execute_on") = EXEC_TIMESTEP_END;
871 params.set<Real>("poissons_ratio") = _poissons_ratio;
872
873 for (unsigned int ring_index = 0; ring_index < _ring_vec.size(); ++ring_index)
874 {
875 std::string ki_name = "II_KI_";
876 std::string kii_name = "II_KII_";
877 std::string kiii_name = "II_KIII_";
878 params.set<unsigned int>("ring_index") = _ring_vec[ring_index];
880 {
881 params.set<VectorPostprocessorName>("KI_vectorpostprocessor") =
882 ki_name + "2DVPP_" + Moose::stringify(_ring_vec[ring_index]);
883 params.set<VectorPostprocessorName>("KII_vectorpostprocessor") =
884 kii_name + "2DVPP_" + Moose::stringify(_ring_vec[ring_index]);
885 params.set<VectorPostprocessorName>("KIII_vectorpostprocessor") =
886 kiii_name + "2DVPP_" + Moose::stringify(_ring_vec[ring_index]);
887 }
888 else
889 {
890 params.set<VectorPostprocessorName>("KI_vectorpostprocessor") =
891 ki_name + Moose::stringify(_ring_vec[ring_index]);
892 params.set<VectorPostprocessorName>("KII_vectorpostprocessor") =
893 kii_name + Moose::stringify(_ring_vec[ring_index]);
894 params.set<VectorPostprocessorName>("KIII_vectorpostprocessor") =
895 kiii_name + Moose::stringify(_ring_vec[ring_index]);
896 }
897 params.set<std::string>("KI_vector_name") =
898 ki_name + Moose::stringify(_ring_vec[ring_index]);
899 params.set<std::string>("KII_vector_name") =
900 kii_name + Moose::stringify(_ring_vec[ring_index]);
901 params.set<std::string>("KIII_vector_name") =
902 kiii_name + Moose::stringify(_ring_vec[ring_index]);
903 std::string vpp_name = vpp_base_name + "_" + Moose::stringify(_ring_vec[ring_index]);
904 _problem->addVectorPostprocessor(vpp_type_name, vpp_name, params);
905 }
906 }
907
909 {
910 for (unsigned int i = 0; i < _output_variables.size(); ++i)
911 {
912 const std::string vpp_type_name("VectorOfPostprocessors");
913 InputParameters params = _factory.getValidParams(vpp_type_name);
914 params.set<ExecFlagEnum>("execute_on") = EXEC_TIMESTEP_END;
915 std::ostringstream vpp_name_stream;
916 vpp_name_stream << _output_variables[i] << "_crack";
917 std::vector<PostprocessorName> postprocessor_names;
918 for (unsigned int cfp_index = 0; cfp_index < num_crack_front_points; ++cfp_index)
919 {
920 std::ostringstream pp_name_stream;
921 pp_name_stream << vpp_name_stream.str() << "_" << cfp_index + 1;
922 postprocessor_names.push_back(pp_name_stream.str());
923 }
924 params.set<std::vector<PostprocessorName>>("postprocessors") = postprocessor_names;
925 _problem->addVectorPostprocessor(vpp_type_name, vpp_name_stream.str(), params);
926 }
927 }
928 }
929
930 else if (_current_task == "add_material")
931 {
932 if (_temp != "")
933 {
934 std::string mater_name;
935 const std::string mater_type_name("ThermalFractureIntegral");
936 mater_name = "ThermalFractureIntegral";
937
938 InputParameters params = _factory.getValidParams(mater_type_name);
939 params.set<std::vector<MaterialPropertyName>>("eigenstrain_names") =
940 getParam<std::vector<MaterialPropertyName>>("eigenstrain_names");
941 params.set<std::vector<VariableName>>("temperature") = {_temp};
942 params.set<std::vector<SubdomainName>>("block") = {_blocks};
943 _problem->addMaterial(mater_type_name, mater_name, params);
944 }
945 MultiMooseEnum integral_moose_enums = getParam<MultiMooseEnum>("integrals");
946 bool have_j_integral = false;
947 bool have_c_integral = false;
948
949 for (auto ime : integral_moose_enums)
950 {
951 if (ime == "JIntegral" || ime == "CIntegral" || ime == "KFromJIntegral" ||
952 ime == "InteractionIntegralKI" || ime == "InteractionIntegralKII" ||
953 ime == "InteractionIntegralKIII" || ime == "InteractionIntegralT")
954 have_j_integral = true;
955
956 if (ime == "CIntegral")
957 have_c_integral = true;
958 }
959 if (have_j_integral)
960 {
961 std::string mater_name;
962 const std::string mater_type_name(ad_prepend + "StrainEnergyDensity");
963 mater_name = ad_prepend + "StrainEnergyDensity";
964
965 InputParameters params = _factory.getValidParams(mater_type_name);
966 _incremental = getParam<bool>("incremental");
967 params.set<bool>("incremental") = _incremental;
968 params.set<std::vector<SubdomainName>>("block") = {_blocks};
969 _problem->addMaterial(mater_type_name, mater_name, params);
970
971 {
972 std::string mater_name;
973 const std::string mater_type_name(ad_prepend + "EshelbyTensor");
974 mater_name = ad_prepend + "EshelbyTensor";
975
976 InputParameters params = _factory.getValidParams(mater_type_name);
977 _displacements = getParam<std::vector<VariableName>>("displacements");
978 params.set<std::vector<VariableName>>("displacements") = _displacements;
979 params.set<std::vector<SubdomainName>>("block") = {_blocks};
980
981 if (have_c_integral)
982 params.set<bool>("compute_dissipation") = true;
983
984 if (_temp != "")
985 params.set<std::vector<VariableName>>("temperature") = {_temp};
986
987 _problem->addMaterial(mater_type_name, mater_name, params);
988 }
989 // Strain energy rate density needed for C(t)/C* integral
990 if (have_c_integral)
991 {
992 std::string mater_name;
993 const std::string mater_type_name(ad_prepend + "StrainEnergyRateDensity");
994 mater_name = ad_prepend + "StrainEnergyRateDensity";
995
996 InputParameters params = _factory.getValidParams(mater_type_name);
997 params.set<std::vector<SubdomainName>>("block") = {_blocks};
998 params.set<std::vector<MaterialName>>("inelastic_models") =
999 getParam<std::vector<MaterialName>>("inelastic_models");
1000
1001 _problem->addMaterial(mater_type_name, mater_name, params);
1002 }
1003 }
1004 }
1005}
1006
1007unsigned int
1009{
1010 unsigned int num_points = 0;
1011 if (_boundary_names.size() != 0)
1012 {
1013 std::vector<BoundaryID> bids = _mesh->getBoundaryIDs(_boundary_names, true);
1014 std::set<unsigned int> nodes;
1015
1016 ConstBndNodeRange & bnd_nodes = *_mesh->getBoundaryNodeRange();
1017 for (ConstBndNodeRange::const_iterator nd = bnd_nodes.begin(); nd != bnd_nodes.end(); ++nd)
1018 {
1019 const BndNode * bnode = *nd;
1020 BoundaryID boundary_id = bnode->_bnd_id;
1021
1022 for (unsigned int ibid = 0; ibid < bids.size(); ++ibid)
1023 {
1024 if (boundary_id == bids[ibid])
1025 {
1026 nodes.insert(bnode->_node->id());
1027 break;
1028 }
1029 }
1030 }
1031 num_points = nodes.size();
1032 }
1033 else if (_crack_front_points.size() != 0)
1034 num_points = _crack_front_points.size();
1036 {
1037 if (isParamValid("number_points_from_provider"))
1038 num_points = getParam<unsigned int>("number_points_from_provider");
1039 else
1040 // Actual count determined at runtime by CrackFrontDefinition::initialSetup()
1041 // which calls provider->getNumberOfCrackFrontPoints(). Use 0 here so the
1042 // action does not create per-point objects that would access crack front data
1043 // before it exists. The VectorPostprocessors (JIntegral, InteractionIntegral,
1044 // etc.) dynamically size based on the runtime count.
1045 num_points = 0;
1046 }
1047 else
1048 mooseError("Must define either 'boundary' or 'crack_front_points'");
1049 return num_points;
1050}
1051
1052void
1054{
1055 if (_integrals.count(INTERACTION_INTEGRAL_T) != 0)
1056 {
1057 InputParameters params = _factory.getValidParams("CrackFrontDefinition");
1058 addRelationshipManagers(input_rm_type, params);
1059 }
1060}
boundary_id_type BoundaryID
registerMooseAction("SolidMechanicsApp", DomainIntegralAction, "add_user_object")
std::vector< VariableName > CoupledName
const ExecFlagType EXEC_TIMESTEP_END
const ExecFlagType EXEC_INITIAL
const ExecFlagType EXEC_XFEM_MARK
Exec flag used to execute MooseObjects while elements are being marked for cutting by XFEM.
void ErrorVector unsigned int
std::shared_ptr< MooseMesh > & _mesh
static InputParameters validParams()
std::shared_ptr< FEProblemBase > & _problem
const std::string & _current_task
static void includeCrackFrontDefinitionParams(InputParameters &params)
used by Actions to add CrackFrontDefinitionParams
Base class for crack front points provider.
virtual unsigned int getNumberOfCrackFrontPoints() const =0
Get the current number of crack front points.
Action to set up all objects used in computation of fracture domain integrals.
const std::string _family
const bool _have_crack_direction_vector_end_2
Whether the crack direction vector at the 2nd end of the crack has been provided.
virtual void act() override
MooseEnum _q_function_type
How the q function is evaluated (geometric distance from crack front or ring of elements)
const RealVectorValue _crack_direction_vector_end_2
Vector optionally used to prescribe direction of crack extension at the 2nd end of the crack.
virtual void addRelationshipManagers(Moose::RelationshipManagerType input_rm_type) override
const bool _use_ad
Whether to create automatic differentiation objects from the action.
std::vector< BoundaryName > _crack_mouth_boundary_names
Names of boundaries optionally used to define the crack mouth location.
MooseEnum _end_direction_method_moose_enum
Enum used to define the method to compute crack front direction at ends of crack front.
std::vector< VariableName > _output_variables
List of variables for which values are to be sampled and output at the crack front points.
static InputParameters validParams()
Real _poissons_ratio
Poisson's ratio of material.
const RealVectorValue _crack_direction_vector
Vector optionally used to prescribe direction of crack extension.
bool _fgm_crack
Whether the crack lives in a functionally-graded material.
VariableName _temp
Temperature variable.
MaterialPropertyName _functionally_graded_youngs_modulus
Material property name for spatially-dependent Youngs modulus for functionally graded materials.
bool _convert_J_to_K
Whether to convert the J-integral to a stress intensity factor (K) –deprecated.
bool _get_equivalent_k
Whether to compute the equivalent K from the individual fracture integrals for mixed-mode fracture.
std::vector< Point > _crack_front_points
User-defined vector of crack front points.
bool _output_q
Whether to ouput the q function as a set of AuxVariables.
const bool _have_crack_direction_vector_end_1
Whether the crack direction vector at the 1st end of the crack has been provided.
unsigned int _ring_last
Number of elements away from the crack tip to outside of outer ring with the topological q function.
INTEGRAL
Enum used to select the type of integral to be performed.
Real _youngs_modulus
Young's modulus of material.
UserObjectName _crack_front_points_provider
Name of crack front points provider user object used to optionally define the crack points.
bool _incremental
Whether the constitutive models for the mechanics calculations use an incremental form.
std::vector< unsigned int > _ring_vec
Vector of ids for the individual rings on which the fracture integral is computed.
std::vector< SubdomainName > _blocks
Blocks for which the domain integrals are to be computed.
unsigned int calcNumCrackFrontPoints()
Compute the number of points on the crack front.
const std::vector< BoundaryName > & _boundary_names
Boundaries containing the crack front points.
const bool _have_crack_direction_vector
Whether the crack direction vector has been provided.
MooseEnum _direction_method_moose_enum
Enum used to define the method to compute crack front direction.
bool _closed_loop
Indicates whether the crack forms a closed loop.
const RealVectorValue _crack_direction_vector_end_1
Vector optionally used to prescribe direction of crack extension at the 1st end of the crack.
DomainIntegralAction(const InputParameters &params)
MaterialPropertyName _functionally_graded_youngs_modulus_crack_dir_gradient
Material property name for the Youngs modulus derivative for functionally graded materials.
std::vector< Real > _radius_inner
Sets of inner and outer radii of the rings used for the domain form of the fracture integrals.
bool _use_displaced_mesh
Whether to compute the fracture integrals on the displaced mesh.
std::set< INTEGRAL > _integrals
Container for enumerations describing the individual integrals computed.
unsigned int _symmetry_plane
Identifier for which plane is the symmetry plane.
unsigned int _axis_2d
Out-of-plane axis for 3D models treated as 2D.
std::vector< VariableName > _displacements
Vector of displacement variables.
unsigned int _ring_first
Number of elements away from the crack tip to inside of inner ring with the topological q function.
std::vector< Real > _radius_outer
bool _has_symmetry_plane
Whether the model has a symmetry plane passing through the plane of the crack.
const std::string _order
Order and family of the AuxVariables optionally created to output the values of q.
bool _treat_as_2d
Whether fracture computations for a 3D model should be treated as though it were a 2D model.
bool _use_crack_front_points_provider
Whether to use a crack front points provider.
std::vector< BoundaryName > _intersecting_boundary_names
Names of boundaries optionally used for improved computation of crack extension direction at ends of ...
MooseEnum _position_type
How the distance along the crack front is measured (angle or distance)
InputParameters getValidParams(const std::string &name) const
void addParamNamesToGroup(const std::string &space_delim_names, const std::string group_name)
void addRequiredParam(const std::string &name, const std::string &doc_string)
void addDeprecatedParam(const std::string &name, const T &value, const std::string &doc_string, const std::string &deprecation_message)
void addParam(const std::string &name, const std::initializer_list< typename T::value_type > &value, const std::string &doc_string)
std::vector< std::pair< R1, R2 > > get(const std::string &param1, const std::string &param2) const
void addClassDescription(const std::string &doc_string)
T & set(const std::string &name, bool quiet_mode=false)
void addCoupledVar(const std::string &name, const std::string &doc_string)
bool isParamValid(const std::string &name) const
const InputParameters & parameters() const
const std::string & name() const
void paramError(const std::string &param, Args... args) const
void mooseError(Args &&... args) const
const T & getParam(const std::string &name) const
bool isParamValid(const std::string &name) const
std::string getRawNames() const
Factory & _factory
dof_id_type id() const
const_iterator begin() const
const_iterator end() const
vec_type::const_iterator const_iterator
std::string stringify(const T &t)
RelationshipManagerType
BoundaryID _bnd_id
libMesh::Node * _node