11 #include "RankFourTensor.h"
12 #include "libmesh/utility.h"
22 params.addRequiredParam<UserObjectName>(
24 "A TensorMechanicsHardening UserObject that defines hardening of the tensile strength");
25 params.addRangeCheckedParam<Real>(
26 "tensile_edge_smoother",
28 "tensile_edge_smoother>=0 & tensile_edge_smoother<=30",
29 "Smoothing parameter: the edges of the cone are smoothed by the given amount.");
30 MooseEnum tip_scheme(
"hyperbolic cap",
"hyperbolic");
31 params.addParam<MooseEnum>(
32 "tip_scheme", tip_scheme,
"Scheme by which the pyramid's tip will be smoothed.");
33 params.addRequiredRangeCheckedParam<Real>(
"tensile_tip_smoother",
34 "tensile_tip_smoother>=0",
35 "For the 'hyperbolic' tip_scheme, the pyramid vertex "
36 "will be smoothed by the given amount. For the 'cap' "
37 "tip_scheme, additional smoothing will occur. Typical "
38 "value is 0.1*tensile_strength");
39 params.addParam<Real>(
42 "For the 'cap' tip_scheme, smoothing is performed in the stress_mean > cap_start region");
43 params.addRangeCheckedParam<Real>(
"cap_rate",
46 "For the 'cap' tip_scheme, this controls how quickly the cap "
47 "degenerates to a hemisphere: small values mean a slow "
48 "degeneration to a hemisphere (and zero means the 'cap' will "
49 "be totally inactive). Typical value is 1/tensile_strength");
50 params.addParam<Real>(
"tensile_lode_cutoff",
51 "If the second invariant of stress is less than "
52 "this amount, the Lode angle is assumed to be zero. "
53 "This is to guard against precision-loss problems, "
54 "and this parameter should be set small. Default = "
55 "0.00001*((yield_Function_tolerance)^2)");
56 params.addClassDescription(
57 "Associative tensile plasticity with hardening/softening, and tensile_strength = 1");
65 _tip_scheme(getParam<MooseEnum>(
"tip_scheme")),
66 _small_smoother2(Utility::
pow<2>(getParam<Real>(
"tensile_tip_smoother"))),
67 _cap_start(getParam<Real>(
"cap_start")),
68 _cap_rate(getParam<Real>(
"cap_rate")),
69 _tt(getParam<Real>(
"tensile_edge_smoother") *
libMesh::pi / 180.0),
70 _sin3tt(std::sin(3.0 * _tt)),
71 _lode_cutoff(parameters.isParamValid(
"tensile_lode_cutoff")
72 ? getParam<Real>(
"tensile_lode_cutoff")
73 : 1.0e-5 * Utility::
pow<2>(_f_tol))
77 mooseError(
"tensile_lode_cutoff must not be negative");
78 _ccc = (-std::cos(3.0 *
_tt) * (std::cos(
_tt) - std::sin(
_tt) / std::sqrt(3.0)) -
79 3.0 *
_sin3tt * (std::sin(
_tt) + std::cos(
_tt) / std::sqrt(3.0))) /
80 (18.0 * Utility::pow<3>(std::cos(3.0 *
_tt)));
81 _bbb = (std::sin(6.0 *
_tt) * (std::cos(
_tt) - std::sin(
_tt) / std::sqrt(3.0)) -
82 6.0 * std::cos(6.0 *
_tt) * (std::sin(
_tt) + std::cos(
_tt) / std::sqrt(3.0))) /
83 (18.0 * Utility::pow<3>(std::cos(3.0 *
_tt)));
91 Real mean_stress = stress.trace() / 3.0;
96 std::vector<Real> eigvals;
97 stress.symmetricEigenvalues(eigvals);
98 return mean_stress + std::sqrt(
smooth(stress) + Utility::pow<2>(eigvals[2] - mean_stress)) -
104 Real kk =
_aaa +
_bbb * sin3Lode +
_ccc * Utility::pow<2>(sin3Lode);
105 Real sibar2 = stress.secondInvariant();
106 return mean_stress + std::sqrt(
smooth(stress) + sibar2 * Utility::pow<2>(kk)) -
115 Real mean_stress = stress.trace() / 3.0;
121 std::vector<Real> eigvals;
122 std::vector<RankTwoTensor> deigvals;
123 stress.dsymmetricEigenvalues(eigvals, deigvals);
124 Real denom = std::sqrt(
smooth(stress) + Utility::pow<2>(eigvals[2] - mean_stress));
125 return dmean_stress + (0.5 *
dsmooth(stress) * dmean_stress +
126 (eigvals[2] - mean_stress) * (deigvals[2] - dmean_stress)) /
132 Real kk =
_aaa +
_bbb * sin3Lode +
_ccc * Utility::pow<2>(sin3Lode);
134 Real sibar2 = stress.secondInvariant();
136 Real denom = std::sqrt(
smooth(stress) + sibar2 * Utility::pow<2>(kk));
137 return dmean_stress + (0.5 *
dsmooth(stress) * dmean_stress +
138 0.5 * dsibar2 * Utility::pow<2>(kk) + sibar2 * kk * dkk) /
161 Real mean_stress = stress.trace() / 3.0;
167 std::vector<Real> eigvals;
168 std::vector<RankTwoTensor> deigvals;
169 std::vector<RankFourTensor> d2eigvals;
170 stress.dsymmetricEigenvalues(eigvals, deigvals);
171 stress.d2symmetricEigenvalues(d2eigvals);
173 Real denom = std::sqrt(
smooth(stress) + Utility::pow<2>(eigvals[2] - mean_stress));
174 Real denom3 = Utility::pow<3>(denom);
177 0.5 *
dsmooth(stress) * dmean_stress + (eigvals[2] - mean_stress) * numer_part;
178 Real d2smooth_over_denom =
d2smooth(stress) / denom;
180 RankFourTensor dr_dstress = (eigvals[2] - mean_stress) * d2eigvals[2] / denom;
181 for (
unsigned i = 0; i < 3; ++i)
182 for (
unsigned j = 0; j < 3; ++j)
183 for (
unsigned k = 0; k < 3; ++k)
184 for (
unsigned l = 0; l < 3; ++l)
186 dr_dstress(i, j, k, l) +=
187 0.5 * d2smooth_over_denom * dmean_stress(i, j) * dmean_stress(k, l);
188 dr_dstress(i, j, k, l) += numer_part(i, j) * numer_part(k, l) / denom;
189 dr_dstress(i, j, k, l) -= numer_full(i, j) * numer_full(k, l) / denom3;
197 Real kk =
_aaa +
_bbb * sin3Lode +
_ccc * Utility::pow<2>(sin3Lode);
200 for (
unsigned i = 0; i < 3; ++i)
201 for (
unsigned j = 0; j < 3; ++j)
202 for (
unsigned k = 0; k < 3; ++k)
203 for (
unsigned l = 0; l < 3; ++l)
204 d2kk(i, j, k, l) += 2.0 *
_ccc * dsin3Lode(i, j) * dsin3Lode(k, l);
206 Real sibar2 = stress.secondInvariant();
210 Real denom = std::sqrt(
smooth(stress) + sibar2 * Utility::pow<2>(kk));
211 Real denom3 = Utility::pow<3>(denom);
212 Real d2smooth_over_denom =
d2smooth(stress) / denom;
214 0.5 *
dsmooth(stress) * dmean_stress + 0.5 * dsibar2 * kk * kk + sibar2 * kk * dkk;
216 RankFourTensor dr_dstress = (0.5 * d2sibar2 * Utility::pow<2>(kk) + sibar2 * kk * d2kk) / denom;
217 for (
unsigned i = 0; i < 3; ++i)
218 for (
unsigned j = 0; j < 3; ++j)
219 for (
unsigned k = 0; k < 3; ++k)
220 for (
unsigned l = 0; l < 3; ++l)
222 dr_dstress(i, j, k, l) +=
223 0.5 * d2smooth_over_denom * dmean_stress(i, j) * dmean_stress(k, l);
224 dr_dstress(i, j, k, l) +=
225 (dsibar2(i, j) * dkk(k, l) * kk + dkk(i, j) * dsibar2(k, l) * kk +
226 sibar2 * dkk(i, j) * dkk(k, l)) /
228 dr_dstress(i, j, k, l) -= numer_full(i, j) * numer_full(k, l) / denom3;
263 smoother2 += Utility::pow<2>(p);
282 dsmoother2 += 2.0 * p * dp_dx;
290 Real d2smoother2 = 0;
304 d2smoother2 += 2.0 * Utility::pow<2>(dp_dx) + 2.0 * p * d2p_dx2;