www.mooseframework.org
NodeFaceConstraint.C
Go to the documentation of this file.
1 //* This file is part of the MOOSE framework
2 //* https://www.mooseframework.org
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 
10 #include "NodeFaceConstraint.h"
11 
12 // MOOSE includes
13 #include "Assembly.h"
14 #include "MooseEnum.h"
15 #include "MooseMesh.h"
16 #include "MooseVariableFE.h"
17 #include "PenetrationLocator.h"
18 #include "SystemBase.h"
19 
20 #include "libmesh/string_to_enum.h"
21 
24 {
25  MooseEnum orders("FIRST SECOND THIRD FOURTH", "FIRST");
27  params.addParam<BoundaryName>("secondary", "The boundary ID associated with the secondary side");
28  params.addParam<BoundaryName>("primary", "The boundary ID associated with the primary side");
29  params.addParam<Real>("tangential_tolerance",
30  "Tangential distance to extend edges of contact surfaces");
31  params.addParam<Real>(
32  "normal_smoothing_distance",
33  "Distance from edge in parametric coordinates over which to smooth contact normal");
34  params.addParam<std::string>("normal_smoothing_method",
35  "Method to use to smooth normals (edge_based|nodal_normal_based)");
36  params.addParam<MooseEnum>("order", orders, "The finite element order used for projections");
37 
38  params.addCoupledVar("primary_variable", "The variable on the primary side of the domain");
39 
40  return params;
41 }
42 
44  : Constraint(parameters),
45  // The secondary side is at nodes (hence passing 'true'). The neighbor side is the primary side
46  // and it is not at nodes (so passing false)
50  _secondary(_mesh.getBoundaryID(getParam<BoundaryName>("secondary"))),
51  _primary(_mesh.getBoundaryID(getParam<BoundaryName>("primary"))),
52  _var(_sys.getFieldVariable<Real>(_tid, parameters.get<NonlinearVariableName>("variable"))),
53 
54  _primary_q_point(_assembly.qPointsFace()),
55  _primary_qrule(_assembly.qRuleFace()),
56 
57  _penetration_locator(
58  getPenetrationLocator(getParam<BoundaryName>("primary"),
59  getParam<BoundaryName>("secondary"),
60  Utility::string_to_enum<Order>(getParam<MooseEnum>("order")))),
61 
62  _current_node(_var.node()),
63  _current_primary(_var.neighbor()),
64  _u_secondary(_var.dofValues()),
65  _phi_secondary(1), // One entry
66  _test_secondary(1), // One entry
67 
68  _primary_var(*getVar("primary_variable", 0)),
69  _primary_var_num(_primary_var.number()),
70 
71  _phi_primary(_assembly.phiFaceNeighbor(_primary_var)),
72  _grad_phi_primary(_assembly.gradPhiFaceNeighbor(_primary_var)),
73 
74  _test_primary(_var.phiFaceNeighbor()),
75  _grad_test_primary(_var.gradPhiFaceNeighbor()),
76 
77  _u_primary(_primary_var.slnNeighbor()),
78  _grad_u_primary(_primary_var.gradSlnNeighbor()),
79 
80  _dof_map(_sys.dofMap()),
81  _node_to_elem_map(_mesh.nodeToElemMap()),
82 
83  _overwrite_secondary_residual(true),
84  _primary_JxW(_assembly.JxWNeighbor())
85 {
87 
88  if (parameters.isParamValid("tangential_tolerance"))
89  {
90  _penetration_locator.setTangentialTolerance(getParam<Real>("tangential_tolerance"));
91  }
92  if (parameters.isParamValid("normal_smoothing_distance"))
93  {
94  _penetration_locator.setNormalSmoothingDistance(getParam<Real>("normal_smoothing_distance"));
95  }
96  if (parameters.isParamValid("normal_smoothing_method"))
97  {
99  parameters.get<std::string>("normal_smoothing_method"));
100  }
101  // Put a "1" into test_secondary
102  // will always only have one entry that is 1
103  _test_secondary[0].push_back(1);
104 }
105 
107 {
109  _test_secondary.release();
110 }
111 
112 void
114 {
115  const dof_id_type & dof_idx = _var.nodalDofIndex();
116  _qp = 0;
117  current_solution.set(dof_idx, computeQpSecondaryValue());
118 }
119 
120 void
122 {
124 }
125 
126 Real
128 {
129  mooseAssert(_secondary_residual_computed,
130  "The secondary residual has not yet been computed, so the value will be garbage!");
131  return _secondary_residual;
132 }
133 
134 void
136 {
137  _qp = 0;
138 
140  for (_i = 0; _i < _test_primary.size(); _i++)
143 
145  _i = 0;
149 }
150 
151 void
153 {
155 
158 
160 
161  _qp = 0;
162 
163  // Fill up _phi_secondary so that it is 1 when j corresponds to this dof and 0 for every other dof
164  // This corresponds to evaluating all of the connected shape functions at _this_ node
165  for (unsigned int j = 0; j < _connected_dof_indices.size(); j++)
166  {
167  _phi_secondary[j].resize(1);
168 
170  _phi_secondary[j][_qp] = 1.0;
171  else
172  _phi_secondary[j][_qp] = 0.0;
173  }
174 
175  for (_i = 0; _i < _test_secondary.size(); _i++)
176  // Loop over the connected dof indices so we can get all the jacobian contributions
177  for (_j = 0; _j < _connected_dof_indices.size(); _j++)
179 
180  // Just do a direct assignment here because the Jacobian coming from assembly has already been
181  // properly sized according to the neighbor _var dof indices. It has also been zeroed
183  if (_Ken.m() && _Ken.n())
184  for (_i = 0; _i < _test_secondary.size(); _i++)
185  for (_j = 0; _j < _phi_primary.size(); _j++)
187  // Don't accumulate here
188 
189  for (_i = 0; _i < _test_primary.size(); _i++)
190  // Loop over the connected dof indices so we can get all the jacobian contributions
191  for (_j = 0; _j < _connected_dof_indices.size(); _j++)
193 
196  if (_local_ke.m() && _local_ke.n())
197  for (_i = 0; _i < _test_primary.size(); _i++)
198  for (_j = 0; _j < _phi_primary.size(); _j++)
201 }
202 
203 void
204 NodeFaceConstraint::computeOffDiagJacobian(const unsigned int jvar_num)
205 {
206  getConnectedDofIndices(jvar_num);
207 
210 
212 
213  _qp = 0;
214 
215  auto primary_jsize = getVariable(jvar_num).dofIndicesNeighbor().size();
216 
217  // Fill up _phi_secondary so that it is 1 when j corresponds to this dof and 0 for every other dof
218  // This corresponds to evaluating all of the connected shape functions at _this_ node
219  for (unsigned int j = 0; j < _connected_dof_indices.size(); j++)
220  {
221  _phi_secondary[j].resize(1);
222 
224  _phi_secondary[j][_qp] = 1.0;
225  else
226  _phi_secondary[j][_qp] = 0.0;
227  }
228 
229  for (_i = 0; _i < _test_secondary.size(); _i++)
230  // Loop over the connected dof indices so we can get all the jacobian contributions
231  for (_j = 0; _j < _connected_dof_indices.size(); _j++)
233 
234  // Just do a direct assignment here because the Jacobian coming from assembly has already been
235  // properly sized according to the jvar neighbor dof indices. It has also been zeroed
237  for (_i = 0; _i < _test_secondary.size(); _i++)
238  for (_j = 0; _j < primary_jsize; _j++)
240  // Don't accumulate here
241 
242  if (_Kne.m() && _Kne.n())
243  for (_i = 0; _i < _test_primary.size(); _i++)
244  // Loop over the connected dof indices so we can get all the jacobian contributions
245  for (_j = 0; _j < _connected_dof_indices.size(); _j++)
247 
249  for (_i = 0; _i < _test_primary.size(); _i++)
250  for (_j = 0; _j < primary_jsize; _j++)
253 }
254 
255 void
257 {
258  MooseVariableFEBase & var = _sys.getVariable(0, var_num);
259 
260  _connected_dof_indices.clear();
261  std::set<dof_id_type> unique_dof_indices;
262 
263  auto node_to_elem_pair = _node_to_elem_map.find(_current_node->id());
264  mooseAssert(node_to_elem_pair != _node_to_elem_map.end(), "Missing entry in node to elem map");
265  const std::vector<dof_id_type> & elems = node_to_elem_pair->second;
266 
267  // Get the dof indices from each elem connected to the node
268  for (const auto & cur_elem : elems)
269  {
270  std::vector<dof_id_type> dof_indices;
271 
272  var.getDofIndices(_mesh.elemPtr(cur_elem), dof_indices);
273 
274  for (const auto & dof : dof_indices)
275  unique_dof_indices.insert(dof);
276  }
277 
278  for (const auto & dof : unique_dof_indices)
279  _connected_dof_indices.push_back(dof);
280 }
281 
282 bool
284 {
286 }
287 
288 const std::set<BoundaryID> &
290 {
291  _boundary_ids.insert(_primary);
292  _boundary_ids.insert(_secondary);
293  return _boundary_ids;
294 }
295 
296 std::set<SubdomainID>
298 {
300 }
MooseMesh & _mesh
Reference to this Kernel&#39;s mesh object.
bool _secondary_residual_computed
Whether the secondary residual has been computed.
VarFieldType
Definition: MooseTypes.h:634
BoundaryID _secondary
Boundary ID for the secondary surface.
virtual void computeResidual() override
Computes the residual Nodal residual.
Order
void accumulateTaggedLocalResidual()
Local residual blocks will be appended by adding the current local kernel residual.
virtual void computeSecondaryValue(NumericVector< Number > &current_solution)
Compute the value the secondary node should have at the beginning of a timestep.
Intermediate base class that ties together all the interfaces for getting MooseVariables with the Moo...
virtual Elem * elemPtr(const dof_id_type i)
Definition: MooseMesh.C:2863
void setNormalSmoothingDistance(Real normal_smoothing_distance)
MooseVariable & _var
unsigned int number() const
Get variable number coming from libMesh.
virtual Real computeQpResidual(Moose::ConstraintType type)=0
This is the virtual that derived classes should override for computing the residual on neighboring el...
std::vector< std::pair< R1, R2 > > get(const std::string &param1, const std::string &param2) const
Combine two vector parameters into a single vector of pairs.
MooseVariable & _primary_var
Primary side variable.
std::set< SubdomainID > getSecondaryConnectedBlocks() const
T * get(const std::unique_ptr< T > &u)
The MooseUtils::get() specializations are used to support making forwards-compatible code changes fro...
Definition: MooseUtils.h:1147
Base class for all Constraint types.
Definition: Constraint.h:19
DenseMatrix< Number > _Kne
The Jacobian corresponding to the derivatives of the neighbor/primary residual with respect to the el...
const std::map< dof_id_type, std::vector< dof_id_type > > & _node_to_elem_map
Real secondaryResidual() const
void assignTaggedLocalResidual()
Local residual blocks will assigned as the current local kernel residual.
DenseMatrix< Number > _Ken
The Jacobian corresponding to the derivatives of the elemental/secondary residual with respect to the...
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system...
static InputParameters validParams()
virtual void getDofIndices(const Elem *, std::vector< dof_id_type > &) const
unsigned int m() const
This class provides an interface for common operations on field variables of both FE and FV types wit...
unsigned int _i
Definition: Constraint.h:35
const VariableTestValue & _test_primary
Side test function.
void setTangentialTolerance(Real tangential_tolerance)
DenseMatrix< Number > _local_ke
Holds local Jacobian entries as they are accumulated by this Kernel.
const MooseVariableFieldBase & getVariable(unsigned int jvar_num) const
Retrieve the variable object from our system associated with jvar_num.
void residualSetup() override
Gets called just before the residual is computed and before this object is asked to do its job...
const Node *const & _current_node
current node being processed
DenseMatrix< Number > _Kee
The Jacobian corresponding to the derivatives of the elemental/secondary residual with respect to the...
SystemBase & _sys
Reference to the EquationSystem object.
void prepareMatrixTagNeighbor(Assembly &assembly, unsigned int ivar, unsigned int jvar, Moose::DGJacobianType type)
Prepare data for computing element jacobian according to the active tags for DG and interface kernels...
BoundaryID getBoundaryID(const BoundaryName &boundary_name, const MeshBase &mesh)
Gets the boundary ID associated with the given BoundaryName.
unsigned int _j
Definition: Constraint.h:35
NodeFaceConstraint(const InputParameters &parameters)
Enhances MooseVariableInterface interface provide values from neighbor elements.
virtual const std::vector< dof_id_type > & dofIndicesNeighbor() const =0
Get neighbor DOF indices for currently selected element.
unsigned int size() const
The number of elements that can currently be stored in the array.
Definition: MooseArray.h:256
virtual void computeJacobian() override
Computes the jacobian for the current element.
std::set< BoundaryID > _boundary_ids
the union of the secondary and primary boundary ids
T string_to_enum(const std::string &s)
VarKindType
Framework-wide stuff.
Definition: MooseTypes.h:627
virtual void getConnectedDofIndices(unsigned int var_num)
Gets the indices for all dofs connected to the constraint.
This is a "smart" enum class intended to replace many of the shortcomings in the C++ enum type It sho...
Definition: MooseEnum.h:31
std::set< SubdomainID > getBoundaryConnectedBlocks(const BoundaryID bid) const
Get the list of subdomains associated with the given boundary.
Definition: MooseMesh.C:3271
Real _secondary_residual
The value of the secondary residual.
void accumulateTaggedLocalMatrix()
Local Jacobian blocks will be appended by adding the current local kernel Jacobian.
const std::set< BoundaryID > & buildBoundaryIDs()
Builds the _boundary_ids data member and returns it.
Assembly & _assembly
Reference to this Kernel&#39;s assembly object.
void addCoupledVar(const std::string &name, const std::string &doc_string)
This method adds a coupled variable name pair.
virtual void computeOffDiagJacobian(unsigned int jvar) override
Computes d-residual / d-jvar...
VariableTestValue _test_secondary
Shape function on the secondary side. This will always only have one entry and that entry will always...
void addMooseVariableDependency(MooseVariableFieldBase *var)
Call this function to add the passed in MooseVariableFieldBase as a variable that this object depends...
void prepareVectorTagNeighbor(Assembly &assembly, unsigned int ivar)
Prepare data for computing element residual the according to active tags for DG and interface kernels...
virtual Real computeQpSecondaryValue()=0
Compute the value the secondary node should have at the beginning of a timestep.
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
const dof_id_type & nodalDofIndex() const override
void release()
Manually deallocates the data pointer.
Definition: MooseArray.h:66
DenseVector< Number > _local_re
Holds local residual entries as they are accumulated by this Kernel.
void resize(const unsigned int new_m, const unsigned int new_n)
void resize(unsigned int size)
Change the number of elements the array can store.
Definition: MooseArray.h:213
std::vector< dof_id_type > _connected_dof_indices
const InputParameters & parameters() const
Get the parameters of the object.
const VariablePhiValue & _phi_primary
Side shape function.
BoundaryID _primary
Boundary ID for the primary surface.
void addParam(const std::string &name, const S &value, const std::string &doc_string)
These methods add an option parameter and a documentation string to the InputParameters object...
bool _overwrite_secondary_residual
Whether or not the secondary&#39;s residual should be overwritten.
virtual void set(const numeric_index_type i, const Number value)=0
VariablePhiValue _phi_secondary
Shape function on the secondary side. This will always.
MOOSE now contains C++17 code, so give a reasonable error message stating what the user can do to add...
void setNormalSmoothingMethod(std::string nsmString)
MooseVariableFieldBase & getVariable(THREAD_ID tid, const std::string &var_name) const
Gets a reference to a variable of with specified name.
Definition: SystemBase.C:79
unsigned int n() const
PenetrationLocator & _penetration_locator
void prepareVectorTag(Assembly &assembly, unsigned int ivar)
Prepare data for computing element residual according to active tags.
virtual bool overwriteSecondaryResidual()
Whether or not the secondary&#39;s residual should be overwritten.
static InputParameters validParams()
Definition: Constraint.C:15
virtual Real computeQpJacobian(Moose::ConstraintJacobianType type)=0
This is the virtual that derived classes should override for computing the Jacobian on neighboring el...
unsigned int _qp
Definition: Constraint.h:36
virtual Real computeQpOffDiagJacobian(Moose::ConstraintJacobianType, unsigned int)
This is the virtual that derived classes should override for computing the off-diag Jacobian...
uint8_t dof_id_type
bool isParamValid(const std::string &name) const
This method returns parameters that have been initialized in one fashion or another, i.e.