https://mooseframework.inl.gov
Loading...
Searching...
No Matches
BiLinearMixedModeTraction.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 "libmesh/utility.h"
12
14
17{
19 params.addClassDescription("Mixed mode bilinear traction separation law.");
20 params.addRequiredParam<Real>("penalty_stiffness", "Penalty stiffness.");
21 params.addRequiredParam<MaterialPropertyName>(
22 "GI_c", "Critical energy release rate in normal direction.");
23 params.addRequiredParam<MaterialPropertyName>("GII_c",
24 "Critical energy release rate in shear direction.");
25 params.addRequiredParam<MaterialPropertyName>("normal_strength",
26 "Tensile strength in normal direction.");
27 params.addRequiredParam<MaterialPropertyName>("shear_strength",
28 "Tensile strength in shear direction.");
29 params.addRequiredParam<Real>("eta", "The power law parameter.");
30 MooseEnum criterion("POWER_LAW BK", "BK");
31 params.addParam<Real>("viscosity", 0.0, "Viscosity.");
32 params.addParam<MooseEnum>(
33 "mixed_mode_criterion", criterion, "Option for mixed mode propagation criterion.");
34
35 // Advanced parameters to improve numerical convergence
36 params.addParam<bool>(
37 "lag_mode_mixity", true, "Whether to use old displacement jumps to compute the mode mixity.");
38 params.addParam<bool>(
39 "lag_displacement_jump",
40 false,
41 "Whether to use old displacement jumps to compute the effective displacement jump.");
42 params.addParam<Real>("alpha", 1e-10, "Regularization parameter for the Macaulay bracket.");
43 params.addParamNamesToGroup("lag_mode_mixity lag_displacement_jump alpha", "Advanced");
44
45 return params;
46}
47
50 _K(getParam<Real>("penalty_stiffness")),
51 _d(declareProperty<Real>(_base_name + "damage")),
52 _d_old(getMaterialPropertyOld<Real>(_base_name + "damage")),
53 _interface_displacement_jump_old(
54 getMaterialPropertyOld<RealVectorValue>(_base_name + "interface_displacement_jump")),
55 _delta_init(
56 declareProperty<Real>(_base_name + "effective_displacement_jump_at_damage_initiation")),
57 _delta_final(
58 declareProperty<Real>(_base_name + "effective_displacement_jump_at_full_degradation")),
59 _delta_m(declareProperty<Real>(_base_name + "effective_displacement_jump")),
60 _GI_c(getMaterialProperty<Real>(_base_name + getParam<MaterialPropertyName>("GI_c"))),
61 _GII_c(getMaterialProperty<Real>(_base_name + getParam<MaterialPropertyName>("GII_c"))),
62 _N(getMaterialProperty<Real>(_base_name + getParam<MaterialPropertyName>("normal_strength"))),
63 _S(getMaterialProperty<Real>(_base_name + getParam<MaterialPropertyName>("shear_strength"))),
64 _eta(getParam<Real>("eta")),
65 _beta(declareProperty<Real>(_base_name + "mode_mixity_ratio")),
66 _viscosity(getParam<Real>("viscosity")),
67 _criterion(getParam<MooseEnum>("mixed_mode_criterion").getEnum<MixedModeCriterion>()),
68 _lag_mode_mixity(getParam<bool>("lag_mode_mixity")),
69 _lag_disp_jump(getParam<bool>("lag_displacement_jump")),
70 _alpha(getParam<Real>("alpha"))
71{
72}
73
74void
81
82void
88
89RealVectorValue
91{
97
98 // Split displacement jump into active and inactive parts
99 const RealVectorValue delta = _interface_displacement_jump[_qp];
100 const RealVectorValue delta_active(std::max(delta(0), 0.), delta(1), delta(2));
101 const RealVectorValue delta_inactive(std::min(delta(0), 0.), 0, 0);
102
103 return (1 - _d[_qp]) * _K * delta_active + _K * delta_inactive;
104}
105
108{
109 // The displacement jump split depends on the displacement jump, obviously
110 const RealVectorValue delta = _interface_displacement_jump[_qp];
111 RankTwoTensor ddelta_active_ddelta, ddelta_inactive_ddelta;
112 ddelta_active_ddelta.fillFromInputVector({delta(0) > 0 ? 1. : 0., 1., 1.});
113 ddelta_inactive_ddelta.fillFromInputVector({delta(0) < 0 ? 1. : 0., 0., 0.});
114
115 RankTwoTensor dtraction_ddelta =
116 (1 - _d[_qp]) * _K * ddelta_active_ddelta + _K * ddelta_inactive_ddelta;
117
118 // The damage may also depend on the displacement jump
119 const RealVectorValue delta_active(std::max(delta(0), 0.), delta(1), delta(2));
121 A.vectorOuterProduct(delta_active, _dd_ddelta);
122 dtraction_ddelta -= _K * A;
123
124 return dtraction_ddelta;
125}
126
127void
129{
130 const RealVectorValue delta =
132
133 if (delta(0) > 0)
134 {
135 const Real delta_s = std::sqrt(delta(1) * delta(1) + delta(2) * delta(2));
136 _beta[_qp] = delta_s / delta(0);
137
138 if (!_lag_mode_mixity)
139 {
140 if (delta_s > 0)
141 // delta_s is nonnegative; only exact zero needs special handling to avoid 0/0.
142 _dbeta_ddelta = RealVectorValue(-delta_s / delta(0) / delta(0),
143 delta(1) / delta_s / delta(0),
144 delta(2) / delta_s / delta(0));
145 else
146 _dbeta_ddelta = RealVectorValue(0, 0, 0);
147 }
148 }
149 else
150 {
151 _beta[_qp] = 0;
152 _dbeta_ddelta = RealVectorValue(0, 0, 0);
153 }
154}
155
156void
158{
159 const RealVectorValue delta =
161
162 const Real delta_normal0 = _N[_qp] / _K;
163 const Real delta_shear0 = _S[_qp] / _K;
164
165 _delta_init[_qp] = delta_shear0;
166 _ddelta_init_ddelta = RealVectorValue(0, 0, 0);
167 if (delta(0) > 0)
168 {
169 const Real delta_mixed =
170 std::sqrt(delta_shear0 * delta_shear0 + Utility::pow<2>(_beta[_qp] * delta_normal0));
172 delta_normal0 * delta_shear0 * std::sqrt(1 + _beta[_qp] * _beta[_qp]) / delta_mixed;
173 if (!_lag_mode_mixity)
174 {
175 const Real ddelta_init_dbeta =
177 (1 / (1 + _beta[_qp] * _beta[_qp]) - Utility::pow<2>(delta_normal0 / delta_mixed));
178 _ddelta_init_ddelta = ddelta_init_dbeta * _dbeta_ddelta;
179 }
180 }
181}
182
183void
185{
186 const RealVectorValue delta =
188
189 _delta_final[_qp] = 2 * _GII_c[_qp] / _S[_qp];
190 _ddelta_final_ddelta = RealVectorValue(0, 0, 0);
191 if (delta(0) > 0)
192 {
194 {
196 2 / _K / _delta_init[_qp] *
197 (_GI_c[_qp] +
198 (_GII_c[_qp] - _GI_c[_qp]) *
199 std::pow(_beta[_qp] * _beta[_qp] / (1 + _beta[_qp] * _beta[_qp]), _eta));
200 if (!_lag_mode_mixity)
201 {
202 const Real ddelta_final_ddelta_init = -_delta_final[_qp] / _delta_init[_qp];
203 const Real ddelta_final_dbeta =
204 MooseUtils::absoluteFuzzyEqual(_beta[_qp], 0.0)
205 ? 0.0
206 : 2 / _K / _delta_init[_qp] * (_GII_c[_qp] - _GI_c[_qp]) * _eta *
207 std::pow(_beta[_qp] * _beta[_qp] / (1 + _beta[_qp] * _beta[_qp]), _eta - 1) *
208 2 * _beta[_qp] / Utility::pow<2>(1 + _beta[_qp] * _beta[_qp]);
210 ddelta_final_ddelta_init * _ddelta_init_ddelta + ddelta_final_dbeta * _dbeta_ddelta;
211 }
212 }
214 {
215 const Real Gc_mixed =
216 std::pow(1 / _GI_c[_qp], _eta) + std::pow(_beta[_qp] * _beta[_qp] / _GII_c[_qp], _eta);
218 (2 + 2 * _beta[_qp] * _beta[_qp]) / _K / _delta_init[_qp] * std::pow(Gc_mixed, -1 / _eta);
219 if (!_lag_mode_mixity)
220 {
221 const Real ddelta_final_ddelta_init = -_delta_final[_qp] / _delta_init[_qp];
222 const Real ddelta_final_dbeta =
223 _delta_final[_qp] * 2 * _beta[_qp] / (1 + _beta[_qp] * _beta[_qp]) -
224 (2 + 2 * _beta[_qp] * _beta[_qp]) / _K / _delta_init[_qp] *
225 std::pow(Gc_mixed, -1 / _eta - 1) *
226 std::pow(_beta[_qp] * _beta[_qp] / _GII_c[_qp], _eta - 1) * 2 * _beta[_qp] /
227 _GII_c[_qp];
229 ddelta_final_ddelta_init * _ddelta_init_ddelta + ddelta_final_dbeta * _dbeta_ddelta;
230 }
231 }
232 }
233}
234
235void
237{
238 const RealVectorValue delta =
240
241 const Real delta_normal_pos = MathUtils::regularizedHeavyside(delta(0), _alpha) * delta(0);
242 _delta_m[_qp] = std::sqrt(Utility::pow<2>(delta(1)) + Utility::pow<2>(delta(2)) +
243 Utility::pow<2>(delta_normal_pos));
244 _ddelta_m_ddelta = RealVectorValue(0, 0, 0);
245 if (!_lag_disp_jump && !MooseUtils::absoluteFuzzyEqual(_delta_m[_qp], 0))
246 {
247 const Real ddelta_normal_pos_ddelta_normal =
251 RealVectorValue(delta_normal_pos * ddelta_normal_pos_ddelta_normal, delta(1), delta(2));
253 }
254}
255
256void
258{
259 if (_delta_m[_qp] < _delta_init[_qp])
260 _d[_qp] = 0;
261 else if (_delta_m[_qp] > _delta_final[_qp])
262 _d[_qp] = 1;
263 else
266
267 _dd_ddelta = RealVectorValue(0, 0, 0);
268 if (_d[_qp] < _d_old[_qp])
269 // Irreversibility
270 _d[_qp] = _d_old[_qp];
271 else if (_delta_m[_qp] >= _delta_init[_qp] && _delta_m[_qp] <= _delta_final[_qp])
278 Utility::pow<2>(_delta_m[_qp] * (_delta_final[_qp] - _delta_init[_qp]));
279
280 // Viscous regularization
281 _d[_qp] = (_d[_qp] + _viscosity * _d_old[_qp] / _dt) / (_viscosity / _dt + 1);
282 _dd_ddelta /= (_viscosity / _dt + 1);
283}
registerMooseObject("SolidMechanicsApp", BiLinearMixedModeTraction)
Implementation of the mixed mode bilinear traction separation law described in Mixed-Mode Decohesion ...
virtual RankTwoTensor computeTractionDerivatives()
Compute the total traction derivatives w.r.t. the interface displacement jump.
virtual RealVectorValue computeTraction()
The traction-separation law.
virtual void computeInterfaceTractionAndDerivatives() override
Compute the local traction and derivatives. This method should fill the _interface_traction and _dint...
const MaterialProperty< RealVectorValue > & _interface_displacement_jump_old
old interface displacement jump value
const MaterialProperty< Real > & _S
The shear strength.
MaterialProperty< Real > & _d
const Real _viscosity
The viscosity.
const MaterialProperty< Real > & _d_old
BiLinearMixedModeTraction(const InputParameters &parameters)
const MaterialProperty< Real > & _GII_c
Mode II critical fracture toughness.
MaterialProperty< Real > & _delta_m
enum BiLinearMixedModeTraction::MixedModeCriterion _criterion
MixedModeCriterion
mixed mode propagation criterion
const MaterialProperty< Real > & _N
The normal strength.
MaterialProperty< Real > & _delta_final
const Real _eta
The B-K power law parameter.
MaterialProperty< Real > & _beta
The mode mixity ratio.
static InputParameters validParams()
const MaterialProperty< Real > & _GI_c
Mode I critical fracture toughness.
virtual void initQpStatefulProperties() override
const Real _K
Penalty elastic stiffness.
MaterialProperty< Real > & _delta_init
MaterialProperty< RankTwoTensor > & _dinterface_traction_djump
the traction's derivatives wrt the displacement jump in local coordinates
const MaterialProperty< RealVectorValue > & _interface_displacement_jump
The displacment jump in local coordaintes.
MaterialProperty< RealVectorValue > & _interface_traction
the value of the traction in local coordinates
Base class used to implement traction separetion laws for materials whose beahvior can be described u...
void addParamNamesToGroup(const std::string &space_delim_names, const std::string group_name)
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)
unsigned int _qp
virtual void initQpStatefulProperties()
void fillFromInputVector(const std::vector< T > &input, FillMethod fill_method=autodetect)
void vectorOuterProduct(const libMesh::TypeVector< T > &, const libMesh::TypeVector< T > &)
T regularizedHeavyside(const T &x, Real smoothing_length)
T regularizedHeavysideDerivative(const T &x, Real smoothing_length)