https://mooseframework.inl.gov
Loading...
Searching...
No Matches
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"
13
16
17template <bool is_ad>
20{
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
46template <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
109template <bool is_ad>
110void
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
172template <bool is_ad>
173void
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
188template <bool is_ad>
189void
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
216template <bool is_ad>
217void
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
331template <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
357template <bool is_ad>
358Real
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
369template <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
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
433template <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);
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
463template <bool is_ad>
464void
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
503template <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
511template <bool is_ad>
512Real
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
520template <bool is_ad>
521void
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
578template <bool is_ad>
579void
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
614template <bool is_ad>
615Real
618 const GenericMaterialProperty<RankTwoTensor, is_ad> & /*strain_rate*/)
619{
620 mooseError("computeStrainEnergyRateDensity not implemented for anisotropic plasticity.");
621 return 0.0;
622}
623
ExpressionBuilder::EBTerm pow(const ExpressionBuilder::EBTerm &left, T exponent)
const double v
Eigen::Matrix< Real, 6, 6 > AnisotropyMatrixReal
registerMooseObject("SolidMechanicsApp", ADHillElastoPlasticityStressUpdate)
typename GenericMaterialPropertyStruct< T, is_ad >::type GenericMaterialProperty
void mooseError(Args &&... args)
Moose::GenericType< RankFourTensor, is_ad > GenericRankFourTensor
Moose::GenericType< DenseVector< Real >, is_ad > GenericDenseVector
Moose::GenericType< Real, is_ad > GenericReal
Moose::GenericType< RankTwoTensor, is_ad > GenericRankTwoTensor
Moose::GenericType< DenseMatrix< Real >, is_ad > GenericDenseMatrix
This class provides baseline functionality for anisotropic (Hill-like) plasticity models based on the...
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.
This class uses the stress update material in an anisotropic return mapping.
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 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)
void computeElasticityTensorEigenDecomposition()
Compute eigendecomposition of element-wise elasticity tensor.
virtual GenericReal< is_ad > computeResidual(const GenericDenseVector< is_ad > &effective_trial_stress, const GenericDenseVector< is_ad > &stress_new, const GenericReal< is_ad > &scalar) override
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 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
virtual void computeStressInitialize(const GenericDenseVector< is_ad > &stress_dev, const GenericDenseVector< is_ad > &stress, const GenericRankFourTensor< is_ad > &elasticity_tensor) override
virtual Real computeStrainEnergyRateDensity(const GenericMaterialProperty< RankTwoTensor, is_ad > &stress, const GenericMaterialProperty< RankTwoTensor, is_ad > &strain_rate) override
HillElastoPlasticityStressUpdateTempl(const InputParameters &parameters)
GenericReal< is_ad > computeHardeningValue(const GenericReal< is_ad > &scalar, const GenericReal< is_ad > &omega)
void paramError(const std::string &param, Args... args) const
GenericReal< is_ad > computeOmega(const GenericReal< is_ad > &delta_gamma, const GenericDenseVector< is_ad > &stress_trial)
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.
bool isParamSetByUser(const std::string &name) const
void addRequiredParam(const std::string &name, const std::string &doc_string)
void addParam(const std::string &name, const std::initializer_list< typename T::value_type > &value, const std::string &doc_string)
void addClassDescription(const std::string &doc_string)
auto raw_value(const Eigen::Map< T > &in)
void setRotationMatrix(const RealVectorValue &outwardnormal, const RealVectorValue &axialVector, RankTwoTensor &rotationMatrix, const bool transpose)
Real elasticity_tensor(unsigned int i, unsigned int j, unsigned int k, unsigned int l)