https://mooseframework.inl.gov
Loading...
Searching...
No Matches
TangentialMortarMechanicalContact.C
Go to the documentation of this file.
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
13
15
18{
20 // Mechanical contact residuals use only primal values and normals
21 params.set<bool>("_compute_primal_gradients") = false;
22
23 MooseEnum component("x=0 y=1 z=2");
25 "component", component, "The force component constraint that this object is supplying");
26
27 // This enum is used to pick the proper 'tangent' vector (i.e. tangent or binormal)
28 MooseEnum direction("direction_1 direction_2", "direction_1");
29 params.addParam<MooseEnum>("direction",
30 direction,
31 "Tangent direction to compute the residual due to frictional contact");
33 "Used to apply tangential stresses from frictional contact using lagrange multipliers");
34 params.addRequiredParam<UserObjectName>("weighted_velocities_uo",
35 "The weighted velocities user object.");
36 params.set<bool>("interpolate_normals") = false;
37 params.set<bool>("compute_lm_residual") = false;
38 return params;
39}
40
42 const InputParameters & parameters)
43 : ADMortarLagrangeConstraint(parameters),
44 _component(getParam<MooseEnum>("component")),
45 _direction(getParam<MooseEnum>("direction")),
46 _weighted_velocities_uo(getUserObject<WeightedVelocitiesUserObject>("weighted_velocities_uo"))
47{
48 if (getParam<bool>("interpolate_normals"))
49 paramError("interpolate_normals",
50 "Mechanical mortar contact uses tangents derived from normalized secondary nodal "
51 "normals and cannot be combined with quadrature-point normal interpolation.");
52}
53
54void
56{
58
60 return;
61
64 paramError("weighted_velocities_uo",
65 "'weighted_velocities_uo' must be defined on the same secondary/primary subdomain "
66 "pair as this constraint when nodal-normal derivatives are enabled.");
67
69 paramError("weighted_velocities_uo",
70 "'weighted_velocities_uo' must use the same displacement variable as this "
71 "constraint's 'variable' when nodal-normal derivatives are enabled.");
72
73 if (getParam<bool>("use_displaced_mesh") !=
74 _weighted_velocities_uo.parameters().get<bool>("use_displaced_mesh"))
75 paramError("weighted_velocities_uo",
76 "'weighted_velocities_uo' must use the same 'use_displaced_mesh' setting as this "
77 "constraint when nodal-normal derivatives are enabled.");
78}
79
80void
82{
83 // Interpolate each nodal tangential pressure with its own Householder tangent frame.
84 const auto direction = cast_int<unsigned int>(static_cast<int>(_direction));
85 // The interpolation basis and nodal coefficient lookup both belong to this direction's tangential
86 // Lagrange multiplier, preserving their node-for-node correspondence.
87 const auto & phi = _weighted_velocities_uo.tangentialTractionBasis(direction);
89
91 if (ad_tangents)
92 for (const auto j : index_range(phi))
93 {
94 const auto nodal_pressure = _weighted_velocities_uo.nodalTangentialPressure(
95 _lower_secondary_elem->node_ref(j), direction);
96 // householderTangents() applies a Householder reflection to two Cartesian basis vectors, so
97 // the frame it returns is already orthonormal and needs no normalization here.
99 _qp_traction_component += phi[j][_qp] * nodal_pressure * tangents[direction](_component);
100 }
101 else
102 {
103 const auto & nodal_tangents = amg().getNodalTangents(*_lower_secondary_elem);
104 for (const auto j : index_range(phi))
105 {
106 const auto nodal_pressure = _weighted_velocities_uo.nodalTangentialPressure(
107 _lower_secondary_elem->node_ref(j), direction);
109 phi[j][_qp] * nodal_pressure * nodal_tangents[direction][j](_component);
110 }
111 }
112}
113
114ADReal
116{
117 switch (type)
118 {
119 case Moose::MortarType::Secondary:
120 // We have taken the convention the lagrange multiplier must have the same sign as the
121 // relative slip velocity of the secondary face. So positive lambda indicates that force is
122 // being applied in the negative direction, so we want to decrease the momentum in the system,
123 // which means we want an outflow of momentum, which means we want the residual to be positive
124 // in that case. Negative lambda means force is being applied in the positive direction, so we
125 // want to increase momentum in the system, which means we want an inflow of momentum, which
126 // means we want the residual to be negative in that case. So the sign of this residual should
127 // be the same as the sign of lambda
129
130 case Moose::MortarType::Primary:
132
133 default:
134 return 0;
135 }
136}
DualNumber< Real, DNDerivativeType, true > ADReal
registerMooseObject("ContactApp", TangentialMortarMechanicalContact)
This class enforces mortar constraints on lower dimensional domains, skipping interior nodes.
static InputParameters validParams()
std::array< MooseUtils::SemidynamicVector< Point, 9 >, 2 > getNodalTangents(const Elem &secondary_elem) const
unsigned int _qp
unsigned int _i
void addRequiredParam(const std::string &name, const std::string &doc_string)
void addParam(const std::string &name, const std::initializer_list< typename T::value_type > &value, const std::string &doc_string)
std::vector< std::pair< R1, R2 > > get(const std::string &param1, const std::string &param2) const
void addClassDescription(const std::string &doc_string)
T & set(const std::string &name, bool quiet_mode=false)
const InputParameters & parameters() const
const std::string & type() const
void paramError(const std::string &param, Args... args) const
const VariableTestValue & _test_secondary
MooseVariableField< Real > & _secondary_var
const VariableTestValue & _test_primary
SubdomainID primarySubdomain() const
Elem const *const & _lower_secondary_elem
const AutomaticMortarGeneration & amg() const
SubdomainID secondarySubdomain() const
ADReal _qp_traction_component
The interpolated tangential traction component at the current quadrature point.
const MooseEnum _component
Displacement component on which the residual will be computed.
const MooseEnum _direction
Tangent direction used for computing the residual.
TangentialMortarMechanicalContact(const InputParameters &parameters)
ADReal computeQpResidual(Moose::MortarType type) final
const WeightedVelocitiesUserObject & _weighted_velocities_uo
The weighted velocities user object which supplies the contact pressure tangential vectors.
void precomputeQpQuantities() override
Compute quantities that depend on the quadrature point but not on the test function index.
virtual bool usesNodalNormalDerivatives() const =0
Whether this formulation includes displacement derivatives of the secondary nodal normals.
bool shouldRecordNodalNormalDerivatives() const
Whether the current assembly records nodal-normal derivatives for this object's system.
const MooseVariable * dispVar(unsigned int component) const
Creates dof object to weighted tangential velocities map.
const std::array< ADRealVectorValue, 2 > & contactTangents(const Elem &lower_secondary_elem, unsigned int nodal_index) const
Return contact tangents for the supplied lower-dimensional secondary element node.
virtual const VariableTestValue & tangentialTractionBasis(unsigned int) const
virtual ADReal nodalTangentialPressure(const Node &node, unsigned int direction) const