23 params.
addClassDescription(
"Computes the mortar normal contact force via a penalty approach.");
28 "penalty_multiplier > 0",
29 "The penalty growth factor between augmented Lagrange "
30 "iterations if weighted gap does not get closed fast enough. For frictional simulations, "
31 "values smaller than 100 are recommended, e.g. 5.");
35 "Whether to use the physical normal gap (not scaled by mortar integration) and normalize the "
36 "penalty coefficient with a representative lower-dimensional volume assigned to the node in "
37 "the contacting boundary. This parameter is defaulted to 'true' in the contact action.");
39 "penetration_tolerance",
40 "penetration_tolerance > 0",
41 "Acceptable penetration distance at which augmented Lagrange iterations can be stopped");
43 "max_penalty_multiplier",
45 "max_penalty_multiplier >= 1.0",
46 "Maximum multiplier applied to penalty factors when adaptivity is used in an augmented "
47 "Lagrange setting. The penalty factor supplied by the user is used as a reference.");
48 MooseEnum adaptivity_penalty_normal(
"SIMPLE BUSSETTA",
"SIMPLE");
49 adaptivity_penalty_normal.addDocumentation(
50 "SIMPLE",
"Keep multiplying by the penalty multiplier between AL iterations");
51 adaptivity_penalty_normal.addDocumentation(
53 "Modify the penalty using an algorithm from Bussetta et al, 2012, Comput Mech 49:259-275 "
54 "between AL iterations.");
56 "adaptivity_penalty_normal",
57 adaptivity_penalty_normal,
58 "The augmented Lagrange update strategy used on the normal penalty coefficient.");
61 "Auxiliary variable that is utilized together with the "
62 "penalty approach to interpolate the resulting contact tractions using dual bases.");
64 "Augmented Lagrange");
72 _penalty(getParam<Real>(
"penalty")),
73 _penalty_multiplier(getParam<Real>(
"penalty_multiplier")),
74 _penetration_tolerance(
75 isParamValid(
"penetration_tolerance") ? getParam<Real>(
"penetration_tolerance") : 0.0),
76 _augmented_lagrange_problem(
78 _lagrangian_iteration_number(_augmented_lagrange_problem
79 ? _augmented_lagrange_problem->getLagrangianIterationNumber()
81 _dt(_fe_problem.dt()),
82 _use_physical_gap(getParam<bool>(
"use_physical_gap")),
83 _aux_lm_var(isCoupled(
"aux_lm") ? getVar(
"aux_lm", 0) : nullptr),
84 _max_penalty_multiplier(getParam<Real>(
"max_penalty_multiplier")),
88 auto check_type = [
this](
const auto & var,
const auto & var_name)
92 "The displacement variables must have degrees of freedom exclusively on "
93 "nodes, e.g. they should probably be of finite element type 'Lagrange'.");
102 "This parameter must be supplied if and only if an augmented Lagrange problem "
145 const auto lagrange_multiplier =
149 auto normal_pressure = min(0.0, penalty * gap + lagrange_multiplier);
192 for (
const auto i : make_range(
_test->size()))
228 using std::max, std::min, std::abs;
230 Real max_positive_gap = 0.0;
231 Real min_negative_gap = 0.0;
241 max_positive_gap = max(max_positive_gap, gap);
242 min_negative_gap = min(min_negative_gap, gap);
248 std::vector<Real> recv;
252 0, -min_negative_gap > max_positive_gap ? min_negative_gap : max_positive_gap, recv);
256 min_negative_gap = *std::min_element(recv.begin(), recv.end());
257 max_positive_gap = *std::max_element(recv.begin(), recv.end());
260 const Real reported_gap =
261 -min_negative_gap > max_positive_gap ? min_negative_gap : max_positive_gap;
268 "). Iteration number is: ",
278 "). Iteration number is: ",
309 const auto gap =
getNormalGap(
static_cast<const Node *
>(dof_object));
312 const auto possible_normalization =
318 if (lagrange_multiplier + gap * penalty / possible_normalization <= 0)
319 lagrange_multiplier += gap * penalty / possible_normalization;
321 lagrange_multiplier = 0.0;
349 if (previous_gap > 0.0)
356 if (previous_gap * gap < 0)
359 eval_tn = penalty * previous_gap;
370 using std::abs, std::max, std::sqrt;
372 const bool condition_one = abs(abs(previous_gap / gap) - 1.0) < 0.01;
373 const bool condition_two = abs(gap) > 1.01 * abs(previous_gap);
375 if (previous_gap * gap < 0)
379 (gap - previous_gap));
381 penalty = abs(penalty * previous_gap / 10.0 / gap);
385 if (abs(gap - previous_gap) >
390 else if (condition_two)
391 penalty *= 10.0 * previous_gap / gap;
void mooseInfoRepeated(Args &&... args)
registerMooseObject("ContactApp", PenaltyWeightedGapUserObject)
Interface class for user objects that support the augmented Lagrange formalism as implemented in Augm...
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
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 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 Real getNormalContactPressure(const Node *const node) const override
virtual void initialize() override
std::unordered_map< const DofObject *, Real > _dof_to_lagrange_multiplier
Map from degree of freedom to augmented lagrange multiplier.
Real _dt_old
previous timestep size
virtual void augmentedLagrangianSetup() override
const Real _penetration_tolerance
penetration tolerance for augmented Lagrange contact
AugmentedLagrangianContactProblemInterface *const _augmented_lagrange_problem
augmented Lagrange problem and iteration number
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
AdaptivityNormalPenalty
The adaptivity method for the penalty factor at augmentations.
const bool _use_physical_gap
Use scaled or physical gap.
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
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
processor_id_type size() const
processor_id_type rank() const
void gather(const unsigned int root_id, const T &send_data, std::vector< T, A > &recv) 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
ADReal adPhysicalGap(const std::pair< ADReal, Real > &gap) const
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