27 params.
addClassDescription(
"Computes the mortar normal contact force via a penalty approach.");
32 "penalty_multiplier > 0",
33 "The penalty growth factor between augmented Lagrange "
34 "iterations if weighted gap does not get closed fast enough. For frictional simulations, "
35 "values smaller than 100 are recommended, e.g. 5.");
39 "Whether to compute the normal pressure as (penalty / A) * (physical gap) instead of penalty "
40 "* (weighted gap), where A is the lower-dimensional area assigned to the node on the "
41 "contacting boundary. This parameter is defaulted to 'true' in the contact action.");
43 "penetration_tolerance",
44 "penetration_tolerance > 0",
45 "Acceptable penetration distance at which augmented Lagrange iterations can be stopped");
47 "max_penalty_multiplier",
49 "max_penalty_multiplier >= 1.0",
50 "Maximum multiplier applied to penalty factors when adaptivity is used in an augmented "
51 "Lagrange setting. The penalty factor supplied by the user is used as a reference.");
52 MooseEnum adaptivity_penalty_normal(
"SIMPLE BUSSETTA",
"SIMPLE");
53 adaptivity_penalty_normal.addDocumentation(
54 "SIMPLE",
"Keep multiplying by the penalty multiplier between AL iterations");
55 adaptivity_penalty_normal.addDocumentation(
57 "Modify the penalty using an algorithm from Bussetta et al, 2012, Comput Mech 49:259-275 "
58 "between AL iterations.");
60 "adaptivity_penalty_normal",
61 adaptivity_penalty_normal,
62 "The augmented Lagrange update strategy used on the normal penalty coefficient.");
65 "Auxiliary variable that is utilized together with the "
66 "penalty approach to interpolate the resulting contact tractions using dual bases.");
68 "Augmented Lagrange");
76 _penalty(getParam<Real>(
"penalty")),
77 _penalty_multiplier(getParam<Real>(
"penalty_multiplier")),
78 _penetration_tolerance(
79 isParamValid(
"penetration_tolerance") ? getParam<Real>(
"penetration_tolerance") : 0.0),
80 _augmented_lagrange_problem(
82 _lagrangian_iteration_number(_augmented_lagrange_problem
83 ? _augmented_lagrange_problem->getLagrangianIterationNumber()
85 _dof_to_lagrange_multiplier(declareRestartableData<
std::unordered_map<dof_id_type, Real>>(
86 "dof_to_lagrange_multiplier")),
87 _t_step_old_normal(declareRestartableData<
int>(
"t_step_old_normal", 0)),
88 _dt(_fe_problem.dt()),
89 _use_physical_gap(getParam<bool>(
"use_physical_gap")),
90 _aux_lm_var(isCoupled(
"aux_lm") ? getVar(
"aux_lm", 0) : nullptr),
91 _max_penalty_multiplier(getParam<Real>(
"max_penalty_multiplier")),
95 auto check_type = [
this](
const auto & var,
const auto & var_name)
99 "The displacement variables must have degrees of freedom exclusively on "
100 "nodes, e.g. they should probably be of finite element type 'Lagrange'.");
109 "This parameter must be supplied if and only if an augmented Lagrange problem "
116 if (getParam<bool>(
"ghost_point_neighbors"))
120 getParam<bool>(
"use_displaced_mesh"))
167 const auto lagrange_multiplier =
171 auto normal_pressure = min(0.0,
penaltyPressure(wgap, penalty) + lagrange_multiplier);
214 for (
const auto i : make_range(
_test->size()))
242 if (retried_timestep)
268 using std::max, std::min, std::abs;
270 Real max_positive_gap = 0.0;
271 Real min_negative_gap = 0.0;
281 max_positive_gap = max(max_positive_gap, gap);
282 min_negative_gap = min(min_negative_gap, gap);
292 const Real reported_gap =
293 -min_negative_gap > max_positive_gap ? min_negative_gap : max_positive_gap;
300 "). Iteration number is: ",
310 "). Iteration number is: ",
340 const auto gap =
getNormalGap(
static_cast<const Node *
>(dof_object));
349 if (lagrange_multiplier + penalty_pressure <= 0)
350 lagrange_multiplier += penalty_pressure;
352 lagrange_multiplier = 0.0;
380 if (previous_gap > 0.0)
387 if (previous_gap * gap < 0)
390 eval_tn = penalty * previous_gap;
401 using std::abs, std::max, std::sqrt;
403 const bool condition_one = abs(abs(previous_gap / gap) - 1.0) < 0.01;
404 const bool condition_two = abs(gap) > 1.01 * abs(previous_gap);
406 if (previous_gap * gap < 0)
410 (gap - previous_gap));
412 penalty = abs(penalty * previous_gap / 10.0 / gap);
416 if (abs(gap - previous_gap) >
421 else if (condition_two)
422 penalty *= 10.0 * previous_gap / gap;
DualNumber< Real, DNDerivativeType, true > ADReal
void mooseInfoRepeated(Args &&... args)
registerMooseObject("ContactApp", PenaltyWeightedGapUserObject)
void ErrorVector unsigned int
Interface class for user objects that support the augmented Lagrange formalism as implemented in Augm...
void requestNonlocalSecondaryCouplings()
const AutomaticMortarGeneration & getMortarInterface(const std::pair< BoundaryID, BoundaryID > &primary_secondary_boundary_pair, const std::pair< SubdomainID, SubdomainID > &primary_secondary_subdomain_pair, bool on_displaced) const
virtual int & timeStep() const
void paramError(const std::string ¶m, Args... args) const
bool isParamValid(const std::string &name) const
virtual const Node * nodePtr(const dof_id_type i) const
virtual const FieldVariablePhiValue & phiLower() const override
Elem const *const & _lower_secondary_elem
const libMesh::QBase *const & _qrule_msm
const BoundaryID _primary_id
const SubdomainID _secondary_subdomain_id
const BoundaryID _secondary_id
const SubdomainID _primary_subdomain_id
User object for computing weighted gaps and contact pressure for penalty based mortar constraints.
const Real _penalty
The penalty factor.
std::unordered_map< const DofObject *, Real > _dof_to_previous_gap
Map from degree of freedom to previous AL iteration gap values.
const unsigned int & _lagrangian_iteration_number
void adaptiveNormalPenalty(const Real previous_gap, const Real gap, Real &penalty)
See Algorithm 3 of 'The adapted augmented Lagrangian method: a new method for the resolution of the m...
virtual bool isAugmentedLagrangianConverged() override
PenaltyWeightedGapUserObject(const InputParameters ¶meters)
virtual ADReal nodalContactPressure(const Node &node) const override
virtual void reinit() override
const Real _penalty_multiplier
penalty growth factor for augmented Lagrange
std::unordered_map< const DofObject *, Real > _dof_to_local_penalty
Map from degree of freedom to local penalty value.
enum PenaltyWeightedGapUserObject::AdaptivityNormalPenalty _adaptivity_normal
virtual const VariableTestValue & tractionBasis() const override
virtual Real getNormalContactPressure(const Node *const node) const override
virtual void initialize() override
Real _dt_old
previous timestep size
virtual void augmentedLagrangianSetup() override
std::unordered_map< dof_id_type, Real > _dof_to_lagrange_multiplier_start
Augmented lagrange multipliers at the start of the current timestep, restored when the timestep is re...
const Real _penetration_tolerance
penetration tolerance for augmented Lagrange contact
AugmentedLagrangianContactProblemInterface *const _augmented_lagrange_problem
augmented Lagrange problem and iteration number
std::unordered_map< dof_id_type, Real > & _dof_to_lagrange_multiplier
Map from node id to augmented lagrange multiplier.
virtual const VariableTestValue & test() const override
ADVariableValue _contact_pressure
The contact pressure on the mortar segument quadrature points.
const MooseVariable *const _aux_lm_var
The auxiliary Lagrange multiplier variable (used together whith the Petrov-Galerkin approach)
const Real & _dt
Current delta t... or timestep size.
virtual void finalize() override
std::unordered_map< const DofObject *, ADReal > _dof_to_normal_pressure
Map from degree of freedom to normal pressure for reporting.
virtual void updateAugmentedLagrangianMultipliers() override
static const unsigned int _no_iterations
virtual const ADVariableValue & contactPressure() const override
int & _t_step_old_normal
The timestep index at which _dof_to_lagrange_multiplier_start was last saved.
AdaptivityNormalPenalty
The adaptivity method for the penalty factor at augmentations.
const Real _max_penalty_multiplier
Maximum multiplier applied to the initial penalty factor in AL.
static InputParameters validParams()
virtual Real getNormalLagrangeMultiplier(const Node *const node) const
ADReal penaltyPressure(const std::pair< ADReal, Real > &wgap, const Real penalty) const
Penalty normal pressure at a node, before the augmented Lagrange multiplier is added.
virtual void timestepSetup() override
void bussettaAdaptivePenalty(const Real previous_gap, const Real gap, Real &penalty, Real &eval_tn)
Adaptive, local penalty for AL.
virtual MooseMesh & mesh()=0
void max(const T &r, T &o, Request &req) const
void min(const T &r, T &o, Request &req) const
Creates dof object to weighted gap map.
static InputParameters validParams()
V findValue(const std::unordered_map< K, V > &map, const K &key, const V &default_value=0) const
Find a value in a map or return a default if the key doesn't exist.
const MooseVariable *const _disp_x_var
The x displacement variable.
const bool _has_disp_z
For 2D mortar contact no displacement will be specified, so const pointers used.
virtual void finalize() override
virtual Real getNormalGap(const Node *const) const
FEProblemBase & _fe_problem
The base finite element problem.
static void addNodalNormalCoupling(InputParameters ¶ms)
Request the secondary face point-neighbor matrix coupling that nodal-normal derivatives need.
const MooseVariable *const _disp_y_var
The y displacement variable.
std::unordered_map< const DofObject *, std::pair< ADReal, Real > > _dof_to_weighted_gap
A map from node to weighted gap and normalization (if requested)
const MooseVariable *const _disp_z_var
The z displacement variable.
virtual void initialize() override
Real physicalGap(const std::pair< ADReal, Real > &gap) const
Compute physical gap from integration gap quantity.
const VariableTestValue * _test
A pointer to the test function associated with the weighted gap.
const Parallel::Communicator & _communicator
unsigned int n_points() const
VariableShapeValue< true > VariableTestValue
VariableValueTempl< true > ADVariableValue