https://mooseframework.inl.gov
MortarFrictionalPressureVectorAux.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"
12 
14 
17 {
19  params.set<ExecFlagEnum>("execute_on") = EXEC_TIMESTEP_END;
20 
21  params.addClassDescription("This class creates an auxiliary vector for outputting the mortar "
22  "frictional pressure vector.");
23  params.addRequiredCoupledVar(
24  "tangent_one",
25  "First tangent vector Lagrange's multiplier for computing the mortar "
26  "frictional pressure vector.");
27  params.addRequiredCoupledVar(
28  "tangent_two",
29  "Second tangent vector Lagrange's multiplier for computing the mortar "
30  "frictional pressure vector.");
31  params.addRequiredParam<unsigned int>("component",
32  "Cartesian component of frictional tangent vector");
33 
34  params.addRequiredParam<BoundaryName>("primary_boundary",
35  "The name of the primary boundary sideset.");
36  params.addRequiredParam<BoundaryName>("secondary_boundary",
37  "The name of the secondary boundary sideset.");
38  params.addParam<bool>(
39  "use_displaced_mesh", true, "Whether to use the displaced mesh to get the mortar interface.");
40  return params;
41 }
42 
44  : AuxKernel(params),
45  _tangent_one(&coupledValueLower("tangent_one")),
46  _tangent_two(&coupledValueLower("tangent_two")),
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<unsigned int>("component")),
51  _use_displaced_mesh(getParam<bool>("use_displaced_mesh"))
52 {
53  // Only consider nodal quantities
54  if (!isNodal())
55  mooseError(
56  "MortarFrictionalPressureVector auxiliary kernel can only be used with nodal kernels.");
57 
59  paramError("use_displaced_mesh",
60  "This auxiliary kernel requires the use of displaced meshes to compute the "
61  "frictional pressure vector.");
62 
63  // Kernel need to be boundary restricted
64  if (!this->_bnd)
65  paramError("boundary",
66  "MortarFrictionalPressureVector auxiliary kernel must be restricted to a boundary.");
67 
68  // Get mortar interfaces
69  const auto & displaced_mortar_interfaces =
71 
72  if (displaced_mortar_interfaces.size() == 0)
73  paramError("tangent_one",
74  "No mortar interface could be identified in this problem. Make sure mortar contact "
75  "is enabled.");
76 
77  const auto mortar_dimension = _fe_problem.mesh().dimension() - 1;
78  if (mortar_dimension == 1)
79  paramError("tangent_two",
80  "MortarFrictionalPressureVector auxiliary kernel can only be used in "
81  "three-dimensional problems");
82 
83  // Get automatic generation object for the boundary pair this auxiliary acts on.
84  if (displaced_mortar_interfaces.count(std::make_pair(_primary_id, _secondary_id)) != 1)
85  mooseError("primary_boundary",
86  "The boundary pairs do not correspond to a single mortar contact boundary pair. "
87  "Please revise your input file for proper mortar contact constraints and mortar "
88  "frictional pressure vector auxiliary variable definition.");
89 
91  &libmesh_map_find(displaced_mortar_interfaces, std::make_pair(_primary_id, _secondary_id));
92 }
93 
94 Real
96 {
97 
98  // A node id may correspond to more than one lower-d elements on the secondary surface.
99  // However, we are looping over nodes below, so we will locate the correct geometry
100  const Elem * lower_dimensional_element =
101  libmesh_map_find(_mortar_generation_object->nodesToSecondaryElem(), _current_node->id())[0];
102 
103  // Get nodal tangents for this element
104  const auto & nodal_tangents =
105  _mortar_generation_object->getNodalTangents(*lower_dimensional_element);
106 
107  Real tangent_one_component = 0;
108  Real tangent_two_component = 0;
109 
110  for (const auto lowerd_node : make_range(lower_dimensional_element->n_nodes()))
111  {
112  if (_current_node->id() == lower_dimensional_element->node_id(lowerd_node))
113  {
114  tangent_one_component = nodal_tangents[0][lowerd_node](_component);
115  tangent_two_component = nodal_tangents[1][lowerd_node](_component);
116  break;
117  }
118  }
119 
120  // Compute nodal tangent vector component
121  const Real tangent_vector_component =
122  tangent_one_component * (*_tangent_one)[_qp] + tangent_two_component * (*_tangent_two)[_qp];
123 
124  return tangent_vector_component;
125 }
const unsigned int _component
The component.
const bool _use_displaced_mesh
Whether to use displaced mesh (required for this auxiliary kernel)
void addParam(const std::string &name, const std::initializer_list< typename T::value_type > &value, const std::string &doc_string)
registerMooseObject("ContactApp", MortarFrictionalPressureVectorAux)
const Node *const & _current_node
T & set(const std::string &name, bool quiet_mode=false)
MeshBase & mesh
const ExecFlagType EXEC_TIMESTEP_END
const BoundaryID _primary_id
Boundary ID for the primary surface.
void addRequiredParam(const std::string &name, const std::string &doc_string)
BoundaryID getBoundaryID(const BoundaryName &boundary_name, const MeshBase &mesh)
virtual unsigned int dimension() const
MortarFrictionalPressureVectorAux(const InputParameters &parameters)
const BoundaryID _secondary_id
Boundary ID for the secondary surface.
std::array< MooseUtils::SemidynamicVector< Point, 9 >, 2 > getNodalTangents(const Elem &secondary_elem) const
void paramError(const std::string &param, Args... args) const
const std::unordered_map< dof_id_type, std::vector< const Elem *> > & nodesToSecondaryElem() const
void addRequiredCoupledVar(const std::string &name, const std::string &doc_string)
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
IntRange< T > make_range(T beg, T end)
virtual MooseMesh & mesh() override
void mooseError(Args &&... args) const
void addClassDescription(const std::string &doc_string)
static InputParameters validParams()
const FEProblemBase & _fe_problem
Fe problem to obtain primary/secondary ids.
const std::unordered_map< std::pair< BoundaryID, BoundaryID >, AutomaticMortarGeneration > & getMortarInterfaces(bool on_displaced) const
void ErrorVector unsigned int
const Elem & get(const ElemType type_in)
const AutomaticMortarGeneration * _mortar_generation_object
Handle to mortar generation object to obtain mortar geometry.
Computes the frictional pressure vector for three-dimensional mortar mechanical contact.