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.");
28 "Hardening constant (H) for anisotropic plasticity");
30 "hardening_exponent", 1.0,
"Hardening exponent (n) for anisotropic plasticity");
32 "Yield stress (constant value) for anisotropic plasticity");
34 "local_cylindrical_csys",
36 "Compute inelastic strain increment in local cylindrical coordinate system");
40 "The axis of cylindrical component about which to rotate when " 41 "computing inelastic strain increment in local coordinate system");
52 _eigenvectors_hill(6, 6),
53 _anisotropic_elastic_tensor(6, 6),
54 _elasticity_tensor_name(this->_base_name +
"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 +
73 _sigma_tilde(this->template declareGenericProperty<DenseVector<
Real>, is_ad>(this->_base_name +
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 +
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")),
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>())
96 "local_cylindrical_csys",
97 "\nIf parameter local_cylindrical_csys is provided then parameter axis should be also " 104 "\nIf parameter axis is provided then the parameter local_cylindrical_csys " 105 "should be set to true");
109 template <
bool is_ad>
116 if (_local_cylindrical_csys)
118 if (_axis == Axis::X)
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;
125 else if (_axis == Axis::Y)
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;
132 else if (_axis == Axis::Z)
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;
140 mooseError(
"\nInvalid value for axis parameter provided in HillElastoPlasticityStressUpdate");
143 if (_local_cylindrical_csys)
145 Real nv_norm = normal_vector.
norm();
148 if (!(MooseUtils::absoluteFuzzyEqual(nv_norm, 0.0)))
149 normal_vector /= nv_norm;
152 mooseError(
"The normal vector cannot be a zero vector in " 153 "HillElastoPlasticityStressUpdate");
156 if (!(MooseUtils::absoluteFuzzyEqual(av_norm, 0.0)))
157 axial_vector /= av_norm;
160 mooseError(
"The axial vector cannot be a zero vector in " 161 "HillElastoPlasticityStressUpdate");
165 normal_vector, axial_vector, _rotation_matrix[_qp],
false);
166 _rotation_matrix_transpose[_qp] = _rotation_matrix[_qp].transpose();
172 template <
bool is_ad>
176 _hardening_variable[_qp] = _hardening_variable_old[_qp];
177 _plasticity_strain[_qp] = _plasticity_strain_old[_qp];
179 if (_local_cylindrical_csys)
181 _rotation_matrix[_qp] = _rotation_matrix_old[_qp];
182 _rotation_matrix_transpose[_qp] = _rotation_matrix_transpose_old[_qp];
188 template <
bool is_ad>
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];
199 _elasticity_eigenvectors[_qp].resize(6, 6);
200 _elasticity_eigenvalues[_qp].resize(6);
202 _b_eigenvectors[_qp].resize(6, 6);
203 _b_eigenvalues[_qp].resize(6);
205 _alpha_matrix[_qp].resize(6, 6);
206 _sigma_tilde[_qp].resize(6);
207 _sigma_tilde_rotated[_qp].resize(6);
210 computeElasticityTensorEigenDecomposition();
212 _yield_condition = 1.0;
213 _yield_condition = -computeResidual(stress_dev, stress, 0.0);
216 template <
bool is_ad>
225 if (_local_cylindrical_csys)
230 ElasticityTensorTools::toVoigtNotation<is_ad>(_anisotropic_elastic_tensor,
elasticity_tensor);
232 const unsigned int dimension = _anisotropic_elastic_tensor.n();
235 for (
unsigned int index_i = 0; index_i < dimension; index_i++)
236 for (
unsigned int index_j = 0; index_j < dimension; index_j++)
239 Eigen::SelfAdjointEigenSolver<AnisotropyMatrixReal> es(
A);
241 auto lambda = es.eigenvalues();
242 auto v = es.eigenvectors();
244 for (
unsigned int index_i = 0; index_i < dimension; index_i++)
245 _elasticity_eigenvalues[_qp](index_i) = lambda(index_i);
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);
253 for (
unsigned int i = 0; i < 6; i++)
255 sqrt_Delta(i, i) =
sqrt(_elasticity_eigenvalues[_qp](i));
259 _elasticity_eigenvectors[_qp].get_transpose(eigenvectors_elasticity_transpose);
262 b_matrix = _hill_tensor[_qp];
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);
271 for (
unsigned int index_i = 0; index_i < dimension; index_i++)
272 for (
unsigned int index_j = 0; index_j < dimension; index_j++)
275 if (isBlockDiagonal(B_eigen))
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));
280 auto lambda_b_left = es_b_left.eigenvalues();
281 auto v_b_left = es_b_left.eigenvectors();
283 auto lambda_b_right = es_b_right.eigenvalues();
284 auto v_b_right = es_b_right.eigenvectors();
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);
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);
314 Eigen::SelfAdjointEigenSolver<AnisotropyMatrixReal> es_b(B_eigen);
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);
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);
326 _alpha_matrix[_qp] = sqrt_Delta;
327 _alpha_matrix[_qp].right_multiply(_b_eigenvectors[_qp]);
328 _alpha_matrix[_qp].left_multiply(_elasticity_eigenvectors[_qp]);
331 template <
bool is_ad>
339 for (
unsigned int i = 0; i < 6; i++)
341 K(i) = _b_eigenvalues[_qp](i) / Utility::pow<2>(1 + delta_gamma * _b_eigenvalues[_qp](i));
343 if (_local_cylindrical_csys)
344 omega +=
K(i) * _sigma_tilde_rotated[_qp](i) * _sigma_tilde_rotated[_qp](i);
346 omega +=
K(i) * _sigma_tilde[_qp](i) * _sigma_tilde[_qp](i);
357 template <
bool is_ad>
369 template <
bool is_ad>
379 if (_yield_condition <= 0.0)
384 if (_local_cylindrical_csys)
388 RankTwoScalarTools::VoigtVectorToRankTwoTensor<is_ad>(stress_sigma, stress);
390 stress.rotate(_rotation_matrix_transpose[_qp]);
393 RankTwoScalarTools::RankTwoTensorToVoigtVector<is_ad>(stress, stress_sigma_rotated);
397 alpha_temp_rotated.lu_solve(stress_sigma_rotated, stress_tilde_rotated);
400 _sigma_tilde_rotated[_qp] = stress_tilde_rotated;
401 omega = computeOmega(delta_gamma, stress_tilde_rotated);
409 alpha_temp.lu_solve(stress_sigma, stress_tilde);
412 _sigma_tilde[_qp] = stress_tilde;
413 omega = computeOmega(delta_gamma, stress_tilde);
417 _hardening_variable[_qp] = computeHardeningValue(delta_gamma, omega);
424 _hardening_constant *
pow(_hardening_variable[_qp] + 1.0e-30, _hardening_exponent) +
428 residual = s_y / omega - 1.0;
433 template <
bool is_ad>
443 if (_yield_condition <= 0.0)
447 _hardening_derivative = computeHardeningDerivative();
451 _hardening_constant *
pow(hardeningVariable + 1.0e-30, _hardening_exponent) + _yield_stress;
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);
460 return residual_derivative;
463 template <
bool is_ad>
478 if (_local_cylindrical_csys)
479 omega = computeOmega(delta_gamma, _sigma_tilde_rotated[_qp]);
481 omega = computeOmega(delta_gamma, _sigma_tilde[_qp]);
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));
487 for (
unsigned int i = 0; i < 6; i++)
489 -2.0 * _b_eigenvalues[_qp](i) *
K(i) / (1 + _b_eigenvalues[_qp](i) * delta_gamma);
491 for (
unsigned int i = 0; i < 6; i++)
493 if (_local_cylindrical_csys)
494 omega_gamma += K_deltaGamma(i) * _sigma_tilde_rotated[_qp](i) * _sigma_tilde_rotated[_qp](i);
496 omega_gamma += K_deltaGamma(i) * _sigma_tilde[_qp](i) * _sigma_tilde[_qp](i);
499 omega_gamma /= 4.0 * omega;
500 sy_gamma = 2.0 * sy_alpha * (omega + delta_gamma * omega_gamma);
503 template <
bool is_ad>
508 return _hardening_variable_old[_qp] + 2.0 * delta_gamma * omega;
511 template <
bool is_ad>
516 return _hardening_constant * _hardening_exponent *
520 template <
bool is_ad>
535 if (_local_cylindrical_csys)
538 stress_rotated.rotate(_rotation_matrix_transpose[_qp]);
540 RankTwoScalarTools::RankTwoTensorToVoigtVector<is_ad>(stress_rotated, stress_vector);
544 RankTwoScalarTools::RankTwoTensorToVoigtVector<is_ad>(stress, stress_vector);
547 _hill_tensor[_qp].vector_mult(hill_stress, stress_vector);
548 hill_stress.scale(delta_gamma);
549 inelasticStrainIncrement_vector = hill_stress;
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;
561 if (_local_cylindrical_csys)
562 inelasticStrainIncrement.rotate(_rotation_matrix[_qp]);
566 _hill_tensor[_qp].vector_mult(Mepsilon, inelasticStrainIncrement_vector);
567 GenericReal<is_ad> eq_plastic_strain_inc = Mepsilon.dot(inelasticStrainIncrement_vector);
569 if (eq_plastic_strain_inc > 0.0)
570 eq_plastic_strain_inc =
sqrt(eq_plastic_strain_inc);
572 _effective_inelastic_strain[_qp] = _effective_inelastic_strain_old[_qp] + eq_plastic_strain_inc;
575 inelasticStrainIncrement, stress, stress_dev, delta_gamma);
578 template <
bool is_ad>
592 if (_yield_condition <= 0.0)
597 for (
unsigned int i = 0; i < 6; i++)
598 inv_matrix(i, i) = 1 / (1 + delta_gamma * _b_eigenvalues[_qp](i));
600 _alpha_matrix[_qp].right_multiply(inv_matrix);
603 if (_local_cylindrical_csys)
604 _alpha_matrix[_qp].vector_mult(stress_output, _sigma_tilde_rotated[_qp]);
606 _alpha_matrix[_qp].vector_mult(stress_output, _sigma_tilde[_qp]);
608 RankTwoScalarTools::VoigtVectorToRankTwoTensor<is_ad>(stress_output, stress_new);
610 if (_local_cylindrical_csys)
611 stress_new.rotate(_rotation_matrix[_qp]);
614 template <
bool is_ad>
620 mooseError(
"computeStrainEnergyRateDensity not implemented for anisotropic plasticity.");
Moose::GenericType< Real, is_ad > GenericReal
void computeElasticityTensorEigenDecomposition()
Compute eigendecomposition of element-wise elasticity tensor.
static InputParameters validParams()
virtual void propagateQpStatefulProperties() override
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
This class uses the stress update material in an anisotropic return mapping.
const bool _local_cylindrical_csys
Moose::GenericType< DenseVector< Real >, is_ad > GenericDenseVector
Moose::GenericType< RankFourTensor, is_ad > GenericRankFourTensor
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 ¶meters)
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
virtual void initQpStatefulProperties() override
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)
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.
Real computeHardeningDerivative()
virtual void computeStressInitialize(const GenericDenseVector< is_ad > &stress_dev, const GenericDenseVector< is_ad > &stress, const GenericRankFourTensor< is_ad > &elasticity_tensor) override
virtual void initQpStatefulProperties() override
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
virtual void propagateQpStatefulProperties() override
CTSub CT_OPERATOR_BINARY CTMul CTCompareLess CTCompareGreater CTCompareEqual _arg template * sqrt(_arg)) *_arg.template D< dtag >()) CT_SIMPLE_UNARY_FUNCTION(tanh
This class provides baseline functionality for anisotropic (Hill-like) plasticity models based on the...
void paramError(const std::string ¶m, 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
static InputParameters validParams()