https://mooseframework.inl.gov
ComputeMultipleCrystalPlasticityStress.C
Go to the documentation of this file.
1 //* This file is part of the MOOSE framework
2 //* https://mooseframework.inl.gov
3 //*
4 //* All rights reserved, see COPYRIGHT for full restrictions
5 //* https://github.com/idaholab/moose/blob/master/COPYRIGHT
6 //*
7 //* Licensed under LGPL 2.1, please see LICENSE for details
8 //* https://www.gnu.org/licenses/lgpl-2.1.html
9 
11 
13 #include "libmesh/utility.h"
14 #include "Conversion.h"
15 #include "MooseException.h"
16 
18 
21 {
23 
24  params.addClassDescription(
25  "Crystal Plasticity base class: handles the Newton iteration over the stress residual and "
26  "calculates the Jacobian based on constitutive laws from multiple material classes "
27  "that are inherited from CrystalPlasticityStressUpdateBase");
28  params.addParam<std::string>(
29  "base_name",
30  "Optional parameter that allows the user to define multiple mechanics material systems on "
31  "the same block, i.e. for multiple phases");
32 
33  params.addRequiredParam<std::vector<MaterialName>>(
34  "crystal_plasticity_models",
35  "The material objects to use to calculate crystal plasticity stress and strains.");
36  params.addParam<std::vector<MaterialName>>(
37  "eigenstrain_names", {}, "The material objects to calculate eigenstrains.");
38  params.addParam<MooseEnum>("tan_mod_type",
39  MooseEnum("exact none", "none"),
40  "Type of tangent moduli for preconditioner: default elastic");
41  params.addParam<Real>("rtol", 1e-6, "Constitutive stress residual relative tolerance");
42  params.addParam<Real>("abs_tol", 1e-6, "Constitutive stress residual absolute tolerance");
43  params.addParam<unsigned int>("maxiter", 100, "Maximum number of iterations for stress update");
44  params.addParam<unsigned int>(
45  "maxiter_state_variable", 100, "Maximum number of iterations for state variable update");
46  params.addParam<unsigned int>(
47  "maximum_substep_iteration", 1, "Maximum number of substep iteration");
48  params.addParam<bool>("use_line_search", false, "Use line search in constitutive update");
49  params.addParam<Real>("min_line_search_step_size", 0.01, "Minimum line search step size");
50  params.addParam<Real>("line_search_tol", 0.5, "Line search bisection method tolerance");
51  params.addParam<unsigned int>(
52  "line_search_maxiter", 20, "Line search bisection method maximum number of iteration");
53  params.addParam<MooseEnum>("line_search_method",
54  MooseEnum("CUT_HALF BISECTION", "CUT_HALF"),
55  "The method used in line search");
56  params.addParam<bool>(
57  "print_state_variable_convergence_error_messages",
58  false,
59  "Whether or not to print warning messages from the crystal plasticity specific convergence "
60  "checks on the stress measure and general constitutive model quantinties.");
61  return params;
62 }
63 
65  const InputParameters & parameters)
67  _num_models(getParam<std::vector<MaterialName>>("crystal_plasticity_models").size()),
68  _num_eigenstrains(getParam<std::vector<MaterialName>>("eigenstrain_names").size()),
69  _base_name(isParamValid("base_name") ? getParam<std::string>("base_name") + "_" : ""),
70  _elasticity_tensor(getMaterialPropertyByName<RankFourTensor>(_base_name + "elasticity_tensor")),
71  _rtol(getParam<Real>("rtol")),
72  _abs_tol(getParam<Real>("abs_tol")),
73  _maxiter(getParam<unsigned int>("maxiter")),
74  _maxiterg(getParam<unsigned int>("maxiter_state_variable")),
75  _tan_mod_type(getParam<MooseEnum>("tan_mod_type").getEnum<TangentModuliType>()),
76  _max_substep_iter(getParam<unsigned int>("maximum_substep_iteration")),
77  _use_line_search(getParam<bool>("use_line_search")),
78  _min_line_search_step_size(getParam<Real>("min_line_search_step_size")),
79  _line_search_tolerance(getParam<Real>("line_search_tol")),
80  _line_search_max_iterations(getParam<unsigned int>("line_search_maxiter")),
81  _line_search_method(getParam<MooseEnum>("line_search_method").getEnum<LineSearchMethod>()),
82  _plastic_deformation_gradient(declareProperty<RankTwoTensor>("plastic_deformation_gradient")),
83  _plastic_deformation_gradient_old(
84  getMaterialPropertyOld<RankTwoTensor>("plastic_deformation_gradient")),
85  _eigenstrain_deformation_gradient(
86  _num_eigenstrains ? &declareProperty<RankTwoTensor>("eigenstrain_deformation_gradient")
87  : nullptr),
88  _eigenstrain_deformation_gradient_old(
89  _num_eigenstrains
90  ? &getMaterialPropertyOld<RankTwoTensor>("eigenstrain_deformation_gradient")
91  : nullptr),
92  _deformation_gradient(getMaterialProperty<RankTwoTensor>(_base_name + "deformation_gradient")),
93  _deformation_gradient_old(
94  getMaterialPropertyOld<RankTwoTensor>(_base_name + "deformation_gradient")),
95  _pk2(declareProperty<RankTwoTensor>("second_piola_kirchhoff_stress")),
96  _pk2_old(getMaterialPropertyOld<RankTwoTensor>("second_piola_kirchhoff_stress")),
97  _total_lagrangian_strain(
98  declareProperty<RankTwoTensor>("total_lagrangian_strain")), // Lagrangian strain
99  _updated_rotation(declareProperty<RankTwoTensor>("updated_rotation")),
100  _updated_rotation_old(getMaterialPropertyOld<RankTwoTensor>("updated_rotation")),
101  _misorientation(declareProperty<Real>("misorientation")),
102  _crysrot(getMaterialProperty<RankTwoTensor>(
103  _base_name + "crysrot")), // defined in the elasticity tensor classes for crystal plasticity
104  _print_convergence_message(getParam<bool>("print_state_variable_convergence_error_messages"))
105 {
106  _convergence_failed = false;
107 }
108 
109 void
111 {
114 
115  if (_num_eigenstrains)
116  {
117  (*_eigenstrain_deformation_gradient)[_qp].zero();
118  (*_eigenstrain_deformation_gradient)[_qp].addIa(1.0);
119  }
120  else
121  {
122  // set to identity if no eigenstrain is added
125  }
126 
127  _pk2[_qp].zero();
128 
130 
131  _updated_rotation[_qp].zero();
132  _updated_rotation[_qp].addIa(1.0);
133 
134  for (unsigned int i = 0; i < _num_models; ++i)
135  {
136  _models[i]->setQp(_qp);
137  _models[i]->initQpStatefulProperties();
138  }
139 
140  for (unsigned int i = 0; i < _num_eigenstrains; ++i)
141  {
142  _eigenstrains[i]->setQp(_qp);
143  _eigenstrains[i]->initQpStatefulProperties();
144  }
145 }
146 
147 void
149 {
150  // get crystal plasticity models
151  std::vector<MaterialName> model_names =
152  getParam<std::vector<MaterialName>>("crystal_plasticity_models");
153 
154  for (unsigned int i = 0; i < _num_models; ++i)
155  {
157  dynamic_cast<CrystalPlasticityStressUpdateBase *>(&getMaterialByName(model_names[i]));
158 
159  if (model)
160  {
161  _models.push_back(model);
162  // TODO: check to make sure that the material model is compatible with this class
163  }
164  else
165  mooseError("Model " + model_names[i] +
166  " is not compatible with ComputeMultipleCrystalPlasticityStress");
167  }
168 
169  // get crystal plasticity eigenstrains
170  std::vector<MaterialName> eigenstrain_names =
171  getParam<std::vector<MaterialName>>("eigenstrain_names");
172 
173  for (unsigned int i = 0; i < _num_eigenstrains; ++i)
174  {
177  &getMaterialByName(eigenstrain_names[i]));
178 
179  if (eigenstrain)
180  _eigenstrains.push_back(eigenstrain);
181  else
182  mooseError("Eigenstrain" + eigenstrain_names[i] +
183  " is not compatible with ComputeMultipleCrystalPlasticityStress");
184  }
185 }
186 
187 void
189 {
190  for (unsigned int i = 0; i < _num_models; ++i)
191  {
192  _models[i]->setQp(_qp);
193  _models[i]->setMaterialVectorSize();
194  }
195 
196  for (unsigned int i = 0; i < _num_eigenstrains; ++i)
197  _eigenstrains[i]->setQp(_qp);
198 
199  updateStress(_stress[_qp], _Jacobian_mult[_qp]); // This is NOT the exact jacobian
200 }
201 
202 void
204  RankFourTensor & jacobian_mult)
205 {
206  // Does not support face/boundary material property calculation
207  if (isBoundaryMaterial())
208  return;
209 
210  // Initialize substepping variables
211  unsigned int substep_iter = 1;
212  unsigned int num_substep = 1;
213 
217 
219 
220  // Loop through all models and calculate the schmid tensor for the current state of the crystal
221  // lattice
222  // Not sure if we should pass in the updated or the original rotation here
223  // If not, then we should not need to compute the flow direction every iteration here
224  for (unsigned int i = 0; i < _num_models; ++i)
225  _models[i]->calculateFlowDirection(_crysrot[_qp]);
226 
227  do
228  {
229  _convergence_failed = false;
230  preSolveQp();
231 
232  _substep_dt = _dt / num_substep;
233  for (unsigned int i = 0; i < _num_models; ++i)
234  _models[i]->setSubstepDt(_substep_dt);
235 
236  // calculate F^{eigen} only when we have eigenstrain
239  if (_num_eigenstrains)
241 
242  for (unsigned int istep = 0; istep < num_substep; ++istep)
243  {
245  (static_cast<Real>(istep) + 1) / num_substep * _delta_deformation_gradient;
247 
248  solveQp();
249 
251  {
253  mooseWarning(
254  "The crystal plasticity constitutive model has failed to converge. Increasing "
255  "the number of substeps.");
256 
257  substep_iter++;
258  num_substep *= 2;
259  break;
260  }
261  }
262 
263  if (substep_iter > _max_substep_iter && _convergence_failed)
264  mooseException("ComputeMultipleCrystalPlasticityStress: Constitutive failure");
265  } while (_convergence_failed);
266 
267  postSolveQp(cauchy_stress, jacobian_mult);
268 }
269 
270 void
272 {
273  for (unsigned int i = 0; i < _num_models; ++i)
274  _models[i]->setInitialConstitutiveVariableValues();
275 
276  _pk2[_qp] = _pk2_old[_qp];
278 }
279 
280 void
282 {
283  for (unsigned int i = 0; i < _num_models; ++i)
284  {
285  _models[i]->setSubstepConstitutiveVariableValues();
286  _models[i]->calculateSlipResistance();
287  }
288 
290 
293  return; // pop back up and take a smaller substep
294 
295  for (unsigned int i = 0; i < _num_models; ++i)
296  _models[i]->updateSubstepConstitutiveVariableValues();
297 
298  // save off the old F^{p} inverse now that have converged on the stress and state variables
300 }
301 
302 void
304  RankFourTensor & jacobian_mult)
305 {
306  cauchy_stress = _elastic_deformation_gradient * _pk2[_qp] *
308 
309  calcTangentModuli(jacobian_mult);
310 
315 
316  // Calculate crystal rotation to track separately
317  RankTwoTensor rot;
319  _updated_rotation[_qp] = rot * _crysrot[_qp];
320 
321  // Calculate the misorientation
322  auto _delta_misorientation_mat = _updated_rotation[_qp] * _updated_rotation_old[_qp].inverse();
323  auto cos_val = (_delta_misorientation_mat.trace() - 1.0) / 2.0;
324  // Mathematically, the values should lie in the range of [-1, 1]. However, there maybe numerical
325  // errors during calculation. Let's guard small numerical errors here and throw an error when the
326  // numerical error is too big, which indicates other issues.
327  if (cos_val > 1.0 || cos_val < -1.0)
328  {
329  if (MooseUtils::absoluteFuzzyEqual(cos_val, -1.0))
330  cos_val = -1.0;
331  else if (MooseUtils::absoluteFuzzyEqual(cos_val, 1.0))
332  cos_val = 1.0;
333  else
334  mooseError("Misorientation value is undefined. This should not happen.");
335  }
336  _misorientation[_qp] = std::acos(cos_val);
337 }
338 
339 void
341 {
342  unsigned int iteration;
343  bool iter_flag = true;
344 
345  iteration = 0;
346  // Check for slip system resistance update tolerance
347  do
348  {
349  solveStress();
351  return;
352 
354  _inverse_plastic_deformation_grad.inverse(); // the postSoveStress
355 
356  // Update slip system resistance and state variable after the stress has been finalized
357  // We loop through all the models for each calculation
358  // in order to make sure that when coupling appears, the state variables are updated based on
359  // the same components
360  for (unsigned int i = 0; i < _num_models; ++i)
361  _models[i]->cacheStateVariablesBeforeUpdate();
362 
363  for (unsigned int i = 0; i < _num_models; ++i)
364  _models[i]->calculateStateVariableEvolutionRateComponent();
365 
366  for (unsigned int i = 0; i < _num_models; ++i)
367  if (!_models[i]->updateStateVariables())
368  _convergence_failed = true;
369 
370  for (unsigned int i = 0; i < _num_models; ++i)
371  _models[i]->calculateSlipResistance();
372 
374  return;
375 
376  for (unsigned int i = 0; i < _num_models; ++i)
377  {
378  // iter_flag = false, stop iteration if all values are converged and good to go
379  // iter_flag = true, continue iteration if any value is not converged
380  if (!_models[i]->areConstitutiveStateVariablesConverged())
381  {
382  iter_flag = true;
383  break;
384  }
385  else
386  iter_flag = false; // iter_flag = false, stop iteration only when all models returns true
387  }
388 
389  if (iter_flag)
390  {
392  mooseWarning("ComputeMultipleCrystalPlasticityStress: State variables (or the system "
393  "resistance) did not converge at element ",
394  _current_elem->id(),
395  " and qp ",
396  _qp,
397  "\n");
398  }
399  iteration++;
400  } while (iter_flag && iteration < _maxiterg);
401 
402  if (iteration == _maxiterg)
403  {
405  mooseWarning(
406  "ComputeMultipleCrystalPlasticityStress: Hardness Integration error. Reached the "
407  "maximum number of iterations to solve for the state variables at element ",
408  _current_elem->id(),
409  " and qp ",
410  _qp,
411  "\n");
412 
413  _convergence_failed = true;
414  }
415 }
416 
417 void
419 {
420  unsigned int iteration = 0;
421  RankTwoTensor dpk2;
422  Real rnorm, rnorm0, rnorm_prev;
423 
424  // Calculate stress residual
427  {
429  mooseWarning("ComputeMultipleCrystalPlasticityStress: the slip increment exceeds tolerance "
430  "at element ",
431  _current_elem->id(),
432  " and Gauss point ",
433  _qp);
434 
435  return;
436  }
437 
438  rnorm = _residual_tensor.L2norm();
439  rnorm0 = rnorm;
440 
441  // Check for stress residual tolerance; different from user object version which
442  // compares the absolute tolerance of only the original rnorm value
443  while (rnorm > _rtol * rnorm0 && rnorm > _abs_tol && iteration < _maxiter)
444  {
445  // Calculate stress increment
446  dpk2 = -_jacobian.invSymm() * _residual_tensor;
447  _pk2[_qp] = _pk2[_qp] + dpk2;
448 
450 
452  {
454  mooseWarning("ComputeMultipleCrystalPlasticityStress: the slip increment exceeds tolerance "
455  "at element ",
456  _current_elem->id(),
457  " and Gauss point ",
458  _qp);
459 
460  return;
461  }
462 
463  rnorm_prev = rnorm;
464  rnorm = _residual_tensor.L2norm();
465 
466  if (_use_line_search && rnorm > rnorm_prev && !lineSearchUpdate(rnorm_prev, dpk2))
467  {
469  mooseWarning("ComputeMultipleCrystalPlasticityStress: Failed with line search");
470 
471  _convergence_failed = true;
472  return;
473  }
474 
475  if (_use_line_search)
476  rnorm = _residual_tensor.L2norm();
477 
478  iteration++;
479  }
480 
481  if (iteration >= _maxiter)
482  {
484  mooseWarning("ComputeMultipleCrystalPlasticityStress: Stress Integration error rmax = ",
485  rnorm,
486  " and the tolerance is ",
487  _rtol * rnorm0,
488  " when the rnorm0 value is ",
489  rnorm0,
490  " for element ",
491  _current_elem->id(),
492  " and qp ",
493  _qp);
494 
495  _convergence_failed = true;
496  }
497 }
498 
499 // Calculates stress residual equation and jacobian
500 void
502 {
505  return;
507 }
508 
509 void
511 {
512  RankTwoTensor ce, elastic_strain, ce_pk2, equivalent_slip_increment_per_model,
513  equivalent_slip_increment, pk2_new;
514 
515  equivalent_slip_increment.zero();
516 
517  // calculate slip rate in order to compute F^{p-1}
518  for (unsigned int i = 0; i < _num_models; ++i)
519  {
520  equivalent_slip_increment_per_model.zero();
521 
522  // calculate shear stress with consideration of contribution from other physics
523  _models[i]->calculateShearStress(
525 
526  _convergence_failed = !_models[i]->calculateSlipRate();
527 
529  return;
530 
531  _models[i]->calculateEquivalentSlipIncrement(equivalent_slip_increment_per_model);
532  equivalent_slip_increment += equivalent_slip_increment_per_model;
533  }
534 
535  RankTwoTensor residual_equivalent_slip_increment =
536  RankTwoTensor::Identity() - equivalent_slip_increment;
538  _inverse_plastic_deformation_grad_old * residual_equivalent_slip_increment;
539 
543 
545 
546  elastic_strain = ce - RankTwoTensor::Identity();
547  elastic_strain *= 0.5;
548 
549  pk2_new = _elasticity_tensor[_qp] * elastic_strain;
550  _residual_tensor = _pk2[_qp] - pk2_new;
551 }
552 
553 void
555 {
556  // may not need to cache the dfpinvdpk2 here. need to double check
557  RankFourTensor dfedfpinv, deedfe, dfpinvdpk2, dfpinvdpk2_per_model;
558 
560 
561  for (const auto i : make_range(Moose::dim))
562  for (const auto j : make_range(Moose::dim))
563  for (const auto k : make_range(Moose::dim))
564  dfedfpinv(i, j, k, j) = ffeiginv(i, k);
565 
566  for (const auto i : make_range(Moose::dim))
567  for (const auto j : make_range(Moose::dim))
568  for (const auto k : make_range(Moose::dim))
569  {
570  deedfe(i, j, k, i) = deedfe(i, j, k, i) + _elastic_deformation_gradient(k, j) * 0.5;
571  deedfe(i, j, k, j) = deedfe(i, j, k, j) + _elastic_deformation_gradient(k, i) * 0.5;
572  }
573 
574  for (unsigned int i = 0; i < _num_models; ++i)
575  {
576  _models[i]->calculateTotalPlasticDeformationGradientDerivative(
577  dfpinvdpk2_per_model,
581  dfpinvdpk2 += dfpinvdpk2_per_model;
582  }
583 
584  _jacobian =
585  RankFourTensor::IdentityFour() - (_elasticity_tensor[_qp] * deedfe * dfedfpinv * dfpinvdpk2);
586 }
587 
588 void
590 {
591  switch (_tan_mod_type)
592  {
594  elastoPlasticTangentModuli(jacobian_mult);
595  break;
596  default:
597  elasticTangentModuli(jacobian_mult);
598  }
599 }
600 
601 void
603 {
604  RankFourTensor tan_mod;
605  RankTwoTensor pk2fet, fepk2, feiginvfpinv;
606  RankFourTensor deedfe, dsigdpk2dfe, dfedf;
607 
608  // Fill in the matrix stiffness material property
609  for (const auto i : make_range(Moose::dim))
610  for (const auto j : make_range(Moose::dim))
611  for (const auto k : make_range(Moose::dim))
612  {
613  deedfe(i, j, k, i) = deedfe(i, j, k, i) + _elastic_deformation_gradient(k, j) * 0.5;
614  deedfe(i, j, k, j) = deedfe(i, j, k, j) + _elastic_deformation_gradient(k, i) * 0.5;
615  }
616 
617  usingTensorIndices(i_, j_, k_, l_);
618  dsigdpk2dfe = _elastic_deformation_gradient.times<i_, k_, j_, l_>(_elastic_deformation_gradient) *
619  _elasticity_tensor[_qp] * deedfe;
620 
623 
624  for (const auto i : make_range(Moose::dim))
625  for (const auto j : make_range(Moose::dim))
626  for (const auto l : make_range(Moose::dim))
627  {
628  tan_mod(i, j, i, l) += pk2fet(l, j);
629  tan_mod(i, j, j, l) += fepk2(i, l);
630  }
631 
632  tan_mod += dsigdpk2dfe;
633 
634  const auto je = _elastic_deformation_gradient.det();
635  if (je > 0.0)
636  tan_mod /= je;
637 
639  for (const auto i : make_range(Moose::dim))
640  for (const auto j : make_range(Moose::dim))
641  for (const auto l : make_range(Moose::dim))
642  dfedf(i, j, i, l) = feiginvfpinv(l, j);
643 
644  jacobian_mult = tan_mod * dfedf;
645 }
646 
647 void
649 {
650  // update jacobian_mult
651  jacobian_mult = _elasticity_tensor[_qp];
652 }
653 
654 bool
656  const RankTwoTensor & dpk2)
657 {
659  {
660  Real rnorm;
661  Real step = 1.0;
662 
663  do
664  {
665  _pk2[_qp] = _pk2[_qp] - step * dpk2;
666  step /= 2.0;
667  _pk2[_qp] = _pk2[_qp] + step * dpk2;
668 
670  rnorm = _residual_tensor.L2norm();
671  } while (rnorm > rnorm_prev && step > _min_line_search_step_size);
672 
673  // has norm improved or is the step still above minumum search step size?
674  return (rnorm <= rnorm_prev || step > _min_line_search_step_size);
675  }
677  {
678  unsigned int count = 0;
679  Real step_a = 0.0;
680  Real step_b = 1.0;
681  Real step = 1.0;
682  Real s_m = 1000.0;
683  Real rnorm = 1000.0;
684 
686  auto s_b = _residual_tensor.doubleContraction(dpk2);
687  const auto rnorm1 = _residual_tensor.L2norm();
688  _pk2[_qp] = _pk2[_qp] - dpk2;
690  auto s_a = _residual_tensor.doubleContraction(dpk2);
691  const auto rnorm0 = _residual_tensor.L2norm();
692  _pk2[_qp] = _pk2[_qp] + dpk2;
693 
694  if ((rnorm1 / rnorm0) < _line_search_tolerance || s_a * s_b > 0)
695  {
697  return true;
698  }
699 
700  while ((rnorm / rnorm0) > _line_search_tolerance && count < _line_search_max_iterations)
701  {
702  _pk2[_qp] = _pk2[_qp] - step * dpk2;
703  step = 0.5 * (step_b + step_a);
704  _pk2[_qp] = _pk2[_qp] + step * dpk2;
707  rnorm = _residual_tensor.L2norm();
708 
709  if (s_m * s_a < 0.0)
710  {
711  step_b = step;
712  s_b = s_m;
713  }
714  if (s_m * s_b < 0.0)
715  {
716  step_a = step;
717  s_a = s_m;
718  }
719  count++;
720  }
721 
722  // below tolerance and max iterations?
723  return ((rnorm / rnorm0) < _line_search_tolerance && count < _line_search_max_iterations);
724  }
725  else
726  mooseError("Line search method is not provided.");
727 }
728 
729 void
731 {
734 
735  for (unsigned int i = 0; i < _num_eigenstrains; ++i)
736  {
737  _eigenstrains[i]->setSubstepDt(_substep_dt);
738  _eigenstrains[i]->computeQpProperties();
739  _inverse_eigenstrain_deformation_grad *= _eigenstrains[i]->getDeformationGradientInverse();
740  }
741  (*_eigenstrain_deformation_gradient)[_qp] = _inverse_eigenstrain_deformation_grad.inverse();
742 }
const MaterialProperty< RankTwoTensor > & _pk2_old
void solveStateVariables()
Solves the internal variables stress as a function of the slip specified by the constitutive model de...
MaterialProperty< RankFourTensor > & _Jacobian_mult
derivative of stress w.r.t. strain (_dstress_dstrain)
virtual void computeQpStress() override
Compute the stress and store it in the _stress material property for the current quadrature point...
MaterialProperty< RankTwoTensor > & _total_lagrangian_strain
Lagrangian total strain measure for the entire crystal.
RankTwoTensorTempl< Real > inverse() const
void postSolveQp(RankTwoTensor &stress_new, RankFourTensor &jacobian_mult)
Save the final stress and internal variable values after the iterative solve.
RankTwoTensor _temporary_deformation_gradient
Helper deformation gradient tensor variables used in iterative solve.
Real _line_search_tolerance
Line search bisection method tolerance.
void calculateEigenstrainDeformationGrad()
Calculates the deformation gradient due to eigenstrain.
bool _convergence_failed
Flag to check whether convergence is achieved or if substepping is needed.
void calculateResidual()
Calculate stress residual as the difference between the stored material property PK2 stress and the e...
void addParam(const std::string &name, const std::initializer_list< typename T::value_type > &value, const std::string &doc_string)
static RankFourTensorTempl< Real > IdentityFour()
registerMooseObject("SolidMechanicsApp", ComputeMultipleCrystalPlasticityStress)
unsigned int _maxiter
Maximum number of iterations for stress update.
ComputeCrystalPlasticityEigenstrainBase is the base class for computing eigenstrain tensors in crysta...
ComputeMultipleCrystalPlasticityStress(const InputParameters &parameters)
static constexpr std::size_t dim
virtual void updateStress(RankTwoTensor &cauchy_stress, RankFourTensor &jacobian_mult)
Updates the stress (PK2) at a quadrature point by calling constiutive relationship as defined in a ch...
virtual bool isBoundaryMaterial() const override
static RankTwoTensorTempl Identity()
void addRequiredParam(const std::string &name, const std::string &doc_string)
const MaterialProperty< RankTwoTensor > & _crysrot
Crystal rotation in the original, or reference, configuration as defined by Euler angle arguments in ...
bool lineSearchUpdate(const Real &rnorm_prev, const RankTwoTensor &dpk2)
performs the line search update
virtual void initQpStatefulProperties() override
initializes the stateful properties such as PK2 stress, resolved shear stress, plastic deformation gr...
enum ComputeMultipleCrystalPlasticityStress::LineSearchMethod _line_search_method
void calculateJacobian()
Calculates the jacobian as ${J} = {I} - {C} {d{E}^e}{d{F}^e} {d{F}^e}{d{F}^P^{-1}} {d{F}^P^{-1}}{d{PK...
const MaterialProperty< RankTwoTensor > & _deformation_gradient
Total deformation gradient RankTwoTensor for the crystal.
void elastoPlasticTangentModuli(RankFourTensor &jacobian_mult)
Real _min_line_search_step_size
Minimum line search step size.
void addIa(const Real &a)
MaterialProperty< RankTwoTensor > & _pk2
Second Piola-Kirchoff stress measure.
Real doubleContraction(const RankTwoTensorTempl< Real > &a) const
Real _abs_tol
Stress residual equation absolute tolerance.
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-")
ComputeFiniteStrainElasticStress computes the stress following elasticity theory for finite strains...
const MaterialProperty< RankFourTensor > & _elasticity_tensor
Elasticity tensor as defined by a separate class.
MaterialBase & getMaterialByName(const std::string &name, bool no_warn=false, bool no_dep=false)
unsigned int _line_search_max_iterations
Line search bisection method maximum iteration number.
MaterialProperty< RankTwoTensor > & _updated_rotation
Tracks the rotation of the crystal during deformation Note: this rotation tensor is not applied to th...
unsigned int _max_substep_iter
Maximum number of substep iterations.
RankTwoTensorTempl< Real > transpose() const
MaterialProperty< RankTwoTensor > & _plastic_deformation_gradient
Plastic deformation gradient RankTwoTensor for the crystal.
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
enum ComputeMultipleCrystalPlasticityStress::TangentModuliType _tan_mod_type
const MaterialProperty< RankTwoTensor > & _updated_rotation_old
std::vector< CrystalPlasticityStressUpdateBase * > _models
The user supplied cyrstal plasticity consititutive models.
unsigned int _maxiterg
Maximum number of iterations for internal variable update.
RankFourTensorTempl< Real > times(const RankTwoTensorTempl< Real > &b) const
const MaterialProperty< RankTwoTensor > & _deformation_gradient_old
const MaterialProperty< RankTwoTensor > & _plastic_deformation_gradient_old
void mooseWarning(Args &&... args) const
IntRange< T > make_range(T beg, T end)
MaterialProperty< Real > & _misorientation
Misorientation angle of the crystal during deformation.
void getRUDecompositionRotation(RankTwoTensorTempl< Real > &rot) const
void mooseError(Args &&... args) const
std::vector< ComputeCrystalPlasticityEigenstrainBase * > _eigenstrains
The user supplied cyrstal plasticity eigenstrains.
void addClassDescription(const std::string &doc_string)
static const std::complex< double > j(0, 1)
Complex number "j" (also known as "i")
MaterialProperty< RankTwoTensor > & _stress
Stress material property.
void calculateResidualAndJacobian()
Calls the residual and jacobian functions used in the stress update algorithm.
void solveQp()
Solve the stress and internal state variables (e.g.
ComputeMultipleCrystalPlasticityStress (used together with CrystalPlasticityStressUpdateBase) uses th...
void solveStress()
solves for stress, updates plastic deformation gradient.
const bool _print_convergence_message
Flag to print to console warning messages on stress, constitutive model convergence.
RankFourTensorTempl< T > invSymm() const
void calcTangentModuli(RankFourTensor &jacobian_mult)
Calculates the tangent moduli for use as a preconditioner, using the elastic or elastic-plastic optio...
RankTwoTensor _delta_deformation_gradient
Used for substepping; Uniformly divides the increment in deformation gradient.
Real _rtol
Stress residual equation relative tolerance.
static const std::string k
Definition: NS.h:134
void ErrorVector unsigned int
void preSolveQp()
Reset the PK2 stress and the inverse deformation gradient to old values and provide an interface for ...