Line data Source code
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
11 : #include "DomainIntegralAction.h"
12 : #include "ExecFlagRegistry.h"
13 : #include "Factory.h"
14 : #include "FEProblem.h"
15 : #include "Moose.h"
16 : #include "Parser.h"
17 : #include "CrackFrontDefinition.h"
18 : #include "MooseMesh.h"
19 : #include "Conversion.h"
20 :
21 : #include "libmesh/string_to_enum.h"
22 :
23 : registerMooseAction("SolidMechanicsApp", DomainIntegralAction, "add_user_object");
24 :
25 : registerMooseAction("SolidMechanicsApp", DomainIntegralAction, "add_aux_variable");
26 :
27 : registerMooseAction("SolidMechanicsApp", DomainIntegralAction, "add_aux_kernel");
28 :
29 : registerMooseAction("SolidMechanicsApp", DomainIntegralAction, "add_postprocessor");
30 :
31 : registerMooseAction("SolidMechanicsApp", DomainIntegralAction, "add_material");
32 :
33 : InputParameters
34 1138 : DomainIntegralAction::validParams()
35 : {
36 1138 : InputParameters params = Action::validParams();
37 1138 : CrackFrontDefinition::includeCrackFrontDefinitionParams(params);
38 : MultiMooseEnum integral_vec(
39 : "JIntegral CIntegral KFromJIntegral InteractionIntegralKI InteractionIntegralKII "
40 1138 : "InteractionIntegralKIII InteractionIntegralT");
41 1138 : params.addClassDescription(
42 : "Creates the MOOSE objects needed to compute fraction domain integrals");
43 2276 : params.addRequiredParam<MultiMooseEnum>("integrals",
44 : integral_vec,
45 1138 : "Domain integrals to calculate. Choices are: " +
46 1138 : integral_vec.getRawNames());
47 2276 : params.addParam<std::vector<BoundaryName>>(
48 : "boundary", {}, "Boundary containing the crack front points");
49 2276 : params.addParam<std::vector<Point>>("crack_front_points", "Set of points to define crack front");
50 2276 : params.addParam<std::string>(
51 : "order", "FIRST", "Specifies the order of the FE shape function to use for q AuxVariables");
52 2276 : params.addParam<std::string>(
53 : "family", "LAGRANGE", "Specifies the family of FE shape functions to use for q AuxVariables");
54 2276 : params.addParam<std::vector<Real>>("radius_inner", "Inner radius for volume integral domain");
55 2276 : params.addParam<std::vector<Real>>("radius_outer", "Outer radius for volume integral domain");
56 2276 : params.addParam<unsigned int>("ring_first",
57 : "The first ring of elements for volume integral domain");
58 2276 : params.addParam<unsigned int>("ring_last",
59 : "The last ring of elements for volume integral domain");
60 2276 : params.addParam<std::vector<VariableName>>(
61 : "output_variable", "Variable values to be reported along the crack front");
62 2276 : params.addParam<Real>("poissons_ratio", "Poisson's ratio");
63 2276 : params.addParam<Real>("youngs_modulus", "Young's modulus");
64 2276 : params.addParam<std::vector<SubdomainName>>(
65 : "block", {}, "The block ids where integrals are defined");
66 2276 : params.addParam<std::vector<VariableName>>(
67 : "displacements",
68 : {},
69 : "The displacements appropriate for the simulation geometry and coordinate system");
70 2276 : params.addParam<VariableName>("temperature", "", "The temperature");
71 2276 : 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 2276 : 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 2276 : 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 2276 : 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 2276 : 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 2276 : 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 2276 : 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 2276 : params.addCoupledVar("additional_eigenstrain_12",
95 : "Optional additional eigenstrain variable that will be accounted for in the "
96 : "interaction integral (component 12 or XZ).");
97 2276 : params.addParamNamesToGroup(
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 2276 : MooseEnum position_type("Angle Distance", "Distance");
102 2276 : params.addParam<MooseEnum>(
103 : "position_type",
104 : position_type,
105 1138 : "The method used to calculate position along crack front. Options are: " +
106 1138 : position_type.getRawNames());
107 2276 : MooseEnum q_function_type("Geometry Topology", "Geometry");
108 2276 : params.addParam<MooseEnum>("q_function_type",
109 : q_function_type,
110 1138 : "The method used to define the integration domain. Options are: " +
111 1138 : q_function_type.getRawNames());
112 2276 : params.addParam<bool>(
113 : "equivalent_k",
114 2276 : false,
115 : "Calculate an equivalent K from KI, KII and KIII, assuming self-similar crack growth.");
116 2276 : params.addParam<bool>("output_q", false, "Output q");
117 2276 : params.addRequiredParam<bool>(
118 : "incremental", "Flag to indicate whether an incremental or total model is being used.");
119 2276 : params.addParam<std::vector<MaterialPropertyName>>(
120 : "eigenstrain_names", "List of eigenstrains applied in the strain calculation");
121 3414 : params.addDeprecatedParam<bool>("convert_J_to_K",
122 2276 : 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 2276 : params.addParam<std::vector<MaterialName>>(
128 : "inelastic_models",
129 : "The material objects to use to calculate the strain energy rate density.");
130 2276 : params.addParam<MaterialPropertyName>("eigenstrain_gradient",
131 : "Material defining gradient of eigenstrain tensor");
132 2276 : params.addParam<MaterialPropertyName>("body_force", "Material defining body force");
133 2276 : params.addParam<bool>("use_automatic_differentiation",
134 2276 : false,
135 : "Flag to use automatic differentiation (AD) objects when possible");
136 2276 : params.addParam<bool>("output_vpp",
137 2276 : 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 1138 : return params;
141 1138 : }
142 :
143 1138 : DomainIntegralAction::DomainIntegralAction(const InputParameters & params)
144 : : Action(params),
145 2276 : _boundary_names(getParam<std::vector<BoundaryName>>("boundary")),
146 2276 : _closed_loop(getParam<bool>("closed_loop")),
147 1138 : _use_crack_front_points_provider(false),
148 2276 : _order(getParam<std::string>("order")),
149 2276 : _family(getParam<std::string>("family")),
150 2276 : _direction_method_moose_enum(getParam<MooseEnum>("crack_direction_method")),
151 2276 : _end_direction_method_moose_enum(getParam<MooseEnum>("crack_end_direction_method")),
152 2276 : _have_crack_direction_vector(isParamValid("crack_direction_vector")),
153 933 : _crack_direction_vector(
154 1138 : _have_crack_direction_vector ? getParam<RealVectorValue>("crack_direction_vector") : 0.0),
155 2276 : _have_crack_direction_vector_end_1(isParamValid("crack_direction_vector_end_1")),
156 157 : _crack_direction_vector_end_1(_have_crack_direction_vector_end_1
157 1138 : ? getParam<RealVectorValue>("crack_direction_vector_end_1")
158 : : 0.0),
159 2276 : _have_crack_direction_vector_end_2(isParamValid("crack_direction_vector_end_2")),
160 157 : _crack_direction_vector_end_2(_have_crack_direction_vector_end_2
161 2276 : ? getParam<RealVectorValue>("crack_direction_vector_end_2")
162 : : 0.0),
163 2276 : _treat_as_2d(getParam<bool>("2d")),
164 2276 : _axis_2d(getParam<unsigned int>("axis_2d")),
165 2276 : _has_symmetry_plane(isParamValid("symmetry_plane")),
166 1952 : _symmetry_plane(_has_symmetry_plane ? getParam<unsigned int>("symmetry_plane")
167 : : std::numeric_limits<unsigned int>::max()),
168 2276 : _position_type(getParam<MooseEnum>("position_type")),
169 2276 : _q_function_type(getParam<MooseEnum>("q_function_type")),
170 2276 : _get_equivalent_k(getParam<bool>("equivalent_k")),
171 1138 : _use_displaced_mesh(false),
172 2276 : _output_q(getParam<bool>("output_q")),
173 2276 : _incremental(getParam<bool>("incremental")),
174 4552 : _convert_J_to_K(isParamValid("convert_J_to_K") ? getParam<bool>("convert_J_to_K") : false),
175 1138 : _fgm_crack(false),
176 3414 : _use_ad(getParam<bool>("use_automatic_differentiation"))
177 : {
178 :
179 2276 : if (isParamValid("functionally_graded_youngs_modulus_crack_dir_gradient") !=
180 2276 : isParamValid("functionally_graded_youngs_modulus"))
181 1 : 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 3411 : if (isParamValid("functionally_graded_youngs_modulus_crack_dir_gradient") &&
190 1233 : isParamValid("functionally_graded_youngs_modulus"))
191 : {
192 48 : _fgm_crack = true;
193 : _functionally_graded_youngs_modulus_crack_dir_gradient =
194 48 : getParam<MaterialPropertyName>("functionally_graded_youngs_modulus_crack_dir_gradient");
195 : _functionally_graded_youngs_modulus =
196 96 : getParam<MaterialPropertyName>("functionally_graded_youngs_modulus");
197 : }
198 :
199 1137 : if (_q_function_type == GEOMETRY)
200 : {
201 4068 : if (isParamValid("radius_inner") && isParamValid("radius_outer"))
202 : {
203 2034 : _radius_inner = getParam<std::vector<Real>>("radius_inner");
204 2034 : _radius_outer = getParam<std::vector<Real>>("radius_outer");
205 : }
206 : else
207 0 : mooseError("DomainIntegral error: must set radius_inner and radius_outer.");
208 4767 : for (unsigned int i = 0; i < _radius_inner.size(); ++i)
209 3750 : _ring_vec.push_back(i + 1);
210 : }
211 120 : else if (_q_function_type == TOPOLOGY)
212 : {
213 480 : if (isParamValid("ring_first") && isParamValid("ring_last"))
214 : {
215 240 : _ring_first = getParam<unsigned int>("ring_first");
216 240 : _ring_last = getParam<unsigned int>("ring_last");
217 : }
218 : else
219 0 : mooseError(
220 : "DomainIntegral error: must set ring_first and ring_last if q_function_type = Topology.");
221 528 : for (unsigned int i = _ring_first; i <= _ring_last; ++i)
222 408 : _ring_vec.push_back(i);
223 : }
224 : else
225 0 : paramError("q_function_type", "DomainIntegral error: invalid q_function_type.");
226 :
227 2274 : if (isParamValid("crack_front_points"))
228 288 : _crack_front_points = getParam<std::vector<Point>>("crack_front_points");
229 :
230 2274 : if (isParamValid("crack_front_points_provider"))
231 : {
232 0 : _use_crack_front_points_provider = true;
233 0 : _crack_front_points_provider = getParam<UserObjectName>("crack_front_points_provider");
234 : }
235 2274 : else if (isParamValid("number_points_from_provider"))
236 0 : paramError("crack_front_points_provider",
237 : "DomainIntegral error: number_points_from_provider is provided but "
238 : "crack_front_points_provider cannot be found.");
239 2274 : if (isParamValid("crack_mouth_boundary"))
240 324 : _crack_mouth_boundary_names = getParam<std::vector<BoundaryName>>("crack_mouth_boundary");
241 2274 : if (isParamValid("intersecting_boundary"))
242 396 : _intersecting_boundary_names = getParam<std::vector<BoundaryName>>("intersecting_boundary");
243 1137 : if (_radius_inner.size() != _radius_outer.size())
244 0 : 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 2274 : _blocks = getParam<std::vector<SubdomainName>>("block");
251 :
252 2274 : MultiMooseEnum integral_moose_enums = getParam<MultiMooseEnum>("integrals");
253 2852 : for (unsigned int i = 0; i < integral_moose_enums.size(); ++i)
254 : {
255 5145 : _displacements = getParam<std::vector<VariableName>>("displacements");
256 :
257 1715 : if (_displacements.size() < 2)
258 0 : paramError(
259 : "displacements",
260 : "DomainIntegral error: The size of the displacements vector should at least be 2.");
261 :
262 2570 : if (integral_moose_enums[i] != "JIntegral" && integral_moose_enums[i] != "CIntegral" &&
263 855 : integral_moose_enums[i] != "KFromJIntegral")
264 : {
265 : // Check that parameters required for interaction integrals are defined
266 3324 : if (!(isParamValid("poissons_ratio")) || !(isParamValid("youngs_modulus")))
267 0 : mooseError(
268 : "DomainIntegral error: must set Poisson's ratio and Young's modulus for integral: ",
269 0 : integral_moose_enums[i]);
270 :
271 1662 : _poissons_ratio = getParam<Real>("poissons_ratio");
272 : poissons_ratio_set = true;
273 1662 : _youngs_modulus = getParam<Real>("youngs_modulus");
274 : youngs_modulus_set = true;
275 : }
276 :
277 1715 : _integrals.insert(INTEGRAL(int(integral_moose_enums.get(i))));
278 : }
279 :
280 1137 : if ((_integrals.count(J_INTEGRAL) != 0 && _integrals.count(C_INTEGRAL) != 0) ||
281 1137 : (_integrals.count(J_INTEGRAL) != 0 && _integrals.count(K_FROM_J_INTEGRAL) != 0) ||
282 1137 : (_integrals.count(C_INTEGRAL) != 0 && _integrals.count(K_FROM_J_INTEGRAL) != 0))
283 0 : paramError("integrals",
284 : "JIntegral, CIntegral, and KFromJIntegral options are mutually exclusive");
285 :
286 : // Acommodate deprecated parameter convert_J_to_K
287 1137 : if (_convert_J_to_K && _integrals.count(K_FROM_J_INTEGRAL) != 0)
288 : {
289 0 : _integrals.insert(K_FROM_J_INTEGRAL);
290 0 : _integrals.erase(J_INTEGRAL);
291 : }
292 :
293 2274 : if (isParamValid("temperature"))
294 2274 : _temp = getParam<VariableName>("temperature");
295 :
296 1572 : if (_temp != "" && !isParamValid("eigenstrain_names"))
297 0 : paramError(
298 : "eigenstrain_names",
299 : "DomainIntegral error: must provide `eigenstrain_names` when temperature is coupled.");
300 :
301 1137 : if (_get_equivalent_k && (_integrals.count(INTERACTION_INTEGRAL_KI) == 0 ||
302 156 : _integrals.count(INTERACTION_INTEGRAL_KII) == 0 ||
303 156 : _integrals.count(INTERACTION_INTEGRAL_KIII) == 0))
304 0 : paramError("integrals",
305 : "DomainIntegral error: must calculate KI, KII and KIII to get equivalent K.");
306 :
307 2274 : if (isParamValid("output_variable"))
308 : {
309 360 : _output_variables = getParam<std::vector<VariableName>>("output_variable");
310 120 : if (_crack_front_points.size() > 0)
311 0 : paramError("output_variables",
312 : "'output_variables' not yet supported with 'crack_front_points'");
313 : }
314 :
315 1137 : if (_integrals.count(K_FROM_J_INTEGRAL) != 0)
316 : {
317 96 : if (!isParamValid("youngs_modulus") || !isParamValid("poissons_ratio"))
318 0 : mooseError("DomainIntegral error: must set Young's modulus and Poisson's ratio "
319 : "if K_FROM_J_INTEGRAL is selected.");
320 24 : if (!youngs_modulus_set)
321 0 : _youngs_modulus = getParam<Real>("youngs_modulus");
322 24 : if (!poissons_ratio_set)
323 0 : _poissons_ratio = getParam<Real>("poissons_ratio");
324 : }
325 :
326 1137 : if (_integrals.count(J_INTEGRAL) != 0 || _integrals.count(C_INTEGRAL) != 0 ||
327 277 : _integrals.count(K_FROM_J_INTEGRAL) != 0)
328 : {
329 1768 : if (isParamValid("eigenstrain_gradient"))
330 1 : paramError("eigenstrain_gradient",
331 : "'eigenstrain_gradient' cannot be specified when the computed integrals include "
332 : "JIntegral, CIntegral, or KFromJIntegral");
333 1766 : if (isParamValid("body_force"))
334 1 : paramError("body_force",
335 : "'body_force' cannot be specified when the computed integrals include JIntegral, "
336 : "CIntegral, or KFromJIntegral");
337 : }
338 2318 : if (isParamValid("eigenstrain_gradient") && (_temp != "" || isParamValid("eigenstrain_names")))
339 1 : 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 1134 : }
344 :
345 5640 : DomainIntegralAction::~DomainIntegralAction() {}
346 :
347 : void
348 1131 : DomainIntegralAction::act()
349 : {
350 1131 : const std::string uo_name("crackFrontDefinition");
351 1131 : const std::string ak_base_name("q");
352 1131 : const std::string av_base_name("q");
353 1131 : const unsigned int num_crack_front_points = calcNumCrackFrontPoints();
354 1131 : const std::string aux_stress_base_name("aux_stress");
355 1131 : 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 3393 : std::vector<std::string> xfem_exec_flags = {EXEC_XFEM_MARK, EXEC_TIMESTEP_END};
359 :
360 1131 : std::string ad_prepend = "";
361 1131 : if (_use_ad)
362 : ad_prepend = "AD";
363 :
364 1131 : if (_current_task == "add_user_object")
365 : {
366 189 : const std::string uo_type_name("CrackFrontDefinition");
367 :
368 189 : InputParameters params = _factory.getValidParams(uo_type_name);
369 : // The CrackFrontDefinition updates the vpps and MUST execute before them
370 189 : params.set<int>("execution_order_group") = -1;
371 189 : if (_use_crack_front_points_provider)
372 0 : params.set<ExecFlagEnum>("execute_on") = xfem_exec_flags;
373 : else
374 756 : params.set<ExecFlagEnum>("execute_on") = {EXEC_INITIAL, EXEC_TIMESTEP_END};
375 :
376 189 : params.set<MooseEnum>("crack_direction_method") = _direction_method_moose_enum;
377 189 : params.set<MooseEnum>("crack_end_direction_method") = _end_direction_method_moose_enum;
378 189 : if (_have_crack_direction_vector)
379 155 : params.set<RealVectorValue>("crack_direction_vector") = _crack_direction_vector;
380 189 : if (_have_crack_direction_vector_end_1)
381 26 : params.set<RealVectorValue>("crack_direction_vector_end_1") = _crack_direction_vector_end_1;
382 189 : if (_have_crack_direction_vector_end_2)
383 26 : params.set<RealVectorValue>("crack_direction_vector_end_2") = _crack_direction_vector_end_2;
384 189 : if (_crack_mouth_boundary_names.size() != 0)
385 36 : params.set<std::vector<BoundaryName>>("crack_mouth_boundary") = _crack_mouth_boundary_names;
386 189 : if (_intersecting_boundary_names.size() != 0)
387 44 : params.set<std::vector<BoundaryName>>("intersecting_boundary") = _intersecting_boundary_names;
388 189 : params.set<bool>("2d") = _treat_as_2d;
389 189 : params.set<unsigned int>("axis_2d") = _axis_2d;
390 189 : if (_has_symmetry_plane)
391 135 : params.set<unsigned int>("symmetry_plane") = _symmetry_plane;
392 189 : if (_boundary_names.size() != 0)
393 346 : params.set<std::vector<BoundaryName>>("boundary") = _boundary_names;
394 189 : if (_crack_front_points.size() != 0)
395 32 : params.set<std::vector<Point>>("crack_front_points") = _crack_front_points;
396 189 : if (_use_crack_front_points_provider)
397 : {
398 0 : params.set<UserObjectName>("crack_front_points_provider") = _crack_front_points_provider;
399 0 : if (isParamValid("number_points_from_provider"))
400 0 : params.set<unsigned int>("number_points_from_provider") =
401 0 : getParam<unsigned int>("number_points_from_provider");
402 : }
403 189 : if (_closed_loop)
404 0 : params.set<bool>("closed_loop") = _closed_loop;
405 189 : params.set<bool>("use_displaced_mesh") = _use_displaced_mesh;
406 189 : if (_integrals.count(INTERACTION_INTEGRAL_T) != 0)
407 : {
408 24 : params.set<VariableName>("disp_x") = _displacements[0];
409 24 : params.set<VariableName>("disp_y") = _displacements[1];
410 12 : if (_displacements.size() == 3)
411 16 : params.set<VariableName>("disp_z") = _displacements[2];
412 12 : params.set<bool>("t_stress") = true;
413 : }
414 :
415 : unsigned int nrings = 0;
416 189 : if (_q_function_type == TOPOLOGY)
417 : {
418 20 : params.set<bool>("q_function_rings") = true;
419 20 : params.set<unsigned int>("last_ring") = _ring_last;
420 20 : params.set<unsigned int>("first_ring") = _ring_first;
421 20 : nrings = _ring_last - _ring_first + 1;
422 : }
423 169 : else if (_q_function_type == GEOMETRY)
424 : {
425 169 : params.set<std::vector<Real>>("j_integral_radius_inner") = _radius_inner;
426 338 : params.set<std::vector<Real>>("j_integral_radius_outer") = _radius_outer;
427 169 : nrings = _ring_vec.size();
428 : }
429 :
430 189 : params.set<unsigned int>("nrings") = nrings;
431 189 : params.set<MooseEnum>("q_function_type") = _q_function_type;
432 :
433 189 : _problem->addUserObject(uo_type_name, uo_name, params);
434 189 : }
435 942 : else if (_current_task == "add_aux_variable" && _output_q)
436 : {
437 120 : if (isParamValid("number_points_from_provider") && num_crack_front_points == 0)
438 : {
439 0 : 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 186 : for (unsigned int ring_index = 0; ring_index < _ring_vec.size(); ++ring_index)
446 : {
447 : std::string aux_var_type;
448 146 : if (_family == "LAGRANGE")
449 : aux_var_type = "MooseVariable";
450 0 : else if (_family == "MONOMIAL")
451 : aux_var_type = "MooseVariableConstMonomial";
452 0 : else if (_family == "SCALAR")
453 : aux_var_type = "MooseVariableScalar";
454 : else
455 0 : mooseError("Unsupported finite element family in, " + name() +
456 : ". Please use LAGRANGE, MONOMIAL, or SCALAR");
457 :
458 146 : auto params = _factory.getValidParams(aux_var_type);
459 146 : params.set<MooseEnum>("order") = _order;
460 146 : params.set<MooseEnum>("family") = _family;
461 :
462 146 : if (_treat_as_2d && _use_crack_front_points_provider == false)
463 : {
464 114 : std::ostringstream av_name_stream;
465 114 : av_name_stream << av_base_name << "_" << _ring_vec[ring_index];
466 114 : _problem->addAuxVariable(aux_var_type, av_name_stream.str(), params);
467 114 : }
468 : else
469 : {
470 128 : for (unsigned int cfp_index = 0; cfp_index < num_crack_front_points; ++cfp_index)
471 : {
472 96 : std::ostringstream av_name_stream;
473 96 : av_name_stream << av_base_name << "_" << cfp_index + 1 << "_" << _ring_vec[ring_index];
474 96 : _problem->addAuxVariable(aux_var_type, av_name_stream.str(), params);
475 96 : }
476 : }
477 146 : }
478 : }
479 :
480 902 : else if (_current_task == "add_aux_kernel" && _output_q)
481 : {
482 : std::string ak_type_name;
483 : unsigned int nrings = 0;
484 40 : if (_q_function_type == GEOMETRY)
485 : {
486 : ak_type_name = "DomainIntegralQFunction";
487 32 : nrings = _ring_vec.size();
488 : }
489 8 : else if (_q_function_type == TOPOLOGY)
490 : {
491 : ak_type_name = "DomainIntegralTopologicalQFunction";
492 8 : nrings = _ring_last - _ring_first + 1;
493 : }
494 :
495 40 : InputParameters params = _factory.getValidParams(ak_type_name);
496 160 : params.set<ExecFlagEnum>("execute_on") = {EXEC_INITIAL, EXEC_TIMESTEP_END};
497 80 : params.set<UserObjectName>("crack_front_definition") = uo_name;
498 40 : params.set<bool>("use_displaced_mesh") = _use_displaced_mesh;
499 :
500 186 : for (unsigned int ring_index = 0; ring_index < nrings; ++ring_index)
501 : {
502 146 : if (_q_function_type == GEOMETRY)
503 : {
504 118 : params.set<Real>("j_integral_radius_inner") = _radius_inner[ring_index];
505 118 : params.set<Real>("j_integral_radius_outer") = _radius_outer[ring_index];
506 : }
507 28 : else if (_q_function_type == TOPOLOGY)
508 : {
509 28 : params.set<unsigned int>("ring_index") = _ring_first + ring_index;
510 : }
511 :
512 146 : if (_treat_as_2d && _use_crack_front_points_provider == false)
513 : {
514 114 : std::ostringstream ak_name_stream;
515 114 : ak_name_stream << ak_base_name << "_" << _ring_vec[ring_index];
516 114 : std::ostringstream av_name_stream;
517 114 : av_name_stream << av_base_name << "_" << _ring_vec[ring_index];
518 228 : params.set<AuxVariableName>("variable") = av_name_stream.str();
519 114 : _problem->addAuxKernel(ak_type_name, ak_name_stream.str(), params);
520 114 : }
521 : else
522 : {
523 128 : for (unsigned int cfp_index = 0; cfp_index < num_crack_front_points; ++cfp_index)
524 : {
525 96 : std::ostringstream ak_name_stream;
526 96 : ak_name_stream << ak_base_name << "_" << cfp_index + 1 << "_" << _ring_vec[ring_index];
527 96 : std::ostringstream av_name_stream;
528 192 : av_name_stream << av_base_name << "_" << cfp_index + 1 << "_" << _ring_vec[ring_index];
529 192 : params.set<AuxVariableName>("variable") = av_name_stream.str();
530 96 : params.set<unsigned int>("crack_front_point_index") = cfp_index;
531 96 : _problem->addAuxKernel(ak_type_name, ak_name_stream.str(), params);
532 96 : }
533 : }
534 : }
535 40 : }
536 :
537 862 : 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 188 : if (_use_crack_front_points_provider && isParamValid("number_points_from_provider"))
543 : {
544 0 : auto crack_front_points_provider = &_problem->getUserObject<CrackFrontPointsProvider>(
545 0 : getParam<UserObjectName>("crack_front_points_provider"));
546 0 : if (crack_front_points_provider->usesMesh())
547 : {
548 0 : auto xfem_cutter_points = crack_front_points_provider->getNumberOfCrackFrontPoints();
549 0 : if (xfem_cutter_points != num_crack_front_points)
550 0 : 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 472 : for (std::set<INTEGRAL>::iterator sit = _integrals.begin(); sit != _integrals.end(); ++sit)
560 : {
561 : std::string pp_base_name;
562 284 : 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 :
572 : case K_FROM_J_INTEGRAL:
573 : pp_base_name = "K";
574 : break;
575 :
576 : case INTERACTION_INTEGRAL_KI:
577 : pp_base_name = "II_KI";
578 : break;
579 :
580 : case INTERACTION_INTEGRAL_KII:
581 : pp_base_name = "II_KII";
582 : break;
583 :
584 : case INTERACTION_INTEGRAL_KIII:
585 : pp_base_name = "II_KIII";
586 : break;
587 :
588 : case INTERACTION_INTEGRAL_T:
589 : pp_base_name = "II_T";
590 : break;
591 : }
592 284 : const std::string pp_type_name("VectorPostprocessorComponent");
593 568 : InputParameters params = _factory.getValidParams(pp_type_name);
594 1290 : for (unsigned int ring_index = 0; ring_index < _ring_vec.size(); ++ring_index)
595 : {
596 1006 : if (_treat_as_2d && _use_crack_front_points_provider == false)
597 : {
598 1448 : params.set<VectorPostprocessorName>("vectorpostprocessor") =
599 1448 : pp_base_name + "_2DVPP_" + Moose::stringify(_ring_vec[ring_index]);
600 1448 : std::string pp_name = pp_base_name + +"_" + Moose::stringify(_ring_vec[ring_index]);
601 724 : params.set<unsigned int>("index") = 0;
602 1448 : params.set<std::string>("vector_name") =
603 2172 : pp_base_name + "_" + Moose::stringify(_ring_vec[ring_index]);
604 724 : _problem->addPostprocessor(pp_type_name, pp_name, params);
605 724 : }
606 : else
607 : {
608 1536 : for (unsigned int cfp_index = 0; cfp_index < num_crack_front_points; ++cfp_index)
609 : {
610 2508 : params.set<VectorPostprocessorName>("vectorpostprocessor") =
611 2508 : pp_base_name + "_" + Moose::stringify(_ring_vec[ring_index]);
612 2508 : std::string pp_name = pp_base_name + "_" + Moose::stringify(cfp_index + 1) + "_" +
613 2508 : Moose::stringify(_ring_vec[ring_index]);
614 1254 : params.set<unsigned int>("index") = cfp_index;
615 2508 : params.set<std::string>("vector_name") =
616 3762 : pp_base_name + "_" + Moose::stringify(_ring_vec[ring_index]);
617 1254 : _problem->addPostprocessor(pp_type_name, pp_name, params);
618 : }
619 : }
620 : }
621 : }
622 :
623 188 : if (_get_equivalent_k)
624 : {
625 26 : std::string pp_base_name("Keq");
626 26 : const std::string pp_type_name("VectorPostprocessorComponent");
627 26 : InputParameters params = _factory.getValidParams(pp_type_name);
628 114 : for (unsigned int ring_index = 0; ring_index < _ring_vec.size(); ++ring_index)
629 : {
630 88 : if (_treat_as_2d && _use_crack_front_points_provider == false)
631 : {
632 120 : params.set<VectorPostprocessorName>("vectorpostprocessor") =
633 120 : pp_base_name + "_2DVPP_" + Moose::stringify(_ring_vec[ring_index]);
634 120 : std::string pp_name = pp_base_name + +"_" + Moose::stringify(_ring_vec[ring_index]);
635 60 : params.set<unsigned int>("index") = 0;
636 120 : params.set<std::string>("vector_name") =
637 180 : pp_base_name + "_" + Moose::stringify(_ring_vec[ring_index]);
638 60 : _problem->addPostprocessor(pp_type_name, pp_name, params);
639 60 : }
640 : else
641 : {
642 112 : for (unsigned int cfp_index = 0; cfp_index < num_crack_front_points; ++cfp_index)
643 : {
644 168 : params.set<VectorPostprocessorName>("vectorpostprocessor") =
645 168 : pp_base_name + "_" + Moose::stringify(_ring_vec[ring_index]);
646 168 : std::string pp_name = pp_base_name + "_" + Moose::stringify(cfp_index + 1) + "_" +
647 168 : Moose::stringify(_ring_vec[ring_index]);
648 84 : params.set<unsigned int>("index") = cfp_index;
649 168 : params.set<std::string>("vector_name") =
650 252 : pp_base_name + "_" + Moose::stringify(_ring_vec[ring_index]);
651 84 : _problem->addPostprocessor(pp_type_name, pp_name, params);
652 : }
653 : }
654 : }
655 26 : }
656 :
657 208 : for (unsigned int i = 0; i < _output_variables.size(); ++i)
658 : {
659 20 : const std::string ov_base_name(_output_variables[i]);
660 20 : const std::string pp_type_name("CrackFrontData");
661 20 : InputParameters params = _factory.getValidParams(pp_type_name);
662 40 : params.set<ExecFlagEnum>("execute_on") = EXEC_TIMESTEP_END;
663 40 : params.set<UserObjectName>("crack_front_definition") = uo_name;
664 20 : if (_treat_as_2d && _use_crack_front_points_provider == false)
665 : {
666 0 : std::ostringstream pp_name_stream;
667 0 : pp_name_stream << ov_base_name << "_crack";
668 0 : params.set<VariableName>("variable") = _output_variables[i];
669 0 : _problem->addPostprocessor(pp_type_name, pp_name_stream.str(), params);
670 0 : }
671 : else
672 : {
673 80 : for (unsigned int cfp_index = 0; cfp_index < num_crack_front_points; ++cfp_index)
674 : {
675 60 : std::ostringstream pp_name_stream;
676 60 : pp_name_stream << ov_base_name << "_crack_" << cfp_index + 1;
677 60 : params.set<VariableName>("variable") = _output_variables[i];
678 60 : params.set<unsigned int>("crack_front_point_index") = cfp_index;
679 60 : _problem->addPostprocessor(pp_type_name, pp_name_stream.str(), params);
680 60 : }
681 : }
682 20 : }
683 : }
684 :
685 674 : else if (_current_task == "add_vector_postprocessor")
686 : {
687 188 : if (_integrals.count(J_INTEGRAL) != 0 || _integrals.count(C_INTEGRAL) != 0 ||
688 192 : _integrals.count(K_FROM_J_INTEGRAL) != 0)
689 : {
690 : std::string vpp_base_name;
691 146 : std::string jintegral_selection = "JIntegral";
692 :
693 146 : if (_integrals.count(J_INTEGRAL) != 0)
694 : {
695 : vpp_base_name = "J";
696 : jintegral_selection = "JIntegral";
697 : }
698 12 : else if (_integrals.count(K_FROM_J_INTEGRAL) != 0)
699 : {
700 : vpp_base_name = "K";
701 : jintegral_selection = "KFromJIntegral";
702 : }
703 8 : else if (_integrals.count(C_INTEGRAL) != 0)
704 : {
705 : vpp_base_name = "C";
706 : jintegral_selection = "CIntegral";
707 : }
708 :
709 146 : if (_treat_as_2d && _use_crack_front_points_provider == false)
710 : vpp_base_name += "_2DVPP";
711 :
712 146 : const std::string vpp_type_name("JIntegral");
713 146 : InputParameters params = _factory.getValidParams(vpp_type_name);
714 292 : if (!getParam<bool>("output_vpp"))
715 24 : params.set<std::vector<OutputName>>("outputs") = {"none"};
716 :
717 292 : params.set<ExecFlagEnum>("execute_on") = EXEC_TIMESTEP_END;
718 292 : params.set<UserObjectName>("crack_front_definition") = uo_name;
719 146 : params.set<std::vector<SubdomainName>>("block") = {_blocks};
720 146 : params.set<MooseEnum>("position_type") = _position_type;
721 :
722 146 : if (_integrals.count(K_FROM_J_INTEGRAL) != 0)
723 : {
724 4 : params.set<Real>("youngs_modulus") = _youngs_modulus;
725 4 : params.set<Real>("poissons_ratio") = _poissons_ratio;
726 : }
727 :
728 146 : if (_has_symmetry_plane)
729 118 : params.set<unsigned int>("symmetry_plane") = _symmetry_plane;
730 :
731 : // Select the integral type to be computed in JIntegral vector postprocessor
732 146 : params.set<MooseEnum>("integral") = jintegral_selection;
733 :
734 146 : params.set<std::vector<VariableName>>("displacements") = _displacements;
735 146 : params.set<bool>("use_displaced_mesh") = _use_displaced_mesh;
736 680 : for (unsigned int ring_index = 0; ring_index < _ring_vec.size(); ++ring_index)
737 : {
738 534 : params.set<unsigned int>("ring_index") = _ring_vec[ring_index];
739 1068 : params.set<MooseEnum>("q_function_type") = _q_function_type;
740 :
741 1068 : std::string vpp_name = vpp_base_name + "_" + Moose::stringify(_ring_vec[ring_index]);
742 534 : _problem->addVectorPostprocessor(vpp_type_name, vpp_name, params);
743 : }
744 146 : }
745 :
746 188 : if (_integrals.count(INTERACTION_INTEGRAL_KI) != 0 ||
747 114 : _integrals.count(INTERACTION_INTEGRAL_KII) != 0 ||
748 114 : _integrals.count(INTERACTION_INTEGRAL_KIII) != 0 ||
749 114 : _integrals.count(INTERACTION_INTEGRAL_T) != 0)
750 : {
751 74 : if (_has_symmetry_plane && (_integrals.count(INTERACTION_INTEGRAL_KII) != 0 ||
752 122 : _integrals.count(INTERACTION_INTEGRAL_KIII) != 0))
753 0 : 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 74 : std::string vpp_type_name(ad_prepend + "InteractionIntegral");
759 :
760 74 : InputParameters params = _factory.getValidParams(vpp_type_name);
761 148 : if (!getParam<bool>("output_vpp"))
762 0 : params.set<std::vector<OutputName>>("outputs") = {"none"};
763 :
764 74 : if (_use_crack_front_points_provider)
765 0 : params.set<ExecFlagEnum>("execute_on") = xfem_exec_flags;
766 : else
767 222 : params.set<ExecFlagEnum>("execute_on") = {EXEC_TIMESTEP_END};
768 :
769 160 : if (isParamValid("additional_eigenstrain_00") && isParamValid("additional_eigenstrain_01") &&
770 94 : isParamValid("additional_eigenstrain_11") && isParamValid("additional_eigenstrain_22"))
771 : {
772 8 : params.set<CoupledName>("additional_eigenstrain_00") =
773 8 : getParam<CoupledName>("additional_eigenstrain_00");
774 8 : params.set<CoupledName>("additional_eigenstrain_01") =
775 8 : getParam<CoupledName>("additional_eigenstrain_01");
776 8 : params.set<CoupledName>("additional_eigenstrain_11") =
777 8 : getParam<CoupledName>("additional_eigenstrain_11");
778 8 : params.set<CoupledName>("additional_eigenstrain_22") =
779 12 : getParam<CoupledName>("additional_eigenstrain_22");
780 : }
781 :
782 148 : params.set<UserObjectName>("crack_front_definition") = uo_name;
783 74 : params.set<bool>("use_displaced_mesh") = _use_displaced_mesh;
784 74 : params.set<std::vector<SubdomainName>>("block") = {_blocks};
785 :
786 74 : if (_has_symmetry_plane)
787 48 : params.set<unsigned int>("symmetry_plane") = _symmetry_plane;
788 :
789 74 : if (_fgm_crack)
790 : {
791 8 : params.set<MaterialPropertyName>(
792 : "functionally_graded_youngs_modulus_crack_dir_gradient") = {
793 : _functionally_graded_youngs_modulus_crack_dir_gradient};
794 16 : params.set<MaterialPropertyName>("functionally_graded_youngs_modulus") = {
795 : _functionally_graded_youngs_modulus};
796 : }
797 :
798 74 : params.set<Real>("poissons_ratio") = _poissons_ratio;
799 74 : params.set<Real>("youngs_modulus") = _youngs_modulus;
800 74 : params.set<std::vector<VariableName>>("displacements") = _displacements;
801 74 : if (_temp != "")
802 24 : params.set<std::vector<VariableName>>("temperature") = {_temp};
803 :
804 74 : if (parameters().isParamValid("eigenstrain_gradient"))
805 4 : params.set<MaterialPropertyName>("eigenstrain_gradient") =
806 8 : parameters().get<MaterialPropertyName>("eigenstrain_gradient");
807 148 : if (parameters().isParamValid("body_force"))
808 4 : params.set<MaterialPropertyName>("body_force") =
809 8 : parameters().get<MaterialPropertyName>("body_force");
810 :
811 244 : for (std::set<INTEGRAL>::iterator sit = _integrals.begin(); sit != _integrals.end(); ++sit)
812 : {
813 170 : switch (*sit)
814 : {
815 24 : case J_INTEGRAL:
816 24 : continue;
817 :
818 4 : case C_INTEGRAL:
819 4 : continue;
820 :
821 4 : case K_FROM_J_INTEGRAL:
822 4 : continue;
823 :
824 : case INTERACTION_INTEGRAL_KI:
825 : vpp_base_name = "II_KI";
826 74 : params.set<Real>("K_factor") =
827 74 : 0.5 * _youngs_modulus / (1.0 - std::pow(_poissons_ratio, 2.0));
828 148 : params.set<MooseEnum>("sif_mode") = "KI";
829 74 : break;
830 :
831 : case INTERACTION_INTEGRAL_KII:
832 : vpp_base_name = "II_KII";
833 26 : params.set<Real>("K_factor") =
834 26 : 0.5 * _youngs_modulus / (1.0 - std::pow(_poissons_ratio, 2.0));
835 52 : params.set<MooseEnum>("sif_mode") = "KII";
836 26 : break;
837 :
838 : case INTERACTION_INTEGRAL_KIII:
839 : vpp_base_name = "II_KIII";
840 26 : params.set<Real>("K_factor") = 0.5 * _youngs_modulus / (1.0 + _poissons_ratio);
841 52 : params.set<MooseEnum>("sif_mode") = "KIII";
842 26 : break;
843 :
844 : case INTERACTION_INTEGRAL_T:
845 : vpp_base_name = "II_T";
846 12 : params.set<Real>("K_factor") = _youngs_modulus / (1 - std::pow(_poissons_ratio, 2));
847 24 : params.set<MooseEnum>("sif_mode") = "T";
848 12 : break;
849 : }
850 138 : if (_treat_as_2d && _use_crack_front_points_provider == false)
851 : vpp_base_name += "_2DVPP";
852 610 : for (unsigned int ring_index = 0; ring_index < _ring_vec.size(); ++ring_index)
853 : {
854 472 : params.set<unsigned int>("ring_index") = _ring_vec[ring_index];
855 944 : params.set<MooseEnum>("q_function_type") = _q_function_type;
856 :
857 944 : std::string vpp_name = vpp_base_name + "_" + Moose::stringify(_ring_vec[ring_index]);
858 472 : _problem->addVectorPostprocessor(vpp_type_name, vpp_name, params);
859 : }
860 : }
861 74 : }
862 :
863 188 : if (_get_equivalent_k)
864 : {
865 26 : std::string vpp_base_name("Keq");
866 26 : if (_treat_as_2d && _use_crack_front_points_provider == false)
867 : vpp_base_name += "_2DVPP";
868 26 : const std::string vpp_type_name("MixedModeEquivalentK");
869 26 : InputParameters params = _factory.getValidParams(vpp_type_name);
870 26 : params.set<ExecFlagEnum>("execute_on") = EXEC_TIMESTEP_END;
871 26 : params.set<Real>("poissons_ratio") = _poissons_ratio;
872 :
873 114 : for (unsigned int ring_index = 0; ring_index < _ring_vec.size(); ++ring_index)
874 : {
875 88 : std::string ki_name = "II_KI_";
876 88 : std::string kii_name = "II_KII_";
877 88 : std::string kiii_name = "II_KIII_";
878 88 : params.set<unsigned int>("ring_index") = _ring_vec[ring_index];
879 88 : if (_treat_as_2d && _use_crack_front_points_provider == false)
880 : {
881 120 : params.set<VectorPostprocessorName>("KI_vectorpostprocessor") =
882 120 : ki_name + "2DVPP_" + Moose::stringify(_ring_vec[ring_index]);
883 120 : params.set<VectorPostprocessorName>("KII_vectorpostprocessor") =
884 120 : kii_name + "2DVPP_" + Moose::stringify(_ring_vec[ring_index]);
885 120 : params.set<VectorPostprocessorName>("KIII_vectorpostprocessor") =
886 120 : kiii_name + "2DVPP_" + Moose::stringify(_ring_vec[ring_index]);
887 : }
888 : else
889 : {
890 56 : params.set<VectorPostprocessorName>("KI_vectorpostprocessor") =
891 56 : ki_name + Moose::stringify(_ring_vec[ring_index]);
892 56 : params.set<VectorPostprocessorName>("KII_vectorpostprocessor") =
893 56 : kii_name + Moose::stringify(_ring_vec[ring_index]);
894 56 : params.set<VectorPostprocessorName>("KIII_vectorpostprocessor") =
895 56 : kiii_name + Moose::stringify(_ring_vec[ring_index]);
896 : }
897 176 : params.set<std::string>("KI_vector_name") =
898 264 : ki_name + Moose::stringify(_ring_vec[ring_index]);
899 176 : params.set<std::string>("KII_vector_name") =
900 264 : kii_name + Moose::stringify(_ring_vec[ring_index]);
901 176 : params.set<std::string>("KIII_vector_name") =
902 264 : kiii_name + Moose::stringify(_ring_vec[ring_index]);
903 176 : std::string vpp_name = vpp_base_name + "_" + Moose::stringify(_ring_vec[ring_index]);
904 88 : _problem->addVectorPostprocessor(vpp_type_name, vpp_name, params);
905 : }
906 26 : }
907 :
908 188 : if (!_treat_as_2d || _use_crack_front_points_provider == true)
909 : {
910 88 : for (unsigned int i = 0; i < _output_variables.size(); ++i)
911 : {
912 20 : const std::string vpp_type_name("VectorOfPostprocessors");
913 20 : InputParameters params = _factory.getValidParams(vpp_type_name);
914 20 : params.set<ExecFlagEnum>("execute_on") = EXEC_TIMESTEP_END;
915 20 : std::ostringstream vpp_name_stream;
916 20 : vpp_name_stream << _output_variables[i] << "_crack";
917 : std::vector<PostprocessorName> postprocessor_names;
918 80 : for (unsigned int cfp_index = 0; cfp_index < num_crack_front_points; ++cfp_index)
919 : {
920 60 : std::ostringstream pp_name_stream;
921 120 : pp_name_stream << vpp_name_stream.str() << "_" << cfp_index + 1;
922 60 : postprocessor_names.push_back(pp_name_stream.str());
923 60 : }
924 20 : params.set<std::vector<PostprocessorName>>("postprocessors") = postprocessor_names;
925 20 : _problem->addVectorPostprocessor(vpp_type_name, vpp_name_stream.str(), params);
926 20 : }
927 : }
928 : }
929 :
930 486 : else if (_current_task == "add_material")
931 : {
932 189 : if (_temp != "")
933 : {
934 : std::string mater_name;
935 24 : const std::string mater_type_name("ThermalFractureIntegral");
936 : mater_name = "ThermalFractureIntegral";
937 :
938 24 : InputParameters params = _factory.getValidParams(mater_type_name);
939 48 : params.set<std::vector<MaterialPropertyName>>("eigenstrain_names") =
940 72 : getParam<std::vector<MaterialPropertyName>>("eigenstrain_names");
941 72 : params.set<std::vector<VariableName>>("temperature") = {_temp};
942 24 : params.set<std::vector<SubdomainName>>("block") = {_blocks};
943 24 : _problem->addMaterial(mater_type_name, mater_name, params);
944 24 : }
945 567 : MultiMooseEnum integral_moose_enums = getParam<MultiMooseEnum>("integrals");
946 : bool have_j_integral = false;
947 : bool have_c_integral = false;
948 :
949 474 : for (auto ime : integral_moose_enums)
950 : {
951 573 : if (ime == "JIntegral" || ime == "CIntegral" || ime == "KFromJIntegral" ||
952 240 : ime == "InteractionIntegralKI" || ime == "InteractionIntegralKII" ||
953 335 : ime == "InteractionIntegralKIII" || ime == "InteractionIntegralT")
954 : have_j_integral = true;
955 :
956 285 : if (ime == "CIntegral")
957 : have_c_integral = true;
958 : }
959 189 : if (have_j_integral)
960 : {
961 : std::string mater_name;
962 189 : const std::string mater_type_name(ad_prepend + "StrainEnergyDensity");
963 189 : mater_name = ad_prepend + "StrainEnergyDensity";
964 :
965 189 : InputParameters params = _factory.getValidParams(mater_type_name);
966 378 : _incremental = getParam<bool>("incremental");
967 189 : params.set<bool>("incremental") = _incremental;
968 189 : params.set<std::vector<SubdomainName>>("block") = {_blocks};
969 189 : _problem->addMaterial(mater_type_name, mater_name, params);
970 :
971 : {
972 : std::string mater_name;
973 189 : const std::string mater_type_name(ad_prepend + "EshelbyTensor");
974 189 : mater_name = ad_prepend + "EshelbyTensor";
975 :
976 189 : InputParameters params = _factory.getValidParams(mater_type_name);
977 378 : _displacements = getParam<std::vector<VariableName>>("displacements");
978 189 : params.set<std::vector<VariableName>>("displacements") = _displacements;
979 189 : params.set<std::vector<SubdomainName>>("block") = {_blocks};
980 :
981 189 : if (have_c_integral)
982 8 : params.set<bool>("compute_dissipation") = true;
983 :
984 189 : if (_temp != "")
985 72 : params.set<std::vector<VariableName>>("temperature") = {_temp};
986 :
987 189 : _problem->addMaterial(mater_type_name, mater_name, params);
988 188 : }
989 : // Strain energy rate density needed for C(t)/C* integral
990 188 : if (have_c_integral)
991 : {
992 : std::string mater_name;
993 8 : const std::string mater_type_name(ad_prepend + "StrainEnergyRateDensity");
994 8 : mater_name = ad_prepend + "StrainEnergyRateDensity";
995 :
996 8 : InputParameters params = _factory.getValidParams(mater_type_name);
997 8 : params.set<std::vector<SubdomainName>>("block") = {_blocks};
998 16 : params.set<std::vector<MaterialName>>("inelastic_models") =
999 16 : getParam<std::vector<MaterialName>>("inelastic_models");
1000 :
1001 8 : _problem->addMaterial(mater_type_name, mater_name, params);
1002 8 : }
1003 188 : }
1004 188 : }
1005 2563 : }
1006 :
1007 : unsigned int
1008 1131 : DomainIntegralAction::calcNumCrackFrontPoints()
1009 : {
1010 : unsigned int num_points = 0;
1011 1131 : if (_boundary_names.size() != 0)
1012 : {
1013 1035 : std::vector<BoundaryID> bids = _mesh->getBoundaryIDs(_boundary_names, true);
1014 : std::set<unsigned int> nodes;
1015 :
1016 1035 : ConstBndNodeRange & bnd_nodes = *_mesh->getBoundaryNodeRange();
1017 108624 : for (ConstBndNodeRange::const_iterator nd = bnd_nodes.begin(); nd != bnd_nodes.end(); ++nd)
1018 : {
1019 107589 : const BndNode * bnode = *nd;
1020 107589 : BoundaryID boundary_id = bnode->_bnd_id;
1021 :
1022 213063 : for (unsigned int ibid = 0; ibid < bids.size(); ++ibid)
1023 : {
1024 107589 : if (boundary_id == bids[ibid])
1025 : {
1026 2115 : nodes.insert(bnode->_node->id());
1027 2115 : break;
1028 : }
1029 : }
1030 : }
1031 1035 : num_points = nodes.size();
1032 1035 : }
1033 96 : else if (_crack_front_points.size() != 0)
1034 96 : num_points = _crack_front_points.size();
1035 0 : else if (_use_crack_front_points_provider)
1036 : {
1037 0 : if (isParamValid("number_points_from_provider"))
1038 0 : 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 0 : mooseError("Must define either 'boundary' or 'crack_front_points'");
1049 1131 : return num_points;
1050 : }
1051 :
1052 : void
1053 3390 : DomainIntegralAction::addRelationshipManagers(Moose::RelationshipManagerType input_rm_type)
1054 : {
1055 3390 : if (_integrals.count(INTERACTION_INTEGRAL_T) != 0)
1056 : {
1057 216 : InputParameters params = _factory.getValidParams("CrackFrontDefinition");
1058 216 : addRelationshipManagers(input_rm_type, params);
1059 216 : }
1060 3390 : }
|