https://mooseframework.inl.gov
Loading...
Searching...
No Matches
SolidMechanicsPlasticWeakPlaneShear.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 TensorMechanicsPlasticWeakPlaneShear,
17 "01/01/2025 00:00",
19
22{
24 params.addRequiredParam<UserObjectName>(
25 "cohesion",
26 "A SolidMechanicsHardening UserObject that defines hardening of the cohesion. "
27 "Physically the cohesion should not be negative.");
28 params.addRequiredParam<UserObjectName>("tan_friction_angle",
29 "A SolidMechanicsHardening UserObject that defines "
30 "hardening of tan(friction angle). Physically the "
31 "friction angle should be between 0 and 90deg.");
32 params.addRequiredParam<UserObjectName>(
33 "tan_dilation_angle",
34 "A SolidMechanicsHardening UserObject that defines hardening of the "
35 "tan(dilation angle). Usually the dilation angle is not greater than "
36 "the friction angle, and it is between 0 and 90deg.");
37 MooseEnum tip_scheme("hyperbolic cap", "hyperbolic");
38 params.addParam<MooseEnum>(
39 "tip_scheme", tip_scheme, "Scheme by which the cone's tip will be smoothed.");
41 "smoother",
42 "smoother>=0",
43 "For the 'hyperbolic' tip_scheme, the cone vertex at shear-stress "
44 "= 0 will be smoothed by the given amount. For the 'cap' "
45 "tip_scheme, additional smoothing will occur. Typical value is "
46 "0.1*cohesion");
47 params.addParam<Real>(
48 "cap_start",
49 0.0,
50 "For the 'cap' tip_scheme, smoothing is performed in the stress_zz > cap_start region");
51 params.addRangeCheckedParam<Real>("cap_rate",
52 0.0,
53 "cap_rate>=0",
54 "For the 'cap' tip_scheme, this controls how quickly the cap "
55 "degenerates to a hemisphere: small values mean a slow "
56 "degeneration to a hemisphere (and zero means the 'cap' will "
57 "be totally inactive). Typical value is 1/cohesion");
58 params.addClassDescription("Non-associative finite-strain weak-plane shear perfect plasticity. "
59 "Here cohesion = 1, tan(phi) = 1 = tan(psi)");
60
61 return params;
62}
63
65 const InputParameters & parameters)
66 : SolidMechanicsPlasticModel(parameters),
67 _cohesion(getUserObject<SolidMechanicsHardeningModel>("cohesion")),
68 _tan_phi(getUserObject<SolidMechanicsHardeningModel>("tan_friction_angle")),
69 _tan_psi(getUserObject<SolidMechanicsHardeningModel>("tan_dilation_angle")),
70 _tip_scheme(getParam<MooseEnum>("tip_scheme")),
71 _small_smoother2(Utility::pow<2>(getParam<Real>("smoother"))),
72 _cap_start(getParam<Real>("cap_start")),
73 _cap_rate(getParam<Real>("cap_rate"))
74{
75 // With arbitary UserObjects, it is impossible to check everything, and
76 // I think this is the best I can do
77 if (tan_phi(0) < 0 || tan_psi(0) < 0)
78 mooseError("Weak-Plane-Shear friction and dilation angles must lie in [0, Pi/2]");
79 if (tan_phi(0) < tan_psi(0))
81 "Weak-Plane-Shear friction angle must not be less than Weak-Plane-Shear dilation angle");
82 if (cohesion(0) < 0)
83 mooseError("Weak-Plane-Shear cohesion must not be negative");
84}
85
86Real
88{
89 // note that i explicitly symmeterise in preparation for Cosserat
90 return std::sqrt(Utility::pow<2>((stress(0, 2) + stress(2, 0)) / 2.0) +
91 Utility::pow<2>((stress(1, 2) + stress(2, 1)) / 2.0) + smooth(stress)) +
92 stress(2, 2) * tan_phi(intnl) - cohesion(intnl);
93}
94
97 Real _tan_phi_or_psi) const
98{
99 RankTwoTensor deriv; // the constructor zeroes this
100
101 Real tau = std::sqrt(Utility::pow<2>((stress(0, 2) + stress(2, 0)) / 2.0) +
102 Utility::pow<2>((stress(1, 2) + stress(2, 1)) / 2.0) + smooth(stress));
103 // note that i explicitly symmeterise in preparation for Cosserat
104 if (tau == 0.0)
105 {
106 // the derivative is not defined here, but i want to set it nonzero
107 // because otherwise the return direction might be too crazy
108 deriv(0, 2) = deriv(2, 0) = 0.5;
109 deriv(1, 2) = deriv(2, 1) = 0.5;
110 }
111 else
112 {
113 deriv(0, 2) = deriv(2, 0) = 0.25 * (stress(0, 2) + stress(2, 0)) / tau;
114 deriv(1, 2) = deriv(2, 1) = 0.25 * (stress(1, 2) + stress(2, 1)) / tau;
115 deriv(2, 2) = 0.5 * dsmooth(stress) / tau;
116 }
117 deriv(2, 2) += _tan_phi_or_psi;
118 return deriv;
119}
120
123 Real intnl) const
124{
125 return df_dsig(stress, tan_phi(intnl));
126}
127
128Real
130 Real intnl) const
131{
132 return stress(2, 2) * dtan_phi(intnl) - dcohesion(intnl);
133}
134
137{
138 return df_dsig(stress, tan_psi(intnl));
139}
140
143 Real /*intnl*/) const
144{
145 RankFourTensor dr_dstress;
146 Real tau = std::sqrt(Utility::pow<2>((stress(0, 2) + stress(2, 0)) / 2.0) +
147 Utility::pow<2>((stress(1, 2) + stress(2, 1)) / 2.0) + smooth(stress));
148 if (tau == 0.0)
149 return dr_dstress;
150
151 // note that i explicitly symmeterise
152 RankTwoTensor dtau;
153 dtau(0, 2) = dtau(2, 0) = 0.25 * (stress(0, 2) + stress(2, 0)) / tau;
154 dtau(1, 2) = dtau(2, 1) = 0.25 * (stress(1, 2) + stress(2, 1)) / tau;
155 dtau(2, 2) = 0.5 * dsmooth(stress) / tau;
156
157 for (unsigned i = 0; i < 3; ++i)
158 for (unsigned j = 0; j < 3; ++j)
159 for (unsigned k = 0; k < 3; ++k)
160 for (unsigned l = 0; l < 3; ++l)
161 dr_dstress(i, j, k, l) = -dtau(i, j) * dtau(k, l) / tau;
162
163 // note that i explicitly symmeterise
164 dr_dstress(0, 2, 0, 2) += 0.25 / tau;
165 dr_dstress(0, 2, 2, 0) += 0.25 / tau;
166 dr_dstress(2, 0, 0, 2) += 0.25 / tau;
167 dr_dstress(2, 0, 2, 0) += 0.25 / tau;
168 dr_dstress(1, 2, 1, 2) += 0.25 / tau;
169 dr_dstress(1, 2, 2, 1) += 0.25 / tau;
170 dr_dstress(2, 1, 1, 2) += 0.25 / tau;
171 dr_dstress(2, 1, 2, 1) += 0.25 / tau;
172 dr_dstress(2, 2, 2, 2) += 0.5 * d2smooth(stress) / tau;
173
174 return dr_dstress;
175}
176
179 Real intnl) const
180{
181 RankTwoTensor dr_dintnl;
182 dr_dintnl(2, 2) = dtan_psi(intnl);
183 return dr_dintnl;
184}
185
186Real
187SolidMechanicsPlasticWeakPlaneShear::cohesion(const Real internal_param) const
188{
189 return _cohesion.value(internal_param);
190}
191
192Real
194{
195 return _cohesion.derivative(internal_param);
196}
197
198Real
199SolidMechanicsPlasticWeakPlaneShear::tan_phi(const Real internal_param) const
200{
201 return _tan_phi.value(internal_param);
202}
203
204Real
205SolidMechanicsPlasticWeakPlaneShear::dtan_phi(const Real internal_param) const
206{
207 return _tan_phi.derivative(internal_param);
208}
209
210Real
211SolidMechanicsPlasticWeakPlaneShear::tan_psi(const Real internal_param) const
212{
213 return _tan_psi.value(internal_param);
214}
215
216Real
217SolidMechanicsPlasticWeakPlaneShear::dtan_psi(const Real internal_param) const
218{
219 return _tan_psi.derivative(internal_param);
220}
221
222Real
224{
225 Real smoother2 = _small_smoother2;
226 if (_tip_scheme == "cap")
227 {
228 Real x = stress(2, 2) - _cap_start;
229 Real p = 0;
230 if (x > 0)
231 p = x * (1 - std::exp(-_cap_rate * x));
232 smoother2 += Utility::pow<2>(p);
233 }
234 return smoother2;
235}
236
237Real
239{
240 Real dsmoother2 = 0;
241 if (_tip_scheme == "cap")
242 {
243 Real x = stress(2, 2) - _cap_start;
244 Real p = 0;
245 Real dp_dx = 0;
246 if (x > 0)
247 {
248 const Real exp_cap_rate_x = std::exp(-_cap_rate * x);
249 p = x * (1 - exp_cap_rate_x);
250 dp_dx = (1 - exp_cap_rate_x) + x * _cap_rate * exp_cap_rate_x;
251 }
252 dsmoother2 += 2 * p * dp_dx;
253 }
254 return dsmoother2;
255}
256
257Real
259{
260 Real d2smoother2 = 0;
261 if (_tip_scheme == "cap")
262 {
263 Real x = stress(2, 2) - _cap_start;
264 Real p = 0;
265 Real dp_dx = 0;
266 Real d2p_dx2 = 0;
267 if (x > 0)
268 {
269 const Real exp_cap_rate_x = std::exp(-_cap_rate * x);
270 p = x * (1.0 - exp_cap_rate_x);
271 dp_dx = (1.0 - exp_cap_rate_x) + x * _cap_rate * exp_cap_rate_x;
272 d2p_dx2 = 2.0 * _cap_rate * exp_cap_rate_x - x * Utility::pow<2>(_cap_rate) * exp_cap_rate_x;
273 }
274 d2smoother2 += 2.0 * Utility::pow<2>(dp_dx) + 2.0 * p * d2p_dx2;
275 }
276 return d2smoother2;
277}
278
279void
281 const RankTwoTensor & stress,
282 Real intnl,
283 const RankFourTensor & Eijkl,
284 std::vector<bool> & act,
285 RankTwoTensor & returned_stress) const
286{
287 act.assign(1, false);
288 returned_stress = stress;
289
290 if (f[0] <= _f_tol)
291 return;
292
293 // in the following i will derive returned_stress for the case smoother=0
294
295 Real tanpsi = tan_psi(intnl);
296 Real tanphi = tan_phi(intnl);
297
298 // norm is the normal to the yield surface
299 // with f having psi (dilation angle) instead of phi:
300 // norm(0) = df/dsig(2,0) = df/dsig(0,2)
301 // norm(1) = df/dsig(2,1) = df/dsig(1,2)
302 // norm(2) = df/dsig(2,2)
303 std::vector<Real> norm(3, 0.0);
304 const Real tau = std::sqrt(Utility::pow<2>((stress(0, 2) + stress(2, 0)) / 2.0) +
305 Utility::pow<2>((stress(1, 2) + stress(2, 1)) / 2.0));
306 if (tau > 0.0)
307 {
308 norm[0] = 0.25 * (stress(0, 2) + stress(2, 0)) / tau;
309 norm[1] = 0.25 * (stress(1, 2) + stress(2, 1)) / tau;
310 }
311 else
312 {
313 returned_stress(2, 2) = cohesion(intnl) / tanphi;
314 act[0] = true;
315 return;
316 }
317 norm[2] = tanpsi;
318
319 // to get the flow directions, we have to multiply norm by Eijkl.
320 // I assume that E(0,2,0,2) = E(1,2,1,2), and E(2,2,0,2) = 0 = E(0,2,1,2), etc
321 // with the usual symmetry. This makes finding the returned_stress
322 // much easier.
323 // returned_stress = stress - alpha*n
324 // where alpha is chosen so that f = 0
325 Real alpha = f[0] / (Eijkl(0, 2, 0, 2) + Eijkl(2, 2, 2, 2) * tanpsi * tanphi);
326
327 if (1 - alpha * Eijkl(0, 2, 0, 2) / tau >= 0)
328 {
329 // returning to the "surface" of the cone
330 returned_stress(2, 2) = stress(2, 2) - alpha * Eijkl(2, 2, 2, 2) * norm[2];
331 returned_stress(0, 2) = returned_stress(2, 0) =
332 stress(0, 2) - alpha * 2.0 * Eijkl(0, 2, 0, 2) * norm[0];
333 returned_stress(1, 2) = returned_stress(2, 1) =
334 stress(1, 2) - alpha * 2.0 * Eijkl(1, 2, 1, 2) * norm[1];
335 }
336 else
337 {
338 // returning to the "tip" of the cone
339 returned_stress(2, 2) = cohesion(intnl) / tanphi;
340 returned_stress(0, 2) = returned_stress(2, 0) = returned_stress(1, 2) = returned_stress(2, 1) =
341 0.0;
342 }
343 returned_stress(0, 0) =
344 stress(0, 0) - Eijkl(0, 0, 2, 2) * (stress(2, 2) - returned_stress(2, 2)) / Eijkl(2, 2, 2, 2);
345 returned_stress(1, 1) =
346 stress(1, 1) - Eijkl(1, 1, 2, 2) * (stress(2, 2) - returned_stress(2, 2)) / Eijkl(2, 2, 2, 2);
347
348 act[0] = true;
349}
350
351std::string
353{
354 return "WeakPlaneShear";
355}
Real f(Real x)
Test function for Brents method.
const std::vector< double > x
ExpressionBuilder::EBTerm pow(const ExpressionBuilder::EBTerm &left, T exponent)
const Real p
registerMooseObjectRenamed("SolidMechanicsApp", TensorMechanicsPlasticWeakPlaneShear, "01/01/2025 00:00", SolidMechanicsPlasticWeakPlaneShear)
registerMooseObject("SolidMechanicsApp", SolidMechanicsPlasticWeakPlaneShear)
void addRequiredRangeCheckedParam(const std::string &name, const std::string &parsed_function, const std::string &doc_string)
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 addRangeCheckedParam(const std::string &name, const T &value, const std::string &parsed_function, const std::string &doc_string)
void mooseError(Args &&... args) const
virtual Real derivative(Real intnl) const
virtual Real value(Real intnl) const
Plastic Model base class The virtual functions written below must be over-ridden in derived classes t...
const Real _f_tol
Tolerance on yield function.
static InputParameters validParams()
Rate-independent associative weak-plane tensile failure with hardening/softening.
virtual Real d2smooth(const RankTwoTensor &stress) const
returns the d^2a/dstress(2,2)^2 - see doco for _tip_scheme
virtual Real dtan_psi(const Real internal_param) const
d(tan_psi)/d(internal_param);
virtual Real smooth(const RankTwoTensor &stress) const
returns the 'a' parameter - see doco for _tip_scheme
Real _cap_start
smoothing parameter dictating when the 'cap' will start - see doco for _tip_scheme
RankTwoTensor df_dsig(const RankTwoTensor &stress, Real _tan_phi_or_psi) const
Function that's used in dyieldFunction_dstress and flowPotential.
virtual Real cohesion(const Real internal_param) const
cohesion as a function of internal parameter
virtual Real tan_phi(const Real internal_param) const
tan_phi as a function of internal parameter
RankTwoTensor flowPotential(const RankTwoTensor &stress, Real intnl) const override
The flow potential.
Real dyieldFunction_dintnl(const RankTwoTensor &stress, Real intnl) const override
The derivative of yield function with respect to the internal parameter.
const SolidMechanicsHardeningModel & _cohesion
Hardening model for cohesion.
RankTwoTensor dyieldFunction_dstress(const RankTwoTensor &stress, Real intnl) const override
The derivative of yield function with respect to stress.
RankFourTensor dflowPotential_dstress(const RankTwoTensor &stress, Real intnl) const override
The derivative of the flow potential with respect to stress.
virtual Real dsmooth(const RankTwoTensor &stress) const
returns the da/dstress(2,2) - see doco for _tip_scheme
virtual void activeConstraints(const std::vector< Real > &f, const RankTwoTensor &stress, Real intnl, const RankFourTensor &Eijkl, std::vector< bool > &act, RankTwoTensor &returned_stress) const override
The active yield surfaces, given a vector of yield functions.
Real _cap_rate
dictates how quickly the 'cap' degenerates to a hemisphere - see doco for _tip_scheme
const SolidMechanicsHardeningModel & _tan_phi
Hardening model for tan(phi)
SolidMechanicsPlasticWeakPlaneShear(const InputParameters &parameters)
virtual Real dcohesion(const Real internal_param) const
d(cohesion)/d(internal_param)
Real _small_smoother2
smoothing parameter for the cone's tip - see doco for _tip_scheme
Real yieldFunction(const RankTwoTensor &stress, Real intnl) const override
The following functions are what you should override when building single-plasticity models.
RankTwoTensor dflowPotential_dintnl(const RankTwoTensor &stress, Real intnl) const override
The derivative of the flow potential with respect to the internal parameter.
MooseEnum _tip_scheme
The yield function is modified to f = sqrt(s_xz^2 + s_yz^2 + a) + s_zz*_tan_phi - _cohesion where "a"...
virtual Real tan_psi(const Real internal_param) const
tan_psi as a function of internal parameter
virtual Real dtan_phi(const Real internal_param) const
d(tan_phi)/d(internal_param);
const SolidMechanicsHardeningModel & _tan_psi
Hardening model for tan(psi)