24 "The material objects used to compute softening behavior for loading a crack."
25 "Either 1 or 3 models must be specified. If a single model is specified, it is"
26 "used for all directions. If 3 models are specified, they will be used for the"
27 "3 crack directions in sequence");
30 "The stress threshold beyond which cracking occurs. Negative values prevent cracking.");
33 "prescribed_crack_directions", direction,
"Prescribed directions of first cracks");
35 "max_cracks", 3,
"The maximum number of cracks allowed at a material point.");
38 "cracking_neg_fraction <= 1 & cracking_neg_fraction >= 0",
39 "The fraction of the cracking strain at which "
40 "a transition begins during decreasing "
41 "strain to the original stiffness.");
43 "max_stress_correction",
45 "Maximum permitted correction to the predicted stress as a ratio of the "
46 "stress change to the predicted stress from the previous step's damage level. "
47 "Values less than 1 will improve robustness, but not be as accurate.");
50 "shear_retention_factor",
52 "shear_retention_factor>=0 & shear_retention_factor<=1.0",
53 "Fraction of original shear stiffness to be retained after cracking");
54 params.
set<std::vector<MaterialName>>(
"inelastic_models") = {};
56 MooseEnum crackedElasticityType(
"DIAGONAL FULL",
"DIAGONAL");
58 "DIAGONAL",
"Zero out terms coupling with directions orthogonal to a crack (legacy)");
60 "FULL",
"Consistently scale all entries based on damage (recommended)");
62 "cracked_elasticity_type",
63 crackedElasticityType,
64 "Method to modify the local elasticity tensor to account for cracking");
71 _cracking_stress(coupledValue(
"cracking_stress")),
72 _max_cracks(getParam<unsigned
int>(
"max_cracks")),
73 _cracking_neg_fraction(getParam<Real>(
"cracking_neg_fraction")),
74 _shear_retention_factor(getParam<Real>(
"shear_retention_factor")),
75 _max_stress_correction(getParam<Real>(
"max_stress_correction")),
76 _cracked_elasticity_type(
78 _crack_damage(declareProperty<RealVectorValue>(_base_name +
"crack_damage")),
79 _crack_damage_old(getMaterialPropertyOld<RealVectorValue>(_base_name +
"crack_damage")),
80 _crack_flags(declareProperty<RealVectorValue>(_base_name +
"crack_flags")),
81 _crack_rotation(declareProperty<
RankTwoTensor>(_base_name +
"crack_rotation")),
82 _crack_rotation_old(getMaterialPropertyOld<
RankTwoTensor>(_base_name +
"crack_rotation")),
83 _crack_initiation_strain(
84 declareProperty<RealVectorValue>(_base_name +
"crack_initiation_strain")),
85 _crack_initiation_strain_old(
86 getMaterialPropertyOld<RealVectorValue>(_base_name +
"crack_initiation_strain")),
87 _crack_max_strain(declareProperty<RealVectorValue>(_base_name +
"crack_max_strain")),
88 _crack_max_strain_old(getMaterialPropertyOld<RealVectorValue>(_base_name +
"crack_max_strain"))
91 getParam<MultiMooseEnum>(
"prescribed_crack_directions");
92 if (prescribed_crack_directions.
size() > 0)
94 if (prescribed_crack_directions.
size() > 3)
95 mooseError(
"A maximum of three crack directions may be specified");
96 for (
unsigned int i = 0; i < prescribed_crack_directions.
size(); ++i)
98 for (
unsigned int j = 0; j < i; ++j)
99 if (prescribed_crack_directions[i] == prescribed_crack_directions[j])
100 mooseError(
"Entries in 'prescribed_crack_directions' cannot be repeated");
102 static_cast<unsigned int>(prescribed_crack_directions.
get(i)));
108 std::set<unsigned int> available_dirs = {0, 1, 2};
110 if (available_dirs.erase(dir) != 1)
112 if (available_dirs.size() != 1)
113 mooseError(
"Error in finding remaining available crack direction");
117 if (!isParamSetByUser(
"cracked_elasticity_type"))
119 "cracked_elasticity_type",
120 "Defaulting to the legacy option of 'DIAGONAL', but the 'FULL' option is preferred");
173 mooseError(
"Number of prescribed crack directions cannot be 2");
180 RealVectorValue crack_dir_vec;
194 mooseError(
"ComputeSmearedCrackingStress requires that the elasticity tensor be "
195 "guaranteed isotropic");
197 std::vector<MaterialName> soft_matls = getParam<std::vector<MaterialName>>(
"softening_models");
198 for (
auto soft_matl : soft_matls)
205 paramError(
"softening_models",
"Model " + soft_matl +
" is not a softening model");
214 paramError(
"softening_models",
"Either 1 or 3 softening models must be specified");
220 bool force_elasticity_rotation =
false;
233 model->propagateQpStatefulProperties();
246 force_elasticity_rotation =
true;
262 const Real youngs_modulus =
265 bool cracking_locally_active =
false;
269 if (cracking_stress > 0)
271 RealVectorValue stiffness_ratio_local(1.0, 1.0, 1.0);
276 for (
unsigned int i = 0; i < 3; ++i)
282 stiffness_ratio_local(i) = 1.0;
290 const Real
a = (Ec - Eo) / (4 * etr);
291 const Real
b = (Ec + Eo) / 2;
293 stiffness_ratio_local(i) = (2.0 *
a * etr +
b) / Eo;
294 cracking_locally_active =
true;
299 cracking_locally_active =
true;
304 if (cracking_locally_active)
309 const bool c0_coupled = MooseUtils::absoluteFuzzyEqual(stiffness_ratio_local(0), 1.0);
310 const bool c1_coupled = MooseUtils::absoluteFuzzyEqual(stiffness_ratio_local(1), 1.0);
311 const bool c2_coupled = MooseUtils::absoluteFuzzyEqual(stiffness_ratio_local(2), 1.0);
313 const Real c01 = (c0_coupled && c1_coupled ? 1.0 : 0.0);
314 const Real c02 = (c0_coupled && c2_coupled ? 1.0 : 0.0);
315 const Real c12 = (c1_coupled && c2_coupled ? 1.0 : 0.0);
322 : stiffness_ratio_local(0) * youngs_modulus);
326 : stiffness_ratio_local(1) * youngs_modulus);
329 : stiffness_ratio_local(2) * youngs_modulus);
336 const Real & c0 = stiffness_ratio_local(0);
337 const Real & c1 = stiffness_ratio_local(1);
338 const Real & c2 = stiffness_ratio_local(2);
340 const Real c01 = c0 * c1;
341 const Real c02 = c0 * c2;
342 const Real c12 = c1 * c2;
368 if (!cracking_locally_active)
375 const Real youngs_modulus =
378 const Real poissons_ratio =
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;
421 for (
unsigned int i = 0; i < 3; ++i)
423 sigma(i) = sigmaPrime(i, i);
428 const bool met_stress_criterion = (sigma(i) > cracking_stress);
429 const bool loading_existing_crack = (strain_in_crack_dir(i) >=
_crack_max_strain[_qp](i));
430 const bool allowed_to_crack = (pre_existing_crack || num_cracks <
_max_cracks);
431 bool new_crack =
false;
433 cracked |= pre_existing_crack;
436 if (met_stress_criterion && !pre_existing_crack && allowed_to_crack)
450 if (new_crack || (pre_existing_crack && loading_existing_crack))
455 strain_in_crack_dir(i),
471 const Real
a = (Ec - Eo) / (4.0 * etr);
472 const Real
b = 0.5 * (Ec + Eo);
473 const Real
c = 0.25 * (Ec - Eo) * etr;
474 sigma(i) = (
a * strain_in_crack_dir(i) +
b) * strain_in_crack_dir(i) +
c;
489 RealVectorValue & strain_in_crack_dir)
496 if (num_known_dirs == 0)
498 std::vector<Real> eigval(3, 0.0);
510 strain_in_crack_dir(0) = eigval[2];
511 strain_in_crack_dir(1) = eigval[1];
512 strain_in_crack_dir(2) = eigval[0];
514 else if (num_known_dirs == 1)
530 e2x2(0, 0) = ePrime(1, 1);
531 e2x2(1, 0) = ePrime(2, 1);
532 e2x2(0, 1) = ePrime(1, 2);
533 e2x2(1, 1) = ePrime(2, 2);
538 e2x2.
eigen(e_val2x1, e_vec2x2);
542 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));
546 strain_in_crack_dir(0) = ePrime(0, 0);
547 strain_in_crack_dir(1) = e_val2x1(1, 0);
548 strain_in_crack_dir(2) = e_val2x1(0, 0);
550 else if (num_known_dirs == 2 || num_known_dirs == 3)
558 strain_in_crack_dir(0) = ePrime(0, 0);
559 strain_in_crack_dir(1) = ePrime(1, 1);
560 strain_in_crack_dir(2) = ePrime(2, 2);
563 mooseError(
"Invalid number of known crack directions");
569 unsigned int num_known_dirs = 0;
570 for (
unsigned int i = 0; i < 3; ++i)
575 return num_known_dirs;
580 const RealVectorValue & sigma)
588 for (
unsigned int i = 0; i < 3; ++i)
591 const Real stress_correction_ratio = (tensor(i, i) - sigma(i)) / tensor(i, i);
597 tensor(i, i) = sigma(i);
607 for (
unsigned int i = 0; i < 3; ++i)
registerMooseObject("SolidMechanicsApp", ComputeSmearedCrackingStress)
const PertinentGeochemicalSystem model(database, {"H2O", "H+", "HCO3-", "O2(aq)", "Ca++", ">(s)FeOH", "radius_neg1", "radius_neg1.5"}, {"Calcite"}, {}, {"Calcite_asdf"}, {"CH4(aq)"}, {">(s)FeOCa+"}, "O2(aq)", "e-")
void mooseError(Args &&... args)
void ErrorVector unsigned int
void eigen(ColumnMajorMatrixTempl< T > &eval, ColumnMajorMatrixTempl< T > &evec) const
const std::string _elasticity_tensor_name
Name of the elasticity tensor material property.
const MaterialProperty< RankTwoTensor > & _rotation_increment
Rotation increment material property.
const MaterialProperty< RankFourTensor > & _elasticity_tensor
Elasticity tensor material property.
virtual void initQpStatefulProperties() override
void initialSetup() override
MaterialProperty< RankFourTensor > & _Jacobian_mult
derivative of stress w.r.t. strain (_dstress_dstrain)
MaterialProperty< RankTwoTensor > & _elastic_strain
Elastic strain material property.
MaterialProperty< RankTwoTensor > & _stress
Stress material property.
virtual void finiteStrainRotation(const bool force_elasticity_rotation=false)
Rotate _elastic_strain, _stress, _inelastic_strain, and _Jacobian_mult to the new configuration.
const MaterialProperty< RankTwoTensor > & _strain_increment
const bool _perform_finite_strain_rotations
after updateQpState, rotate the stress, elastic_strain, inelastic_strain and Jacobian_mult using _rot...
std::vector< StressUpdateBase * > _models
The user supplied list of inelastic models to use in the simulation.
MaterialProperty< Real > & _material_timestep_limit
MaterialProperty< RankTwoTensor > & _inelastic_strain
The sum of the inelastic strains that come from the plastic models.
virtual void computeQpStressIntermediateConfiguration()
Compute the stress for the current QP, but do not rotate tensors from the intermediate configuration ...
const MaterialProperty< RankTwoTensor > & _inelastic_strain_old
old value of inelastic strain
const MaterialProperty< RankTwoTensor > & _elastic_strain_old
Strain tensors.
ComputeMultipleInelasticStress computes the stress, the consistent tangent operator (or an approximat...
static InputParameters validParams()
ComputeSmearedCrackingStress computes the stress for a finite strain material with smeared cracking.
const Real _cracking_neg_fraction
Defines transition to changed stiffness during unloading.
const VariableValue & _cracking_stress
Input parameters for smeared crack models.
virtual void updateCrackingStateAndStress()
Update all cracking-related state variables and the stress tensor due to cracking in all directions.
void updateLocalElasticityTensor()
Update the local elasticity tensor (_local_elasticity_tensor) due to the effects of cracking.
ComputeSmearedCrackingStress(const InputParameters ¶meters)
virtual void computeQpStress() override
Compute the stress and store it in the _stress material property for the current quadrature point.
MaterialProperty< RealVectorValue > & _crack_max_strain
std::vector< unsigned int > _prescribed_crack_directions
User-prescribed cracking directions.
const MaterialProperty< RealVectorValue > & _crack_initiation_strain_old
MaterialProperty< RealVectorValue > & _crack_damage
std::vector< SmearedCrackSofteningBase * > _softening_models
The user-supplied list of softening models to be used in the 3 crack directions.
std::vector< Real > _local_elastic_vector
Vector helper to update local elasticity tensor.
virtual void initQpStatefulProperties() override
const MaterialProperty< RealVectorValue > & _crack_damage_old
MaterialProperty< RankTwoTensor > & _crack_rotation
const unsigned int _max_cracks
Maximum number of cracks permitted at a material point.
void updateStressTensorForCracking(RankTwoTensor &tensor, const RealVectorValue &sigma)
Updates the full stress tensor to account for the effect of cracking using the provided stresses in t...
static InputParameters validParams()
bool previouslyCracked()
Check to see whether there was cracking in any diretion in the previous time step.
MaterialProperty< RealVectorValue > & _crack_initiation_strain
const MaterialProperty< RankTwoTensor > & _crack_rotation_old
MaterialProperty< RealVectorValue > & _crack_flags
Vector of values going from 1 to 0 as crack damage accumulates.
void computeCrackStrainAndOrientation(RealVectorValue &strain_in_crack_dir)
Compute the crack strain in the crack coordinate system.
virtual unsigned int getNumKnownCrackDirs() const
Get the number of known crack directions.
CrackedElasticityType
Enum defining the method used to adjust the elasticity tensor for cracking.
const Real _shear_retention_factor
Controls the amount of shear retained.
RankFourTensor _local_elasticity_tensor
const MaterialProperty< RealVectorValue > & _crack_max_strain_old
enum ComputeSmearedCrackingStress::CrackedElasticityType _cracked_elasticity_type
virtual void initialSetup() override
const Real _max_stress_correction
Controls the maximum amount that the damaged elastic stress is corrected to folow the release model d...
bool hasGuaranteedMaterialProperty(const MaterialPropertyName &prop, Guarantee guarantee)
virtual unsigned int size() const override final
void addDocumentation(const std::string &name, const std::string &doc)
unsigned int get(unsigned int i) const
unsigned int size() const
void fillFromInputVector(const std::vector< T > &input, FillMethod fill_method)
void rotate(const TypeTensor< T > &R)
void rotate(const RankTwoTensorTempl< T > &R)
libMesh::VectorValue< T > column(const unsigned int i) const
void symmetricEigenvaluesEigenvectors(std::vector< T > &eigvals, RankTwoTensorTempl< T > &eigvecs) const
static RankTwoTensorTempl Identity()
SmearedCrackSofteningBase is the base class for a set of models that define the softening behavior of...
std::string stringify(const T &t)