https://mooseframework.inl.gov
Loading...
Searching...
No Matches
ComputeSimoHughesJ2PlasticityStress.C
Go to the documentation of this file.
1//* This file is part of the MOOSE framework
2//* https://mooseframework.inl.gov
3//*
4//* All rights reserved, see COPYRIGHT for full restrictions
5//* https://github.com/idaholab/moose/blob/master/COPYRIGHT
6//*
7//* Licensed under LGPL 2.1, please see LICENSE for details
8//* https://www.gnu.org/licenses/lgpl-2.1.html
9
11
13
16{
19 params.addClassDescription("The Simo-Hughes style J2 plasticity.");
20 params.addParam<MaterialPropertyName>(
21 "elasticity_tensor", "elasticity_tensor", "The name of the elasticity tensor.");
22 params.addRequiredParam<MaterialName>("flow_stress_material",
23 "The material defining the flow stress");
24 return params;
25}
26
28 const InputParameters & parameters)
31 _elasticity_tensor_name(_base_name + getParam<MaterialPropertyName>("elasticity_tensor")),
32 _elasticity_tensor(getMaterialProperty<RankFourTensor>(_elasticity_tensor_name)),
33 _F_old(getMaterialPropertyOld<RankTwoTensor>(_base_name + "deformation_gradient")),
34 _ep_name(_base_name + "effective_plastic_strain"),
35 _ep(declareProperty<Real>(_ep_name)),
36 _ep_old(getMaterialPropertyOldByName<Real>(_ep_name)),
37 _be(declareProperty<RankTwoTensor>(_base_name +
38 "volume_preserving_elastic_left_cauchy_green_strain")),
39 _be_old(getMaterialPropertyOldByName<RankTwoTensor>(
40 _base_name + "volume_preserving_elastic_left_cauchy_green_strain")),
41 _Np(declareProperty<RankTwoTensor>(_base_name + "flow_direction")),
42 _flow_stress_material(nullptr),
43 _flow_stress_name(_base_name + "flow_stress"),
44 _H(getMaterialPropertyByName<Real>(_flow_stress_name)),
45 _dH(getDefaultMaterialPropertyByName<Real, false>(
46 derivativePropertyName(_flow_stress_name, {_ep_name}))),
47 _d2H(getDefaultMaterialPropertyByName<Real, false>(
48 derivativePropertyName(_flow_stress_name, {_ep_name, _ep_name})))
49{
50}
51
52void
54{
56
57 _flow_stress_material = &getMaterial("flow_stress_material");
58
59 // Enforce isotropic elastic tensor
60 if (!hasGuaranteedMaterialProperty(_elasticity_tensor_name, Guarantee::ISOTROPIC))
61 mooseError("ComputeSimoHughesJ2PlasticityStress requires an isotropic elasticity tensor");
62}
63
64void
71
72void
74{
75 usingTensorIndices(i, j, k, l, m);
78 const auto I = RankTwoTensor::Identity();
79 const auto Fit = _F[_qp].inverse().transpose();
80 const auto detJ = _F[_qp].det();
81
82 // Update configuration
83 RankTwoTensor f = _inv_df[_qp].inverse();
84 RankTwoTensor f_bar = f / std::cbrt(f.det());
85
86 // Elastic predictor
87 _be[_qp] = f_bar * _be_old[_qp] * f_bar.transpose();
88 RankTwoTensor s = G * _be[_qp].deviatoric();
89 _Np[_qp] = MooseUtils::absoluteFuzzyEqual(s.norm(), 0) ? std::sqrt(1. / 2.) * I
90 : std::sqrt(3. / 2.) * s / s.norm();
91 Real s_eff = s.doubleContraction(_Np[_qp]);
92
93 // Compute the derivative of the strain before return mapping
94 if (_fe_problem.currentlyComputingJacobian())
95 _d_be_d_F = _F_old[_qp].inverse().times<l, m, i, j, k, m>(
96 (I.times<i, k, j, l>(f_bar * _be_old[_qp].transpose()) +
97 I.times<j, k, i, l>(f_bar * _be_old[_qp])) /
98 std::cbrt(f.det()) -
99 2. / 3. * _be[_qp].times<i, j, l, k>(_inv_df[_qp]));
100
101 // Check for plastic loading and do return mapping
102 Real delta_ep = 0;
103 if (computeResidual(s_eff, 0) > 0)
104 {
105 // Initialize the derivative of the internal variable
106 if (_fe_problem.currentlyComputingJacobian())
107 {
108 _d_deltaep_d_betr.zero();
109 if (MooseUtils::absoluteFuzzyEqual(s.norm(), 0))
110 _d_n_d_be.zero();
111 else
112 _d_n_d_be = G / std::sqrt(6) / s.norm() *
113 (3 * I.times<i, k, j, l>(I) - 2 * _Np[_qp].times<i, j, k, l>(_Np[_qp]) -
114 I.times<i, j, k, l>(I));
115 }
116
117 returnMappingSolve(s_eff, delta_ep, _console);
118
119 // Correct the derivative of the strain after return mapping
120 if (_fe_problem.currentlyComputingJacobian())
121 _d_be_d_F -=
122 2. / 3. *
123 (_be[_qp].trace() * _Np[_qp].times<i, j, k, l>(_d_deltaep_d_betr) +
124 delta_ep * _Np[_qp].times<i, j, k, l>(I) + delta_ep * _be[_qp].trace() * _d_n_d_be) *
125 _d_be_d_F;
126 }
127
128 // Update intermediate and current configurations
129 _ep[_qp] = _ep_old[_qp] + delta_ep;
130 _be[_qp] -= 2. / 3. * delta_ep * _be[_qp].trace() * _Np[_qp];
131 s = G * _be[_qp].deviatoric();
132 RankTwoTensor tau = (K * (detJ * detJ - 1) / 2) * I + s;
133 _pk1_stress[_qp] = tau * Fit;
134
135 // Compute the consistent tangent, i.e. the derivative of the PK1 stress w.r.t. the deformation
136 // gradient.
137 if (_fe_problem.currentlyComputingJacobian())
138 {
139 RankFourTensor d_tau_d_F = K * detJ * detJ * I.times<i, j, k, l>(Fit) +
140 G * (_d_be_d_F - I.times<i, j, k, l>(I) * _d_be_d_F / 3);
141 _pk1_jacobian[_qp] = Fit.times<m, j, i, m, k, l>(d_tau_d_F) - Fit.times<k, j, i, l>(tau * Fit);
142 }
143}
144
145Real
147 const Real & scalar)
148{
150 return effective_trial_stress - G * scalar * _be[_qp].trace();
151}
152
153Real
155 const Real & scalar)
156{
158
159 // Update the flow stress
160 _ep[_qp] = _ep_old[_qp] + scalar;
162
163 return effective_trial_stress - G * scalar * _be[_qp].trace() - _H[_qp];
164}
165
166Real
167ComputeSimoHughesJ2PlasticityStress::computeDerivative(const Real & /*effective_trial_stress*/,
168 const Real & scalar)
169{
171
172 // Update the flow stress
173 _ep[_qp] = _ep_old[_qp] + scalar;
175
176 return -G * _be[_qp].trace() - _dH[_qp];
177}
178
179void
180ComputeSimoHughesJ2PlasticityStress::preStep(const Real & scalar, const Real & R, const Real & J)
181{
182 if (!_fe_problem.currentlyComputingJacobian())
183 return;
184
185 const auto I = RankTwoTensor::Identity();
187
188 // Update the flow stress
189 _ep[_qp] = _ep_old[_qp] + scalar;
191
193 G * _Np[_qp] - G * scalar * I - (G * _be[_qp].trace() + _dH[_qp]) * _d_deltaep_d_betr;
194 _d_J_d_betr = -G * I - _d2H[_qp] * _d_deltaep_d_betr;
195 _d_deltaep_d_betr += -1 / J * _d_R_d_betr + R / J / J * _d_J_d_betr;
196}
Real f(Real x)
Test function for Brents method.
registerMooseObject("SolidMechanicsApp", ComputeSimoHughesJ2PlasticityStress)
const double R
void mooseError(Args &&... args)
virtual void initialSetup() override
Derive _large_kinematics from the strain calculator's LARGE_KINEMATICS guarantee.
Native interface for providing the 1st Piola Kirchhoff stress.
virtual Real computeDerivative(const Real &effective_trial_stress, const Real &scalar) override
virtual Real computeResidual(const Real &effective_trial_stress, const Real &scalar) override
const MaterialProperty< RankFourTensor > & _elasticity_tensor
const MaterialProperty< RankTwoTensor > & _F_old
virtual Real computeReferenceResidual(const Real &effective_trial_stress, const Real &scalar) override
The return mapping residual and derivative.
ComputeSimoHughesJ2PlasticityStress(const InputParameters &parameters)
const MaterialProperty< RankTwoTensor > & _be_old
virtual void preStep(const Real &scalar_old, const Real &residual, const Real &jacobian) override
RankFourTensor _d_be_d_F
Helper (dummy) variables for iteratively updating the consistant tangent during return mapping.
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)
virtual void initQpStatefulProperties()
virtual void computePropertiesAtQp(unsigned int qp)
RankFourTensorTempl< T > inverse() const
T doubleContraction(const RankTwoTensorTempl< T > &a) const
RankTwoTensorTempl< T > inverse() const
RankTwoTensorTempl< T > transpose() const
static RankTwoTensorTempl Identity()
Base class that provides capability for Newton return mapping iterations on a single variable.
void returnMappingSolve(const GenericReal< is_ad > &effective_trial_stress, GenericReal< is_ad > &scalar, const ConsoleStream &console)
Perform the return mapping iterations.
T getIsotropicBulkModulus(const RankFourTensorTempl< T > &elasticity_tensor)
Get the bulk modulus for an isotropic elasticity tensor param elasticity_tensor the tensor (must be i...
T getIsotropicShearModulus(const RankFourTensorTempl< T > &elasticity_tensor)
Get the shear modulus for an isotropic elasticity tensor param elasticity_tensor the tensor (must be ...