https://mooseframework.inl.gov
SolidMechanicsPlasticDruckerPrager.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 "RankFourTensor.h"
12 #include "libmesh/utility.h"
13 
15 registerMooseObjectRenamed("SolidMechanicsApp",
16  TensorMechanicsPlasticDruckerPrager,
17  "01/01/2025 00:00",
19 
22 {
24  MooseEnum mc_interpolation_scheme("outer_tip=0 inner_tip=1 lode_zero=2 inner_edge=3 native=4",
25  "lode_zero");
26  params.addParam<MooseEnum>(
27  "mc_interpolation_scheme",
28  mc_interpolation_scheme,
29  "Scheme by which the Drucker-Prager cohesion, friction angle and dilation angle are set from "
30  "the Mohr-Coulomb parameters mc_cohesion, mc_friction_angle and mc_dilation_angle. Consider "
31  "the DP and MC yield surfaces on the deviatoric (octahedral) plane. Outer_tip: the DP "
32  "circle touches the outer tips of the MC hex. Inner_tip: the DP circle touches the inner "
33  "tips of the MC hex. Lode_zero: the DP circle intersects the MC hex at lode angle=0. "
34  "Inner_edge: the DP circle is the largest circle that wholly fits inside the MC hex. "
35  "Native: The DP cohesion, friction angle and dilation angle are set equal to the mc_ "
36  "parameters entered.");
37  params.addRequiredParam<UserObjectName>(
38  "mc_cohesion",
39  "A SolidMechanicsHardening UserObject that defines hardening of the "
40  "Mohr-Coulomb cohesion. Physically this should not be negative.");
41  params.addRequiredParam<UserObjectName>(
42  "mc_friction_angle",
43  "A SolidMechanicsHardening UserObject that defines hardening of the "
44  "Mohr-Coulomb friction angle (in radians). Physically this should be "
45  "between 0 and Pi/2.");
46  params.addRequiredParam<UserObjectName>(
47  "mc_dilation_angle",
48  "A SolidMechanicsHardening UserObject that defines hardening of the "
49  "Mohr-Coulomb dilation angle (in radians). Usually the dilation angle "
50  "is not greater than the friction angle, and it is between 0 and Pi/2.");
51  params.addClassDescription(
52  "Non-associative Drucker Prager plasticity with no smoothing of the cone tip.");
53  return params;
54 }
55 
57  const InputParameters & parameters)
58  : SolidMechanicsPlasticModel(parameters),
59  _mc_cohesion(getUserObject<SolidMechanicsHardeningModel>("mc_cohesion")),
60  _mc_phi(getUserObject<SolidMechanicsHardeningModel>("mc_friction_angle")),
61  _mc_psi(getUserObject<SolidMechanicsHardeningModel>("mc_dilation_angle")),
62  _mc_interpolation_scheme(getParam<MooseEnum>("mc_interpolation_scheme")),
63  _zero_cohesion_hardening(_mc_cohesion.modelName().compare("Constant") == 0),
64  _zero_phi_hardening(_mc_phi.modelName().compare("Constant") == 0),
65  _zero_psi_hardening(_mc_psi.modelName().compare("Constant") == 0)
66 {
67  if (_mc_phi.value(0.0) < 0.0 || _mc_psi.value(0.0) < 0.0 ||
68  _mc_phi.value(0.0) > libMesh::pi / 2.0 || _mc_psi.value(0.0) > libMesh::pi / 2.0)
69  mooseError("SolidMechanicsPlasticDruckerPrager: MC friction and dilation angles must lie in "
70  "[0, Pi/2]");
71  if (_mc_phi.value(0) < _mc_psi.value(0.0))
72  mooseError("SolidMechanicsPlasticDruckerPrager: MC friction angle must not be less than MC "
73  "dilation angle");
74  if (_mc_cohesion.value(0.0) < 0)
75  mooseError("SolidMechanicsPlasticDruckerPrager: MC cohesion should not be negative");
76 
77  initializeAandB(0.0, _aaa, _bbb);
79 }
80 
81 Real
83 {
84  Real aaa;
85  Real bbb;
86  bothAB(intnl, aaa, bbb);
87  return std::sqrt(stress.secondInvariant()) + stress.trace() * bbb - aaa;
88 }
89 
92 {
93  return 0.5 * stress.dsecondInvariant() / std::sqrt(stress.secondInvariant()) +
94  stress.dtrace() * bbb;
95 }
96 
99  Real intnl) const
100 {
101  Real bbb;
102  onlyB(intnl, friction, bbb);
103  return df_dsig(stress, bbb);
104 }
105 
106 Real
108  Real intnl) const
109 {
110  Real daaa;
111  Real dbbb;
112  dbothAB(intnl, daaa, dbbb);
113  return stress.trace() * dbbb - daaa;
114 }
115 
118 {
119  Real bbb_flow;
120  onlyB(intnl, dilation, bbb_flow);
121  return df_dsig(stress, bbb_flow);
122 }
123 
126  Real /*intnl*/) const
127 {
128  RankFourTensor dr_dstress;
129  dr_dstress = 0.5 * stress.d2secondInvariant() / std::sqrt(stress.secondInvariant());
130  dr_dstress += -0.5 * 0.5 * stress.dsecondInvariant().outerProduct(stress.dsecondInvariant()) /
131  std::pow(stress.secondInvariant(), 1.5);
132  return dr_dstress;
133 }
134 
137  Real intnl) const
138 {
139  Real dbbb;
140  donlyB(intnl, dilation, dbbb);
141  return stress.dtrace() * dbbb;
142 }
143 
144 std::string
146 {
147  return "DruckerPrager";
148 }
149 
150 void
151 SolidMechanicsPlasticDruckerPrager::bothAB(Real intnl, Real & aaa, Real & bbb) const
152 {
154  {
155  aaa = _aaa;
156  bbb = _bbb;
157  return;
158  }
159  initializeAandB(intnl, aaa, bbb);
160 }
161 
162 void
163 SolidMechanicsPlasticDruckerPrager::onlyB(Real intnl, int fd, Real & bbb) const
164 {
165  if (_zero_phi_hardening && (fd == friction))
166  {
167  bbb = _bbb;
168  return;
169  }
170  if (_zero_psi_hardening && (fd == dilation))
171  {
172  bbb = _bbb_flow;
173  return;
174  }
175  initializeB(intnl, fd, bbb);
176 }
177 
178 void
179 SolidMechanicsPlasticDruckerPrager::donlyB(Real intnl, int fd, Real & dbbb) const
180 {
181  if (_zero_phi_hardening && (fd == friction))
182  {
183  dbbb = 0;
184  return;
185  }
186  if (_zero_psi_hardening && (fd == dilation))
187  {
188  dbbb = 0;
189  return;
190  }
191  const Real s = (fd == friction) ? std::sin(_mc_phi.value(intnl)) : std::sin(_mc_psi.value(intnl));
192  const Real ds = (fd == friction) ? std::cos(_mc_phi.value(intnl)) * _mc_phi.derivative(intnl)
193  : std::cos(_mc_psi.value(intnl)) * _mc_psi.derivative(intnl);
194  switch (_mc_interpolation_scheme)
195  {
196  case 0: // outer_tip
197  dbbb = 2.0 / std::sqrt(3.0) * (ds / (3.0 - s) + s * ds / Utility::pow<2>(3.0 - s));
198  break;
199  case 1: // inner_tip
200  dbbb = 2.0 / std::sqrt(3.0) * (ds / (3.0 + s) - s * ds / Utility::pow<2>(3.0 + s));
201  break;
202  case 2: // lode_zero
203  dbbb = ds / 3.0;
204  break;
205  case 3: // inner_edge
206  dbbb = ds / std::sqrt(9.0 + 3.0 * Utility::pow<2>(s)) -
207  3 * s * s * ds / std::pow(9.0 + 3.0 * Utility::pow<2>(s), 1.5);
208  break;
209  case 4: // native
210  const Real c =
211  (fd == friction) ? std::cos(_mc_phi.value(intnl)) : std::cos(_mc_psi.value(intnl));
212  const Real dc = (fd == friction)
213  ? -std::sin(_mc_phi.value(intnl)) * _mc_phi.derivative(intnl)
214  : -std::sin(_mc_psi.value(intnl)) * _mc_psi.derivative(intnl);
215  dbbb = ds / c - s * dc / Utility::pow<2>(c);
216  break;
217  }
218 }
219 
220 void
221 SolidMechanicsPlasticDruckerPrager::dbothAB(Real intnl, Real & daaa, Real & dbbb) const
222 {
224  {
225  daaa = 0;
226  dbbb = 0;
227  return;
228  }
229 
230  const Real C = _mc_cohesion.value(intnl);
231  const Real dC = _mc_cohesion.derivative(intnl);
232  const Real cosphi = std::cos(_mc_phi.value(intnl));
233  const Real dcosphi = -std::sin(_mc_phi.value(intnl)) * _mc_phi.derivative(intnl);
234  const Real sinphi = std::sin(_mc_phi.value(intnl));
235  const Real dsinphi = std::cos(_mc_phi.value(intnl)) * _mc_phi.derivative(intnl);
236  switch (_mc_interpolation_scheme)
237  {
238  case 0: // outer_tip
239  daaa = 2.0 * std::sqrt(3.0) *
240  (dC * cosphi / (3.0 - sinphi) + C * dcosphi / (3.0 - sinphi) +
241  C * cosphi * dsinphi / Utility::pow<2>(3.0 - sinphi));
242  dbbb = 2.0 / std::sqrt(3.0) *
243  (dsinphi / (3.0 - sinphi) + sinphi * dsinphi / Utility::pow<2>(3.0 - sinphi));
244  break;
245  case 1: // inner_tip
246  daaa = 2.0 * std::sqrt(3.0) *
247  (dC * cosphi / (3.0 + sinphi) + C * dcosphi / (3.0 + sinphi) -
248  C * cosphi * dsinphi / Utility::pow<2>(3.0 + sinphi));
249  dbbb = 2.0 / std::sqrt(3.0) *
250  (dsinphi / (3.0 + sinphi) - sinphi * dsinphi / Utility::pow<2>(3.0 + sinphi));
251  break;
252  case 2: // lode_zero
253  daaa = dC * cosphi + C * dcosphi;
254  dbbb = dsinphi / 3.0;
255  break;
256  case 3: // inner_edge
257  daaa = 3.0 * dC * cosphi / std::sqrt(9.0 + 3.0 * Utility::pow<2>(sinphi)) +
258  3.0 * C * dcosphi / std::sqrt(9.0 + 3.0 * Utility::pow<2>(sinphi)) -
259  3.0 * C * cosphi * 3.0 * sinphi * dsinphi /
260  std::pow(9.0 + 3.0 * Utility::pow<2>(sinphi), 1.5);
261  dbbb = dsinphi / std::sqrt(9.0 + 3.0 * Utility::pow<2>(sinphi)) -
262  3.0 * sinphi * sinphi * dsinphi / std::pow(9.0 + 3.0 * Utility::pow<2>(sinphi), 1.5);
263  break;
264  case 4: // native
265  daaa = dC;
266  dbbb = dsinphi / cosphi - sinphi * dcosphi / Utility::pow<2>(cosphi);
267  break;
268  }
269 }
270 
271 void
272 SolidMechanicsPlasticDruckerPrager::initializeAandB(Real intnl, Real & aaa, Real & bbb) const
273 {
274  const Real C = _mc_cohesion.value(intnl);
275  const Real cosphi = std::cos(_mc_phi.value(intnl));
276  const Real sinphi = std::sin(_mc_phi.value(intnl));
277  switch (_mc_interpolation_scheme)
278  {
279  case 0: // outer_tip
280  aaa = 2.0 * std::sqrt(3.0) * C * cosphi / (3.0 - sinphi);
281  bbb = 2.0 * sinphi / std::sqrt(3.0) / (3.0 - sinphi);
282  break;
283  case 1: // inner_tip
284  aaa = 2.0 * std::sqrt(3.0) * C * cosphi / (3.0 + sinphi);
285  bbb = 2.0 * sinphi / std::sqrt(3.0) / (3.0 + sinphi);
286  break;
287  case 2: // lode_zero
288  aaa = C * cosphi;
289  bbb = sinphi / 3.0;
290  break;
291  case 3: // inner_edge
292  aaa = 3.0 * C * cosphi / std::sqrt(9.0 + 3.0 * Utility::pow<2>(sinphi));
293  bbb = sinphi / std::sqrt(9.0 + 3.0 * Utility::pow<2>(sinphi));
294  break;
295  case 4: // native
296  aaa = C;
297  bbb = sinphi / cosphi;
298  break;
299  }
300 }
301 
302 void
303 SolidMechanicsPlasticDruckerPrager::initializeB(Real intnl, int fd, Real & bbb) const
304 {
305  const Real s = (fd == friction) ? std::sin(_mc_phi.value(intnl)) : std::sin(_mc_psi.value(intnl));
306  switch (_mc_interpolation_scheme)
307  {
308  case 0: // outer_tip
309  bbb = 2.0 * s / std::sqrt(3.0) / (3.0 - s);
310  break;
311  case 1: // inner_tip
312  bbb = 2.0 * s / std::sqrt(3.0) / (3.0 + s);
313  break;
314  case 2: // lode_zero
315  bbb = s / 3.0;
316  break;
317  case 3: // inner_edge
318  bbb = s / std::sqrt(9.0 + 3.0 * Utility::pow<2>(s));
319  break;
320  case 4: // native
321  const Real c =
322  (fd == friction) ? std::cos(_mc_phi.value(intnl)) : std::cos(_mc_psi.value(intnl));
323  bbb = s / c;
324  break;
325  }
326 }
RankFourTensorTempl< Real > outerProduct(const RankTwoTensorTempl< Real > &b) const
RankTwoTensorTempl< Real > dsecondInvariant() const
RankFourTensorTempl< Real > d2secondInvariant() const
SolidMechanicsPlasticDruckerPrager(const InputParameters &parameters)
void addParam(const std::string &name, const std::initializer_list< typename T::value_type > &value, const std::string &doc_string)
const bool _zero_cohesion_hardening
True if there is no hardening of cohesion.
const SolidMechanicsHardeningModel & _mc_psi
Hardening model for tan(psi)
void donlyB(Real intnl, int fd, Real &dbbb) const
Calculate d(bbb)/d(intnl) or d(bbb_flow)/d(intnl)
virtual RankTwoTensor df_dsig(const RankTwoTensor &stress, Real bbb) const
Function that&#39;s used in dyieldFunction_dstress and flowPotential.
void bothAB(Real intnl, Real &aaa, Real &bbb) const
Calculates aaa and bbb as a function of the internal parameter intnl.
void initializeB(Real intnl, int fd, Real &bbb) const
Returns the Drucker-Prager parameters A nice reference on the different relationships between Drucker...
const bool _zero_phi_hardening
True if there is no hardening of friction angle.
RankTwoTensorTempl< Real > dtrace() const
const MooseEnum _mc_interpolation_scheme
The parameters aaa and bbb are chosen to closely match the Mohr-Coulomb yield surface.
virtual Real value(Real intnl) const
void addRequiredParam(const std::string &name, const std::string &doc_string)
registerMooseObject("SolidMechanicsApp", SolidMechanicsPlasticDruckerPrager)
void onlyB(Real intnl, int fd, Real &bbb) const
Calculate bbb or bbb_flow.
Rate-independent non-associative Drucker Prager with hardening/softening.
registerMooseObjectRenamed("SolidMechanicsApp", TensorMechanicsPlasticDruckerPrager, "01/01/2025 00:00", SolidMechanicsPlasticDruckerPrager)
static InputParameters validParams()
const bool _zero_psi_hardening
True if there is no hardening of dilation angle.
virtual RankFourTensor dflowPotential_dstress(const RankTwoTensor &stress, Real intnl) const override
The derivative of the flow potential with respect to stress.
void dbothAB(Real intnl, Real &daaa, Real &dbbb) const
Calculates d(aaa)/d(intnl) and d(bbb)/d(intnl) as a function of the internal parameter intnl...
virtual Real derivative(Real intnl) const
virtual Real yieldFunction(const RankTwoTensor &stress, Real intnl) const override
The following functions are what you should override when building single-plasticity models...
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
const SolidMechanicsHardeningModel & _mc_cohesion
Hardening model for cohesion.
virtual RankTwoTensor dflowPotential_dintnl(const RankTwoTensor &stress, Real intnl) const override
The derivative of the flow potential with respect to the internal parameter.
void mooseError(Args &&... args) const
virtual RankTwoTensor dyieldFunction_dstress(const RankTwoTensor &stress, Real intnl) const override
The derivative of yield function with respect to stress.
void addClassDescription(const std::string &doc_string)
virtual Real dyieldFunction_dintnl(const RankTwoTensor &stress, Real intnl) const override
The derivative of yield function with respect to the internal parameter.
const SolidMechanicsHardeningModel & _mc_phi
Hardening model for tan(phi)
Plastic Model base class The virtual functions written below must be over-ridden in derived classes t...
MooseUnits pow(const MooseUnits &, int)
void initializeAandB(Real intnl, Real &aaa, Real &bbb) const
Returns the Drucker-Prager parameters A nice reference on the different relationships between Drucker...
virtual RankTwoTensor flowPotential(const RankTwoTensor &stress, Real intnl) const override
The flow potential.
static const std::string C
Definition: NS.h:168
const Real pi
virtual std::string modelName() const override