https://mooseframework.inl.gov
Loading...
Searching...
No Matches
NodalStickConstraint.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// MOOSE includes
12#include "DisplacedProblem.h"
13#include "MooseMesh.h"
14#include "Assembly.h"
15#include "SystemBase.h"
16
17// C++ includes
18#include <limits.h>
19
21
24{
26 params.addClassDescription("Sticky nodal constraint for contact");
27 params.addRequiredParam<BoundaryName>("boundary", "The primary boundary");
28 params.addRequiredParam<BoundaryName>("secondary", "The secondary boundary");
29 params.addRequiredParam<Real>("penalty", "Stiffness of the spring.");
30 return params;
31}
32
34 : NodalConstraint(parameters),
35 _primary_boundary_id(getParam<BoundaryName>("boundary")),
36 _secondary_boundary_id(getParam<BoundaryName>("secondary")),
37 _penalty(getParam<Real>("penalty"))
38{
40 paramError("variable_secondary",
41 "Primary variable must be identical to secondary variable. "
42 "Different variables are currently not supported.");
43
45}
46
47void
52
53void
55{
57 _connected_nodes.clear();
58 _primary_conn.clear();
59
60 std::vector<dof_id_type> secondary_nodelist =
62 std::vector<dof_id_type> primary_nodelist =
64
65 // Fill in _connected_nodes, which defines secondary nodes in the base class
66 for (auto in : secondary_nodelist)
67 {
68 if (_mesh.nodeRef(in).processor_id() == _subproblem.processor_id())
69 _connected_nodes.push_back(in);
70 }
71
72 // Fill in _primary_node_vector, which defines secondary nodes in the base class
73 for (auto in : primary_nodelist)
74 _primary_node_vector.push_back(in);
75
77 for (const auto elem_id : elem_ids)
79
81 {
82 const auto displaced_elem_ids =
84 if (displaced_elem_ids != elem_ids)
85 mooseError("Reference and displaced meshes selected different primary elements");
86 }
87
88 // Cache map between secondary node and primary node
89 _connected_nodes.clear();
90 _primary_conn.clear();
91 for (unsigned int j = 0; j < secondary_nodelist.size(); ++j)
92 {
93 if (_mesh.nodeRef(secondary_nodelist[j]).processor_id() == _subproblem.processor_id())
94 {
95 Node & secondary_node = _mesh.nodeRef(secondary_nodelist[j]);
96 for (unsigned int i = 0; i < _primary_node_vector.size(); ++i)
97 {
98 Node & primary_node = _mesh.nodeRef(_primary_node_vector[i]);
99 Real d = (secondary_node - primary_node).norm();
100 if (MooseUtils::absoluteFuzzyEqual(d, 0.0))
101 {
102 _primary_conn.push_back(i);
103 _connected_nodes.push_back(secondary_nodelist[j]);
104 break;
105 }
106 }
107 }
108 }
109}
110
111void
112NodalStickConstraint::computeJacobian(const SparseMatrix<Number> & jacobian)
113{
114 // Calculate Jacobian enteries and cache those entries along with the row and column indices
115 std::vector<dof_id_type> secondarydof = _var.dofIndicesNeighbor();
116 std::vector<dof_id_type> primarydof = _var.dofIndices();
117
118 DenseMatrix<Number> Kee(primarydof.size(), primarydof.size());
119 DenseMatrix<Number> Ken(primarydof.size(), secondarydof.size());
120 DenseMatrix<Number> Kne(secondarydof.size(), primarydof.size());
121 DenseMatrix<Number> Knn(secondarydof.size(), secondarydof.size());
122
123 Kee.zero();
124 Ken.zero();
125 Kne.zero();
126 Knn.zero();
127
128 for (_i = 0; _i < secondarydof.size(); ++_i)
129 {
131 switch (_formulation)
132 {
133 case Moose::Penalty:
138 break;
139 case Moose::Kinematic:
140 Kee(_j, _j) = 0.;
141 Ken(_j, _i) += jacobian(secondarydof[_i], primarydof[_j]);
142 Kne(_i, _j) += -jacobian(secondarydof[_i], primarydof[_j]) +
144 Knn(_i, _i) += -jacobian(secondarydof[_i], secondarydof[_i]) +
146 break;
147 }
148 }
149 addJacobian(_assembly, Kee, primarydof, primarydof, _var.scalingFactor());
150 addJacobian(_assembly, Ken, primarydof, secondarydof, _var.scalingFactor());
151 addJacobian(_assembly, Kne, secondarydof, primarydof, _var.scalingFactor());
152 addJacobian(_assembly, Knn, secondarydof, secondarydof, _var.scalingFactor());
153}
154
155void
156NodalStickConstraint::computeResidual(const NumericVector<Number> & residual)
157{
158 std::vector<dof_id_type> primarydof = _var.dofIndices();
159 std::vector<dof_id_type> secondarydof = _var.dofIndicesNeighbor();
160 DenseVector<Number> re(primarydof.size());
161 DenseVector<Number> neighbor_re(secondarydof.size());
162
163 re.zero();
164 neighbor_re.zero();
165 for (_i = 0; _i < secondarydof.size(); ++_i)
166 {
168 switch (_formulation)
169 {
170 case Moose::Penalty:
173 break;
174 case Moose::Kinematic:
175 // Transfer the current residual of the secondary node to the primary nodes
176 Real res = residual(secondarydof[_i]);
177 re(_j) += res;
178 neighbor_re(_i) += -res + computeQpResidual(Moose::Secondary);
179 break;
180 }
181 }
182 // We've already applied scaling
183 addResiduals(_assembly, re, primarydof, /*scaling_factor=*/1);
184 addResiduals(_assembly, neighbor_re, secondarydof, /*scaling_fator=*/1);
185}
186
187Real
189{
190 switch (type)
191 {
192 case Moose::Secondary:
193 return (_u_secondary[_i] - _u_primary[_j]) * _penalty;
194 case Moose::Primary:
195 return (_u_primary[_j] - _u_secondary[_i]) * _penalty;
196 }
197 return 0.;
198}
199
200Real
202{
203 switch (type)
204 {
206 return _penalty;
208 return -_penalty;
210 return _penalty;
212 return -_penalty;
213 default:
214 mooseError("Invalid type");
215 }
216 return 0.;
217}
registerMooseObject("SolidMechanicsApp", NodalStickConstraint)
std::shared_ptr< DisplacedProblem > displaced_problem
virtual std::shared_ptr< const DisplacedProblem > getDisplacedProblem() const
virtual MooseMesh & mesh() override
void addRequiredParam(const std::string &name, const std::string &doc_string)
void addClassDescription(const std::string &doc_string)
const std::string & type() const
void paramError(const std::string &param, Args... args) const
void mooseError(Args &&... args) const
virtual const Node & nodeRef(const dof_id_type i) const
BoundaryID getBoundaryID(const BoundaryName &boundary_name) const
const std::vector< dof_id_type > & getNodeList(boundary_id_type nodeset_id) const
void scalingFactor(const std::vector< Real > &factor)
unsigned int number() const
const std::vector< dof_id_type > & dofIndicesNeighbor() const final
const std::vector< dof_id_type > & dofIndices() const final
Moose::ConstraintFormulationType _formulation
unsigned int _i
unsigned int _j
std::vector< dof_id_type > _primary_node_vector
std::vector< dof_id_type > _connected_nodes
std::vector< dof_id_type > gatherAndRetainConnectedElems(MooseMesh &mesh, const std::vector< dof_id_type > &node_ids)
static InputParameters validParams()
MooseVariable & _var
MooseVariable & _var_secondary
const VariableValue & _u_secondary
const VariableValue & _u_primary
const Real & _penalty
Tangential stiffness of spring in all directions.
virtual void meshChanged() override
virtual void computeResidual() override final
std::vector< dof_id_type > _primary_conn
primary node id connected to each secondary node in _connected_nodes
NodalStickConstraint(const InputParameters &parameters)
virtual Real computeQpResidual(Moose::ConstraintType type) override
void updateConstrainedNodes()
Update the sets of nodes with constrained DOFs.
static InputParameters validParams()
BoundaryName _secondary_boundary_id
Holds the secondary node set or side set.
BoundaryName _primary_boundary_id
Holds the secondary node set or side set.
virtual Real computeQpJacobian(Moose::ConstraintJacobianType type) override
virtual void computeJacobian() override final
MooseMesh & _mesh
Assembly & _assembly
SubProblem & _subproblem
FEProblemBase & _fe_problem
virtual void addGhostedElem(dof_id_type elem_id)=0
void addJacobian(Assembly &assembly, const Residuals &residuals, const Indices &dof_indices, Real scaling_factor)
void addResiduals(Assembly &assembly, const Residuals &residuals, const Indices &dof_indices, Real scaling_factor)
processor_id_type processor_id() const
ConstraintType
ConstraintJacobianType
SecondarySecondary
SecondaryPrimary
PrimarySecondary
PrimaryPrimary