| Base 4fcf7b | Head #33358 34476d | ||||
|---|---|---|---|---|---|
| Total | Total | +/- | New | ||
| Rate | 91.27% | 91.38% | +0.12% | 100.00% | |
| Hits | 5005 | 5081 | +76 | 129 | |
| Misses | 479 | 479 | - | 0 | |
| Filename | Stmts | Miss | Cover |
|---|---|---|---|
| modules/contact/include/userobjects/WeightedVelocitiesUserObject.h | +1 | 0 | +100.00% |
| modules/contact/include/utils/ContactFrictionUtils.h | +11 | +1 | +90.91% |
| modules/contact/src/actions/ContactAction.C | +23 | 0 | +0.13% |
| modules/contact/src/constraints/ComputeDynamicFrictionalForceLMMechanicalContact.C | +22 | -1 | +1.32% |
| modules/contact/src/constraints/ComputeFrictionalForceLMMechanicalContact.C | +19 | 0 | +1.07% |
| TOTAL | +76 | 0 | +0.12% |
codecodecode+
117 118 119 120 + 121 122 |
inline const std::unordered_map<const DofObject *, std::array<ADReal, 2>> & WeightedVelocitiesUserObject::dofToRealVelocities() const { return _dof_to_real_tangential_velocity; } |
22 23 24 25 + 26 27 28 + 29 30 + 31 + 32 + 33 34 35 + 36 + 37 38 39 40 + 41 42 43 |
namespace Contact { CreateMooseEnumClass(FrictionCoefficientRegularization, NONE, ARCTAN_SLIP); inline MooseEnum frictionCoefficientRegularizationOptions() { MooseEnum options(getFrictionCoefficientRegularizationOptions(), "NONE"); options.addDocumentation("NONE", "Use the supplied Coulomb friction coefficient."); options.addDocumentation( "ARCTAN_SLIP", "Scale the Coulomb friction coefficient by an arctangent function of the slip increment."); return options; } template <typename TMu, typename TSlip> auto regularizedFrictionCoefficient(const TMu & mu, const TSlip & slip_increment, const FrictionCoefficientRegularization regularization, const Real reference_slip) -> decltype(mu + mu * slip_increment) |
45 46 47 48 + 49 + 50 51 52 53 54 + 55 56 57 |
using std::atan; using Result = decltype(mu + mu * slip_increment); if (regularization == FrictionCoefficientRegularization::NONE) return Result(mu); mooseAssert(reference_slip > 0.0, "Friction coefficient regularization requires a positive reference slip"); return mu * (2.0 / libMesh::pi) * atan(slip_increment / reference_slip); } } // namespace Contact |
141 142 143 144 + 145 + 146 147 + 148 149 + 150 151 152 + 153 154 + 155 156 157 |
"iterations for penalizing relative slip distance if the node is under stick conditions.(a " "value larger than one, e.g., 10, tends to speed up convergence.)"); params.addParam<Real>("friction_coefficient", 0, "The friction coefficient"); params.addParam<MooseEnum>("friction_coefficient_regularization", Moose::Contact::frictionCoefficientRegularizationOptions(), "The regularization applied to the Coulomb friction coefficient."); params.addRangeCheckedParam<Real>( "friction_reference_slip", 0.0, "friction_reference_slip >= 0", "Reference slip increment used by friction coefficient regularization."); params.addRangeCheckedParam<Real>( "friction_elastic_slip", 0.0, "friction_elastic_slip >= 0", "Tangential elastic slip distance over which the Coulomb friction bound is reached."); params.addParam<Real>("tension_release", |
343 344 345 346 + 347 348 349 |
"adaptivity_penalty_normal adaptivity_penalty_friction", "Augmented Lagrange"); // Friction params.addParamNamesToGroup( "friction_coefficient friction_coefficient_regularization friction_reference_slip " "friction_elastic_slip tension_release", "Friction"); |
422 423 424 425 + 426 427 428 + 429 + 430 + 431 432 + 433 + 434 435 436 + 437 + 438 + 439 440 441 442 + 443 + 444 + 445 + 446 447 448 |
"The 'tangential_penalty' formulation can only be used with the 'coulomb' model"); const auto friction_coefficient_regularization = getParam<MooseEnum>("friction_coefficient_regularization") .getEnum<Moose::Contact::FrictionCoefficientRegularization>(); const bool has_friction_regularization = params.isParamSetByUser("friction_elastic_slip") || params.isParamSetByUser("friction_coefficient_regularization") || params.isParamSetByUser("friction_reference_slip"); if (_model != ContactModel::COULOMB && has_friction_regularization) paramError("model", "The friction regularization options can only be used with the 'coulomb' model."); if (_model == ContactModel::COULOMB && has_friction_regularization && !supportsFrictionRegularization(_formulation)) paramError("formulation", "The friction regularization options are only supported with the 'mortar' " "formulation."); if (friction_coefficient_regularization != Moose::Contact::FrictionCoefficientRegularization::NONE && getParam<Real>("friction_reference_slip") <= 0.0) paramError("friction_reference_slip", "A positive friction_reference_slip is required when " "friction_coefficient_regularization is not NONE."); |
1318 1319 1320 1321 + 1322 + 1323 + 1324 + 1325 1326 1327 |
tangential_lagrange_multiplier_3d_name}; params.set<Real>("mu") = getParam<Real>("friction_coefficient"); params.set<MooseEnum>("friction_coefficient_regularization") = getParam<MooseEnum>("friction_coefficient_regularization"); params.set<Real>("friction_reference_slip") = getParam<Real>("friction_reference_slip"); params.set<Real>("friction_elastic_slip") = getParam<Real>("friction_elastic_slip"); params.applySpecificParameters(parameters(), {"triangulation", "triangulate_triangles", |
43 44 45 46 + 47 48 49 50 51 + 52 53 + 54 + 55 56 + 57 58 + 59 60 61 + 62 63 + 64 65 66 |
"Coupled function to evaluate friction with values from contact pressure and relative " "tangential velocities (from the previous step)."); params.addParam<Real>("c_t", 1e0, "Numerical parameter for tangential constraints"); params.addRangeCheckedParam<Real>( "epsilon", 1.0e-7, "epsilon > 0", "Minimum value of contact pressure that will trigger frictional enforcement"); params.addRangeCheckedParam<Real>( "mu", "mu >= 0", "The friction coefficient for the Coulomb friction law"); params.addParam<MooseEnum>("friction_coefficient_regularization", Moose::Contact::frictionCoefficientRegularizationOptions(), "The regularization applied to the Coulomb friction coefficient."); params.addRangeCheckedParam<Real>( "friction_reference_slip", 0.0, "friction_reference_slip >= 0", "Reference slip increment used by friction coefficient regularization."); params.addRangeCheckedParam<Real>( "friction_elastic_slip", 0.0, "friction_elastic_slip >= 0", "Tangential elastic slip distance over which the Coulomb friction bound is reached."); return params; |
78 79 80 81 + 82 + 83 84 + 85 + 86 87 88 89 90 91 92 + 93 94 95 |
_primary_z_dot(_has_disp_z ? &adCoupledNeighborValueDot("disp_z") : nullptr), _epsilon(getParam<Real>("epsilon")), _mu(isParamValid("mu") ? getParam<Real>("mu") : std::numeric_limits<double>::quiet_NaN()), _friction_coefficient_regularization( getParam<MooseEnum>("friction_coefficient_regularization") .getEnum<Moose::Contact::FrictionCoefficientRegularization>()), _friction_reference_slip(getParam<Real>("friction_reference_slip")), _friction_elastic_slip(getParam<Real>("friction_elastic_slip")), _function_friction(isParamValid("function_friction") ? &getFunction("function_friction") : nullptr), _has_friction_function(isParamValid("function_friction")), _3d(_has_disp_z) { if (!_has_friction_function && !isParamValid("mu")) paramError("mu", "A coefficient of friction needs to be provided as a constant value or via a " "function."); |
108 109 110 111 + 112 + 113 + 114 + 115 116 117 |
"Three-dimensional mortar frictional contact simulations require an additional " "frictional Lagrange's multiplier to enforce a second tangential pressure"); if (_friction_coefficient_regularization != Moose::Contact::FrictionCoefficientRegularization::NONE && _friction_reference_slip <= 0.0) paramError("friction_reference_slip", "A positive friction_reference_slip is required when " "friction_coefficient_regularization is not NONE."); |
160 161 162 163 + 164 165 166 |
_test[_i][_qp] * _qp_tangential_velocity_nodal * nodal_tangents[0][_i]; _dof_to_real_tangential_velocity[dof][0] += _test[_i][_qp] * _qp_real_tangential_velocity_nodal * nodal_tangents[0][_i]; // Get the _dof_to_weighted_tangential_velocity map for a second direction if (_3d) |
169 170 171 172 + 173 174 175 |
_test[_i][_qp] * _qp_tangential_velocity_nodal * nodal_tangents[1][_i]; _dof_to_real_tangential_velocity[dof][1] += _test[_i][_qp] * _qp_real_tangential_velocity_nodal * nodal_tangents[1][_i]; } } |
190 191 192 193 + 194 195 196 + 197 198 199 |
_dof_to_old_real_tangential_velocity.clear(); for (const auto & [dof, real_tangential_velocity] : _dof_to_real_tangential_velocity) _dof_to_old_real_tangential_velocity.emplace( dof, std::array<Real, 2>{{MetaPhysicL::raw_value(real_tangential_velocity[0]), MetaPhysicL::raw_value(real_tangential_velocity[1])}}); } |
205 206 207 208 + 209 + 210 211 212 |
Moose::Mortar::Contact::communicateVelocities( _dof_to_weighted_tangential_velocity, _mesh, _nodal, _communicator, false); Moose::Mortar::Contact::communicateVelocities( _dof_to_real_tangential_velocity, _mesh, _nodal, _communicator, false); // Enforce frictional complementarity constraints for (const auto & pr : _dof_to_weighted_tangential_velocity) |
243 244 245 246 + 247 + 248 249 250 |
Moose::Mortar::Contact::communicateVelocities( _dof_to_weighted_tangential_velocity, _mesh, _nodal, _communicator, false); Moose::Mortar::Contact::communicateVelocities( _dof_to_real_tangential_velocity, _mesh, _nodal, _communicator, false); // Enforce frictional complementarity constraints for (const auto & pr : _dof_to_weighted_tangential_velocity) |
304 305 306 307 + 308 309 310 311 + 312 313 314 + 315 316 317 + 318 + 319 + 320 321 322 323 + 324 325 326 |
// Compute the friction coefficient (constant or function) const auto & current_real_tangential_velocity = libmesh_map_find(_dof_to_real_tangential_velocity, dof); const auto old_real_tangential_velocity_it = _dof_to_old_real_tangential_velocity.find(dof); const std::array<Real, 2> current_function_real_tangential_velocity{ {MetaPhysicL::raw_value(current_real_tangential_velocity[0]), MetaPhysicL::raw_value(current_real_tangential_velocity[1])}}; const auto & function_real_tangential_velocity = old_real_tangential_velocity_it != _dof_to_old_real_tangential_velocity.end() ? old_real_tangential_velocity_it->second : current_function_real_tangential_velocity; const ADReal slip_increment = sqrt(current_real_tangential_velocity[0] * current_real_tangential_velocity[0] + current_real_tangential_velocity[1] * current_real_tangential_velocity[1] + 1.0e-24) * _dt; ADReal mu_ad = computeFrictionValue(contact_pressure_old, function_real_tangential_velocity[0], function_real_tangential_velocity[1], slip_increment); ADReal dof_residual; ADReal dof_residual_dir; |
336 337 338 339 + 340 341 342 + 343 344 345 346 + 347 + 348 349 + 350 + 351 352 353 + 354 + 355 356 + 357 358 + 359 360 361 |
const Real epsilon_sqrt = 1.0e-48; const auto lamdba_plus_cg = contact_pressure + c * weighted_gap; const auto normal_bound = max(0.0, lamdba_plus_cg); const auto friction_bound = mu_ad * normal_bound; const auto tangential_compliance = _friction_elastic_slip > 0.0 ? _friction_elastic_slip / (friction_bound + _epsilon) : 0.0; std::array<ADReal, 2> lambda_t_plus_ctu; lambda_t_plus_ctu[0] = friction_lm_values[0] + c_t * (*tangential_vel[0] * _dt - tangential_compliance * friction_lm_values[0]); lambda_t_plus_ctu[1] = friction_lm_values[1] + c_t * (*tangential_vel[1] * _dt - tangential_compliance * friction_lm_values[1]); const auto tangential_trial_norm = sqrt(lambda_t_plus_ctu[0] * lambda_t_plus_ctu[0] + lambda_t_plus_ctu[1] * lambda_t_plus_ctu[1] + epsilon_sqrt); const auto term_1_x = max(friction_bound, tangential_trial_norm) * friction_lm_values[0]; const auto term_1_y = max(friction_bound, tangential_trial_norm) * friction_lm_values[1]; const auto term_2_x = friction_bound * lambda_t_plus_ctu[0]; |
401 402 403 404 + 405 406 407 408 + 409 410 411 + 412 413 414 + 415 + 416 417 + 418 419 420 |
// Compute the friction coefficient (constant or function) const auto & current_real_tangential_velocity = libmesh_map_find(_dof_to_real_tangential_velocity, dof); const auto old_real_tangential_velocity_it = _dof_to_old_real_tangential_velocity.find(dof); const std::array<Real, 2> current_function_real_tangential_velocity{ {MetaPhysicL::raw_value(current_real_tangential_velocity[0]), MetaPhysicL::raw_value(current_real_tangential_velocity[1])}}; const auto & function_real_tangential_velocity = old_real_tangential_velocity_it != _dof_to_old_real_tangential_velocity.end() ? old_real_tangential_velocity_it->second : current_function_real_tangential_velocity; const ADReal slip_increment = sqrt(current_real_tangential_velocity[0] * current_real_tangential_velocity[0] + 1.0e-24) * _dt; ADReal mu_ad = computeFrictionValue( contact_pressure_old, function_real_tangential_velocity[0], 0.0, slip_increment); ADReal dof_residual; // Primal-dual active set strategy (PDASS) |
422 423 424 425 + 426 + 427 428 429 + 430 431 432 + 433 434 + 435 436 437 |
dof_residual = friction_lm_value; else { const auto lambda_plus_cg = contact_pressure + c * weighted_gap; const auto normal_bound = max(0.0, lambda_plus_cg); const auto friction_bound = mu_ad * normal_bound; const auto tangential_compliance = _friction_elastic_slip > 0.0 ? _friction_elastic_slip / (friction_bound + _epsilon) : 0.0; const auto lambda_t_plus_ctu = friction_lm_value + c_t * (tangential_vel * _dt - tangential_compliance * friction_lm_value); const auto term_1 = max(friction_bound, abs(lambda_t_plus_ctu)) * friction_lm_value; const auto term_2 = friction_bound * lambda_t_plus_ctu; dof_residual = term_1 - term_2; |
460 461 462 463 + 464 + 465 466 467 468 469 470 + 471 472 |
else { ADReal tangential_vel_magnitude = sqrt(function_tangential_vel * function_tangential_vel + function_tangential_vel_dir * function_tangential_vel_dir + 1.0e-24); mu_ad = _function_friction->value<ADReal>(0.0, contact_pressure, tangential_vel_magnitude, 0.0); } return Moose::Contact::regularizedFrictionCoefficient( mu_ad, slip_increment, _friction_coefficient_regularization, _friction_reference_slip); } |
42 43 44 45 + 46 47 48 49 50 51 52 + 53 + 54 55 + 56 57 + 58 59 60 + 61 62 + 63 64 65 |
"Coupled function to evaluate friction with values from contact pressure and relative " "tangential velocities"); params.addParam<Real>("c_t", 1e0, "Numerical parameter for tangential constraints"); params.addRangeCheckedParam<Real>( "epsilon", 1.0e-7, "epsilon > 0", "Minimum value of contact pressure that will trigger frictional enforcement"); params.addRangeCheckedParam<Real>( "mu", "mu >= 0", "The friction coefficient for the Coulomb friction law"); params.addParam<MooseEnum>("friction_coefficient_regularization", Moose::Contact::frictionCoefficientRegularizationOptions(), "The regularization applied to the Coulomb friction coefficient."); params.addRangeCheckedParam<Real>( "friction_reference_slip", 0.0, "friction_reference_slip >= 0", "Reference slip increment used by friction coefficient regularization."); params.addRangeCheckedParam<Real>( "friction_elastic_slip", 0.0, "friction_elastic_slip >= 0", "Tangential elastic slip distance over which the Coulomb friction bound is reached."); params.addRequiredParam<UserObjectName>("weighted_velocities_uo", |
82 83 84 85 + 86 + 87 88 + 89 + 90 91 92 |
_epsilon(getParam<Real>("epsilon")), _mu(isParamValid("function_friction") ? std::numeric_limits<double>::quiet_NaN() : getParam<Real>("mu")), _friction_coefficient_regularization( getParam<MooseEnum>("friction_coefficient_regularization") .getEnum<Moose::Contact::FrictionCoefficientRegularization>()), _friction_reference_slip(getParam<Real>("friction_reference_slip")), _friction_elastic_slip(getParam<Real>("friction_elastic_slip")), _function_friction(isParamValid("function_friction") ? &getFunction("function_friction") : nullptr), _has_friction_function(isParamValid("function_friction")), |
110 111 112 113 + 114 + 115 + 116 + 117 118 119 |
"Three-dimensional mortar frictional contact simulations require an additional " "frictional Lagrange's multiplier to enforce a second tangential pressure"); if (_friction_coefficient_regularization != Moose::Contact::FrictionCoefficientRegularization::NONE && _friction_reference_slip <= 0.0) paramError("friction_reference_slip", "A positive friction_reference_slip is required when " "friction_coefficient_regularization is not NONE."); |
238 239 240 241 + 242 243 + 244 245 246 |
// Compute the friction coefficient (constant or function) const auto & real_tangential_velocity = libmesh_map_find(_weighted_velocities_uo.dofToRealVelocities(), dof); ADReal mu_ad = computeFrictionValue( contact_pressure, real_tangential_velocity[0], real_tangential_velocity[1]); ADReal dof_residual; ADReal dof_residual_dir; |
257 258 259 260 + 261 262 263 + 264 265 266 267 + 268 + 269 270 + 271 + 272 273 274 + 275 + 276 277 + 278 279 + 280 281 282 |
const Real epsilon_sqrt = 1.0e-48; const auto lamdba_plus_cg = contact_pressure + c * weighted_gap; const auto normal_bound = max(0.0, lamdba_plus_cg); const auto friction_bound = mu_ad * normal_bound; const auto tangential_compliance = _friction_elastic_slip > 0.0 ? _friction_elastic_slip / (friction_bound + _epsilon) : 0.0; std::array<ADReal, 2> lambda_t_plus_ctu; lambda_t_plus_ctu[0] = friction_lm_values[0] + c_t * (*tangential_vel[0] * _dt - tangential_compliance * friction_lm_values[0]); lambda_t_plus_ctu[1] = friction_lm_values[1] + c_t * (*tangential_vel[1] * _dt - tangential_compliance * friction_lm_values[1]); const auto tangential_trial_norm = sqrt(lambda_t_plus_ctu[0] * lambda_t_plus_ctu[0] + lambda_t_plus_ctu[1] * lambda_t_plus_ctu[1] + epsilon_sqrt); const auto term_1_x = max(friction_bound, tangential_trial_norm) * friction_lm_values[0]; const auto term_1_y = max(friction_bound, tangential_trial_norm) * friction_lm_values[1]; const auto term_2_x = friction_bound * lambda_t_plus_ctu[0]; |
321 322 323 324 + 325 + 326 327 328 |
// Compute the friction coefficient (constant or function) const auto & real_tangential_velocity = libmesh_map_find(_weighted_velocities_uo.dofToRealVelocities(), dof); ADReal mu_ad = computeFrictionValue(contact_pressure, real_tangential_velocity[0], 0.0); ADReal dof_residual; // Primal-dual active set strategy (PDASS) |
330 331 332 333 + 334 + 335 336 337 + 338 339 340 + 341 342 + 343 344 345 |
dof_residual = friction_lm_value; else { const auto lambda_plus_cg = contact_pressure + c * weighted_gap; const auto normal_bound = max(0.0, lambda_plus_cg); const auto friction_bound = mu_ad * normal_bound; const auto tangential_compliance = _friction_elastic_slip > 0.0 ? _friction_elastic_slip / (friction_bound + _epsilon) : 0.0; const auto lambda_t_plus_ctu = friction_lm_value + c_t * (tangential_vel * _dt - tangential_compliance * friction_lm_value); const auto term_1 = max(friction_bound, abs(lambda_t_plus_ctu)) * friction_lm_value; const auto term_2 = friction_bound * lambda_t_plus_ctu; dof_residual = term_1 - term_2; |
371 372 373 374 + 375 + 376 377 + 378 379 |
} const auto slip_increment = sqrt(tangential_vel * tangential_vel + tangential_vel_dir * tangential_vel_dir + 1.0e-24) * _dt; return Moose::Contact::regularizedFrictionCoefficient( mu_ad, slip_increment, _friction_coefficient_regularization, _friction_reference_slip); } |