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)
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 
52 void
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 
64 void
66 {
68  _be[_qp].setToIdentity();
69  _ep[_qp] = 0;
70 }
71 
72 void
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  {
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 
145 Real
147  const Real & scalar)
148 {
150  return effective_trial_stress - G * scalar * _be[_qp].trace();
151 }
152 
153 Real
154 ComputeSimoHughesJ2PlasticityStress::computeResidual(const Real & effective_trial_stress,
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 
166 Real
167 ComputeSimoHughesJ2PlasticityStress::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 
179 void
180 ComputeSimoHughesJ2PlasticityStress::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 
192  _d_R_d_betr =
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 }
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 ...
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:174
Real trace(const RealTensor &A, const unsigned int &dim)
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
const double R
static RankTwoTensorTempl Identity()
void addRequiredParam(const std::string &name, const std::string &doc_string)
virtual void initialSetup() override
Derive _large_kinematics from the strain calculator&#39;s LARGE_KINEMATICS guarantee. ...
const MaterialProperty< RankTwoTensor > & _be_old
static const std::string G
Definition: NS.h:170
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
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)
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:134