https://mooseframework.inl.gov
HillElastoPlasticityStressUpdate.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 #include "RankTwoScalarTools.h"
12 #include "ElasticityTensorTools.h"
13 
16 
17 template <bool is_ad>
20 {
22  params.addClassDescription(
23  "This class uses the generalized radial return for anisotropic elasto-plasticity model."
24  "This class can be used in conjunction with other creep and plasticity materials for "
25  "more complex simulations.");
26 
27  params.addRequiredParam<Real>("hardening_constant",
28  "Hardening constant (H) for anisotropic plasticity");
29  params.addParam<Real>(
30  "hardening_exponent", 1.0, "Hardening exponent (n) for anisotropic plasticity");
31  params.addRequiredParam<Real>("yield_stress",
32  "Yield stress (constant value) for anisotropic plasticity");
33  params.addParam<bool>(
34  "local_cylindrical_csys",
35  false,
36  "Compute inelastic strain increment in local cylindrical coordinate system");
37 
38  params.addParam<MooseEnum>("axis",
39  MooseEnum("x y z", "y"),
40  "The axis of cylindrical component about which to rotate when "
41  "computing inelastic strain increment in local coordinate system");
42 
43  return params;
44 }
45 
46 template <bool is_ad>
48  const InputParameters & parameters)
50  _qsigma(0.0),
51  _eigenvalues_hill(6),
52  _eigenvectors_hill(6, 6),
53  _anisotropic_elastic_tensor(6, 6),
54  _elasticity_tensor_name(this->_base_name + "elasticity_tensor"),
55  _elasticity_tensor(
56  this->template getGenericMaterialProperty<RankFourTensor, is_ad>(_elasticity_tensor_name)),
57  _hardening_constant(this->template getParam<Real>("hardening_constant")),
58  _hardening_exponent(this->template getParam<Real>("hardening_exponent")),
59  _hardening_variable(this->template declareGenericProperty<Real, is_ad>(this->_base_name +
60  "hardening_variable")),
61  _hardening_variable_old(
62  this->template getMaterialPropertyOld<Real>(this->_base_name + "hardening_variable")),
63  _elasticity_eigenvectors(this->template declareGenericProperty<DenseMatrix<Real>, is_ad>(
64  this->_base_name + "elasticity_eigenvectors")),
65  _elasticity_eigenvalues(this->template declareGenericProperty<DenseVector<Real>, is_ad>(
66  this->_base_name + "elasticity_eigenvalues")),
67  _b_eigenvectors(this->template declareGenericProperty<DenseMatrix<Real>, is_ad>(
68  this->_base_name + "b_eigenvectors")),
69  _b_eigenvalues(this->template declareGenericProperty<DenseVector<Real>, is_ad>(
70  this->_base_name + "b_eigenvalues")),
71  _alpha_matrix(this->template declareGenericProperty<DenseMatrix<Real>, is_ad>(this->_base_name +
72  "alpha_matrix")),
73  _sigma_tilde(this->template declareGenericProperty<DenseVector<Real>, is_ad>(this->_base_name +
74  "sigma_tilde")),
75  _sigma_tilde_rotated(this->template declareGenericProperty<DenseVector<Real>, is_ad>(
76  this->_base_name + "sigma_tilde_rotated")),
77  _hardening_derivative(0.0),
78  _yield_condition(1.0),
79  _yield_stress(this->template getParam<Real>("yield_stress")),
80  _hill_tensor(this->template getMaterialPropertyByName<DenseMatrix<Real>>(this->_base_name +
81  "hill_tensor")),
82  _rotation_matrix(
83  this->template declareProperty<RankTwoTensor>(this->_base_name + "rotation_matrix")),
84  _rotation_matrix_transpose(this->template declareProperty<RankTwoTensor>(
85  this->_base_name + "rotation_matrix_transpose")),
86  _rotation_matrix_old(
87  this->template getMaterialPropertyOld<RankTwoTensor>(this->_base_name + "rotation_matrix")),
88  _rotation_matrix_transpose_old(this->template getMaterialPropertyOld<RankTwoTensor>(
89  this->_base_name + "rotation_matrix_transpose")),
90  _local_cylindrical_csys(this->template getParam<bool>("local_cylindrical_csys")),
91  _axis(this->template getParam<MooseEnum>("axis").template getEnum<Axis>())
92 {
93  if (_local_cylindrical_csys && !parameters.isParamSetByUser("axis"))
94  {
95  this->paramError(
96  "local_cylindrical_csys",
97  "\nIf parameter local_cylindrical_csys is provided then parameter axis should be also "
98  "provided.");
99  }
100 
101  if (!_local_cylindrical_csys && parameters.isParamSetByUser("axis"))
102  {
103  this->paramError("axis",
104  "\nIf parameter axis is provided then the parameter local_cylindrical_csys "
105  "should be set to true");
106  }
107 }
108 
109 template <bool is_ad>
110 void
112 {
113  RealVectorValue normal_vector(0, 0, 0);
114  RealVectorValue axial_vector(0, 0, 0);
115 
116  if (_local_cylindrical_csys)
117  {
118  if (_axis == Axis::X)
119  {
120  normal_vector(0) = 0.0;
121  normal_vector(1) = _q_point[_qp](1);
122  normal_vector(2) = _q_point[_qp](2);
123  axial_vector(0) = 1.0;
124  }
125  else if (_axis == Axis::Y)
126  {
127  normal_vector(0) = _q_point[_qp](0);
128  normal_vector(1) = 0.0;
129  normal_vector(2) = _q_point[_qp](2);
130  axial_vector(1) = 1.0;
131  }
132  else if (_axis == Axis::Z)
133  {
134  normal_vector(0) = _q_point[_qp](0);
135  normal_vector(1) = _q_point[_qp](1);
136  normal_vector(2) = 0.0;
137  axial_vector(2) = 1.0;
138  }
139  else
140  mooseError("\nInvalid value for axis parameter provided in HillElastoPlasticityStressUpdate");
141  }
142 
143  if (_local_cylindrical_csys)
144  {
145  Real nv_norm = normal_vector.norm();
146  Real av_norm = axial_vector.norm();
147 
148  if (!(MooseUtils::absoluteFuzzyEqual(nv_norm, 0.0)))
149  normal_vector /= nv_norm;
150  else
151  {
152  mooseError("The normal vector cannot be a zero vector in "
153  "HillElastoPlasticityStressUpdate");
154  }
155 
156  if (!(MooseUtils::absoluteFuzzyEqual(av_norm, 0.0)))
157  axial_vector /= av_norm;
158  else
159  {
160  mooseError("The axial vector cannot be a zero vector in "
161  "HillElastoPlasticityStressUpdate");
162  }
163 
165  normal_vector, axial_vector, _rotation_matrix[_qp], false);
166  _rotation_matrix_transpose[_qp] = _rotation_matrix[_qp].transpose();
167  }
168 
170 }
171 
172 template <bool is_ad>
173 void
175 {
176  _hardening_variable[_qp] = _hardening_variable_old[_qp];
177  _plasticity_strain[_qp] = _plasticity_strain_old[_qp];
178 
179  if (_local_cylindrical_csys)
180  {
181  _rotation_matrix[_qp] = _rotation_matrix_old[_qp];
182  _rotation_matrix_transpose[_qp] = _rotation_matrix_transpose_old[_qp];
183  }
184 
186 }
187 
188 template <bool is_ad>
189 void
191  const GenericDenseVector<is_ad> & stress_dev,
192  const GenericDenseVector<is_ad> & stress,
193  const GenericRankFourTensor<is_ad> & /*elasticity_tensor*/)
194 {
195  _hardening_variable[_qp] = _hardening_variable_old[_qp];
196  _plasticity_strain[_qp] = _plasticity_strain_old[_qp];
197  _effective_inelastic_strain[_qp] = _effective_inelastic_strain_old[_qp];
198 
199  _elasticity_eigenvectors[_qp].resize(6, 6);
200  _elasticity_eigenvalues[_qp].resize(6);
201 
202  _b_eigenvectors[_qp].resize(6, 6);
203  _b_eigenvalues[_qp].resize(6);
204 
205  _alpha_matrix[_qp].resize(6, 6);
206  _sigma_tilde[_qp].resize(6);
207  _sigma_tilde_rotated[_qp].resize(6);
208 
209  // Algebra needed for the generalized return mapping of anisotropic elastoplasticity
210  computeElasticityTensorEigenDecomposition();
211 
212  _yield_condition = 1.0; // Some positive value
213  _yield_condition = -computeResidual(stress_dev, stress, 0.0);
214 }
215 
216 template <bool is_ad>
217 void
219 {
220  // Helper method to compute qp matrices required for the elasto-plasticity algorithm.
221  using std::sqrt;
222 
223  GenericRankFourTensor<is_ad> elasticity_tensor = _elasticity_tensor[_qp];
224 
225  if (_local_cylindrical_csys)
226  {
227  elasticity_tensor.rotate(_rotation_matrix_transpose[_qp]);
228  }
229 
230  ElasticityTensorTools::toVoigtNotation<is_ad>(_anisotropic_elastic_tensor, elasticity_tensor);
231 
232  const unsigned int dimension = _anisotropic_elastic_tensor.n();
233 
234  AnisotropyMatrixReal A = AnisotropyMatrixReal::Zero();
235  for (unsigned int index_i = 0; index_i < dimension; index_i++)
236  for (unsigned int index_j = 0; index_j < dimension; index_j++)
237  A(index_i, index_j) = MetaPhysicL::raw_value(_anisotropic_elastic_tensor(index_i, index_j));
238 
239  Eigen::SelfAdjointEigenSolver<AnisotropyMatrixReal> es(A);
240 
241  auto lambda = es.eigenvalues();
242  auto v = es.eigenvectors();
243 
244  for (unsigned int index_i = 0; index_i < dimension; index_i++)
245  _elasticity_eigenvalues[_qp](index_i) = lambda(index_i);
246 
247  for (unsigned int index_i = 0; index_i < dimension; index_i++)
248  for (unsigned int index_j = 0; index_j < dimension; index_j++)
249  _elasticity_eigenvectors[_qp](index_i, index_j) = v(index_i, index_j);
250 
251  // Compute sqrt(Delta_c) * QcT * A * Qc * sqrt(Delta_c)
252  GenericDenseMatrix<is_ad> sqrt_Delta(6, 6);
253  for (unsigned int i = 0; i < 6; i++)
254  {
255  sqrt_Delta(i, i) = sqrt(_elasticity_eigenvalues[_qp](i));
256  }
257 
258  GenericDenseMatrix<is_ad> eigenvectors_elasticity_transpose(6, 6);
259  _elasticity_eigenvectors[_qp].get_transpose(eigenvectors_elasticity_transpose);
260 
261  GenericDenseMatrix<is_ad> b_matrix(6, 6);
262  b_matrix = _hill_tensor[_qp];
263 
264  // Right multiply by matrix of eigenvectors transpose
265  b_matrix.right_multiply(_elasticity_eigenvectors[_qp]);
266  b_matrix.right_multiply(sqrt_Delta);
267  b_matrix.left_multiply(eigenvectors_elasticity_transpose);
268  b_matrix.left_multiply(sqrt_Delta);
269 
270  AnisotropyMatrixReal B_eigen = AnisotropyMatrixReal::Zero();
271  for (unsigned int index_i = 0; index_i < dimension; index_i++)
272  for (unsigned int index_j = 0; index_j < dimension; index_j++)
273  B_eigen(index_i, index_j) = MetaPhysicL::raw_value(b_matrix(index_i, index_j));
274 
275  if (isBlockDiagonal(B_eigen))
276  {
277  Eigen::SelfAdjointEigenSolver<AnisotropyMatrixRealBlock> es_b_left(B_eigen.block<3, 3>(0, 0));
278  Eigen::SelfAdjointEigenSolver<AnisotropyMatrixRealBlock> es_b_right(B_eigen.block<3, 3>(3, 3));
279 
280  auto lambda_b_left = es_b_left.eigenvalues();
281  auto v_b_left = es_b_left.eigenvectors();
282 
283  auto lambda_b_right = es_b_right.eigenvalues();
284  auto v_b_right = es_b_right.eigenvectors();
285 
286  _b_eigenvalues[_qp](0) = lambda_b_left(0);
287  _b_eigenvalues[_qp](1) = lambda_b_left(1);
288  _b_eigenvalues[_qp](2) = lambda_b_left(2);
289  _b_eigenvalues[_qp](3) = lambda_b_right(0);
290  _b_eigenvalues[_qp](4) = lambda_b_right(1);
291  _b_eigenvalues[_qp](5) = lambda_b_right(2);
292 
293  _b_eigenvectors[_qp](0, 0) = v_b_left(0, 0);
294  _b_eigenvectors[_qp](0, 1) = v_b_left(0, 1);
295  _b_eigenvectors[_qp](0, 2) = v_b_left(0, 2);
296  _b_eigenvectors[_qp](1, 0) = v_b_left(1, 0);
297  _b_eigenvectors[_qp](1, 1) = v_b_left(1, 1);
298  _b_eigenvectors[_qp](1, 2) = v_b_left(1, 2);
299  _b_eigenvectors[_qp](2, 0) = v_b_left(2, 0);
300  _b_eigenvectors[_qp](2, 1) = v_b_left(2, 1);
301  _b_eigenvectors[_qp](2, 2) = v_b_left(2, 2);
302  _b_eigenvectors[_qp](3, 3) = v_b_right(0, 0);
303  _b_eigenvectors[_qp](3, 4) = v_b_right(0, 1);
304  _b_eigenvectors[_qp](3, 5) = v_b_right(0, 2);
305  _b_eigenvectors[_qp](4, 3) = v_b_right(1, 0);
306  _b_eigenvectors[_qp](4, 4) = v_b_right(1, 1);
307  _b_eigenvectors[_qp](4, 5) = v_b_right(1, 2);
308  _b_eigenvectors[_qp](5, 3) = v_b_right(2, 0);
309  _b_eigenvectors[_qp](5, 4) = v_b_right(2, 1);
310  _b_eigenvectors[_qp](5, 5) = v_b_right(2, 2);
311  }
312  else
313  {
314  Eigen::SelfAdjointEigenSolver<AnisotropyMatrixReal> es_b(B_eigen);
315 
316  auto lambda_b = es_b.eigenvalues();
317  auto v_b = es_b.eigenvectors();
318  for (unsigned int index_i = 0; index_i < dimension; index_i++)
319  _b_eigenvalues[_qp](index_i) = lambda_b(index_i);
320 
321  for (unsigned int index_i = 0; index_i < dimension; index_i++)
322  for (unsigned int index_j = 0; index_j < dimension; index_j++)
323  _b_eigenvectors[_qp](index_i, index_j) = v_b(index_i, index_j);
324  }
325 
326  _alpha_matrix[_qp] = sqrt_Delta;
327  _alpha_matrix[_qp].right_multiply(_b_eigenvectors[_qp]);
328  _alpha_matrix[_qp].left_multiply(_elasticity_eigenvectors[_qp]);
329 }
330 
331 template <bool is_ad>
334  const GenericReal<is_ad> & delta_gamma, const GenericDenseVector<is_ad> & /*stress_trial*/)
335 {
337  GenericReal<is_ad> omega = 0.0;
338 
339  for (unsigned int i = 0; i < 6; i++)
340  {
341  K(i) = _b_eigenvalues[_qp](i) / Utility::pow<2>(1 + delta_gamma * _b_eigenvalues[_qp](i));
342 
343  if (_local_cylindrical_csys)
344  omega += K(i) * _sigma_tilde_rotated[_qp](i) * _sigma_tilde_rotated[_qp](i);
345  else
346  omega += K(i) * _sigma_tilde[_qp](i) * _sigma_tilde[_qp](i);
347  }
348  omega *= 0.5;
349 
350  if (omega == 0.0)
351  omega = 1.0e-36;
352 
353  using std::sqrt;
354  return sqrt(omega);
355 }
356 
357 template <bool is_ad>
358 Real
360  const GenericDenseVector<is_ad> & /*effective_trial_stress*/,
361  const GenericDenseVector<is_ad> & /*stress_new*/,
362  const GenericReal<is_ad> & /*residual*/,
363  const GenericReal<is_ad> & /*scalar_effective_inelastic_strain*/)
364 {
365  // Equation is already normalized.
366  return 1.0;
367 }
368 
369 template <bool is_ad>
372  const GenericDenseVector<is_ad> & /*stress_dev*/,
373  const GenericDenseVector<is_ad> & stress_sigma,
374  const GenericReal<is_ad> & delta_gamma)
375 {
376  using std::pow;
377 
378  // If in elastic regime, just return
379  if (_yield_condition <= 0.0)
380  return 0.0;
381 
382  GenericReal<is_ad> omega;
383 
384  if (_local_cylindrical_csys)
385  {
386  // Get stress_tilde_rotated
388  RankTwoScalarTools::VoigtVectorToRankTwoTensor<is_ad>(stress_sigma, stress);
389 
390  stress.rotate(_rotation_matrix_transpose[_qp]);
391 
392  GenericDenseVector<is_ad> stress_sigma_rotated(6);
393  RankTwoScalarTools::RankTwoTensorToVoigtVector<is_ad>(stress, stress_sigma_rotated);
394 
395  GenericDenseVector<is_ad> stress_tilde_rotated(6);
396  GenericDenseMatrix<is_ad> alpha_temp_rotated(_alpha_matrix[_qp]);
397  alpha_temp_rotated.lu_solve(stress_sigma_rotated, stress_tilde_rotated);
398 
399  // Material property used in computeStressFinalize
400  _sigma_tilde_rotated[_qp] = stress_tilde_rotated;
401  omega = computeOmega(delta_gamma, stress_tilde_rotated);
402  }
403 
404  else
405  {
406  // Get stress_tilde
407  GenericDenseVector<is_ad> stress_tilde(6);
408  GenericDenseMatrix<is_ad> alpha_temp(_alpha_matrix[_qp]);
409  alpha_temp.lu_solve(stress_sigma, stress_tilde);
410 
411  // Material property used in computeStressFinalize
412  _sigma_tilde[_qp] = stress_tilde;
413  omega = computeOmega(delta_gamma, stress_tilde);
414  }
415 
416  // Hardening variable is \alpha isotropic hardening for now.
417  _hardening_variable[_qp] = computeHardeningValue(delta_gamma, omega);
418 
419  // A small value of 1.0e-30 is added to the hardening variable to avoid numerical issues
420  // related to hardening variable becoming negative early in the iteration leading to non-
421  // convergence. Note that pow(x,n) requires x to be positive if n is less than 1.
422 
423  GenericReal<is_ad> s_y =
424  _hardening_constant * pow(_hardening_variable[_qp] + 1.0e-30, _hardening_exponent) +
425  _yield_stress;
426 
427  GenericReal<is_ad> residual = 0.0;
428  residual = s_y / omega - 1.0;
429 
430  return residual;
431 }
432 
433 template <bool is_ad>
436  const GenericDenseVector<is_ad> & /*stress_dev*/,
437  const GenericDenseVector<is_ad> & stress_sigma,
438  const GenericReal<is_ad> & delta_gamma)
439 {
440  using std::pow;
441 
442  // If in elastic regime, return unit derivative
443  if (_yield_condition <= 0.0)
444  return 1.0;
445 
446  GenericReal<is_ad> omega = computeOmega(delta_gamma, stress_sigma);
447  _hardening_derivative = computeHardeningDerivative();
448 
449  GenericReal<is_ad> hardeningVariable = computeHardeningValue(delta_gamma, omega);
450  GenericReal<is_ad> sy =
451  _hardening_constant * pow(hardeningVariable + 1.0e-30, _hardening_exponent) + _yield_stress;
452  GenericReal<is_ad> sy_alpha = _hardening_derivative;
453 
454  GenericReal<is_ad> omega_gamma;
455  GenericReal<is_ad> sy_gamma;
456 
457  computeDeltaDerivatives(delta_gamma, stress_sigma, sy_alpha, omega, omega_gamma, sy_gamma);
458  GenericReal<is_ad> residual_derivative = 1 / omega * (sy_gamma - 1 / omega * omega_gamma * sy);
459 
460  return residual_derivative;
461 }
462 
463 template <bool is_ad>
464 void
466  const GenericReal<is_ad> & delta_gamma,
467  const GenericDenseVector<is_ad> & /*stress_trial*/,
468  const GenericReal<is_ad> & sy_alpha,
469  GenericReal<is_ad> & omega,
470  GenericReal<is_ad> & omega_gamma,
471  GenericReal<is_ad> & sy_gamma)
472 {
473  omega_gamma = 0.0;
474  sy_gamma = 0.0;
475 
476  GenericDenseVector<is_ad> K_deltaGamma(6);
477 
478  if (_local_cylindrical_csys)
479  omega = computeOmega(delta_gamma, _sigma_tilde_rotated[_qp]);
480  else
481  omega = computeOmega(delta_gamma, _sigma_tilde[_qp]);
482 
484  for (unsigned int i = 0; i < 6; i++)
485  K(i) = _b_eigenvalues[_qp](i) / Utility::pow<2>(1 + delta_gamma * _b_eigenvalues[_qp](i));
486 
487  for (unsigned int i = 0; i < 6; i++)
488  K_deltaGamma(i) =
489  -2.0 * _b_eigenvalues[_qp](i) * K(i) / (1 + _b_eigenvalues[_qp](i) * delta_gamma);
490 
491  for (unsigned int i = 0; i < 6; i++)
492  {
493  if (_local_cylindrical_csys)
494  omega_gamma += K_deltaGamma(i) * _sigma_tilde_rotated[_qp](i) * _sigma_tilde_rotated[_qp](i);
495  else
496  omega_gamma += K_deltaGamma(i) * _sigma_tilde[_qp](i) * _sigma_tilde[_qp](i);
497  }
498 
499  omega_gamma /= 4.0 * omega;
500  sy_gamma = 2.0 * sy_alpha * (omega + delta_gamma * omega_gamma);
501 }
502 
503 template <bool is_ad>
506  const GenericReal<is_ad> & delta_gamma, const GenericReal<is_ad> & omega)
507 {
508  return _hardening_variable_old[_qp] + 2.0 * delta_gamma * omega;
509 }
510 
511 template <bool is_ad>
512 Real
514 {
515  using std::pow;
516  return _hardening_constant * _hardening_exponent *
517  MetaPhysicL::raw_value(pow(_hardening_variable[_qp] + 1.0e-30, _hardening_exponent - 1));
518 }
519 
520 template <bool is_ad>
521 void
523  GenericRankTwoTensor<is_ad> & inelasticStrainIncrement,
524  const GenericRankTwoTensor<is_ad> & stress,
525  const GenericDenseVector<is_ad> & stress_dev,
526  const GenericReal<is_ad> & delta_gamma)
527 {
528  using std::sqrt;
529 
530  // e^P = delta_gamma * hill_tensor * stress
531  GenericDenseVector<is_ad> inelasticStrainIncrement_vector(6);
532  GenericDenseVector<is_ad> hill_stress(6);
533  GenericDenseVector<is_ad> stress_vector(6);
534 
535  if (_local_cylindrical_csys)
536  {
537  GenericRankTwoTensor<is_ad> stress_rotated(stress);
538  stress_rotated.rotate(_rotation_matrix_transpose[_qp]);
539 
540  RankTwoScalarTools::RankTwoTensorToVoigtVector<is_ad>(stress_rotated, stress_vector);
541  }
542  else
543  {
544  RankTwoScalarTools::RankTwoTensorToVoigtVector<is_ad>(stress, stress_vector);
545  }
546 
547  _hill_tensor[_qp].vector_mult(hill_stress, stress_vector);
548  hill_stress.scale(delta_gamma);
549  inelasticStrainIncrement_vector = hill_stress;
550 
551  inelasticStrainIncrement(0, 0) = inelasticStrainIncrement_vector(0);
552  inelasticStrainIncrement(1, 1) = inelasticStrainIncrement_vector(1);
553  inelasticStrainIncrement(2, 2) = inelasticStrainIncrement_vector(2);
554  inelasticStrainIncrement(0, 1) = inelasticStrainIncrement(1, 0) =
555  inelasticStrainIncrement_vector(3) / 2.0;
556  inelasticStrainIncrement(1, 2) = inelasticStrainIncrement(2, 1) =
557  inelasticStrainIncrement_vector(4) / 2.0;
558  inelasticStrainIncrement(0, 2) = inelasticStrainIncrement(2, 0) =
559  inelasticStrainIncrement_vector(5) / 2.0;
560 
561  if (_local_cylindrical_csys)
562  inelasticStrainIncrement.rotate(_rotation_matrix[_qp]);
563 
564  // Calculate equivalent plastic strain
565  GenericDenseVector<is_ad> Mepsilon(6);
566  _hill_tensor[_qp].vector_mult(Mepsilon, inelasticStrainIncrement_vector);
567  GenericReal<is_ad> eq_plastic_strain_inc = Mepsilon.dot(inelasticStrainIncrement_vector);
568 
569  if (eq_plastic_strain_inc > 0.0)
570  eq_plastic_strain_inc = sqrt(eq_plastic_strain_inc);
571 
572  _effective_inelastic_strain[_qp] = _effective_inelastic_strain_old[_qp] + eq_plastic_strain_inc;
573 
575  inelasticStrainIncrement, stress, stress_dev, delta_gamma);
576 }
577 
578 template <bool is_ad>
579 void
581  const GenericRankTwoTensor<is_ad> & /*plastic_strain_increment*/,
582  const GenericReal<is_ad> & delta_gamma,
583  GenericRankTwoTensor<is_ad> & stress_new,
584  const GenericDenseVector<is_ad> & /*stress_dev*/,
585  const GenericRankTwoTensor<is_ad> & /*stress_old*/,
586  const GenericRankFourTensor<is_ad> & /*elasticity_tensor*/)
587 {
588  // Need to compute this iteration's stress tensor based on the scalar variable
589  // For deviatoric
590  // sigma(n+1) = {Alpha [I + delta_gamma*Delta_b]^(-1) A^-1} sigma(trial)
591 
592  if (_yield_condition <= 0.0)
593  return;
594  GenericDenseMatrix<is_ad> inv_matrix(6, 6);
595  inv_matrix.zero();
596 
597  for (unsigned int i = 0; i < 6; i++)
598  inv_matrix(i, i) = 1 / (1 + delta_gamma * _b_eigenvalues[_qp](i));
599 
600  _alpha_matrix[_qp].right_multiply(inv_matrix);
601 
602  GenericDenseVector<is_ad> stress_output(6);
603  if (_local_cylindrical_csys)
604  _alpha_matrix[_qp].vector_mult(stress_output, _sigma_tilde_rotated[_qp]);
605  else
606  _alpha_matrix[_qp].vector_mult(stress_output, _sigma_tilde[_qp]);
607 
608  RankTwoScalarTools::VoigtVectorToRankTwoTensor<is_ad>(stress_output, stress_new);
609 
610  if (_local_cylindrical_csys)
611  stress_new.rotate(_rotation_matrix[_qp]);
612 }
613 
614 template <bool is_ad>
615 Real
618  const GenericMaterialProperty<RankTwoTensor, is_ad> & /*strain_rate*/)
619 {
620  mooseError("computeStrainEnergyRateDensity not implemented for anisotropic plasticity.");
621  return 0.0;
622 }
623 
Moose::GenericType< Real, is_ad > GenericReal
auto norm() const
void computeElasticityTensorEigenDecomposition()
Compute eigendecomposition of element-wise elasticity tensor.
void addParam(const std::string &name, const std::initializer_list< typename T::value_type > &value, const std::string &doc_string)
void mooseError(Args &&... args)
virtual void computeStrainFinalize(GenericRankTwoTensor< is_ad > &inelasticStrainIncrement, const GenericRankTwoTensor< is_ad > &stress, const GenericDenseVector< is_ad > &stress_dev, const GenericReal< is_ad > &delta_gamma) override
Perform any necessary steps to finalize strain increment after return mapping iterations.
Eigen::Matrix< Real, 6, 6 > AnisotropyMatrixReal
static const std::string K
Definition: NS.h:174
auto raw_value(const Eigen::Map< T > &in)
const double v
This class uses the stress update material in an anisotropic return mapping.
Moose::GenericType< DenseVector< Real >, is_ad > GenericDenseVector
Moose::GenericType< RankFourTensor, is_ad > GenericRankFourTensor
void addRequiredParam(const std::string &name, const std::string &doc_string)
Real elasticity_tensor(unsigned int i, unsigned int j, unsigned int k, unsigned int l)
virtual GenericReal< is_ad > computeResidual(const GenericDenseVector< is_ad > &effective_trial_stress, const GenericDenseVector< is_ad > &stress_new, const GenericReal< is_ad > &scalar) override
GenericReal< is_ad > computeHardeningValue(const GenericReal< is_ad > &scalar, const GenericReal< is_ad > &omega)
virtual Real computeReferenceResidual(const GenericDenseVector< is_ad > &effective_trial_stress, const GenericDenseVector< is_ad > &stress_new, const GenericReal< is_ad > &residual, const GenericReal< is_ad > &scalar_effective_inelastic_strain) override
HillElastoPlasticityStressUpdateTempl(const InputParameters &parameters)
typename GenericMaterialPropertyStruct< T, is_ad >::type GenericMaterialProperty
virtual GenericReal< is_ad > computeDerivative(const GenericDenseVector< is_ad > &effective_trial_stress, const GenericDenseVector< is_ad > &stress_new, const GenericReal< is_ad > &scalar) override
void setRotationMatrix(const RealVectorValue &outwardnormal, const RealVectorValue &axialVector, RankTwoTensor &rotationMatrix, const bool transpose)
GenericReal< is_ad > computeOmega(const GenericReal< is_ad > &delta_gamma, const GenericDenseVector< is_ad > &stress_trial)
virtual void computeStrainFinalize(GenericRankTwoTensor< is_ad > &, const GenericRankTwoTensor< is_ad > &, const GenericDenseVector< is_ad > &, const GenericReal< is_ad > &) override
Perform any necessary steps to finalize strain increment after return mapping iterations.
registerMooseObject("SolidMechanicsApp", ADHillElastoPlasticityStressUpdate)
ExpressionBuilder::EBTerm pow(const ExpressionBuilder::EBTerm &left, T exponent)
bool isParamSetByUser(const std::string &name) const
virtual void computeStressFinalize(const GenericRankTwoTensor< is_ad > &inelasticStrainIncrement, const GenericReal< is_ad > &delta_gamma, GenericRankTwoTensor< is_ad > &stress, const GenericDenseVector< is_ad > &stress_dev, const GenericRankTwoTensor< is_ad > &stress_old, const GenericRankFourTensor< is_ad > &elasticity_tensor) override
Perform any necessary steps to finalize state after return mapping iterations.
virtual void computeStressInitialize(const GenericDenseVector< is_ad > &stress_dev, const GenericDenseVector< is_ad > &stress, const GenericRankFourTensor< is_ad > &elasticity_tensor) override
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
CTSub CT_OPERATOR_BINARY CTMul CTCompareLess CTCompareGreater CTCompareEqual _arg template * sqrt(_arg)) *_arg.template D< dtag >()) CT_SIMPLE_UNARY_FUNCTION(tanh
void addClassDescription(const std::string &doc_string)
This class provides baseline functionality for anisotropic (Hill-like) plasticity models based on the...
void paramError(const std::string &param, Args... args) const
void computeDeltaDerivatives(const GenericReal< is_ad > &delta_gamma, const GenericDenseVector< is_ad > &stress_trial, const GenericReal< is_ad > &sy_alpha, GenericReal< is_ad > &omega, GenericReal< is_ad > &omega_gamma, GenericReal< is_ad > &sy_gamma)
MooseUnits pow(const MooseUnits &, int)
Moose::GenericType< DenseMatrix< Real >, is_ad > GenericDenseMatrix
Moose::GenericType< RankTwoTensor, is_ad > GenericRankTwoTensor
virtual Real computeStrainEnergyRateDensity(const GenericMaterialProperty< RankTwoTensor, is_ad > &stress, const GenericMaterialProperty< RankTwoTensor, is_ad > &strain_rate) override