https://mooseframework.inl.gov
Loading...
Searching...
No Matches
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
15registerMooseObjectRenamed("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.");
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
79}
80
81Real
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
106Real
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
144std::string
146{
147 return "DruckerPrager";
148}
149
150void
151SolidMechanicsPlasticDruckerPrager::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
162void
163SolidMechanicsPlasticDruckerPrager::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
178void
179SolidMechanicsPlasticDruckerPrager::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);
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
220void
221SolidMechanicsPlasticDruckerPrager::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);
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
271void
272SolidMechanicsPlasticDruckerPrager::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));
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
302void
303SolidMechanicsPlasticDruckerPrager::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));
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}
registerMooseObjectRenamed("SolidMechanicsApp", TensorMechanicsPlasticDruckerPrager, "01/01/2025 00:00", SolidMechanicsPlasticDruckerPrager)
registerMooseObject("SolidMechanicsApp", SolidMechanicsPlasticDruckerPrager)
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)
void mooseError(Args &&... args) const
T secondInvariant() const
RankTwoTensorTempl< T > dsecondInvariant() const
RankTwoTensorTempl< T > dtrace() const
RankFourTensorTempl< T > d2secondInvariant() const
virtual Real derivative(Real intnl) const
virtual Real value(Real intnl) const
Rate-independent non-associative Drucker Prager with hardening/softening.
virtual RankTwoTensor dyieldFunction_dstress(const RankTwoTensor &stress, Real intnl) const override
The derivative of yield function with respect to stress.
SolidMechanicsPlasticDruckerPrager(const InputParameters &parameters)
void initializeAandB(Real intnl, Real &aaa, Real &bbb) const
Returns the Drucker-Prager parameters A nice reference on the different relationships between Drucker...
void onlyB(Real intnl, int fd, Real &bbb) const
Calculate bbb or bbb_flow.
const SolidMechanicsHardeningModel & _mc_phi
Hardening model for tan(phi)
virtual RankTwoTensor df_dsig(const RankTwoTensor &stress, Real bbb) const
Function that's used in dyieldFunction_dstress and flowPotential.
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 RankTwoTensor dflowPotential_dintnl(const RankTwoTensor &stress, Real intnl) const override
The derivative of the flow potential with respect to the internal parameter.
virtual RankFourTensor dflowPotential_dstress(const RankTwoTensor &stress, Real intnl) const override
The derivative of the flow potential with respect to stress.
void bothAB(Real intnl, Real &aaa, Real &bbb) const
Calculates aaa and bbb as a function of the internal parameter intnl.
void donlyB(Real intnl, int fd, Real &dbbb) const
Calculate d(bbb)/d(intnl) or d(bbb_flow)/d(intnl)
const bool _zero_phi_hardening
True if there is no hardening of friction angle.
virtual Real yieldFunction(const RankTwoTensor &stress, Real intnl) const override
The following functions are what you should override when building single-plasticity models.
virtual RankTwoTensor flowPotential(const RankTwoTensor &stress, Real intnl) const override
The flow potential.
void initializeB(Real intnl, int fd, Real &bbb) const
Returns the Drucker-Prager parameters A nice reference on the different relationships between Drucker...
const MooseEnum _mc_interpolation_scheme
The parameters aaa and bbb are chosen to closely match the Mohr-Coulomb yield surface.
virtual std::string modelName() const override
const bool _zero_cohesion_hardening
True if there is no hardening of cohesion.
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_psi
Hardening model for tan(psi)
const bool _zero_psi_hardening
True if there is no hardening of dilation angle.
const SolidMechanicsHardeningModel & _mc_cohesion
Hardening model for cohesion.
Plastic Model base class The virtual functions written below must be over-ridden in derived classes t...
static InputParameters validParams()
const Real pi