https://mooseframework.inl.gov
BilinearMixedModeCohesiveZoneModel.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 "MooseVariableFE.h"
12 #include "SystemBase.h"
13 #include "MortarUtils.h"
14 #include "MooseUtils.h"
15 #include "MathUtils.h"
16 
17 #include "MortarContactUtils.h"
19 
20 #include "ADReal.h"
21 #include "CohesiveZoneModelTools.h"
22 #include <Eigen/Core>
23 
25 
28 {
30 
31  params.addClassDescription("Computes the bilinear mixed mode cohesive zone model.");
32 
33  // Input parameters for bilinear mixed mode traction.
34  params.addParam<MaterialPropertyName>("GI_c",
35  "Critical energy release rate in normal direction.");
36  params.addParam<MaterialPropertyName>("GII_c",
37  "Critical energy release rate in shear direction.");
38  params.addParam<MaterialPropertyName>("normal_strength", "Tensile strength in normal direction.");
39  params.addParam<MaterialPropertyName>("shear_strength", "Tensile strength in shear direction.");
40  params.addParam<Real>("power_law_parameter", "The power law parameter.");
41  MooseEnum criterion("POWER_LAW BK", "BK");
42  params.addParam<Real>("viscosity", 0.0, "Viscosity for damage model.");
43  params.addParam<MooseEnum>(
44  "mixed_mode_criterion", criterion, "Option for mixed mode propagation criterion.");
45  params.addParam<bool>(
46  "lag_displacement_jump",
47  false,
48  "Whether to use old displacement jumps to compute the effective displacement jump.");
49  params.addParam<bool>("set_compressive_traction_to_zero",
50  false,
51  "Zero compressive traction (set to true, allowing the use of standard "
52  "zero-penetration mortar contact constraints in "
53  "the normal direction).");
54  params.addParam<Real>(
55  "regularization_alpha", 1e-10, "Regularization parameter for the Macaulay bracket.");
56  params.addRangeCheckedParam<Real>(
57  "penalty_stiffness", "penalty_stiffness > 0.0", "Penalty stiffness for CZM.");
58  params.addParamNamesToGroup(
59  "GI_c GII_c normal_strength shear_strength power_law_parameter viscosity "
60  "mixed_mode_criterion lag_displacement_jump regularization_alpha "
61  "penalty_stiffness",
62  "Bilinear mixed mode traction");
63  // End of input parameters for bilinear mixed mode traction.
64 
65  return params;
66 }
67 
69  const InputParameters & parameters)
70  : WeightedGapUserObject(parameters),
71  PenaltyWeightedGapUserObject(parameters),
72  WeightedVelocitiesUserObject(parameters),
73  CohesiveZoneModelBase(parameters),
74  _set_compressive_traction_to_zero(getParam<bool>("set_compressive_traction_to_zero")),
75  _normal_strength(getMaterialProperty<Real>("normal_strength")),
76  _shear_strength(getMaterialProperty<Real>("shear_strength")),
77  _GI_c(getMaterialProperty<Real>("GI_c")),
78  _GII_c(getMaterialProperty<Real>("GII_c")),
79  _penalty_stiffness_czm(getParam<Real>("penalty_stiffness")),
80  _mix_mode_criterion(getParam<MooseEnum>("mixed_mode_criterion").getEnum<MixedModeCriterion>()),
81  _power_law_parameter(getParam<Real>("power_law_parameter")),
82  _viscosity(getParam<Real>("viscosity")),
83  _regularization_alpha(getParam<Real>("regularization_alpha"))
84 {
85 
86  // Checks for bilinear traction input.
87  if (!isParamValid("GI_c") || !isParamValid("GII_c") || !isParamValid("normal_strength") ||
88  !isParamValid("shear_strength") || !isParamValid("power_law_parameter") ||
89  !isParamValid("penalty_stiffness"))
90  paramError("GI_c",
91  "The CZM bilinear mixed mode traction parameters GI_c, GII_c, normal_strength, "
92  "shear_strength, and power_law_parameter are required. Revise your input and add "
93  "those parameters if you want to use the bilinear mixed mode traction model. ");
94 }
95 
96 void
98 {
100 
105 }
106 
107 void
109 {
111 
112  // Get the _dof_to_weighted_gap map
113  const auto * const dof = static_cast<const DofObject *>(_lower_secondary_elem->node_ptr(_i));
114 
115  // TODO: Probably better to interpolate the deformation gradients.
118 
119  _dof_to_GI_c[dof] += (*_test)[_i][_qp] * _GI_c_interpolation;
120  _dof_to_GII_c[dof] += (*_test)[_i][_qp] * _GII_c_interpolation;
121 }
122 
123 void
125 {
126  // instead we call it explicitly here
128 
129  // Avoid accumulating interpolation over the time step
131  _dof_to_normal_strength.clear();
132  _dof_to_shear_strength.clear();
133  _dof_to_GI_c.clear();
134  _dof_to_GII_c.clear();
135  _dof_to_delta_initial.clear();
136  _dof_to_delta_final.clear();
137  _dof_to_delta_max.clear();
138 }
139 
140 void
142 {
143  using std::max, std::min;
144 
145  // First call does not have maps available
146  const bool return_boolean = _dof_to_weighted_gap.find(node) == _dof_to_weighted_gap.end();
147  if (return_boolean)
148  return;
149 
150  computeModeMixity(node);
154  computeDamage(node);
155 
156  // Split displacement jump into active and inactive parts
157  const auto interface_displacement_jump =
159 
160  const ADRealVectorValue delta_active(max(interface_displacement_jump(0), 0.0),
161  interface_displacement_jump(1),
162  interface_displacement_jump(2));
163  const ADRealVectorValue delta_inactive(min(interface_displacement_jump(0), 0.0), 0.0, 0.0);
164 
165  // This traction vector is local at this point.
166  _dof_to_czm_traction[node] =
167  -(1.0 - libmesh_map_find(_dof_to_damage, node->id()).first) * _penalty_stiffness_czm *
168  delta_active -
170 }
171 
172 void
174 {
175  using std::sqrt;
176 
177  const auto interface_displacement_jump =
179 
180  if (interface_displacement_jump(0) > _epsilon_tolerance)
181  {
182  const auto delta_s =
183  sqrt(interface_displacement_jump(1) * interface_displacement_jump(1) +
184  interface_displacement_jump(2) * interface_displacement_jump(2) + _epsilon_tolerance);
185 
186  _dof_to_mode_mixity_ratio[node] = delta_s / interface_displacement_jump(0);
187  }
188  else
189  _dof_to_mode_mixity_ratio[node] = 0;
190 }
191 
192 void
194 {
195  using std::sqrt;
196 
197  const auto interface_displacement_jump =
199 
200  const auto mixity_ratio = libmesh_map_find(_dof_to_mode_mixity_ratio, node);
201 
202  const auto delta_normal_knot =
204  const auto delta_shear_knot =
206 
207  _dof_to_delta_initial[node] = delta_shear_knot;
208 
209  if (interface_displacement_jump(0) > _epsilon_tolerance)
210  {
211  const auto delta_mixed = sqrt(delta_shear_knot * delta_shear_knot +
212  Utility::pow<2>(mixity_ratio * delta_normal_knot));
213 
214  _dof_to_delta_initial[node] = delta_normal_knot * delta_shear_knot *
215  sqrt(1.0 + mixity_ratio * mixity_ratio) / delta_mixed;
216  }
217 }
218 
219 void
221 {
222  using std::sqrt, std::pow;
223 
224  const auto interface_displacement_jump =
226 
227  const auto mixity_ratio = libmesh_map_find(_dof_to_mode_mixity_ratio, node);
228 
229  const auto normalized_GI_c = normalizeQuantity(_dof_to_GI_c, node);
230  const auto normalized_GII_c = normalizeQuantity(_dof_to_GII_c, node);
231 
232  _dof_to_delta_final[node] =
233  sqrt(2.0) * 2.0 * normalized_GII_c / normalizeQuantity(_dof_to_shear_strength, node);
234 
235  if (interface_displacement_jump(0) > _epsilon_tolerance)
236  {
238  {
239  _dof_to_delta_final[node] =
240  2.0 / _penalty_stiffness_czm / libmesh_map_find(_dof_to_delta_initial, node) *
241  (normalized_GI_c +
242  (normalized_GII_c - normalized_GI_c) *
243  pow(mixity_ratio * mixity_ratio / (1 + mixity_ratio * mixity_ratio),
245  }
247  {
248  const auto Gc_mixed =
249  pow(1.0 / normalized_GI_c, _power_law_parameter) +
250  pow(mixity_ratio * mixity_ratio / normalized_GII_c, _power_law_parameter);
251  _dof_to_delta_final[node] = (2.0 + 2.0 * mixity_ratio * mixity_ratio) /
253  libmesh_map_find(_dof_to_delta_initial, node) *
254  pow(Gc_mixed, -1.0 / _power_law_parameter);
255  }
256  }
257 }
258 
259 void
261 {
262  using std::sqrt;
263 
264  const auto interface_displacement_jump =
266 
267  const auto delta_normal_pos =
268  MathUtils::regularizedHeavyside(interface_displacement_jump(0), _regularization_alpha) *
269  interface_displacement_jump(0);
270 
271  _dof_to_delta_max[node] = sqrt(Utility::pow<2>(interface_displacement_jump(1)) +
272  Utility::pow<2>(interface_displacement_jump(2)) +
273  Utility::pow<2>(delta_normal_pos) + _epsilon_tolerance);
274 }
275 
276 void
278 {
279  const auto delta_max = libmesh_map_find(_dof_to_delta_max, node);
280  const auto delta_initial = libmesh_map_find(_dof_to_delta_initial, node);
281  const auto delta_final = libmesh_map_find(_dof_to_delta_final, node);
282 
283  auto & [damage, damage_old] = _dof_to_damage[node->id()];
284  if (delta_max < delta_initial)
285  damage = 0;
286  else if (delta_max > delta_final)
287  damage = 1.0;
288  else
289  damage = delta_final * (delta_max - delta_initial) / delta_max / (delta_final - delta_initial);
290 
291  if (damage < damage_old)
292  // Irreversibility
293  damage = damage_old;
294 
295  // Viscous regularization
296  damage = (damage + _viscosity * damage_old / _dt) / (_viscosity / _dt + 1.0);
297 }
298 
299 void
301 {
303 
304  const bool send_data_back = !constrainedByOwner();
305 
308 
311 
313  _dof_to_GI_c, _subproblem.mesh(), _nodal, _communicator, send_data_back);
314 
316  _dof_to_GII_c, _subproblem.mesh(), _nodal, _communicator, send_data_back);
317 }
318 
319 Real
321 {
322  const auto it = _dof_to_mode_mixity_ratio.find(_subproblem.mesh().nodePtr(node->id()));
323 
324  if (it != _dof_to_mode_mixity_ratio.end())
325  return MetaPhysicL::raw_value(it->second);
326  else
327  return 0.0;
328 }
329 
330 Real
332 {
333  const auto it = _dof_to_damage.find(node->id());
334 
335  if (it != _dof_to_damage.end())
336  return MetaPhysicL::raw_value(it->second.first);
337  else
338  return 0.0;
339 }
340 
341 Real
343 {
344  const auto it = _dof_to_interface_displacement_jump.find(_subproblem.mesh().nodePtr(node->id()));
345  const auto it2 = _dof_to_weighted_gap.find(_subproblem.mesh().nodePtr(node->id()));
346 
347  if (it != _dof_to_interface_displacement_jump.end() && it2 != _dof_to_weighted_gap.end())
348  return MetaPhysicL::raw_value(it->second(0) / it2->second.second);
349  else
350  return 0.0;
351 }
352 
353 Real
355 {
356  const auto it = _dof_to_interface_displacement_jump.find(_subproblem.mesh().nodePtr(node->id()));
357  const auto it2 = _dof_to_weighted_gap.find(_subproblem.mesh().nodePtr(node->id()));
358 
359  if (it != _dof_to_interface_displacement_jump.end() && it2 != _dof_to_weighted_gap.end())
360  return MetaPhysicL::raw_value(it->second(1) / it2->second.second);
361  else
362  return 0.0;
363 }
virtual MooseMesh & mesh()=0
std::unordered_map< const DofObject *, ADReal > _dof_to_normal_strength
ADReal _normal_strength_interpolation
Interpolated value of normal_strength.
Real getModeMixityRatio(const Node *const node) const
unsigned int _qp
Quadrature point index for the mortar segments.
void paramError(const std::string &param, Args... args) const
void addParam(const std::string &name, const std::initializer_list< typename T::value_type > &value, const std::string &doc_string)
const MaterialProperty< Real > & _GI_c
Fracture parameter mode I.
std::unordered_map< const DofObject *, ADRealVectorValue > _dof_to_czm_traction
Total Lagrangian stress to be applied on CZM interface.
const Real _regularization_alpha
Parameter for the regularization of the Macaulay bracket.
const bool _set_compressive_traction_to_zero
Zero compressive traction.
static InputParameters validParams()
T normalizeQuantity(const std::unordered_map< const DofObject *, T > &map, const Node *const node)
Normalize mortar quantities (remove mortar integral scaling)
const Real & _dt
Current delta t... or timestep size.
void communicateRealObject(std::unordered_map< const DofObject *, T > &dof_to_adreal, const MooseMesh &mesh, const bool nodal, const Parallel::Communicator &communicator, const bool send_data_back)
auto raw_value(const Eigen::Map< T > &in)
virtual void computeQpProperties() override
Computes properties that are functions only of the current quadrature point (_qp), e.g.
std::unordered_map< const DofObject *, ADRealVectorValue > _dof_to_interface_displacement_jump
Map from degree of freedom to local displacement jump.
std::unordered_map< const DofObject *, ADReal > _dof_to_delta_initial
registerMooseObject("ContactApp", BilinearMixedModeCohesiveZoneModel)
User object for computing weighted gaps and contact pressure for penalty based mortar constraints...
const bool _nodal
Whether the dof objects are nodal; if they&#39;re not, then they&#39;re elemental.
const std::vector< Real > & _JxW_msm
const Parallel::Communicator & _communicator
Creates dof object to weighted tangential velocities map.
const Real _epsilon_tolerance
Tolerance to avoid NaN/Inf in automatic differentiation operations.
const MaterialProperty< Real > & _GII_c
Fracture parameter mode II.
Real getCohesiveDamage(const Node *const node) const
const Real _viscosity
Viscosity for damage model.
ADReal _shear_strength_interpolation
Interpolated value of shear_strength.
std::unordered_map< const DofObject *, ADReal > _dof_to_delta_max
std::unordered_map< const DofObject *, ADReal > _dof_to_GII_c
auto max(const L &left, const R &right)
virtual void computeQpIProperties() override
Computes properties that are functions both of _qp and _i, for example the weighted gap...
MixedModeCriterion
Mixed-mode propagation criterion.
virtual void computeQpProperties() override
Computes properties that are functions only of the current quadrature point (_qp), e.g.
Real getLocalDisplacementTangential(const Node *const node) const
Elem const *const & _lower_secondary_elem
const MaterialProperty< Real > & _shear_strength
The shear strength material property.
const MaterialProperty< Real > & _normal_strength
The normal strength material property.
virtual const Node * nodePtr(const dof_id_type i) const
std::unordered_map< const DofObject *, ADReal > _dof_to_delta_final
virtual void computeDamage(const Node *const node) override
virtual void computeModeMixity(const Node *const node)
SubProblem & _subproblem
BilinearMixedModeCohesiveZoneModel(const InputParameters &parameters)
ExpressionBuilder::EBTerm pow(const ExpressionBuilder::EBTerm &left, T exponent)
std::unordered_map< const DofObject *, ADReal > _dof_to_shear_strength
const MooseArray< Real > & _coord
Member for handling change of coordinate systems (xyz, rz, spherical)
ADReal _GI_c_interpolation
Interpolated value of fracture paramter mode I.
virtual void computeQpIProperties() override
Computes properties that are functions both of _qp and _i, for example the weighted gap...
virtual void computeCriticalDisplacementJump(const Node *const node)
Creates dof object to weighted gap map.
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
CTSub CT_OPERATOR_BINARY CTMul CTCompareLess CTCompareGreater CTCompareEqual _arg template * sqrt(_arg)) *_arg.template D< dtag >()) CT_SIMPLE_UNARY_FUNCTION(tanh
std::unordered_map< const DofObject *, ADReal > _dof_to_GI_c
T regularizedHeavyside(const T &x, Real smoothing_length)
User object that computes bilinear mixed mode traction separation law.
unsigned int _i
Test function index.
void addClassDescription(const std::string &doc_string)
enum BilinearMixedModeCohesiveZoneModel::MixedModeCriterion _mix_mode_criterion
void addRangeCheckedParam(const std::string &name, const T &value, const std::string &parsed_function, const std::string &doc_string)
bool isParamValid(const std::string &name) const
virtual void computeFinalDisplacementJump(const Node *const node)
const Real _power_law_parameter
Power law parameter for bilinear traction model.
virtual void initialize() override
virtual void computeCZMTraction(const Node *const node) override
Encapsulate the CZM constitutive behavior.
Real getLocalDisplacementNormal(const Node *const node) const
virtual void computeEffectiveDisplacementJump(const Node *const node)
std::unordered_map< const DofObject *, std::pair< ADReal, Real > > _dof_to_weighted_gap
A map from node to weighted gap and normalization (if requested)
Base class for mortar-based cohesive zone model.
auto min(const L &left, const R &right)
MooseUnits pow(const MooseUnits &, int)
std::unordered_map< dof_id_type, std::pair< ADReal, Real > > & _dof_to_damage
Damage values (pair of current and old) on CZM interface.
ADReal _GII_c_interpolation
Interpolated value of fracture paramter mode II.
std::unordered_map< const DofObject *, ADReal > _dof_to_mode_mixity_ratio
Map from degree of freedom to mode mixity ratio (AD needed?)
virtual void finalize() override
void addParamNamesToGroup(const std::string &space_delim_names, const std::string group_name)