26 params.
addClassDescription(
"Computes the mortar normal contact force via a penalty approach.");
31 "penalty_multiplier > 0",
32 "The penalty growth factor between augmented Lagrange "
33 "iterations if weighted gap does not get closed fast enough. For frictional simulations, "
34 "values smaller than 100 are recommended, e.g. 5.");
38 "Whether to use the physical normal gap (not scaled by mortar integration) and normalize the "
39 "penalty coefficient with a representative lower-dimensional volume assigned to the node in "
40 "the contacting boundary. This parameter is defaulted to 'true' in the contact action.");
42 "penetration_tolerance",
43 "penetration_tolerance > 0",
44 "Acceptable penetration distance at which augmented Lagrange iterations can be stopped");
46 "max_penalty_multiplier",
48 "max_penalty_multiplier >= 1.0",
49 "Maximum multiplier applied to penalty factors when adaptivity is used in an augmented "
50 "Lagrange setting. The penalty factor supplied by the user is used as a reference.");
51 MooseEnum adaptivity_penalty_normal(
"SIMPLE BUSSETTA",
"SIMPLE");
52 adaptivity_penalty_normal.addDocumentation(
53 "SIMPLE",
"Keep multiplying by the penalty multiplier between AL iterations");
54 adaptivity_penalty_normal.addDocumentation(
56 "Modify the penalty using an algorithm from Bussetta et al, 2012, Comput Mech 49:259-275 "
57 "between AL iterations.");
59 "adaptivity_penalty_normal",
60 adaptivity_penalty_normal,
61 "The augmented Lagrange update strategy used on the normal penalty coefficient.");
64 "Auxiliary variable that is utilized together with the "
65 "penalty approach to interpolate the resulting contact tractions using dual bases.");
67 "Augmented Lagrange");
75 _penalty(getParam<Real>(
"penalty")),
76 _penalty_multiplier(getParam<Real>(
"penalty_multiplier")),
77 _penetration_tolerance(
78 isParamValid(
"penetration_tolerance") ? getParam<Real>(
"penetration_tolerance") : 0.0),
79 _augmented_lagrange_problem(
81 _lagrangian_iteration_number(_augmented_lagrange_problem
82 ? _augmented_lagrange_problem->getLagrangianIterationNumber()
84 _t_step_old_normal(declareRestartableData<
int>(
"t_step_old_normal", 0)),
85 _dt(_fe_problem.dt()),
86 _use_physical_gap(getParam<bool>(
"use_physical_gap")),
87 _aux_lm_var(isCoupled(
"aux_lm") ? getVar(
"aux_lm", 0) : nullptr),
88 _max_penalty_multiplier(getParam<Real>(
"max_penalty_multiplier")),
92 auto check_type = [
this](
const auto & var,
const auto & var_name)
96 "The displacement variables must have degrees of freedom exclusively on "
97 "nodes, e.g. they should probably be of finite element type 'Lagrange'.");
106 "This parameter must be supplied if and only if an augmented Lagrange problem "
156 const auto lagrange_multiplier =
160 auto normal_pressure = min(0.0, penalty * gap + lagrange_multiplier);
203 for (
const auto i : make_range(
_test->size()))
231 if (retried_timestep)
257 using std::max, std::min, std::abs;
259 Real max_positive_gap = 0.0;
260 Real min_negative_gap = 0.0;
270 max_positive_gap = max(max_positive_gap, gap);
271 min_negative_gap = min(min_negative_gap, gap);
277 std::vector<Real> recv;
281 0, -min_negative_gap > max_positive_gap ? min_negative_gap : max_positive_gap, recv);
285 min_negative_gap = *std::min_element(recv.begin(), recv.end());
286 max_positive_gap = *std::max_element(recv.begin(), recv.end());
289 const Real reported_gap =
290 -min_negative_gap > max_positive_gap ? min_negative_gap : max_positive_gap;
297 "). Iteration number is: ",
307 "). Iteration number is: ",
338 const auto gap =
getNormalGap(
static_cast<const Node *
>(dof_object));
341 const auto possible_normalization =
347 if (lagrange_multiplier + gap * penalty / possible_normalization <= 0)
348 lagrange_multiplier += gap * penalty / possible_normalization;
350 lagrange_multiplier = 0.0;
378 if (previous_gap > 0.0)
385 if (previous_gap * gap < 0)
388 eval_tn = penalty * previous_gap;
399 using std::abs, std::max, std::sqrt;
401 const bool condition_one = abs(abs(previous_gap / gap) - 1.0) < 0.01;
402 const bool condition_two = abs(gap) > 1.01 * abs(previous_gap);
404 if (previous_gap * gap < 0)
408 (gap - previous_gap));
410 penalty = abs(penalty * previous_gap / 10.0 / gap);
414 if (abs(gap - previous_gap) >
419 else if (condition_two)
420 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...
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
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
std::unordered_map< const DofObject *, Real > _dof_to_lagrange_multiplier_start
Augmented lagrange multipliers at the start of the current timestep, restored when the timestep is re...
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
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
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 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
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.
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