Line data Source code
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 :
10 : #include "BilinearMixedModeCohesiveZoneModel.h"
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"
18 : #include "FactorizedRankTwoTensor.h"
19 :
20 : #include "ADReal.h"
21 : #include "CohesiveZoneModelTools.h"
22 : #include <Eigen/Core>
23 :
24 : registerMooseObject("ContactApp", BilinearMixedModeCohesiveZoneModel);
25 :
26 : InputParameters
27 144 : BilinearMixedModeCohesiveZoneModel::validParams()
28 : {
29 144 : InputParameters params = PenaltySimpleCohesiveZoneModel::validParams();
30 :
31 144 : params.addClassDescription("Computes the bilinear mixed mode cohesive zone model.");
32 288 : params.addRequiredCoupledVar("displacements",
33 : "The string of displacements suitable for the problem statement");
34 :
35 : // Input parameters for bilinear mixed mode traction.
36 288 : params.addParam<MaterialPropertyName>("GI_c",
37 : "Critical energy release rate in normal direction.");
38 288 : params.addParam<MaterialPropertyName>("GII_c",
39 : "Critical energy release rate in shear direction.");
40 288 : params.addParam<MaterialPropertyName>("normal_strength", "Tensile strength in normal direction.");
41 288 : params.addParam<MaterialPropertyName>("shear_strength", "Tensile strength in shear direction.");
42 288 : params.addParam<Real>("power_law_parameter", "The power law parameter.");
43 288 : MooseEnum criterion("POWER_LAW BK", "BK");
44 288 : params.addParam<Real>("viscosity", 0.0, "Viscosity for damage model.");
45 288 : params.addParam<MooseEnum>(
46 : "mixed_mode_criterion", criterion, "Option for mixed mode propagation criterion.");
47 288 : params.addParam<bool>(
48 : "lag_displacement_jump",
49 288 : false,
50 : "Whether to use old displacement jumps to compute the effective displacement jump.");
51 288 : params.addParam<Real>(
52 288 : "regularization_alpha", 1e-10, "Regularization parameter for the Macaulay bracket.");
53 288 : params.addRangeCheckedParam<Real>(
54 : "penalty_stiffness", "penalty_stiffness > 0.0", "Penalty stiffness for CZM.");
55 288 : params.addParamNamesToGroup(
56 : "GI_c GII_c normal_strength shear_strength power_law_parameter viscosity "
57 : "mixed_mode_criterion lag_displacement_jump regularization_alpha "
58 : "penalty_stiffness",
59 : "Bilinear mixed mode traction");
60 : // End of input parameters for bilinear mixed mode traction.
61 :
62 : // Suppress augmented Lagrange parameters. AL implementation for CZM remains to be done.
63 144 : params.suppressParameter<Real>("max_penalty_multiplier");
64 144 : params.suppressParameter<Real>("penalty_multiplier");
65 144 : params.suppressParameter<Real>("penetration_tolerance");
66 144 : return params;
67 144 : }
68 :
69 72 : BilinearMixedModeCohesiveZoneModel::BilinearMixedModeCohesiveZoneModel(
70 72 : const InputParameters & parameters)
71 : : WeightedGapUserObject(parameters),
72 : PenaltyWeightedGapUserObject(parameters),
73 : WeightedVelocitiesUserObject(parameters),
74 : PenaltySimpleCohesiveZoneModel(parameters),
75 72 : _ndisp(coupledComponents("displacements")),
76 144 : _normal_strength(getMaterialProperty<Real>("normal_strength")),
77 144 : _shear_strength(getMaterialProperty<Real>("shear_strength")),
78 144 : _GI_c(getMaterialProperty<Real>("GI_c")),
79 144 : _GII_c(getMaterialProperty<Real>("GII_c")),
80 144 : _penalty_stiffness_czm(getParam<Real>("penalty_stiffness")),
81 144 : _mix_mode_criterion(getParam<MooseEnum>("mixed_mode_criterion").getEnum<MixedModeCriterion>()),
82 144 : _power_law_parameter(getParam<Real>("power_law_parameter")),
83 144 : _viscosity(getParam<Real>("viscosity")),
84 288 : _regularization_alpha(getParam<Real>("regularization_alpha"))
85 : {
86 72 : _czm_interpolated_traction.resize(_ndisp);
87 :
88 216 : for (unsigned int i = 0; i < _ndisp; ++i)
89 : {
90 144 : _grad_disp.push_back(&adCoupledGradient("displacements", i));
91 288 : _grad_disp_neighbor.push_back(&adCoupledGradient("displacements", i));
92 : }
93 :
94 : // Set non-intervening components to zero
95 144 : for (unsigned int i = _ndisp; i < 3; i++)
96 : {
97 72 : _grad_disp.push_back(&_ad_grad_zero);
98 72 : _grad_disp_neighbor.push_back(&_ad_grad_zero);
99 : }
100 :
101 : // Checks for bilinear traction input.
102 504 : if (!isParamValid("GI_c") || !isParamValid("GII_c") || !isParamValid("normal_strength") ||
103 504 : !isParamValid("shear_strength") || !isParamValid("power_law_parameter") ||
104 216 : !isParamValid("penalty_stiffness"))
105 0 : paramError("GI_c",
106 : "The CZM bilinear mixed mode traction parameters GI_c, GII_c, normal_strength, "
107 : "shear_strength, and power_law_parameter are required. Revise your input and add "
108 : "those parameters if you want to use the bilinear mixed mode traction model. ");
109 72 : }
110 :
111 : void
112 30068 : BilinearMixedModeCohesiveZoneModel::computeQpProperties()
113 : {
114 30068 : WeightedVelocitiesUserObject::computeQpProperties();
115 :
116 : // Called after computeQpProperties() within the same algorithmic step.
117 :
118 : // Compute F and R.
119 30068 : const auto F = (ADRankTwoTensor::Identity() +
120 60136 : ADRankTwoTensor::initializeFromRows(
121 60136 : (*_grad_disp[0])[_qp], (*_grad_disp[1])[_qp], (*_grad_disp[2])[_qp]));
122 30068 : const auto F_neighbor = (ADRankTwoTensor::Identity() +
123 60136 : ADRankTwoTensor::initializeFromRows((*_grad_disp_neighbor[0])[_qp],
124 30068 : (*_grad_disp_neighbor[1])[_qp],
125 60136 : (*_grad_disp_neighbor[2])[_qp]));
126 :
127 : // TODO in follow-on PRs: Trim interior node variable derivatives
128 30068 : _F_interpolation = F * (_JxW_msm[_qp] * _coord[_qp]);
129 30068 : _F_neighbor_interpolation = F_neighbor * (_JxW_msm[_qp] * _coord[_qp]);
130 30068 : _normal_strength_interpolation = _normal_strength[_qp] * _JxW_msm[_qp] * _coord[_qp];
131 30068 : _shear_strength_interpolation = _shear_strength[_qp] * _JxW_msm[_qp] * _coord[_qp];
132 30068 : _GI_c_interpolation = _GI_c[_qp] * _JxW_msm[_qp] * _coord[_qp];
133 30068 : _GII_c_interpolation = _GII_c[_qp] * _JxW_msm[_qp] * _coord[_qp];
134 30068 : }
135 :
136 : void
137 60136 : BilinearMixedModeCohesiveZoneModel::computeQpIProperties()
138 : {
139 60136 : WeightedVelocitiesUserObject::computeQpIProperties();
140 :
141 : // Get the _dof_to_weighted_gap map
142 60136 : const auto * const dof = static_cast<const DofObject *>(_lower_secondary_elem->node_ptr(_i));
143 :
144 : // TODO: Probably better to interpolate the deformation gradients.
145 120272 : _dof_to_F[dof] += (*_test)[_i][_qp] * _F_interpolation;
146 120272 : _dof_to_F_neighbor[dof] += (*_test)[_i][_qp] * _F_neighbor_interpolation;
147 120272 : _dof_to_normal_strength[dof] += (*_test)[_i][_qp] * _normal_strength_interpolation;
148 120272 : _dof_to_shear_strength[dof] += (*_test)[_i][_qp] * _shear_strength_interpolation;
149 :
150 120272 : _dof_to_GI_c[dof] += (*_test)[_i][_qp] * _GI_c_interpolation;
151 120272 : _dof_to_GII_c[dof] += (*_test)[_i][_qp] * _GII_c_interpolation;
152 60136 : }
153 :
154 : template <class T>
155 : T
156 360816 : BilinearMixedModeCohesiveZoneModel::normalizeQuantity(
157 : const std::unordered_map<const DofObject *, T> & map, const Node * const node)
158 : {
159 360816 : return libmesh_map_find(map, node) / _dof_to_weighted_gap[node].second;
160 : }
161 :
162 : void
163 585 : BilinearMixedModeCohesiveZoneModel::timestepSetup()
164 : {
165 : // instead we call it explicitly here
166 585 : PenaltySimpleCohesiveZoneModel::timestepSetup();
167 :
168 : // save off tangential traction from the last timestep
169 1996 : for (auto & map_pr : _dof_to_damage)
170 : {
171 : auto & [damage, old_damage] = map_pr.second;
172 1411 : old_damage = {MetaPhysicL::raw_value(damage)};
173 1411 : damage = {0.0};
174 : }
175 :
176 585 : for (auto & [dof_object, delta_tangential_lm] : _dof_to_frictional_lagrange_multipliers)
177 : delta_tangential_lm.setZero();
178 585 : }
179 :
180 : void
181 7091 : BilinearMixedModeCohesiveZoneModel::initialize()
182 : {
183 : // instead we call it explicitly here
184 7091 : PenaltySimpleCohesiveZoneModel::initialize();
185 :
186 : // Avoid accumulating interpolation over the time step
187 : _dof_to_F.clear();
188 : _dof_to_F_neighbor.clear();
189 : _dof_to_mode_mixity_ratio.clear();
190 : _dof_to_normal_strength.clear();
191 : _dof_to_shear_strength.clear();
192 : _dof_to_GI_c.clear();
193 : _dof_to_GII_c.clear();
194 : _dof_to_delta_initial.clear();
195 : _dof_to_delta_final.clear();
196 : _dof_to_delta_max.clear();
197 : _dof_to_czm_traction.clear();
198 : _dof_to_interface_displacement_jump.clear();
199 7091 : _dof_to_czm_normal_traction.clear();
200 : _dof_to_interface_F.clear();
201 : _dof_to_interface_R.clear();
202 :
203 21572 : for (auto & map_pr : _dof_to_rotation_matrix)
204 14481 : map_pr.second.setToIdentity();
205 7091 : }
206 :
207 : void
208 15034 : BilinearMixedModeCohesiveZoneModel::prepareJumpKinematicQuantities()
209 : {
210 : // Compute rotation matrix from secondary surface
211 : // Rotation matrices and local interface displacement jump.
212 45102 : for (const auto i : make_range(_test->size()))
213 : {
214 30068 : const Node * const node = _lower_secondary_elem->node_ptr(i);
215 :
216 : // First call does not have maps available
217 30068 : const bool return_boolean = _dof_to_weighted_gap.find(node) == _dof_to_weighted_gap.end();
218 30068 : if (return_boolean)
219 0 : return;
220 :
221 60136 : _dof_to_rotation_matrix[node] = CohesiveZoneModelTools::computeReferenceRotation<true>(
222 30068 : _normals[i], _subproblem.mesh().dimension());
223 :
224 : // Every time we used quantities from a map we "denormalize" it from the mortar integral.
225 : // See normalizing member functions.
226 30068 : if (_dof_to_weighted_displacements.find(node) != _dof_to_weighted_displacements.end())
227 60136 : _dof_to_interface_displacement_jump[node] =
228 30068 : (libmesh_map_find(_dof_to_weighted_displacements, node));
229 : }
230 : }
231 :
232 : void
233 30068 : BilinearMixedModeCohesiveZoneModel::computeFandR(const Node * const node)
234 : {
235 : // First call does not have maps available
236 30068 : const bool return_boolean = _dof_to_F.find(node) == _dof_to_F.end();
237 30068 : if (return_boolean)
238 0 : return;
239 :
240 30068 : const auto normalized_F = normalizeQuantity(_dof_to_F, node);
241 30068 : const auto normalized_F_neighbor = normalizeQuantity(_dof_to_F_neighbor, node);
242 :
243 : // This 'averaging' assumption below can probably be improved upon.
244 90204 : _dof_to_interface_F[node] = 0.5 * (normalized_F + normalized_F_neighbor);
245 :
246 120272 : for (const auto i : make_range(3))
247 360816 : for (const auto j : make_range(3))
248 270612 : if (!std::isfinite(MetaPhysicL::raw_value(normalized_F(i, j))))
249 0 : throw MooseException(
250 : "The deformation gradient on the secondary surface is not finite in "
251 0 : "PenaltySimpleCohesiveZoneModel. MOOSE needs to cut the time step size.");
252 :
253 30068 : const auto dof_to_interface_F_node = libmesh_map_find(_dof_to_interface_F, node);
254 :
255 30068 : const ADFactorizedRankTwoTensor C = dof_to_interface_F_node.transpose() * dof_to_interface_F_node;
256 30068 : const auto Uinv = MathUtils::sqrt(C).inverse().get();
257 60136 : _dof_to_interface_R[node] = dof_to_interface_F_node * Uinv;
258 :
259 : // Transform interface jump according to two rotation matrices
260 30068 : const auto global_interface_displacement = _dof_to_interface_displacement_jump[node];
261 60136 : _dof_to_interface_displacement_jump[node] =
262 30068 : (_dof_to_interface_R[node] * _dof_to_rotation_matrix[node]).transpose() *
263 30068 : global_interface_displacement;
264 : }
265 :
266 : void
267 30068 : BilinearMixedModeCohesiveZoneModel::computeBilinearMixedModeTraction(const Node * const node)
268 : {
269 : // First call does not have maps available
270 30068 : const bool return_boolean = _dof_to_weighted_gap.find(node) == _dof_to_weighted_gap.end();
271 30068 : if (return_boolean)
272 0 : return;
273 :
274 30068 : computeModeMixity(node);
275 30068 : computeCriticalDisplacementJump(node);
276 30068 : computeFinalDisplacementJump(node);
277 30068 : computeEffectiveDisplacementJump(node);
278 30068 : computeDamage(node);
279 :
280 : // Split displacement jump into active and inactive parts
281 : const auto interface_displacement_jump =
282 30068 : normalizeQuantity(_dof_to_interface_displacement_jump, node);
283 :
284 30068 : const ADRealVectorValue delta_active(std::max(interface_displacement_jump(0), 0.0),
285 : interface_displacement_jump(1),
286 : interface_displacement_jump(2));
287 30068 : const ADRealVectorValue delta_inactive(std::min(interface_displacement_jump(0), 0.0), 0.0, 0.0);
288 :
289 : // This traction vector is local at this point.
290 60136 : _dof_to_czm_traction[node] =
291 90204 : -(1.0 - _dof_to_damage[node].first) * _penalty_stiffness_czm * delta_active -
292 60136 : _penalty_stiffness_czm * delta_inactive;
293 : }
294 :
295 : void
296 30068 : BilinearMixedModeCohesiveZoneModel::computeGlobalTraction(const Node * const node)
297 : {
298 : // First call does not have maps available
299 30068 : const bool return_boolean = _dof_to_czm_traction.find(node) == _dof_to_czm_traction.end();
300 30068 : if (return_boolean)
301 0 : return;
302 :
303 30068 : const auto local_traction_vector = libmesh_map_find(_dof_to_czm_traction, node);
304 30068 : const auto rotation_matrix = libmesh_map_find(_dof_to_rotation_matrix, node);
305 :
306 60136 : _dof_to_czm_traction[node] = rotation_matrix * local_traction_vector;
307 : }
308 :
309 : void
310 30068 : BilinearMixedModeCohesiveZoneModel::computeModeMixity(const Node * const node)
311 : {
312 : const auto interface_displacement_jump =
313 30068 : normalizeQuantity(_dof_to_interface_displacement_jump, node);
314 :
315 30068 : if (interface_displacement_jump(0) > _epsilon_tolerance)
316 : {
317 26596 : const auto delta_s = std::sqrt(interface_displacement_jump(1) * interface_displacement_jump(1) +
318 26596 : interface_displacement_jump(2) * interface_displacement_jump(2) +
319 26596 : _epsilon_tolerance);
320 :
321 26596 : _dof_to_mode_mixity_ratio[node] = delta_s / interface_displacement_jump(0);
322 : }
323 : else
324 3472 : _dof_to_mode_mixity_ratio[node] = 0;
325 30068 : }
326 :
327 : void
328 30068 : BilinearMixedModeCohesiveZoneModel::computeCriticalDisplacementJump(const Node * const node)
329 : {
330 : const auto interface_displacement_jump =
331 30068 : normalizeQuantity(_dof_to_interface_displacement_jump, node);
332 :
333 30068 : const auto mixity_ratio = libmesh_map_find(_dof_to_mode_mixity_ratio, node);
334 :
335 : const auto delta_normal_knot =
336 30068 : normalizeQuantity(_dof_to_normal_strength, node) / _penalty_stiffness_czm;
337 : const auto delta_shear_knot =
338 30068 : normalizeQuantity(_dof_to_shear_strength, node) / _penalty_stiffness_czm;
339 :
340 30068 : _dof_to_delta_initial[node] = delta_shear_knot;
341 :
342 30068 : if (interface_displacement_jump(0) > _epsilon_tolerance)
343 : {
344 26596 : const auto delta_mixed = std::sqrt(delta_shear_knot * delta_shear_knot +
345 26596 : Utility::pow<2>(mixity_ratio * delta_normal_knot));
346 :
347 53192 : _dof_to_delta_initial[node] = delta_normal_knot * delta_shear_knot *
348 79788 : std::sqrt(1.0 + mixity_ratio * mixity_ratio) / delta_mixed;
349 : }
350 30068 : }
351 :
352 : void
353 30068 : BilinearMixedModeCohesiveZoneModel::computeFinalDisplacementJump(const Node * const node)
354 : {
355 : const auto interface_displacement_jump =
356 30068 : normalizeQuantity(_dof_to_interface_displacement_jump, node);
357 :
358 30068 : const auto mixity_ratio = libmesh_map_find(_dof_to_mode_mixity_ratio, node);
359 :
360 30068 : const auto normalized_GI_c = normalizeQuantity(_dof_to_GI_c, node);
361 30068 : const auto normalized_GII_c = normalizeQuantity(_dof_to_GII_c, node);
362 :
363 60136 : _dof_to_delta_final[node] =
364 60136 : std::sqrt(2.0) * 2.0 * normalized_GII_c / normalizeQuantity(_dof_to_shear_strength, node);
365 :
366 30068 : if (interface_displacement_jump(0) > _epsilon_tolerance)
367 : {
368 26596 : if (_mix_mode_criterion == MixedModeCriterion::BK)
369 : {
370 18524 : _dof_to_delta_final[node] =
371 9262 : 2.0 / _penalty_stiffness_czm / libmesh_map_find(_dof_to_delta_initial, node) *
372 9262 : (normalized_GI_c +
373 9262 : (normalized_GII_c - normalized_GI_c) *
374 27786 : std::pow(mixity_ratio * mixity_ratio / (1 + mixity_ratio * mixity_ratio),
375 18524 : _power_law_parameter));
376 : }
377 17334 : else if (_mix_mode_criterion == MixedModeCriterion::POWER_LAW)
378 : {
379 : const auto Gc_mixed =
380 34668 : std::pow(1.0 / normalized_GI_c, _power_law_parameter) +
381 34668 : std::pow(mixity_ratio * mixity_ratio / normalized_GII_c, _power_law_parameter);
382 52002 : _dof_to_delta_final[node] = (2.0 + 2.0 * mixity_ratio * mixity_ratio) /
383 17334 : _penalty_stiffness_czm /
384 17334 : libmesh_map_find(_dof_to_delta_initial, node) *
385 34668 : std::pow(Gc_mixed, -1.0 / _power_law_parameter);
386 : }
387 : }
388 30068 : }
389 :
390 : void
391 30068 : BilinearMixedModeCohesiveZoneModel::computeEffectiveDisplacementJump(const Node * const node)
392 : {
393 : const auto interface_displacement_jump =
394 30068 : normalizeQuantity(_dof_to_interface_displacement_jump, node);
395 :
396 : const auto delta_normal_pos =
397 30068 : MathUtils::regularizedHeavyside(interface_displacement_jump(0), _regularization_alpha) *
398 : interface_displacement_jump(0);
399 :
400 60136 : _dof_to_delta_max[node] = std::sqrt(Utility::pow<2>(interface_displacement_jump(1)) +
401 30068 : Utility::pow<2>(interface_displacement_jump(2)) +
402 60136 : Utility::pow<2>(delta_normal_pos) + _epsilon_tolerance);
403 30068 : }
404 :
405 : void
406 30068 : BilinearMixedModeCohesiveZoneModel::computeDamage(const Node * const node)
407 : {
408 30068 : const auto delta_max = libmesh_map_find(_dof_to_delta_max, node);
409 30068 : const auto delta_initial = libmesh_map_find(_dof_to_delta_initial, node);
410 30068 : const auto delta_final = libmesh_map_find(_dof_to_delta_final, node);
411 :
412 30068 : if (delta_max < delta_initial)
413 30068 : _dof_to_damage[node].first = 0;
414 0 : else if (delta_max > delta_final)
415 0 : _dof_to_damage[node].first = 1.0;
416 : else
417 0 : _dof_to_damage[node].first =
418 0 : delta_final * (delta_max - delta_initial) / delta_max / (delta_final - delta_initial);
419 :
420 30068 : if (_dof_to_damage[node].first < _dof_to_damage[node].second)
421 : // Irreversibility
422 0 : _dof_to_damage[node].first = _dof_to_damage[node].second;
423 :
424 : // Viscous regularization
425 30068 : _dof_to_damage[node].first =
426 30068 : (_dof_to_damage[node].first + _viscosity * _dof_to_damage[node].second / _dt) /
427 60136 : (_viscosity / _dt + 1.0);
428 30068 : }
429 :
430 : void
431 15034 : BilinearMixedModeCohesiveZoneModel::reinit()
432 : {
433 : // Normal contact pressure with penalty
434 15034 : PenaltySimpleCohesiveZoneModel::reinit();
435 :
436 45102 : for (const auto i : index_range(_czm_interpolated_traction))
437 : {
438 30068 : _czm_interpolated_traction[i].resize(_qrule_msm->n_points());
439 :
440 90204 : for (const auto qp : make_range(_qrule_msm->n_points()))
441 60136 : _czm_interpolated_traction[i][qp] = 0.0;
442 : }
443 :
444 : // iterate over nodes
445 45102 : for (const auto i : make_range(_test->size()))
446 : {
447 : // current node
448 30068 : const Node * const node = _lower_secondary_elem->node_ptr(i);
449 :
450 : // End of CZM bilinear computations
451 30068 : if (_dof_to_czm_traction.find(node) == _dof_to_czm_traction.end())
452 : return;
453 :
454 30068 : const auto & test_i = (*_test)[i];
455 90204 : for (const auto qp : make_range(_qrule_msm->n_points()))
456 180408 : for (const auto idx : index_range(_czm_interpolated_traction))
457 240544 : _czm_interpolated_traction[idx][qp] += test_i[qp] * _dof_to_czm_traction[node](idx);
458 : }
459 : }
460 :
461 : void
462 7091 : BilinearMixedModeCohesiveZoneModel::finalize()
463 : {
464 7091 : PenaltySimpleCohesiveZoneModel::finalize();
465 :
466 7091 : const bool send_data_back = !constrainedByOwner();
467 :
468 14182 : Moose::Mortar::Contact::communicateR2T(
469 7091 : _dof_to_F, _subproblem.mesh(), _nodal, _communicator, send_data_back);
470 :
471 14182 : Moose::Mortar::Contact::communicateR2T(
472 7091 : _dof_to_F_neighbor, _subproblem.mesh(), _nodal, _communicator, send_data_back);
473 :
474 14182 : Moose::Mortar::Contact::communicateRealObject(
475 7091 : _dof_to_normal_strength, _subproblem.mesh(), _nodal, _communicator, send_data_back);
476 :
477 14182 : Moose::Mortar::Contact::communicateRealObject(
478 7091 : _dof_to_shear_strength, _subproblem.mesh(), _nodal, _communicator, send_data_back);
479 :
480 14182 : Moose::Mortar::Contact::communicateRealObject(
481 7091 : _dof_to_GI_c, _subproblem.mesh(), _nodal, _communicator, send_data_back);
482 :
483 14182 : Moose::Mortar::Contact::communicateRealObject(
484 7091 : _dof_to_GII_c, _subproblem.mesh(), _nodal, _communicator, send_data_back);
485 :
486 14182 : Moose::Mortar::Contact::communicateRealObject(
487 7091 : _dof_to_weighted_displacements, _subproblem.mesh(), _nodal, _communicator, send_data_back);
488 7091 : }
489 :
490 : const ADVariableValue &
491 240544 : BilinearMixedModeCohesiveZoneModel::czmGlobalTraction(const unsigned int i) const
492 : {
493 : mooseAssert(i <= 3,
494 : "Internal error in czmGlobalTraction. Index exceeds the traction vector size.");
495 :
496 240544 : return _czm_interpolated_traction[i];
497 : }
498 :
499 : Real
500 960 : BilinearMixedModeCohesiveZoneModel::getModeMixityRatio(const Node * const node) const
501 : {
502 960 : const auto it = _dof_to_mode_mixity_ratio.find(_subproblem.mesh().nodePtr(node->id()));
503 :
504 960 : if (it != _dof_to_mode_mixity_ratio.end())
505 960 : return MetaPhysicL::raw_value(it->second);
506 : else
507 : return 0.0;
508 : }
509 :
510 : Real
511 960 : BilinearMixedModeCohesiveZoneModel::getCohesiveDamage(const Node * const node) const
512 : {
513 960 : const auto it = _dof_to_damage.find(_subproblem.mesh().nodePtr(node->id()));
514 :
515 960 : if (it != _dof_to_damage.end())
516 960 : return MetaPhysicL::raw_value(it->second.first);
517 : else
518 : return 0.0;
519 : }
520 :
521 : Real
522 960 : BilinearMixedModeCohesiveZoneModel::getLocalDisplacementNormal(const Node * const node) const
523 : {
524 960 : const auto it = _dof_to_interface_displacement_jump.find(_subproblem.mesh().nodePtr(node->id()));
525 960 : const auto it2 = _dof_to_weighted_gap.find(_subproblem.mesh().nodePtr(node->id()));
526 :
527 960 : if (it != _dof_to_interface_displacement_jump.end() && it2 != _dof_to_weighted_gap.end())
528 1920 : return MetaPhysicL::raw_value(it->second(0) / it2->second.second);
529 : else
530 : return 0.0;
531 : }
532 :
533 : Real
534 960 : BilinearMixedModeCohesiveZoneModel::getLocalDisplacementTangential(const Node * const node) const
535 : {
536 960 : const auto it = _dof_to_interface_displacement_jump.find(_subproblem.mesh().nodePtr(node->id()));
537 960 : const auto it2 = _dof_to_weighted_gap.find(_subproblem.mesh().nodePtr(node->id()));
538 :
539 960 : if (it != _dof_to_interface_displacement_jump.end() && it2 != _dof_to_weighted_gap.end())
540 1920 : return MetaPhysicL::raw_value(it->second(1) / it2->second.second);
541 : else
542 : return 0.0;
543 : }
|