https://mooseframework.inl.gov
Loading...
Searching...
No Matches
NodeFaceConstraint.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
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 params.addParam<bool>(
38 "ghost_whole_interface",
39 false,
40 "Whether to geometrically and algebraically ghost the entire primary side of the interface "
41 "for node-face constraints.");
43 "GhostPrimaryFace",
45 [](const InputParameters & obj_params, InputParameters & rm_params)
46 {
47 const auto enabled = obj_params.get<bool>("ghost_whole_interface");
48 rm_params.set<bool>("enabled") = enabled;
49 // If we don't actually want this object to ghost anything, then let's not have it impede
50 // possibly early (more like on-time) remote element deletion
51 rm_params.set<bool>("attach_geometric_early") = !enabled;
52 rm_params.set<bool>("use_displaced_mesh") = obj_params.get<bool>("use_displaced_mesh");
53 rm_params.set<BoundaryName>("secondary_boundary") =
54 obj_params.get<BoundaryName>("secondary");
55 rm_params.set<BoundaryName>("primary_boundary") = obj_params.get<BoundaryName>("primary");
56 });
57
58 params.addCoupledVar("primary_variable", "The variable on the primary side of the domain");
59
60 return params;
61}
62
64 : Constraint(parameters),
65 // The secondary side is at nodes (hence passing 'true'). The neighbor side is the primary side
66 // and it is not at nodes (so passing false)
69 this, true, Moose::VarKindType::VAR_SOLVER, Moose::VarFieldType::VAR_FIELD_STANDARD),
70 _secondary(_mesh.getBoundaryID(getParam<BoundaryName>("secondary"))),
71 _primary(_mesh.getBoundaryID(getParam<BoundaryName>("primary"))),
72 _var(_sys.getFieldVariable<Real>(_tid, parameters.get<NonlinearVariableName>("variable"))),
73
74 _primary_q_point(_assembly.qPointsFace()),
75 _primary_qrule(_assembly.qRuleFace()),
76
77 _penetration_locator(
78 getPenetrationLocator(getParam<BoundaryName>("primary"),
79 getParam<BoundaryName>("secondary"),
80 Utility::string_to_enum<Order>(getParam<MooseEnum>("order")))),
81
82 _current_node(_var.node()),
83 _current_primary(_var.neighbor()),
84 _u_secondary(_var.dofValues()),
85 _phi_secondary(1), // One entry
86 _test_secondary(1), // One entry
87
88 _primary_var(*getVar("primary_variable", 0)),
89 _primary_var_num(_primary_var.number()),
90
91 _phi_primary(_assembly.phiFaceNeighbor(_primary_var)),
92 _grad_phi_primary(_assembly.gradPhiFaceNeighbor(_primary_var)),
93
94 _test_primary(_var.phiFaceNeighbor()),
95 _grad_test_primary(_var.gradPhiFaceNeighbor()),
96
97 _u_primary(_primary_var.slnNeighbor()),
98 _grad_u_primary(_primary_var.gradSlnNeighbor()),
99
100 _dof_map(_sys.dofMap()),
101 _node_to_elem_map(_mesh.nodeToElemMap()),
102
103 _overwrite_secondary_residual(true),
104 _primary_JxW(_assembly.JxWNeighbor())
105{
107
108 if (parameters.isParamValid("tangential_tolerance"))
109 {
110 _penetration_locator.setTangentialTolerance(getParam<Real>("tangential_tolerance"));
111 }
112 if (parameters.isParamValid("normal_smoothing_distance"))
113 {
114 _penetration_locator.setNormalSmoothingDistance(getParam<Real>("normal_smoothing_distance"));
115 }
116 if (parameters.isParamValid("normal_smoothing_method"))
117 {
119 parameters.get<std::string>("normal_smoothing_method"));
120 }
121 // Put a "1" into test_secondary
122 // will always only have one entry that is 1
123 _test_secondary[0].push_back(1);
124}
125
131
132void
133NodeFaceConstraint::computeSecondaryValue(NumericVector<Number> & current_solution)
134{
135 const dof_id_type & dof_idx = _var.nodalDofIndex();
136 _qp = 0;
137 current_solution.set(dof_idx, computeQpSecondaryValue());
138}
139
140void
145
146Real
148{
150 "The secondary residual has not yet been computed, so the value will be garbage!");
151 return _secondary_residual;
152}
153
154void
170
171void
173{
175
178
180
181 _qp = 0;
182
183 // Fill up _phi_secondary so that it is 1 when j corresponds to this dof and 0 for every other dof
184 // This corresponds to evaluating all of the connected shape functions at _this_ node
185 for (unsigned int j = 0; j < _connected_dof_indices.size(); j++)
186 {
187 _phi_secondary[j].resize(1);
188
190 _phi_secondary[j][_qp] = 1.0;
191 else
192 _phi_secondary[j][_qp] = 0.0;
193 }
194
195 for (_i = 0; _i < _test_secondary.size(); _i++)
196 // Loop over the connected dof indices so we can get all the jacobian contributions
197 for (_j = 0; _j < _connected_dof_indices.size(); _j++)
199
200 // Just do a direct assignment here because the Jacobian coming from assembly has already been
201 // properly sized according to the neighbor _var dof indices. It has also been zeroed
203 if (_Ken.m() && _Ken.n())
204 for (_i = 0; _i < _test_secondary.size(); _i++)
205 for (_j = 0; _j < _phi_primary.size(); _j++)
207 // Don't accumulate here
208
209 for (_i = 0; _i < _test_primary.size(); _i++)
210 // Loop over the connected dof indices so we can get all the jacobian contributions
211 for (_j = 0; _j < _connected_dof_indices.size(); _j++)
213
216 if (_local_ke.m() && _local_ke.n())
217 for (_i = 0; _i < _test_primary.size(); _i++)
218 for (_j = 0; _j < _phi_primary.size(); _j++)
221}
222
223void
225{
226 getConnectedDofIndices(jvar_num);
227
230
232
233 _qp = 0;
234
235 auto primary_jsize = getVariable(jvar_num).dofIndicesNeighbor().size();
236
237 // Fill up _phi_secondary so that it is 1 when j corresponds to this dof and 0 for every other dof
238 // This corresponds to evaluating all of the connected shape functions at _this_ node
239 for (unsigned int j = 0; j < _connected_dof_indices.size(); j++)
240 {
241 _phi_secondary[j].resize(1);
242
244 _phi_secondary[j][_qp] = 1.0;
245 else
246 _phi_secondary[j][_qp] = 0.0;
247 }
248
249 for (_i = 0; _i < _test_secondary.size(); _i++)
250 // Loop over the connected dof indices so we can get all the jacobian contributions
251 for (_j = 0; _j < _connected_dof_indices.size(); _j++)
253
254 // Just do a direct assignment here because the Jacobian coming from assembly has already been
255 // properly sized according to the jvar neighbor dof indices. It has also been zeroed
257 for (_i = 0; _i < _test_secondary.size(); _i++)
258 for (_j = 0; _j < primary_jsize; _j++)
260 // Don't accumulate here
261
262 if (_Kne.m() && _Kne.n())
263 for (_i = 0; _i < _test_primary.size(); _i++)
264 // Loop over the connected dof indices so we can get all the jacobian contributions
265 for (_j = 0; _j < _connected_dof_indices.size(); _j++)
267
269 for (_i = 0; _i < _test_primary.size(); _i++)
270 for (_j = 0; _j < primary_jsize; _j++)
273}
274
275void
277{
278 MooseVariableFEBase & var = _sys.getVariable(0, var_num);
279
281 std::set<dof_id_type> unique_dof_indices;
282
283 auto node_to_elem_pair = _node_to_elem_map.find(_current_node->id());
284 mooseAssert(node_to_elem_pair != _node_to_elem_map.end(), "Missing entry in node to elem map");
285 const std::vector<dof_id_type> & elems = node_to_elem_pair->second;
286
287 // Get the dof indices from each elem connected to the node
288 for (const auto & cur_elem : elems)
289 {
290 std::vector<dof_id_type> dof_indices;
291
292 var.getDofIndices(_mesh.elemPtr(cur_elem), dof_indices);
293
294 for (const auto & dof : dof_indices)
295 unique_dof_indices.insert(dof);
296 }
297
298 for (const auto & dof : unique_dof_indices)
299 _connected_dof_indices.push_back(dof);
300}
301
302bool
307
308const std::set<BoundaryID> &
315
316std::set<SubdomainID>
Base class for all Constraint types.
Definition Constraint.h:20
unsigned int _qp
Definition Constraint.h:36
unsigned int _j
Definition Constraint.h:35
unsigned int _i
Definition Constraint.h:35
static InputParameters validParams()
Definition Constraint.C:15
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system.
void addParam(const std::string &name, const S &value, const std::string &doc_string)
These methods add an optional parameter and a documentation string to the InputParameters object.
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.
void addRelationshipManager(const std::string &name, Moose::RelationshipManagerType rm_type, Moose::RelationshipManagerInputParameterCallback input_parameter_callback=nullptr)
Tells MOOSE about a RelationshipManager that this object needs.
T & set(const std::string &name, bool quiet_mode=false)
Returns a writable reference to the named parameters.
void addCoupledVar(const std::string &name, const std::string &doc_string)
This method adds a coupled variable name pair.
bool isParamValid(const std::string &name) const
This method returns parameters that have been initialized in one fashion or another,...
const InputParameters & parameters() const
Get the parameters of the object.
Definition MooseBase.h:131
This is a "smart" enum class intended to replace many of the shortcomings in the C++ enum type It sho...
Definition MooseEnum.h:55
virtual Elem * elemPtr(const dof_id_type i)
Definition MooseMesh.C:3214
std::set< SubdomainID > getBoundaryConnectedBlocks(const BoundaryID bid) const
Get the list of subdomains associated with the given boundary.
Definition MooseMesh.C:3622
virtual bool enabled() const
Return the enabled status of the object.
Definition MooseObject.h:49
virtual void getDofIndices(const Elem *, std::vector< dof_id_type > &) const
unsigned int number() const
Get variable number coming from libMesh.
void addMooseVariableDependency(MooseVariableFieldBase *var)
Call this function to add the passed in MooseVariableFieldBase as a variable that this object depends...
const dof_id_type & nodalDofIndex() const override
This class provides an interface for common operations on field variables of both FE and FV types wit...
virtual const std::vector< dof_id_type > & dofIndicesNeighbor() const =0
Get neighbor DOF indices for currently selected element.
Intermediate base class that ties together all the interfaces for getting MooseVariables with the Moo...
Enhances MooseVariableInterface interface provide values from neighbor elements.
std::set< SubdomainID > getSecondaryConnectedBlocks() const
PenetrationLocator & _penetration_locator
const Node *const & _current_node
current node being processed
virtual Real computeQpSecondaryValue()=0
Compute the value the secondary node should have at the beginning of a timestep.
virtual void computeOffDiagJacobian(unsigned int jvar) override
Computes d-residual / d-jvar...
void residualSetup() override
Gets called just before the residual is computed and before this object is asked to do its job.
DenseMatrix< Number > _Kee
The Jacobian corresponding to the derivatives of the elemental/secondary residual with respect to the...
VariableTestValue _test_secondary
Shape function on the secondary side. This will always only have one entry and that entry will always...
std::vector< dof_id_type > _connected_dof_indices
virtual Real computeQpJacobian(Moose::ConstraintJacobianType type)=0
This is the virtual that derived classes should override for computing the Jacobian on neighboring el...
const VariableTestValue & _test_primary
Side test function.
bool _overwrite_secondary_residual
Whether or not the secondary's residual should be overwritten.
Real _secondary_residual
The value of the secondary residual.
DenseMatrix< Number > _Kne
The Jacobian corresponding to the derivatives of the neighbor/primary residual with respect to the el...
NodeFaceConstraint(const InputParameters &parameters)
virtual void computeJacobian() override
Computes the jacobian for the current element.
static InputParameters validParams()
const std::set< BoundaryID > & buildBoundaryIDs()
Builds the _boundary_ids data member and returns it.
virtual void computeResidual() override
Computes the residual Nodal residual.
const VariablePhiValue & _phi_primary
Side shape function.
virtual bool overwriteSecondaryResidual()
Whether or not the secondary's residual should be overwritten.
virtual Real computeQpOffDiagJacobian(Moose::ConstraintJacobianType, unsigned int)
This is the virtual that derived classes should override for computing the off-diag Jacobian.
VariablePhiValue _phi_secondary
Shape function on the secondary side. This will always.
MooseVariable & _primary_var
Primary side variable.
std::set< BoundaryID > _boundary_ids
the union of the secondary and primary boundary ids
virtual void getConnectedDofIndices(unsigned int var_num)
Gets the indices for all dofs connected to the constraint.
BoundaryID _secondary
Boundary ID for the secondary surface.
Real secondaryResidual() const
DenseMatrix< Number > _Ken
The Jacobian corresponding to the derivatives of the elemental/secondary residual with respect to the...
const std::unordered_map< dof_id_type, std::vector< dof_id_type > > & _node_to_elem_map
virtual Real computeQpResidual(Moose::ConstraintType type)=0
This is the virtual that derived classes should override for computing the residual on neighboring el...
virtual void computeSecondaryValue(NumericVector< Number > &current_solution)
Compute the value the secondary node should have at the beginning of a timestep.
BoundaryID _primary
Boundary ID for the primary surface.
bool _secondary_residual_computed
Whether the secondary residual has been computed.
void setNormalSmoothingMethod(std::string nsmString)
void setTangentialTolerance(Real tangential_tolerance)
void setNormalSmoothingDistance(Real normal_smoothing_distance)
MooseMesh & _mesh
Reference to this Kernel's mesh object.
Assembly & _assembly
Reference to this Kernel's assembly object.
const MooseVariableFieldBase & getVariable(unsigned int jvar_num) const
Retrieve the variable object from our system associated with jvar_num.
SystemBase & _sys
Reference to the EquationSystem object.
MooseVariableFieldBase & getVariable(THREAD_ID tid, const std::string &var_name) const
Gets a reference to a variable of with specified name.
Definition SystemBase.C:91
DenseMatrix< Number > _local_ke
Holds local Jacobian entries as they are accumulated by this Kernel.
void accumulateTaggedLocalMatrix()
Local Jacobian blocks will be appended by adding the current local kernel Jacobian.
void accumulateTaggedLocalResidual()
Local residual blocks will be appended by adding the current local kernel residual.
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...
void prepareVectorTagNeighbor(Assembly &assembly, unsigned int ivar)
Prepare data for computing element residual the according to active tags for DG and interface kernels...
void prepareVectorTag(Assembly &assembly, unsigned int ivar)
Prepare data for computing element residual according to active tags.
void assignTaggedLocalResidual()
Local residual blocks will assigned as the current local kernel residual.
DenseVector< Number > _local_re
Holds local residual entries as they are accumulated by this Kernel.
unsigned int n() const
unsigned int m() const
void resize(const unsigned int new_m, const unsigned int new_n)
MOOSE now contains C++17 code, so give a reasonable error message stating what the user can do to add...
@ Primary
Definition MooseTypes.h:814
@ Secondary
Definition MooseTypes.h:813
@ SecondarySecondary
Definition MooseTypes.h:852
@ SecondaryPrimary
Definition MooseTypes.h:853
@ PrimarySecondary
Definition MooseTypes.h:854
@ PrimaryPrimary
Definition MooseTypes.h:855
@ NeighborNeighbor
Definition MooseTypes.h:808
@ ElementNeighbor
Definition MooseTypes.h:806