13 #include "Conversion.h"
23 params.addClassDescription(
"Compute stress using a fixed smeared cracking model");
24 MooseEnum cracking_release(
"abrupt exponential power",
"abrupt");
25 params.addDeprecatedParam<MooseEnum>(
28 "The cracking release type. 'abrupt' (default) gives an abrupt "
29 "stress release, 'exponential' uses an exponential softening model, "
30 "and 'power' uses a power law",
31 "This is replaced by the use of 'softening_models' together with a separate block defining "
33 params.addParam<std::vector<MaterialName>>(
35 "The material objects used to compute softening behavior for loading a crack."
36 "Either 1 or 3 models must be specified. If a single model is specified, it is"
37 "used for all directions. If 3 models are specified, they will be used for the"
38 "3 crack directions in sequence");
39 params.addDeprecatedParam<Real>(
40 "cracking_residual_stress",
42 "The fraction of the cracking stress allowed to be maintained following a crack.",
43 "This is replaced by the use of 'softening_models' together with a separate block defining "
45 params.addRequiredCoupledVar(
47 "The stress threshold beyond which cracking occurs. Negative values prevent cracking.");
48 MultiMooseEnum direction(
"x y z");
49 params.addParam<MultiMooseEnum>(
50 "prescribed_crack_directions", direction,
"Prescribed directions of first cracks");
51 params.addParam<
unsigned int>(
52 "max_cracks", 3,
"The maximum number of cracks allowed at a material point.");
53 params.addRangeCheckedParam<Real>(
"cracking_neg_fraction",
55 "cracking_neg_fraction <= 1 & cracking_neg_fraction >= 0",
56 "The fraction of the cracking strain at which "
57 "a transition begins during decreasing "
58 "strain to the original stiffness.");
59 params.addDeprecatedParam<Real>(
62 "Coefficient used to control the softening in the exponential model. "
63 "When set to 1, the initial softening slope is equal to the negative "
64 "of the Young's modulus. Smaller numbers scale down that slope.",
65 "This is replaced by the use of 'softening_models' together with a separate block defining "
67 params.addParam<Real>(
68 "max_stress_correction",
70 "Maximum permitted correction to the predicted stress as a ratio of the "
71 "stress change to the predicted stress from the previous step's damage level. "
72 "Values less than 1 will improve robustness, but not be as accurate.");
74 params.addRangeCheckedParam<Real>(
75 "shear_retention_factor",
77 "shear_retention_factor>=0 & shear_retention_factor<=1.0",
78 "Fraction of original shear stiffness to be retained after cracking");
79 params.set<std::vector<MaterialName>>(
"inelastic_models") = {};
86 _cracking_release(getParam<MooseEnum>(
"cracking_release").getEnum<
CrackingRelease>()),
87 _cracking_residual_stress(getParam<Real>(
"cracking_residual_stress")),
88 _cracking_stress(coupledValue(
"cracking_stress")),
89 _max_cracks(getParam<unsigned int>(
"max_cracks")),
90 _cracking_neg_fraction(getParam<Real>(
"cracking_neg_fraction")),
91 _cracking_beta(getParam<Real>(
"cracking_beta")),
92 _shear_retention_factor(getParam<Real>(
"shear_retention_factor")),
93 _max_stress_correction(getParam<Real>(
"max_stress_correction")),
94 _crack_damage(declareProperty<RealVectorValue>(_base_name +
"crack_damage")),
95 _crack_damage_old(getMaterialPropertyOld<RealVectorValue>(_base_name +
"crack_damage")),
96 _crack_flags(declareProperty<RealVectorValue>(_base_name +
"crack_flags")),
97 _crack_rotation(declareProperty<
RankTwoTensor>(_base_name +
"crack_rotation")),
98 _crack_rotation_old(getMaterialPropertyOld<
RankTwoTensor>(_base_name +
"crack_rotation")),
99 _crack_initiation_strain(
100 declareProperty<RealVectorValue>(_base_name +
"crack_initiation_strain")),
101 _crack_initiation_strain_old(
102 getMaterialPropertyOld<RealVectorValue>(_base_name +
"crack_initiation_strain")),
103 _crack_max_strain(declareProperty<RealVectorValue>(_base_name +
"crack_max_strain")),
104 _crack_max_strain_old(getMaterialPropertyOld<RealVectorValue>(_base_name +
"crack_max_strain"))
106 MultiMooseEnum prescribed_crack_directions =
107 getParam<MultiMooseEnum>(
"prescribed_crack_directions");
108 if (prescribed_crack_directions.size() > 0)
110 if (prescribed_crack_directions.size() > 3)
111 mooseError(
"A maximum of three crack directions may be specified");
112 for (
unsigned int i = 0; i < prescribed_crack_directions.size(); ++i)
114 for (
unsigned int j = 0; j < i; ++j)
115 if (prescribed_crack_directions[i] == prescribed_crack_directions[j])
116 mooseError(
"Entries in 'prescribed_crack_directions' cannot be repeated");
118 static_cast<unsigned int>(prescribed_crack_directions.get(i)));
124 std::set<unsigned int> available_dirs = {0, 1, 2};
126 if (available_dirs.erase(dir) != 1)
127 mooseError(
"Invalid prescribed crack direction:" + Moose::stringify(dir));
128 if (available_dirs.size() != 1)
129 mooseError(
"Error in finding remaining available crack direction");
134 if (parameters.isParamSetByUser(
"softening_models"))
136 if (parameters.isParamSetByUser(
"cracking_release"))
137 mooseError(
"In ComputeSmearedCrackingStress cannot specify both 'cracking_release' and "
138 "'softening_models'");
139 if (parameters.isParamSetByUser(
"cracking_residual_stress"))
140 mooseError(
"In ComputeSmearedCrackingStress cannot specify both 'cracking_residual_stress' "
141 "and 'softening_models'");
142 if (parameters.isParamSetByUser(
"cracking_beta"))
143 mooseError(
"In ComputeSmearedCrackingStress cannot specify both 'cracking_beta' and "
144 "'softening_models'");
196 mooseError(
"Number of prescribed crack directions cannot be 2");
203 RealVectorValue crack_dir_vec;
217 mooseError(
"ComputeSmearedCrackingStress requires that the elasticity tensor be "
218 "guaranteed isotropic");
220 std::vector<MaterialName> soft_matls = getParam<std::vector<MaterialName>>(
"softening_models");
221 if (soft_matls.size() != 0)
223 for (
auto soft_matl : soft_matls)
226 dynamic_cast<SmearedCrackSofteningBase *>(&getMaterialByName(soft_matl));
230 mooseError(
"Model " + soft_matl +
231 " is not a softening model that can be used with ComputeSmearedCrackingStress");
240 mooseError(
"If 'softening_models' is specified in ComputeSmearedCrackingStress, either 1 or "
241 "3 models must be provided");
248 bool force_elasticity_rotation =
false;
261 model->propagateQpStatefulProperties();
274 force_elasticity_rotation =
true;
290 const Real youngs_modulus =
293 bool cracking_locally_active =
false;
297 if (cracking_stress > 0)
299 RealVectorValue stiffness_ratio_local(1.0, 1.0, 1.0);
302 ePrime.rotate(R.transpose());
304 for (
unsigned int i = 0; i < 3; ++i)
310 stiffness_ratio_local(i) = 1.0;
318 const Real a = (Ec - Eo) / (4 * etr);
319 const Real b = (Ec + Eo) / 2;
321 stiffness_ratio_local(i) = (2.0 * a * etr + b) / Eo;
322 cracking_locally_active =
true;
327 cracking_locally_active =
true;
332 if (cracking_locally_active)
335 const bool c0_coupled = MooseUtils::absoluteFuzzyEqual(stiffness_ratio_local(0), 1.0);
336 const bool c1_coupled = MooseUtils::absoluteFuzzyEqual(stiffness_ratio_local(1), 1.0);
337 const bool c2_coupled = MooseUtils::absoluteFuzzyEqual(stiffness_ratio_local(2), 1.0);
339 const Real c01 = (c0_coupled && c1_coupled ? 1.0 : 0.0);
340 const Real c02 = (c0_coupled && c2_coupled ? 1.0 : 0.0);
341 const Real c12 = (c1_coupled && c2_coupled ? 1.0 : 0.0);
349 std::vector<Real> local_elastic(9);
352 : stiffness_ratio_local(0) * youngs_modulus);
356 : stiffness_ratio_local(1) * youngs_modulus);
359 : stiffness_ratio_local(2) * youngs_modulus);
370 if (!cracking_locally_active)
377 const Real youngs_modulus =
379 const Real cracking_alpha = -youngs_modulus;
383 if (cracking_stress > 0)
388 for (
unsigned i = 0; i < 3; ++i)
396 RealVectorValue strain_in_crack_dir;
399 for (
unsigned i = 0; i < 3; ++i)
409 sigmaPrime.rotate(R.transpose());
411 unsigned int num_cracks = 0;
412 for (
unsigned int i = 0; i < 3; ++i)
419 RealVectorValue sigma;
420 for (
unsigned int i = 0; i < 3; ++i)
422 sigma(i) = sigmaPrime(i, i);
427 const bool met_stress_criterion = (sigma(i) > cracking_stress);
428 const bool loading_existing_crack = (strain_in_crack_dir(i) >=
_crack_max_strain[_qp](i));
429 const bool allowed_to_crack = (pre_existing_crack || num_cracks <
_max_cracks);
430 bool new_crack =
false;
432 cracked |= pre_existing_crack;
435 if (met_stress_criterion && !pre_existing_crack && allowed_to_crack)
449 if (new_crack || (pre_existing_crack && loading_existing_crack))
455 strain_in_crack_dir(i),
464 strain_in_crack_dir(i),
478 const Real a = (Ec - Eo) / (4.0 * etr);
479 const Real b = 0.5 * (Ec + Eo);
480 const Real c = 0.25 * (Ec - Eo) * etr;
481 sigma(i) = (a * strain_in_crack_dir(i) + b) * strain_in_crack_dir(i) + c;
496 RealVectorValue & strain_in_crack_dir)
503 if (num_known_dirs == 0)
505 std::vector<Real> eigval(3, 0.0);
517 strain_in_crack_dir(0) = eigval[2];
518 strain_in_crack_dir(1) = eigval[1];
519 strain_in_crack_dir(2) = eigval[0];
521 else if (num_known_dirs == 1)
533 ePrime.rotate(R.transpose());
536 ColumnMajorMatrix e2x2(2, 2);
537 e2x2(0, 0) = ePrime(1, 1);
538 e2x2(1, 0) = ePrime(2, 1);
539 e2x2(0, 1) = ePrime(1, 2);
540 e2x2(1, 1) = ePrime(2, 2);
543 ColumnMajorMatrix e_val2x1(2, 1);
544 ColumnMajorMatrix e_vec2x2(2, 2);
545 e2x2.eigen(e_val2x1, e_vec2x2);
549 1.0, 0.0, 0.0, 0.0, e_vec2x2(0, 1), e_vec2x2(1, 1), 0.0, e_vec2x2(0, 0), e_vec2x2(1, 0));
553 strain_in_crack_dir(0) = ePrime(0, 0);
554 strain_in_crack_dir(1) = e_val2x1(1, 0);
555 strain_in_crack_dir(2) = e_val2x1(0, 0);
557 else if (num_known_dirs == 2 || num_known_dirs == 3)
563 ePrime.rotate(R.transpose());
565 strain_in_crack_dir(0) = ePrime(0, 0);
566 strain_in_crack_dir(1) = ePrime(1, 1);
567 strain_in_crack_dir(2) = ePrime(2, 2);
570 mooseError(
"Invalid number of known crack directions");
576 unsigned int num_known_dirs = 0;
577 for (
unsigned int i = 0; i < 3; ++i)
582 return num_known_dirs;
588 Real & stiffness_ratio,
589 const Real strain_in_crack_dir,
590 const Real cracking_stress,
591 const Real cracking_alpha,
592 const Real youngs_modulus)
598 if (sigma > cracking_stress)
600 stiffness_ratio /= 3.0;
601 sigma = stiffness_ratio * youngs_modulus * strain_in_crack_dir;
609 "crack_max_strain must be >= crack_initiation_strain");
626 const Real tiny = 1e-16;
627 stiffness_ratio = tiny;
639 if (stiffness_ratio < 0)
641 std::stringstream err;
642 err <<
"Negative stiffness ratio: " << i <<
" " << stiffness_ratio <<
", "
645 mooseError(err.str());
651 const RealVectorValue & sigma)
656 tensor.rotate(R.transpose());
659 for (
unsigned int i = 0; i < 3; ++i)
662 const Real stress_correction_ratio = (tensor(i, i) - sigma(i)) / tensor(i, i);
668 tensor(i, i) = sigma(i);
678 for (
unsigned int i = 0; i < 3; ++i)