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 
222  GenericRankFourTensor<is_ad> elasticity_tensor = _elasticity_tensor[_qp];
223 
224  if (_local_cylindrical_csys)
225  {
226  elasticity_tensor.rotate(_rotation_matrix_transpose[_qp]);
227  }
228 
229  ElasticityTensorTools::toVoigtNotation<is_ad>(_anisotropic_elastic_tensor, elasticity_tensor);
230 
231  const unsigned int dimension = _anisotropic_elastic_tensor.n();
232 
233  AnisotropyMatrixReal A = AnisotropyMatrixReal::Zero();
234  for (unsigned int index_i = 0; index_i < dimension; index_i++)
235  for (unsigned int index_j = 0; index_j < dimension; index_j++)
236  A(index_i, index_j) = MetaPhysicL::raw_value(_anisotropic_elastic_tensor(index_i, index_j));
237 
238  Eigen::SelfAdjointEigenSolver<AnisotropyMatrixReal> es(A);
239 
240  auto lambda = es.eigenvalues();
241  auto v = es.eigenvectors();
242 
243  for (unsigned int index_i = 0; index_i < dimension; index_i++)
244  _elasticity_eigenvalues[_qp](index_i) = lambda(index_i);
245 
246  for (unsigned int index_i = 0; index_i < dimension; index_i++)
247  for (unsigned int index_j = 0; index_j < dimension; index_j++)
248  _elasticity_eigenvectors[_qp](index_i, index_j) = v(index_i, index_j);
249 
250  // Compute sqrt(Delta_c) * QcT * A * Qc * sqrt(Delta_c)
251  GenericDenseMatrix<is_ad> sqrt_Delta(6, 6);
252  for (unsigned int i = 0; i < 6; i++)
253  {
254  sqrt_Delta(i, i) = std::sqrt(_elasticity_eigenvalues[_qp](i));
255  }
256 
257  GenericDenseMatrix<is_ad> eigenvectors_elasticity_transpose(6, 6);
258  _elasticity_eigenvectors[_qp].get_transpose(eigenvectors_elasticity_transpose);
259 
260  GenericDenseMatrix<is_ad> b_matrix(6, 6);
261  b_matrix = _hill_tensor[_qp];
262 
263  // Right multiply by matrix of eigenvectors transpose
264  b_matrix.right_multiply(_elasticity_eigenvectors[_qp]);
265  b_matrix.right_multiply(sqrt_Delta);
266  b_matrix.left_multiply(eigenvectors_elasticity_transpose);
267  b_matrix.left_multiply(sqrt_Delta);
268 
269  AnisotropyMatrixReal B_eigen = AnisotropyMatrixReal::Zero();
270  for (unsigned int index_i = 0; index_i < dimension; index_i++)
271  for (unsigned int index_j = 0; index_j < dimension; index_j++)
272  B_eigen(index_i, index_j) = MetaPhysicL::raw_value(b_matrix(index_i, index_j));
273 
274  if (isBlockDiagonal(B_eigen))
275  {
276  Eigen::SelfAdjointEigenSolver<AnisotropyMatrixRealBlock> es_b_left(B_eigen.block<3, 3>(0, 0));
277  Eigen::SelfAdjointEigenSolver<AnisotropyMatrixRealBlock> es_b_right(B_eigen.block<3, 3>(3, 3));
278 
279  auto lambda_b_left = es_b_left.eigenvalues();
280  auto v_b_left = es_b_left.eigenvectors();
281 
282  auto lambda_b_right = es_b_right.eigenvalues();
283  auto v_b_right = es_b_right.eigenvectors();
284 
285  _b_eigenvalues[_qp](0) = lambda_b_left(0);
286  _b_eigenvalues[_qp](1) = lambda_b_left(1);
287  _b_eigenvalues[_qp](2) = lambda_b_left(2);
288  _b_eigenvalues[_qp](3) = lambda_b_right(0);
289  _b_eigenvalues[_qp](4) = lambda_b_right(1);
290  _b_eigenvalues[_qp](5) = lambda_b_right(2);
291 
292  _b_eigenvectors[_qp](0, 0) = v_b_left(0, 0);
293  _b_eigenvectors[_qp](0, 1) = v_b_left(0, 1);
294  _b_eigenvectors[_qp](0, 2) = v_b_left(0, 2);
295  _b_eigenvectors[_qp](1, 0) = v_b_left(1, 0);
296  _b_eigenvectors[_qp](1, 1) = v_b_left(1, 1);
297  _b_eigenvectors[_qp](1, 2) = v_b_left(1, 2);
298  _b_eigenvectors[_qp](2, 0) = v_b_left(2, 0);
299  _b_eigenvectors[_qp](2, 1) = v_b_left(2, 1);
300  _b_eigenvectors[_qp](2, 2) = v_b_left(2, 2);
301  _b_eigenvectors[_qp](3, 3) = v_b_right(0, 0);
302  _b_eigenvectors[_qp](3, 4) = v_b_right(0, 1);
303  _b_eigenvectors[_qp](3, 5) = v_b_right(0, 2);
304  _b_eigenvectors[_qp](4, 3) = v_b_right(1, 0);
305  _b_eigenvectors[_qp](4, 4) = v_b_right(1, 1);
306  _b_eigenvectors[_qp](4, 5) = v_b_right(1, 2);
307  _b_eigenvectors[_qp](5, 3) = v_b_right(2, 0);
308  _b_eigenvectors[_qp](5, 4) = v_b_right(2, 1);
309  _b_eigenvectors[_qp](5, 5) = v_b_right(2, 2);
310  }
311  else
312  {
313  Eigen::SelfAdjointEigenSolver<AnisotropyMatrixReal> es_b(B_eigen);
314 
315  auto lambda_b = es_b.eigenvalues();
316  auto v_b = es_b.eigenvectors();
317  for (unsigned int index_i = 0; index_i < dimension; index_i++)
318  _b_eigenvalues[_qp](index_i) = lambda_b(index_i);
319 
320  for (unsigned int index_i = 0; index_i < dimension; index_i++)
321  for (unsigned int index_j = 0; index_j < dimension; index_j++)
322  _b_eigenvectors[_qp](index_i, index_j) = v_b(index_i, index_j);
323  }
324 
325  _alpha_matrix[_qp] = sqrt_Delta;
326  _alpha_matrix[_qp].right_multiply(_b_eigenvectors[_qp]);
327  _alpha_matrix[_qp].left_multiply(_elasticity_eigenvectors[_qp]);
328 }
329 
330 template <bool is_ad>
333  const GenericReal<is_ad> & delta_gamma, const GenericDenseVector<is_ad> & /*stress_trial*/)
334 {
336  GenericReal<is_ad> omega = 0.0;
337 
338  for (unsigned int i = 0; i < 6; i++)
339  {
340  K(i) = _b_eigenvalues[_qp](i) / Utility::pow<2>(1 + delta_gamma * _b_eigenvalues[_qp](i));
341 
342  if (_local_cylindrical_csys)
343  omega += K(i) * _sigma_tilde_rotated[_qp](i) * _sigma_tilde_rotated[_qp](i);
344  else
345  omega += K(i) * _sigma_tilde[_qp](i) * _sigma_tilde[_qp](i);
346  }
347  omega *= 0.5;
348 
349  if (omega == 0.0)
350  omega = 1.0e-36;
351 
352  return std::sqrt(omega);
353 }
354 
355 template <bool is_ad>
356 Real
358  const GenericDenseVector<is_ad> & /*effective_trial_stress*/,
359  const GenericDenseVector<is_ad> & /*stress_new*/,
360  const GenericReal<is_ad> & /*residual*/,
361  const GenericReal<is_ad> & /*scalar_effective_inelastic_strain*/)
362 {
363  // Equation is already normalized.
364  return 1.0;
365 }
366 
367 template <bool is_ad>
370  const GenericDenseVector<is_ad> & /*stress_dev*/,
371  const GenericDenseVector<is_ad> & stress_sigma,
372  const GenericReal<is_ad> & delta_gamma)
373 {
374 
375  // If in elastic regime, just return
376  if (_yield_condition <= 0.0)
377  return 0.0;
378 
379  GenericReal<is_ad> omega;
380 
381  if (_local_cylindrical_csys)
382  {
383  // Get stress_tilde_rotated
385  RankTwoScalarTools::VoigtVectorToRankTwoTensor<is_ad>(stress_sigma, stress);
386 
387  stress.rotate(_rotation_matrix_transpose[_qp]);
388 
389  GenericDenseVector<is_ad> stress_sigma_rotated(6);
390  RankTwoScalarTools::RankTwoTensorToVoigtVector<is_ad>(stress, stress_sigma_rotated);
391 
392  GenericDenseVector<is_ad> stress_tilde_rotated(6);
393  GenericDenseMatrix<is_ad> alpha_temp_rotated(_alpha_matrix[_qp]);
394  alpha_temp_rotated.lu_solve(stress_sigma_rotated, stress_tilde_rotated);
395 
396  // Material property used in computeStressFinalize
397  _sigma_tilde_rotated[_qp] = stress_tilde_rotated;
398  omega = computeOmega(delta_gamma, stress_tilde_rotated);
399  }
400 
401  else
402  {
403  // Get stress_tilde
404  GenericDenseVector<is_ad> stress_tilde(6);
405  GenericDenseMatrix<is_ad> alpha_temp(_alpha_matrix[_qp]);
406  alpha_temp.lu_solve(stress_sigma, stress_tilde);
407 
408  // Material property used in computeStressFinalize
409  _sigma_tilde[_qp] = stress_tilde;
410  omega = computeOmega(delta_gamma, stress_tilde);
411  }
412 
413  // Hardening variable is \alpha isotropic hardening for now.
414  _hardening_variable[_qp] = computeHardeningValue(delta_gamma, omega);
415 
416  // A small value of 1.0e-30 is added to the hardening variable to avoid numerical issues
417  // related to hardening variable becoming negative early in the iteration leading to non-
418  // convergence. Note that std::pow(x,n) requires x to be positive if n is less than 1.
419 
420  GenericReal<is_ad> s_y =
421  _hardening_constant * std::pow(_hardening_variable[_qp] + 1.0e-30, _hardening_exponent) +
422  _yield_stress;
423 
424  GenericReal<is_ad> residual = 0.0;
425  residual = s_y / omega - 1.0;
426 
427  return residual;
428 }
429 
430 template <bool is_ad>
433  const GenericDenseVector<is_ad> & /*stress_dev*/,
434  const GenericDenseVector<is_ad> & stress_sigma,
435  const GenericReal<is_ad> & delta_gamma)
436 {
437  // If in elastic regime, return unit derivative
438  if (_yield_condition <= 0.0)
439  return 1.0;
440 
441  GenericReal<is_ad> omega = computeOmega(delta_gamma, stress_sigma);
442  _hardening_derivative = computeHardeningDerivative();
443 
444  GenericReal<is_ad> hardeningVariable = computeHardeningValue(delta_gamma, omega);
445  GenericReal<is_ad> sy =
446  _hardening_constant * std::pow(hardeningVariable + 1.0e-30, _hardening_exponent) +
447  _yield_stress;
448  GenericReal<is_ad> sy_alpha = _hardening_derivative;
449 
450  GenericReal<is_ad> omega_gamma;
451  GenericReal<is_ad> sy_gamma;
452 
453  computeDeltaDerivatives(delta_gamma, stress_sigma, sy_alpha, omega, omega_gamma, sy_gamma);
454  GenericReal<is_ad> residual_derivative = 1 / omega * (sy_gamma - 1 / omega * omega_gamma * sy);
455 
456  return residual_derivative;
457 }
458 
459 template <bool is_ad>
460 void
462  const GenericReal<is_ad> & delta_gamma,
463  const GenericDenseVector<is_ad> & /*stress_trial*/,
464  const GenericReal<is_ad> & sy_alpha,
465  GenericReal<is_ad> & omega,
466  GenericReal<is_ad> & omega_gamma,
467  GenericReal<is_ad> & sy_gamma)
468 {
469  omega_gamma = 0.0;
470  sy_gamma = 0.0;
471 
472  GenericDenseVector<is_ad> K_deltaGamma(6);
473 
474  if (_local_cylindrical_csys)
475  omega = computeOmega(delta_gamma, _sigma_tilde_rotated[_qp]);
476  else
477  omega = computeOmega(delta_gamma, _sigma_tilde[_qp]);
478 
480  for (unsigned int i = 0; i < 6; i++)
481  K(i) = _b_eigenvalues[_qp](i) / Utility::pow<2>(1 + delta_gamma * _b_eigenvalues[_qp](i));
482 
483  for (unsigned int i = 0; i < 6; i++)
484  K_deltaGamma(i) =
485  -2.0 * _b_eigenvalues[_qp](i) * K(i) / (1 + _b_eigenvalues[_qp](i) * delta_gamma);
486 
487  for (unsigned int i = 0; i < 6; i++)
488  {
489  if (_local_cylindrical_csys)
490  omega_gamma += K_deltaGamma(i) * _sigma_tilde_rotated[_qp](i) * _sigma_tilde_rotated[_qp](i);
491  else
492  omega_gamma += K_deltaGamma(i) * _sigma_tilde[_qp](i) * _sigma_tilde[_qp](i);
493  }
494 
495  omega_gamma /= 4.0 * omega;
496  sy_gamma = 2.0 * sy_alpha * (omega + delta_gamma * omega_gamma);
497 }
498 
499 template <bool is_ad>
502  const GenericReal<is_ad> & delta_gamma, const GenericReal<is_ad> & omega)
503 {
504  return _hardening_variable_old[_qp] + 2.0 * delta_gamma * omega;
505 }
506 
507 template <bool is_ad>
508 Real
510 {
511  return _hardening_constant * _hardening_exponent *
513  std::pow(_hardening_variable[_qp] + 1.0e-30, _hardening_exponent - 1));
514 }
515 
516 template <bool is_ad>
517 void
519  GenericRankTwoTensor<is_ad> & inelasticStrainIncrement,
520  const GenericRankTwoTensor<is_ad> & stress,
521  const GenericDenseVector<is_ad> & stress_dev,
522  const GenericReal<is_ad> & delta_gamma)
523 {
524  // e^P = delta_gamma * hill_tensor * stress
525  GenericDenseVector<is_ad> inelasticStrainIncrement_vector(6);
526  GenericDenseVector<is_ad> hill_stress(6);
527  GenericDenseVector<is_ad> stress_vector(6);
528 
529  if (_local_cylindrical_csys)
530  {
531  GenericRankTwoTensor<is_ad> stress_rotated(stress);
532  stress_rotated.rotate(_rotation_matrix_transpose[_qp]);
533 
534  RankTwoScalarTools::RankTwoTensorToVoigtVector<is_ad>(stress_rotated, stress_vector);
535  }
536  else
537  {
538  RankTwoScalarTools::RankTwoTensorToVoigtVector<is_ad>(stress, stress_vector);
539  }
540 
541  _hill_tensor[_qp].vector_mult(hill_stress, stress_vector);
542  hill_stress.scale(delta_gamma);
543  inelasticStrainIncrement_vector = hill_stress;
544 
545  inelasticStrainIncrement(0, 0) = inelasticStrainIncrement_vector(0);
546  inelasticStrainIncrement(1, 1) = inelasticStrainIncrement_vector(1);
547  inelasticStrainIncrement(2, 2) = inelasticStrainIncrement_vector(2);
548  inelasticStrainIncrement(0, 1) = inelasticStrainIncrement(1, 0) =
549  inelasticStrainIncrement_vector(3) / 2.0;
550  inelasticStrainIncrement(1, 2) = inelasticStrainIncrement(2, 1) =
551  inelasticStrainIncrement_vector(4) / 2.0;
552  inelasticStrainIncrement(0, 2) = inelasticStrainIncrement(2, 0) =
553  inelasticStrainIncrement_vector(5) / 2.0;
554 
555  if (_local_cylindrical_csys)
556  inelasticStrainIncrement.rotate(_rotation_matrix[_qp]);
557 
558  // Calculate equivalent plastic strain
559  GenericDenseVector<is_ad> Mepsilon(6);
560  _hill_tensor[_qp].vector_mult(Mepsilon, inelasticStrainIncrement_vector);
561  GenericReal<is_ad> eq_plastic_strain_inc = Mepsilon.dot(inelasticStrainIncrement_vector);
562 
563  if (eq_plastic_strain_inc > 0.0)
564  eq_plastic_strain_inc = std::sqrt(eq_plastic_strain_inc);
565 
566  _effective_inelastic_strain[_qp] = _effective_inelastic_strain_old[_qp] + eq_plastic_strain_inc;
567 
569  inelasticStrainIncrement, stress, stress_dev, delta_gamma);
570 }
571 
572 template <bool is_ad>
573 void
575  const GenericRankTwoTensor<is_ad> & /*plastic_strain_increment*/,
576  const GenericReal<is_ad> & delta_gamma,
577  GenericRankTwoTensor<is_ad> & stress_new,
578  const GenericDenseVector<is_ad> & /*stress_dev*/,
579  const GenericRankTwoTensor<is_ad> & /*stress_old*/,
580  const GenericRankFourTensor<is_ad> & /*elasticity_tensor*/)
581 {
582  // Need to compute this iteration's stress tensor based on the scalar variable
583  // For deviatoric
584  // sigma(n+1) = {Alpha [I + delta_gamma*Delta_b]^(-1) A^-1} sigma(trial)
585 
586  if (_yield_condition <= 0.0)
587  return;
588  GenericDenseMatrix<is_ad> inv_matrix(6, 6);
589  inv_matrix.zero();
590 
591  for (unsigned int i = 0; i < 6; i++)
592  inv_matrix(i, i) = 1 / (1 + delta_gamma * _b_eigenvalues[_qp](i));
593 
594  _alpha_matrix[_qp].right_multiply(inv_matrix);
595 
596  GenericDenseVector<is_ad> stress_output(6);
597  if (_local_cylindrical_csys)
598  _alpha_matrix[_qp].vector_mult(stress_output, _sigma_tilde_rotated[_qp]);
599  else
600  _alpha_matrix[_qp].vector_mult(stress_output, _sigma_tilde[_qp]);
601 
602  RankTwoScalarTools::VoigtVectorToRankTwoTensor<is_ad>(stress_output, stress_new);
603 
604  if (_local_cylindrical_csys)
605  stress_new.rotate(_rotation_matrix[_qp]);
606 }
607 
608 template <bool is_ad>
609 Real
612  const GenericMaterialProperty<RankTwoTensor, is_ad> & /*strain_rate*/)
613 {
614  mooseError("computeStrainEnergyRateDensity not implemented for anisotropic plasticity.");
615  return 0.0;
616 }
617 
Moose::GenericType< Real, is_ad > GenericReal
auto norm() const -> decltype(std::norm(Real()))
bool absoluteFuzzyEqual(const T &var1, const T2 &var2, const T3 &tol=libMesh::TOLERANCE *libMesh::TOLERANCE)
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:170
auto raw_value(const Eigen::Map< T > &in)
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)
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.
static const std::string Z
Definition: NS.h:169
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
static const std::string v
Definition: NS.h:84
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