www.mooseframework.org
ComputeSmearedCrackingStress.C
Go to the documentation of this file.
1 //* This file is part of the MOOSE framework
2 //* https://www.mooseframework.org
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 
11 #include "ElasticityTensorTools.h"
12 #include "StressUpdateBase.h"
13 #include "Conversion.h"
14 
16 
18 
19 InputParameters
21 {
22  InputParameters params = ComputeMultipleInelasticStress::validParams();
23  params.addClassDescription("Compute stress using a fixed smeared cracking model");
24  MooseEnum cracking_release("abrupt exponential power", "abrupt");
25  params.addDeprecatedParam<MooseEnum>(
26  "cracking_release",
27  cracking_release,
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 "
32  "a softening model");
33  params.addParam<std::vector<MaterialName>>(
34  "softening_models",
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",
41  0.0,
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 "
44  "a softening model");
45  params.addRequiredCoupledVar(
46  "cracking_stress",
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",
54  0,
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>(
60  "cracking_beta",
61  1.0,
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 "
66  "a softening model");
67  params.addParam<Real>(
68  "max_stress_correction",
69  1.0,
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.");
73 
74  params.addRangeCheckedParam<Real>(
75  "shear_retention_factor",
76  0.0,
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") = {};
80 
81  return params;
82 }
83 
85  : ComputeMultipleInelasticStress(parameters),
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"))
105 {
106  MultiMooseEnum prescribed_crack_directions =
107  getParam<MultiMooseEnum>("prescribed_crack_directions");
108  if (prescribed_crack_directions.size() > 0)
109  {
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)
113  {
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)));
119  }
120 
121  // Fill in the last remaining direction if 2 are specified
122  if (_prescribed_crack_directions.size() == 2)
123  {
124  std::set<unsigned int> available_dirs = {0, 1, 2};
125  for (auto dir : _prescribed_crack_directions)
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");
130  _prescribed_crack_directions.push_back(*available_dirs.begin());
131  }
132  }
133 
134  if (parameters.isParamSetByUser("softening_models"))
135  {
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'");
145  }
146 }
147 
148 void
150 {
152 
153  _crack_damage[_qp] = 0.0;
154 
155  _crack_initiation_strain[_qp] = 0.0;
156  _crack_max_strain[_qp](0) = 0.0;
157 
158  switch (_prescribed_crack_directions.size())
159  {
160  case 0:
161  {
162  _crack_rotation[_qp] = RankTwoTensor::Identity();
163  break;
164  }
165  case 1:
166  {
167  _crack_rotation[_qp].zero();
168  switch (_prescribed_crack_directions[0])
169  {
170  case 0:
171  {
172  _crack_rotation[_qp](0, 0) = 1.0;
173  _crack_rotation[_qp](1, 1) = 1.0;
174  _crack_rotation[_qp](2, 2) = 1.0;
175  break;
176  }
177  case 1:
178  {
179  _crack_rotation[_qp](1, 0) = 1.0;
180  _crack_rotation[_qp](0, 1) = 1.0;
181  _crack_rotation[_qp](2, 2) = 1.0;
182  break;
183  }
184  case 2:
185  {
186  _crack_rotation[_qp](2, 0) = 1.0;
187  _crack_rotation[_qp](0, 1) = 1.0;
188  _crack_rotation[_qp](1, 2) = 1.0;
189  break;
190  }
191  }
192  break;
193  }
194  case 2:
195  {
196  mooseError("Number of prescribed crack directions cannot be 2");
197  break;
198  }
199  case 3:
200  {
201  for (unsigned int i = 0; i < _prescribed_crack_directions.size(); ++i)
202  {
203  RealVectorValue crack_dir_vec;
204  crack_dir_vec(_prescribed_crack_directions[i]) = 1.0;
205  _crack_rotation[_qp].fillColumn(i, crack_dir_vec);
206  }
207  }
208  }
209 }
210 
211 void
213 {
215 
217  mooseError("ComputeSmearedCrackingStress requires that the elasticity tensor be "
218  "guaranteed isotropic");
219 
220  std::vector<MaterialName> soft_matls = getParam<std::vector<MaterialName>>("softening_models");
221  if (soft_matls.size() != 0)
222  {
223  for (auto soft_matl : soft_matls)
224  {
226  dynamic_cast<SmearedCrackSofteningBase *>(&getMaterialByName(soft_matl));
227  if (scsb)
228  _softening_models.push_back(scsb);
229  else
230  mooseError("Model " + soft_matl +
231  " is not a softening model that can be used with ComputeSmearedCrackingStress");
232  }
233  if (_softening_models.size() == 1)
234  {
235  // Reuse the same model in all 3 directions
236  _softening_models.push_back(_softening_models[0]);
237  _softening_models.push_back(_softening_models[0]);
238  }
239  else if (_softening_models.size() != 3)
240  mooseError("If 'softening_models' is specified in ComputeSmearedCrackingStress, either 1 or "
241  "3 models must be provided");
242  }
243 }
244 
245 void
247 {
248  bool force_elasticity_rotation = false;
249 
250  if (!previouslyCracked())
252  else
253  {
255 
256  // Propagate behavior from the (now inactive) inelastic models
258  for (auto model : _models)
259  {
260  model->setQp(_qp);
261  model->propagateQpStatefulProperties();
262  }
263 
264  // Since the other inelastic models are inactive, they will not limit the time step
265  _matl_timestep_limit[_qp] = std::numeric_limits<Real>::max();
266 
267  // update _local_elasticity_tensor based on cracking state in previous time step
269 
270  // Calculate stress in intermediate configuration
272 
274  force_elasticity_rotation = true;
275  }
276 
277  // compute crack status and adjust stress
279 
281  {
282  finiteStrainRotation(force_elasticity_rotation);
284  }
285 }
286 
287 void
289 {
290  const Real youngs_modulus =
292 
293  bool cracking_locally_active = false;
294 
295  const Real cracking_stress = _cracking_stress[_qp];
296 
297  if (cracking_stress > 0)
298  {
299  RealVectorValue stiffness_ratio_local(1.0, 1.0, 1.0);
300  const RankTwoTensor & R = _crack_rotation_old[_qp];
301  RankTwoTensor ePrime(_elastic_strain_old[_qp]);
302  ePrime.rotate(R.transpose());
303 
304  for (unsigned int i = 0; i < 3; ++i)
305  {
306  // Update elasticity tensor based on crack status of the end of last time step
307  if (_crack_damage_old[_qp](i) > 0.0)
308  {
309  if (_cracking_neg_fraction == 0.0 && MooseUtils::absoluteFuzzyLessThan(ePrime(i, i), 0.0))
310  stiffness_ratio_local(i) = 1.0;
311  else if (_cracking_neg_fraction > 0.0 &&
312  ePrime(i, i) < _crack_initiation_strain_old[_qp](i) * _cracking_neg_fraction &&
313  ePrime(i, i) > -_crack_initiation_strain_old[_qp](i) * _cracking_neg_fraction)
314  {
315  const Real etr = _cracking_neg_fraction * _crack_initiation_strain_old[_qp](i);
316  const Real Eo = cracking_stress / _crack_initiation_strain_old[_qp](i);
317  const Real Ec = Eo * (1.0 - _crack_damage_old[_qp](i));
318  const Real a = (Ec - Eo) / (4 * etr);
319  const Real b = (Ec + Eo) / 2;
320  // Compute the ratio of the current transition stiffness to the original stiffness
321  stiffness_ratio_local(i) = (2.0 * a * etr + b) / Eo;
322  cracking_locally_active = true;
323  }
324  else
325  {
326  stiffness_ratio_local(i) = (1.0 - _crack_damage_old[_qp](i));
327  cracking_locally_active = true;
328  }
329  }
330  }
331 
332  if (cracking_locally_active)
333  {
334  // Update the elasticity tensor in the crack coordinate system
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);
338 
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);
342 
343  const Real c01_shear_retention = (c0_coupled && c1_coupled ? 1.0 : _shear_retention_factor);
344  const Real c02_shear_retention = (c0_coupled && c2_coupled ? 1.0 : _shear_retention_factor);
345  const Real c12_shear_retention = (c1_coupled && c2_coupled ? 1.0 : _shear_retention_factor);
346 
347  // Filling with 9 components is sufficient because these are the only nonzero entries
348  // for isotropic or orthotropic materials.
349  std::vector<Real> local_elastic(9);
350 
351  local_elastic[0] = (c0_coupled ? _elasticity_tensor[_qp](0, 0, 0, 0)
352  : stiffness_ratio_local(0) * youngs_modulus);
353  local_elastic[1] = _elasticity_tensor[_qp](0, 0, 1, 1) * c01;
354  local_elastic[2] = _elasticity_tensor[_qp](0, 0, 2, 2) * c02;
355  local_elastic[3] = (c1_coupled ? _elasticity_tensor[_qp](1, 1, 1, 1)
356  : stiffness_ratio_local(1) * youngs_modulus);
357  local_elastic[4] = _elasticity_tensor[_qp](1, 1, 2, 2) * c12;
358  local_elastic[5] = (c2_coupled ? _elasticity_tensor[_qp](2, 2, 2, 2)
359  : stiffness_ratio_local(2) * youngs_modulus);
360  local_elastic[6] = _elasticity_tensor[_qp](1, 2, 1, 2) * c12_shear_retention;
361  local_elastic[7] = _elasticity_tensor[_qp](0, 2, 0, 2) * c02_shear_retention;
362  local_elastic[8] = _elasticity_tensor[_qp](0, 1, 0, 1) * c01_shear_retention;
363 
364  _local_elasticity_tensor.fillFromInputVector(local_elastic, RankFourTensor::symmetric9);
365 
366  // Rotate the modified elasticity tensor back into global coordinates
367  _local_elasticity_tensor.rotate(R);
368  }
369  }
370  if (!cracking_locally_active)
372 }
373 
374 void
376 {
377  const Real youngs_modulus =
379  const Real cracking_alpha = -youngs_modulus;
380 
381  Real cracking_stress = _cracking_stress[_qp];
382 
383  if (cracking_stress > 0)
384  {
385  // Initializing crack states
387 
388  for (unsigned i = 0; i < 3; ++i)
389  {
390  _crack_max_strain[_qp](i) = _crack_max_strain_old[_qp](i);
392  _crack_damage[_qp](i) = _crack_damage_old[_qp](i);
393  }
394 
395  // Compute crack orientations: updated _crack_rotation[_qp] based on current strain
396  RealVectorValue strain_in_crack_dir;
397  computeCrackStrainAndOrientation(strain_in_crack_dir);
398 
399  for (unsigned i = 0; i < 3; ++i)
400  {
401  if (strain_in_crack_dir(i) > _crack_max_strain[_qp](i))
402  _crack_max_strain[_qp](i) = strain_in_crack_dir(i);
403  }
404 
405  // Check for new cracks.
406  // Rotate stress to cracked orientation.
407  const RankTwoTensor & R = _crack_rotation[_qp];
408  RankTwoTensor sigmaPrime(_stress[_qp]);
409  sigmaPrime.rotate(R.transpose()); // stress in crack coordinates
410 
411  unsigned int num_cracks = 0;
412  for (unsigned int i = 0; i < 3; ++i)
413  {
414  if (_crack_damage_old[_qp](i) > 0.0)
415  ++num_cracks;
416  }
417 
418  bool cracked(false);
419  RealVectorValue sigma;
420  for (unsigned int i = 0; i < 3; ++i)
421  {
422  sigma(i) = sigmaPrime(i, i);
423 
424  Real stiffness_ratio = 1.0 - _crack_damage[_qp](i);
425 
426  const bool pre_existing_crack = (_crack_damage_old[_qp](i) > 0.0);
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;
431 
432  cracked |= pre_existing_crack;
433 
434  // Adjustments for newly created cracks
435  if (met_stress_criterion && !pre_existing_crack && allowed_to_crack)
436  {
437  new_crack = true;
438  ++num_cracks;
439 
440  // Assume Poisson's ratio drops to zero for this direction. Stiffness is then Young's
441  // modulus.
442  _crack_initiation_strain[_qp](i) = cracking_stress / youngs_modulus;
443 
444  if (_crack_max_strain[_qp](i) < _crack_initiation_strain[_qp](i))
446  }
447 
448  // Update stress and stiffness ratio according to specified crack release model
449  if (new_crack || (pre_existing_crack && loading_existing_crack))
450  {
451  cracked = true;
452  if (_softening_models.size() != 0)
454  stiffness_ratio,
455  strain_in_crack_dir(i),
456  _crack_initiation_strain[_qp](i),
457  _crack_max_strain[_qp](i),
458  cracking_stress,
459  youngs_modulus);
460  else
462  sigma(i),
463  stiffness_ratio,
464  strain_in_crack_dir(i),
465  cracking_stress,
466  cracking_alpha,
467  youngs_modulus);
468  _crack_damage[_qp](i) = 1.0 - stiffness_ratio;
469  }
470 
471  else if (cracked && _cracking_neg_fraction > 0 &&
472  _crack_initiation_strain[_qp](i) * _cracking_neg_fraction > strain_in_crack_dir(i) &&
473  -_crack_initiation_strain[_qp](i) * _cracking_neg_fraction < strain_in_crack_dir(i))
474  {
475  const Real etr = _cracking_neg_fraction * _crack_initiation_strain[_qp](i);
476  const Real Eo = cracking_stress / _crack_initiation_strain[_qp](i);
477  const Real Ec = Eo * (1.0 - _crack_damage_old[_qp](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;
482  }
483  }
484 
485  if (cracked)
487  }
488 
489  _crack_flags[_qp](0) = 1.0 - _crack_damage[_qp](2);
490  _crack_flags[_qp](1) = 1.0 - _crack_damage[_qp](1);
491  _crack_flags[_qp](2) = 1.0 - _crack_damage[_qp](0);
492 }
493 
494 void
496  RealVectorValue & strain_in_crack_dir)
497 {
498  // The rotation tensor is ordered such that directions for pre-existing cracks appear first
499  // in the list of columns. For example, if there is one existing crack, its direction is in the
500  // first column in the rotation tensor.
501  const unsigned int num_known_dirs = getNumKnownCrackDirs();
502 
503  if (num_known_dirs == 0)
504  {
505  std::vector<Real> eigval(3, 0.0);
506  RankTwoTensor eigvec;
507 
508  _elastic_strain[_qp].symmetricEigenvaluesEigenvectors(eigval, eigvec);
509 
510  // If the elastic strain is beyond the cracking strain, save the eigen vectors as
511  // the rotation tensor. Reverse their order so that the third principal strain
512  // (most tensile) will correspond to the first crack.
513  _crack_rotation[_qp].fillColumn(0, eigvec.column(2));
514  _crack_rotation[_qp].fillColumn(1, eigvec.column(1));
515  _crack_rotation[_qp].fillColumn(2, eigvec.column(0));
516 
517  strain_in_crack_dir(0) = eigval[2];
518  strain_in_crack_dir(1) = eigval[1];
519  strain_in_crack_dir(2) = eigval[0];
520  }
521  else if (num_known_dirs == 1)
522  {
523  // This is easily the most complicated case.
524  // 1. Rotate the elastic strain to the orientation associated with the known
525  // crack.
526  // 2. Extract the lower 2x2 block into a separate tensor.
527  // 3. Run the eigen solver on the result.
528  // 4. Update the rotation tensor to reflect the effect of the 2 eigenvectors.
529 
530  // 1.
531  const RankTwoTensor & R = _crack_rotation[_qp];
532  RankTwoTensor ePrime(_elastic_strain[_qp]);
533  ePrime.rotate(R.transpose()); // elastic strain in crack coordinates
534 
535  // 2.
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);
541 
542  // 3.
543  ColumnMajorMatrix e_val2x1(2, 1);
544  ColumnMajorMatrix e_vec2x2(2, 2);
545  e2x2.eigen(e_val2x1, e_vec2x2);
546 
547  // 4.
548  RankTwoTensor eigvec(
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));
550 
551  _crack_rotation[_qp] = _crack_rotation_old[_qp] * eigvec; // Roe implementation
552 
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);
556  }
557  else if (num_known_dirs == 2 || num_known_dirs == 3)
558  {
559  // Rotate to cracked orientation and pick off the strains in the rotated
560  // coordinate directions.
561  const RankTwoTensor & R = _crack_rotation[_qp];
562  RankTwoTensor ePrime(_elastic_strain[_qp]);
563  ePrime.rotate(R.transpose()); // elastic strain in crack coordinates
564 
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);
568  }
569  else
570  mooseError("Invalid number of known crack directions");
571 }
572 
573 unsigned int
575 {
576  unsigned int num_known_dirs = 0;
577  for (unsigned int i = 0; i < 3; ++i)
578  {
579  if (_crack_damage_old[_qp](i) > 0.0 || _prescribed_crack_directions.size() >= i + 1)
580  ++num_known_dirs;
581  }
582  return num_known_dirs;
583 }
584 
585 void
587  Real & sigma,
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)
593 {
594  switch (_cracking_release)
595  {
597  {
598  if (sigma > cracking_stress)
599  {
600  stiffness_ratio /= 3.0;
601  sigma = stiffness_ratio * youngs_modulus * strain_in_crack_dir;
602  }
603  break;
604  }
606  {
607  const Real crack_max_strain = _crack_max_strain[_qp](i);
608  mooseAssert(crack_max_strain >= _crack_initiation_strain[_qp](i),
609  "crack_max_strain must be >= crack_initiation_strain");
610 
611  // Compute stress that follows exponental curve
612  sigma =
613  cracking_stress * (_cracking_residual_stress +
614  (1.0 - _cracking_residual_stress) *
615  std::exp(cracking_alpha * _cracking_beta / cracking_stress *
616  (crack_max_strain - _crack_initiation_strain[_qp](i))));
617  // Compute ratio of current stiffness to original stiffness
618  stiffness_ratio =
619  sigma * _crack_initiation_strain[_qp](i) / (crack_max_strain * cracking_stress);
620  break;
621  }
623  {
624  if (_cracking_residual_stress == 0)
625  {
626  const Real tiny = 1e-16;
627  stiffness_ratio = tiny;
628  sigma = tiny * _crack_initiation_strain[_qp](i) * youngs_modulus;
629  }
630  else
631  {
632  sigma = _cracking_residual_stress * cracking_stress;
633  stiffness_ratio = sigma / (_crack_max_strain[_qp](i) * youngs_modulus);
634  }
635  break;
636  }
637  }
638 
639  if (stiffness_ratio < 0)
640  {
641  std::stringstream err;
642  err << "Negative stiffness ratio: " << i << " " << stiffness_ratio << ", "
643  << _crack_max_strain[_qp](i) << ", " << _crack_initiation_strain[_qp](i) << ", "
644  << std::endl;
645  mooseError(err.str());
646  }
647 }
648 
649 void
651  const RealVectorValue & sigma)
652 {
653  // Get transformation matrix
654  const RankTwoTensor & R = _crack_rotation[_qp];
655  // Rotate to crack frame
656  tensor.rotate(R.transpose());
657 
658  // Reset stress if cracked
659  for (unsigned int i = 0; i < 3; ++i)
660  if (_crack_damage[_qp](i) > 0.0)
661  {
662  const Real stress_correction_ratio = (tensor(i, i) - sigma(i)) / tensor(i, i);
663  if (stress_correction_ratio > _max_stress_correction)
664  tensor(i, i) *= (1.0 - _max_stress_correction);
665  else if (stress_correction_ratio < -_max_stress_correction)
666  tensor(i, i) *= (1.0 + _max_stress_correction);
667  else
668  tensor(i, i) = sigma(i);
669  }
670 
671  // Rotate back to global frame
672  tensor.rotate(R);
673 }
674 
675 bool
677 {
678  for (unsigned int i = 0; i < 3; ++i)
679  if (_crack_damage_old[_qp](i) > 0.0)
680  return true;
681  return false;
682 }
ComputeMultipleInelasticStress
ComputeMultipleInelasticStress computes the stress, the consistent tangent operator (or an approximat...
Definition: ComputeMultipleInelasticStress.h:38
ComputeSmearedCrackingStress::_crack_initiation_strain_old
const MaterialProperty< RealVectorValue > & _crack_initiation_strain_old
Definition: ComputeSmearedCrackingStress.h:149
ComputeFiniteStrainElasticStress::_elasticity_tensor
const MaterialProperty< RankFourTensor > & _elasticity_tensor
Elasticity tensor material property.
Definition: ComputeFiniteStrainElasticStress.h:39
ComputeSmearedCrackingStress::_shear_retention_factor
const Real _shear_retention_factor
Controls the amount of shear retained.
Definition: ComputeSmearedCrackingStress.h:126
ComputeSmearedCrackingStress::computeCrackingRelease
virtual void computeCrackingRelease(int i, Real &sigma, Real &stiffness_ratio, const Real strain_in_crack_dir, const Real cracking_stress, const Real cracking_alpha, const Real youngs_modulus)
Compute the effect of the cracking release model on the stress and stiffness in the direction of a si...
Definition: ComputeSmearedCrackingStress.C:586
ComputeSmearedCrackingStress::_prescribed_crack_directions
std::vector< unsigned int > _prescribed_crack_directions
User-prescribed cracking directions.
Definition: ComputeSmearedCrackingStress.h:114
ComputeSmearedCrackingStress.h
ComputeSmearedCrackingStress::initQpStatefulProperties
virtual void initQpStatefulProperties() override
Definition: ComputeSmearedCrackingStress.C:149
defineLegacyParams
defineLegacyParams(ComputeSmearedCrackingStress)
ComputeStressBase::_stress
MaterialProperty< RankTwoTensor > & _stress
Stress material property.
Definition: ComputeStressBase.h:50
ComputeMultipleInelasticStress::validParams
static InputParameters validParams()
Definition: ComputeMultipleInelasticStress.C:21
ComputeFiniteStrainElasticStress::_elasticity_tensor_name
const std::string _elasticity_tensor_name
Name of the elasticity tensor material property.
Definition: ComputeFiniteStrainElasticStress.h:37
ComputeMultipleInelasticStress::initialSetup
virtual void initialSetup() override
Definition: ComputeMultipleInelasticStress.C:122
ComputeSmearedCrackingStress::_cracking_release
enum ComputeSmearedCrackingStress::CrackingRelease _cracking_release
ComputeStressBase::_Jacobian_mult
MaterialProperty< RankFourTensor > & _Jacobian_mult
derivative of stress w.r.t. strain (_dstress_dstrain)
Definition: ComputeStressBase.h:61
ComputeMultipleInelasticStress::_inelastic_strain_old
const MaterialProperty< RankTwoTensor > & _inelastic_strain_old
old value of inelastic strain
Definition: ComputeMultipleInelasticStress.h:140
ComputeFiniteStrainElasticStress::_rotation_increment
const MaterialProperty< RankTwoTensor > & _rotation_increment
Rotation increment material property.
Definition: ComputeFiniteStrainElasticStress.h:43
ComputeSmearedCrackingStress::validParams
static InputParameters validParams()
Definition: ComputeSmearedCrackingStress.C:20
ComputeSmearedCrackingStress::_max_cracks
const unsigned int _max_cracks
Maximum number of cracks permitted at a material point.
Definition: ComputeSmearedCrackingStress.h:117
ComputeMultipleInelasticStress::_models
std::vector< StressUpdateBase * > _models
The user supplied list of inelastic models to use in the simulation.
Definition: ComputeMultipleInelasticStress.h:177
ComputeSmearedCrackingStress::CrackingRelease
CrackingRelease
Enum defining the crack release model.
Definition: ComputeSmearedCrackingStress.h:102
ComputeMultipleInelasticStress::_perform_finite_strain_rotations
const bool _perform_finite_strain_rotations
after updateQpState, rotate the stress, elastic_strain, inelastic_strain and Jacobian_mult using _rot...
Definition: ComputeMultipleInelasticStress.h:129
ComputeSmearedCrackingStress::updateCrackingStateAndStress
virtual void updateCrackingStateAndStress()
Update all cracking-related state variables and the stress tensor due to cracking in all directions.
Definition: ComputeSmearedCrackingStress.C:375
ComputeSmearedCrackingStress::initialSetup
virtual void initialSetup() override
Definition: ComputeSmearedCrackingStress.C:212
ComputeSmearedCrackingStress::_crack_damage_old
const MaterialProperty< RealVectorValue > & _crack_damage_old
Definition: ComputeSmearedCrackingStress.h:135
SmearedCrackSofteningBase
SmearedCrackSofteningBase is the base class for a set of models that define the softening behavior of...
Definition: SmearedCrackSofteningBase.h:28
ComputeSmearedCrackingStress::updateStressTensorForCracking
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...
Definition: ComputeSmearedCrackingStress.C:650
ComputeSmearedCrackingStress::_crack_flags
MaterialProperty< RealVectorValue > & _crack_flags
Vector of values going from 1 to 0 as crack damage accumulates.
Definition: ComputeSmearedCrackingStress.h:140
ComputeMultipleInelasticStress::_elastic_strain_old
const MaterialProperty< RankTwoTensor > & _elastic_strain_old
Strain tensors.
Definition: ComputeMultipleInelasticStress.h:132
ComputeSmearedCrackingStress::CrackingRelease::abrupt
ComputeMultipleInelasticStress::_inelastic_strain
MaterialProperty< RankTwoTensor > & _inelastic_strain
The sum of the inelastic strains that come from the plastic models.
Definition: ComputeMultipleInelasticStress.h:137
ComputeMultipleInelasticStress::_strain_increment
const MaterialProperty< RankTwoTensor > & _strain_increment
Definition: ComputeMultipleInelasticStress.h:133
ElasticityTensorTools::getIsotropicYoungsModulus
T getIsotropicYoungsModulus(const RankFourTensorTempl< T > &elasticity_tensor)
Get the Young's modulus for an isotropic elasticity tensor param elasticity_tensor the tensor (must b...
Definition: ElasticityTensorTools.h:98
ComputeSmearedCrackingStress::_softening_models
std::vector< SmearedCrackSofteningBase * > _softening_models
The user-supplied list of softening models to be used in the 3 crack directions.
Definition: ComputeSmearedCrackingStress.h:162
ComputeSmearedCrackingStress::_crack_damage
MaterialProperty< RealVectorValue > & _crack_damage
Definition: ComputeSmearedCrackingStress.h:134
ComputeMultipleInelasticStress::finiteStrainRotation
virtual void finiteStrainRotation(const bool force_elasticity_rotation=false)
Rotate _elastic_strain, _stress, _inelastic_strain, and _Jacobian_mult to the new configuration.
Definition: ComputeMultipleInelasticStress.C:255
ComputeMultipleInelasticStress::computeQpStressIntermediateConfiguration
virtual void computeQpStressIntermediateConfiguration()
Compute the stress for the current QP, but do not rotate tensors from the intermediate configuration ...
Definition: ComputeMultipleInelasticStress.C:215
ElasticityTensorTools.h
ComputeSmearedCrackingStress::computeQpStress
virtual void computeQpStress() override
Compute the stress and store it in the _stress material property for the current quadrature point.
Definition: ComputeSmearedCrackingStress.C:246
ComputeSmearedCrackingStress::previouslyCracked
bool previouslyCracked()
Check to see whether there was cracking in any diretion in the previous time step.
Definition: ComputeSmearedCrackingStress.C:676
ComputeSmearedCrackingStress::updateLocalElasticityTensor
void updateLocalElasticityTensor()
Update the local elasticity tensor (_local_elasticity_tensor) due to the effects of cracking.
Definition: ComputeSmearedCrackingStress.C:288
ComputeSmearedCrackingStress::_cracking_stress
const VariableValue & _cracking_stress
Threshold at which cracking initiates if tensile stress exceeds it.
Definition: ComputeSmearedCrackingStress.h:111
ComputeSmearedCrackingStress::ComputeSmearedCrackingStress
ComputeSmearedCrackingStress(const InputParameters &parameters)
Definition: ComputeSmearedCrackingStress.C:84
ComputeSmearedCrackingStress::computeCrackStrainAndOrientation
void computeCrackStrainAndOrientation(RealVectorValue &strain_in_crack_dir)
Compute the crack strain in the crack coordinate system.
Definition: ComputeSmearedCrackingStress.C:495
ComputeSmearedCrackingStress::_local_elasticity_tensor
RankFourTensor _local_elasticity_tensor
Definition: ComputeSmearedCrackingStress.h:158
ComputeStressBase::_elastic_strain
MaterialProperty< RankTwoTensor > & _elastic_strain
Elastic strain material property.
Definition: ComputeStressBase.h:52
ComputeMultipleInelasticStress::initQpStatefulProperties
virtual void initQpStatefulProperties() override
Definition: ComputeMultipleInelasticStress.C:115
ComputeSmearedCrackingStress
ComputeSmearedCrackingStress computes the stress for a finite strain material with smeared cracking.
Definition: ComputeSmearedCrackingStress.h:26
GuaranteeConsumer::hasGuaranteedMaterialProperty
bool hasGuaranteedMaterialProperty(const MaterialPropertyName &prop, Guarantee guarantee)
Definition: GuaranteeConsumer.C:28
ComputeMultipleInelasticStress::_matl_timestep_limit
MaterialProperty< Real > & _matl_timestep_limit
Definition: ComputeMultipleInelasticStress.h:163
ComputeSmearedCrackingStress::CrackingRelease::exponential
ComputeSmearedCrackingStress::_crack_rotation_old
const MaterialProperty< RankTwoTensor > & _crack_rotation_old
Definition: ComputeSmearedCrackingStress.h:144
ComputeSmearedCrackingStress::_crack_initiation_strain
MaterialProperty< RealVectorValue > & _crack_initiation_strain
Definition: ComputeSmearedCrackingStress.h:148
ComputeSmearedCrackingStress::_crack_max_strain
MaterialProperty< RealVectorValue > & _crack_max_strain
Definition: ComputeSmearedCrackingStress.h:153
ComputeSmearedCrackingStress::_cracking_residual_stress
const Real _cracking_residual_stress
Input parameters for smeared crack models.
Definition: ComputeSmearedCrackingStress.h:108
ComputeSmearedCrackingStress::_crack_max_strain_old
const MaterialProperty< RealVectorValue > & _crack_max_strain_old
Definition: ComputeSmearedCrackingStress.h:154
ComputeSmearedCrackingStress::_crack_rotation
MaterialProperty< RankTwoTensor > & _crack_rotation
Definition: ComputeSmearedCrackingStress.h:143
registerMooseObject
registerMooseObject("TensorMechanicsApp", ComputeSmearedCrackingStress)
RankTwoTensorTempl
Definition: ACGrGrElasticDrivingForce.h:17
ComputeSmearedCrackingStress::_max_stress_correction
const Real _max_stress_correction
Controls the maximum amount that the damaged elastic stress is corrected to folow the release model d...
Definition: ComputeSmearedCrackingStress.h:130
StressUpdateBase.h
ComputeSmearedCrackingStress::_cracking_neg_fraction
const Real _cracking_neg_fraction
Defines transition to changed stiffness during unloading.
Definition: ComputeSmearedCrackingStress.h:120
ComputeSmearedCrackingStress::getNumKnownCrackDirs
virtual unsigned int getNumKnownCrackDirs() const
Get the number of known crack directions.
Definition: ComputeSmearedCrackingStress.C:574
ComputeSmearedCrackingStress::CrackingRelease::power
Guarantee::ISOTROPIC
ComputeSmearedCrackingStress::_cracking_beta
const Real _cracking_beta
Controls slope of exponential softening curve.
Definition: ComputeSmearedCrackingStress.h:123