https://mooseframework.inl.gov
MortarPressureComponentAux.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 
11 #include "SystemBase.h"
13 
15 
18 {
20  params.set<ExecFlagEnum>("execute_on") = EXEC_TIMESTEP_END;
21 
22  params.addClassDescription(
23  "This class transforms the Cartesian Lagrange multiplier vector to local coordinates and "
24  "outputs each individual component along the normal or tangential direction.");
25  params.addRequiredCoupledVar("lm_var_x", "Lagrange multiplier variable along the x direction.");
26  params.addRequiredCoupledVar("lm_var_y", "Lagrange multiplier variable along the y direction.");
27  params.addCoupledVar(
28  "lm_var_z",
29  "Lagrange multiplier variable along the z direction (only exist for 3D problems).");
30  params.addRequiredParam<MooseEnum>("component",
31  MooseEnum("normal tangent1 tangent2"),
32  "The component of the Lagrange multiplier to compute.");
33  params.addRequiredParam<BoundaryName>("primary_boundary",
34  "The name of the primary boundary sideset.");
35  params.addRequiredParam<BoundaryName>("secondary_boundary",
36  "The name of the secondary boundary sideset.");
37  params.addParam<bool>(
38  "use_displaced_mesh", true, "Whether to use the displaced mesh to get the mortar interface.");
39  return params;
40 }
41 
43  : AuxKernel(params),
44  _lm_var_x(&coupledValueLower("lm_var_x")),
45  _lm_var_y(&coupledValueLower("lm_var_y")),
46  _lm_var_z(params.isParamValid("lm_var_z") ? &coupledValueLower("lm_var_z") : nullptr),
47  _fe_problem(*params.get<FEProblemBase *>("_fe_problem_base")),
48  _primary_id(_fe_problem.mesh().getBoundaryID(getParam<BoundaryName>("primary_boundary"))),
49  _secondary_id(_fe_problem.mesh().getBoundaryID(getParam<BoundaryName>("secondary_boundary"))),
50  _component(getParam<MooseEnum>("component").getEnum<ComponentType>()),
51  _use_displaced_mesh(getParam<bool>("use_displaced_mesh"))
52 {
53  // Only consider nodal quantities
54  if (!isNodal())
55  mooseError("MortarPressureComponent auxiliary kernel can only be used with nodal kernels.");
56 
58  paramError("use_displaced_mesh",
59  "This auxiliary kernel requires the use of displaced meshes to compute the "
60  "frictional pressure vector.");
61 
62  // Kernel need to be boundary restricted
63  if (!this->_bnd)
64  paramError("boundary",
65  "MortarPressureComponent auxiliary kernel must be restricted to a boundary.");
66 
67  // Get mortar interfaces
68  const auto & displaced_mortar_interfaces =
70 
71  if (displaced_mortar_interfaces.size() == 0)
72  paramError("lm_var_x",
73  "No mortar interface could be identified in this problem. Make sure mortar contact "
74  "is enabled.");
75 
76  // Get automatic generation object for the boundary pair this auxiliary acts on.
77  if (displaced_mortar_interfaces.count(std::make_pair(_primary_id, _secondary_id)) != 1)
78  mooseError("primary_boundary",
79  "The boundary pairs do not correspond to a single mortar contact boundary pair. "
80  "Please revise your input file for proper mortar contact constraints and mortar "
81  "frictional pressure vector auxiliary variable definition.");
82 
84  libmesh_map_find(displaced_mortar_interfaces, std::make_pair(_primary_id, _secondary_id))
85  .get();
86 }
87 
88 Real
90 {
91  // A node id may correspond to more than one lower-d elements on the secondary surface.
92  // However, we are looping over nodes below, so we will locate the correct geometry
93  const Elem * lower_dimensional_element =
94  libmesh_map_find(_mortar_generation_object->nodesToSecondaryElem(), _current_node->id())[0];
95 
96  // Get the nodal normals for this element
97  const auto & nodal_normals =
98  _mortar_generation_object->getNodalNormals(*lower_dimensional_element);
99 
100  // Get nodal tangents for this element
101  const auto & nodal_tangents =
102  _mortar_generation_object->getNodalTangents(*lower_dimensional_element);
103 
104  Point normal_vector, tangent1, tangent2;
105 
106  for (const auto lowerd_node : make_range(lower_dimensional_element->n_nodes()))
107  if (_current_node->id() == lower_dimensional_element->node_id(lowerd_node))
108  {
109  normal_vector = nodal_normals[lowerd_node];
110  tangent1 = nodal_tangents[0][lowerd_node];
111  tangent2 = nodal_tangents[1][lowerd_node];
112  break;
113  }
114 
115  Point lm_vector_value(
116  (*_lm_var_x)[_qp], (*_lm_var_y)[_qp], _lm_var_z == nullptr ? 0.0 : (*_lm_var_z)[_qp]);
117 
118  Real pressure_component_value = 0.0;
119 
120  switch (_component)
121  {
123  pressure_component_value = lm_vector_value * normal_vector;
124  break;
125 
127  pressure_component_value = lm_vector_value * tangent1;
128  break;
129 
131  pressure_component_value = lm_vector_value * tangent2;
132  break;
133  }
134 
135  return pressure_component_value;
136 }
const BoundaryID _primary_id
Boundary ID for the primary surface.
void paramError(const std::string &param, Args... args) const
void addParam(const std::string &name, const std::initializer_list< typename T::value_type > &value, const std::string &doc_string)
const Node *const & _current_node
ComponentType
The component of the Lagrange multiplier to compute.
T & set(const std::string &name, bool quiet_mode=false)
MeshBase & mesh
const bool _use_displaced_mesh
Whether to use displaced mesh (required for this auxiliary kernel)
enum MortarPressureComponentAux::ComponentType _component
const MooseArray< Real > *const _lm_var_x
Lagrange multiplier variable along the x direction.
const ExecFlagType EXEC_TIMESTEP_END
std::vector< Point > getNodalNormals(const Elem &secondary_elem) const
const FEProblemBase & _fe_problem
Fe problem to obtain primary/secondary ids.
void addRequiredParam(const std::string &name, const std::string &doc_string)
registerMooseObject("ContactApp", MortarPressureComponentAux)
BoundaryID getBoundaryID(const BoundaryName &boundary_name, const MeshBase &mesh)
const BoundaryID _secondary_id
Boundary ID for the secondary surface.
static InputParameters validParams()
const std::unordered_map< std::pair< BoundaryID, BoundaryID >, std::unique_ptr< AutomaticMortarGeneration > > & getMortarInterfaces(bool on_displaced) const
Transforms a Cartesian Lagrange multiplier vector, typically employed for mortar mechanical contact...
std::array< MooseUtils::SemidynamicVector< Point, 9 >, 2 > getNodalTangents(const Elem &secondary_elem) const
const MooseArray< Real > *const _lm_var_z
Lagrange multiplier variable along the z direction (3D)
const std::unordered_map< dof_id_type, std::vector< const Elem *> > & nodesToSecondaryElem() const
void addCoupledVar(const std::string &name, const std::string &doc_string)
void addRequiredCoupledVar(const std::string &name, const std::string &doc_string)
MortarPressureComponentAux(const InputParameters &parameters)
const AutomaticMortarGeneration * _mortar_generation_object
Handle to mortar generation object to obtain mortar geometry.
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
virtual Real computeValue() override
IntRange< T > make_range(T beg, T end)
void mooseError(Args &&... args) const
void addClassDescription(const std::string &doc_string)
static InputParameters validParams()
const MooseArray< Real > *const _lm_var_y
Lagrange multiplier variable along the y direction.
const Elem & get(const ElemType type_in)