https://mooseframework.inl.gov
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)
30  GuaranteeConsumer(this),
32  _elasticity_tensor_name(_base_name + getParam<MaterialPropertyName>("elasticity_tensor")),
33  _elasticity_tensor(getMaterialProperty<RankFourTensor>(_elasticity_tensor_name)),
34  _F_old(getMaterialPropertyOld<RankTwoTensor>(_base_name + "deformation_gradient")),
35  _ep_name(_base_name + "effective_plastic_strain"),
36  _ep(declareProperty<Real>(_ep_name)),
37  _ep_old(getMaterialPropertyOldByName<Real>(_ep_name)),
38  _be(declareProperty<RankTwoTensor>(_base_name +
39  "volume_preserving_elastic_left_cauchy_green_strain")),
40  _be_old(getMaterialPropertyOldByName<RankTwoTensor>(
41  _base_name + "volume_preserving_elastic_left_cauchy_green_strain")),
42  _Np(declareProperty<RankTwoTensor>(_base_name + "flow_direction")),
43  _flow_stress_material(nullptr),
44  _flow_stress_name(_base_name + "flow_stress"),
45  _H(getMaterialPropertyByName<Real>(_flow_stress_name)),
46  _dH(getDefaultMaterialPropertyByName<Real, false>(
47  derivativePropertyName(_flow_stress_name, {_ep_name}))),
48  _d2H(getDefaultMaterialPropertyByName<Real, false>(
49  derivativePropertyName(_flow_stress_name, {_ep_name, _ep_name})))
50 {
51 }
52 
53 void
55 {
56  _flow_stress_material = &getMaterial("flow_stress_material");
57 
58  // Enforce isotropic elastic tensor
60  mooseError("ComputeSimoHughesJ2PlasticityStress requires an isotropic elasticity tensor");
61 }
62 
63 void
65 {
67  _be[_qp].setToIdentity();
68  _ep[_qp] = 0;
69 }
70 
71 void
73 {
74  usingTensorIndices(i, j, k, l, m);
77  const auto I = RankTwoTensor::Identity();
78  const auto Fit = _F[_qp].inverse().transpose();
79  const auto detJ = _F[_qp].det();
80 
81  // Update configuration
82  RankTwoTensor f = _inv_df[_qp].inverse();
83  RankTwoTensor f_bar = f / std::cbrt(f.det());
84 
85  // Elastic predictor
86  _be[_qp] = f_bar * _be_old[_qp] * f_bar.transpose();
87  RankTwoTensor s = G * _be[_qp].deviatoric();
88  _Np[_qp] = MooseUtils::absoluteFuzzyEqual(s.norm(), 0) ? std::sqrt(1. / 2.) * I
89  : std::sqrt(3. / 2.) * s / s.norm();
90  Real s_eff = s.doubleContraction(_Np[_qp]);
91 
92  // Compute the derivative of the strain before return mapping
93  if (_fe_problem.currentlyComputingJacobian())
94  _d_be_d_F = _F_old[_qp].inverse().times<l, m, i, j, k, m>(
95  (I.times<i, k, j, l>(f_bar * _be_old[_qp].transpose()) +
96  I.times<j, k, i, l>(f_bar * _be_old[_qp])) /
97  std::cbrt(f.det()) -
98  2. / 3. * _be[_qp].times<i, j, l, k>(_inv_df[_qp]));
99 
100  // Check for plastic loading and do return mapping
101  Real delta_ep = 0;
102  if (computeResidual(s_eff, 0) > 0)
103  {
104  // Initialize the derivative of the internal variable
105  if (_fe_problem.currentlyComputingJacobian())
106  {
109  _d_n_d_be.zero();
110  else
111  _d_n_d_be = G / std::sqrt(6) / s.norm() *
112  (3 * I.times<i, k, j, l>(I) - 2 * _Np[_qp].times<i, j, k, l>(_Np[_qp]) -
113  I.times<i, j, k, l>(I));
114  }
115 
116  returnMappingSolve(s_eff, delta_ep, _console);
117 
118  // Correct the derivative of the strain after return mapping
119  if (_fe_problem.currentlyComputingJacobian())
120  _d_be_d_F -=
121  2. / 3. *
122  (_be[_qp].trace() * _Np[_qp].times<i, j, k, l>(_d_deltaep_d_betr) +
123  delta_ep * _Np[_qp].times<i, j, k, l>(I) + delta_ep * _be[_qp].trace() * _d_n_d_be) *
124  _d_be_d_F;
125  }
126 
127  // Update intermediate and current configurations
128  _ep[_qp] = _ep_old[_qp] + delta_ep;
129  _be[_qp] -= 2. / 3. * delta_ep * _be[_qp].trace() * _Np[_qp];
130  s = G * _be[_qp].deviatoric();
131  RankTwoTensor tau = (K * (detJ * detJ - 1) / 2) * I + s;
132  _pk1_stress[_qp] = tau * Fit;
133 
134  // Compute the consistent tangent, i.e. the derivative of the PK1 stress w.r.t. the deformation
135  // gradient.
136  if (_fe_problem.currentlyComputingJacobian())
137  {
138  RankFourTensor d_tau_d_F = K * detJ * detJ * I.times<i, j, k, l>(Fit) +
139  G * (_d_be_d_F - I.times<i, j, k, l>(I) * _d_be_d_F / 3);
140  _pk1_jacobian[_qp] = Fit.times<m, j, i, m, k, l>(d_tau_d_F) - Fit.times<k, j, i, l>(tau * Fit);
141  }
142 }
143 
144 Real
146  const Real & scalar)
147 {
149  return effective_trial_stress - G * scalar * _be[_qp].trace();
150 }
151 
152 Real
153 ComputeSimoHughesJ2PlasticityStress::computeResidual(const Real & effective_trial_stress,
154  const Real & scalar)
155 {
157 
158  // Update the flow stress
159  _ep[_qp] = _ep_old[_qp] + scalar;
161 
162  return effective_trial_stress - G * scalar * _be[_qp].trace() - _H[_qp];
163 }
164 
165 Real
166 ComputeSimoHughesJ2PlasticityStress::computeDerivative(const Real & /*effective_trial_stress*/,
167  const Real & scalar)
168 {
170 
171  // Update the flow stress
172  _ep[_qp] = _ep_old[_qp] + scalar;
174 
175  return -G * _be[_qp].trace() - _dH[_qp];
176 }
177 
178 void
179 ComputeSimoHughesJ2PlasticityStress::preStep(const Real & scalar, const Real & R, const Real & J)
180 {
181  if (!_fe_problem.currentlyComputingJacobian())
182  return;
183 
184  const auto I = RankTwoTensor::Identity();
186 
187  // Update the flow stress
188  _ep[_qp] = _ep_old[_qp] + scalar;
190 
191  _d_R_d_betr =
192  G * _Np[_qp] - G * scalar * I - (G * _be[_qp].trace() + _dH[_qp]) * _d_deltaep_d_betr;
193  _d_J_d_betr = -G * I - _d2H[_qp] * _d_deltaep_d_betr;
194  _d_deltaep_d_betr += -1 / J * _d_R_d_betr + R / J / J * _d_J_d_betr;
195 }
Native interface for providing the 1st Piola Kirchhoff stress.
const MaterialProperty< RankFourTensor > & _elasticity_tensor
virtual Real computeReferenceResidual(const Real &effective_trial_stress, const Real &scalar) override
The return mapping residual and derivative.
T getIsotropicShearModulus(const RankFourTensorTempl< T > &elasticity_tensor)
Get the shear modulus for an isotropic elasticity tensor param elasticity_tensor the tensor (must be ...
bool absoluteFuzzyEqual(const T &var1, const T2 &var2, const T3 &tol=libMesh::TOLERANCE *libMesh::TOLERANCE)
registerMooseObject("SolidMechanicsApp", ComputeSimoHughesJ2PlasticityStress)
void addParam(const std::string &name, const std::initializer_list< typename T::value_type > &value, const std::string &doc_string)
void mooseError(Args &&... args)
static const std::string K
Definition: NS.h:170
void inverse(const std::vector< std::vector< Real >> &m, std::vector< std::vector< Real >> &m_inv)
virtual Real computeResidual(const Real &effective_trial_stress, const Real &scalar) override
static RankTwoTensorTempl Identity()
void addRequiredParam(const std::string &name, const std::string &doc_string)
const MaterialProperty< RankTwoTensor > & _be_old
auto norm() const -> decltype(std::norm(T()))
static const std::string G
Definition: NS.h:166
virtual void initQpStatefulProperties() override
Initialize everything with zeros.
T getIsotropicBulkModulus(const RankFourTensorTempl< T > &elasticity_tensor)
Get the bulk modulus for an isotropic elasticity tensor param elasticity_tensor the tensor (must be i...
void returnMappingSolve(const GenericReal< is_ad > &effective_trial_stress, GenericReal< is_ad > &scalar, const ConsoleStream &console)
Perform the return mapping iterations.
const MaterialProperty< RankTwoTensor > & _F_old
InputParameters validParams()
Real f(Real x)
Test function for Brents method.
virtual Real computeDerivative(const Real &effective_trial_stress, const Real &scalar) override
Base class that provides capability for Newton return mapping iterations on a single variable...
Real doubleContraction(const RankTwoTensorTempl< Real > &a) const
virtual void preStep(const Real &scalar_old, const Real &residual, const Real &jacobian) override
static const std::string R
Definition: NS.h:162
RankTwoTensorTempl< Real > transpose() const
ComputeSimoHughesJ2PlasticityStress(const InputParameters &parameters)
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
void addClassDescription(const std::string &doc_string)
static const std::complex< double > j(0, 1)
Complex number "j" (also known as "i")
virtual void computePropertiesAtQp(unsigned int qp)
bool hasGuaranteedMaterialProperty(const MaterialPropertyName &prop, Guarantee guarantee)
Add-on class that provides the functionality to check if guarantees for material properties are provi...
RankFourTensor _d_be_d_F
Helper (dummy) variables for iteratively updating the consistant tangent during return mapping...
static const std::string k
Definition: NS.h:130