https://mooseframework.inl.gov
Loading...
Searching...
No Matches
EqualValueEmbeddedConstraint.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
11#include "EigenADReal.h"
13#include "FEProblem.h"
14#include "DisplacedProblem.h"
15#include "AuxiliarySystem.h"
16#include "SystemBase.h"
17#include "Assembly.h"
18#include "MooseMesh.h"
19#include "AddVariableAction.h"
20
21#include "libmesh/sparse_matrix.h"
22
25
26template <bool is_ad>
29{
32 params.addClassDescription("This is a constraint enforcing overlapping portions of two blocks to "
33 "have the same variable value");
34 params.set<bool>("use_displaced_mesh") = false;
35 MooseEnum formulation(getFormulationOptions(), "kinematic");
36 params.addParam<MooseEnum>(
37 "formulation", formulation, "Formulation used to enforce the constraint");
38 params.addRequiredParam<Real>(
39 "penalty",
40 "Penalty parameter used in constraint enforcement for kinematic and penalty formulations.");
41
42 return params;
43}
44
45template <bool is_ad>
47 const InputParameters & parameters)
48 : GenericNodeElemConstraint<is_ad>(parameters),
49 _displaced_problem(parameters.get<FEProblemBase *>("_fe_problem_base")->getDisplacedProblem()),
50 _fe_problem(*parameters.get<FEProblem *>("_fe_problem")),
51 _formulation(this->template getParam<MooseEnum>("formulation").template getEnum<Formulation>()),
52 _penalty(this->template getParam<Real>("penalty")),
53 _residual_copy(_sys.residualGhosted())
54{
57 if constexpr (is_ad)
58 {
59 if (_formulation == Formulation::KINEMATIC)
60 this->paramError("formulation", "AD constraints cannot be used with KINEMATIC formulation.");
61 }
62}
63
64template <bool is_ad>
65void
67{
68 // get mesh pointLocator
69 std::unique_ptr<libMesh::PointLocatorBase> pointLocator = _mesh.getPointLocator();
70 pointLocator->enable_out_of_mesh_mode();
71 const std::set<subdomain_id_type> allowed_subdomains{_primary};
72
73 // secondary id and primary id
74 dof_id_type sid, mid;
75
76 // prepare _secondary_to_primary_map
77 std::set<dof_id_type> unique_secondary_node_ids;
78 const MeshBase & meshhelper = _mesh.getMesh();
79 for (const auto & elem : as_range(meshhelper.active_subdomain_elements_begin(_secondary),
80 meshhelper.active_subdomain_elements_end(_secondary)))
81 {
82 for (auto & sn : elem->node_ref_range())
83 {
84 sid = sn.id();
85 if (_secondary_to_primary_map.find(sid) == _secondary_to_primary_map.end())
86 {
87 // primary element
88 const Elem * me = pointLocator->operator()(sn, &allowed_subdomains);
89 if (me != NULL)
90 {
91 mid = me->id();
92 _secondary_to_primary_map.insert(std::pair<dof_id_type, dof_id_type>(sid, mid));
93 _subproblem.addGhostedElem(mid);
94 }
95 }
96 }
97 }
98}
99
100template <bool is_ad>
101bool
103{
104 // primary element
105 auto it = _secondary_to_primary_map.find(_current_node->id());
106
107 if (it != _secondary_to_primary_map.end())
108 {
109 const Elem * primary_elem = _mesh.elemPtr(it->second);
110 std::vector<Point> points = {*_current_node};
111
112 // reinit variables on the primary element at the secondary point
113 _fe_problem.setNeighborSubdomainID(primary_elem, 0);
114 _fe_problem.reinitNeighborPhys(primary_elem, points, 0);
115
116 reinitConstraint();
117
118 return true;
119 }
120 return false;
121}
122
123template <bool is_ad>
124void
126{
127 const Node * node = _current_node;
128 unsigned int sys_num = _sys.number();
129 dof_id_type dof_number = node->dof_number(sys_num, _var.number(), 0);
130
131 switch (_formulation)
132 {
133 case Formulation::KINEMATIC:
134 _constraint_residual = -_residual_copy(dof_number);
135 break;
136
137 case Formulation::PENALTY:
138 _constraint_residual = _penalty * (_u_secondary[0] - _u_primary[0]);
139 break;
140
141 default:
142 mooseError("Invalid formulation");
143 break;
144 }
145}
146
147template <bool is_ad>
148Real
153
154template <bool is_ad>
157{
158 GenericReal<is_ad> resid = _constraint_residual;
159
160 switch (type)
161 {
162 case Moose::Secondary:
163 {
164 if (_formulation == Formulation::KINEMATIC)
165 {
166 GenericReal<is_ad> pen_force = _penalty * (_u_secondary[_qp] - _u_primary[_qp]);
167 resid += pen_force;
168 }
169 return _test_secondary[_i][_qp] * resid;
170 }
171
172 case Moose::Primary:
173 return _test_primary[_i][_qp] * -resid;
174 }
175
176 return 0.0;
177}
178
179template <bool is_ad>
180Real
182{
183 mooseAssert(!is_ad,
184 "In ADEqualValueEmbeddedConstraint, computeQpJacobian should not be called. "
185 "Check computeJacobian implementation.");
186
187 unsigned int sys_num = _sys.number();
188 const Real penalty = MetaPhysicL::raw_value(_penalty);
189 Real curr_jac, secondary_jac;
190
191 switch (type)
192 {
194 switch (_formulation)
195 {
196 case Formulation::KINEMATIC:
197 curr_jac = (*_jacobian)(_current_node->dof_number(sys_num, _var.number(), 0),
198 _connected_dof_indices[_j]);
199 return -curr_jac + _phi_secondary[_j][_qp] * penalty * _test_secondary[_i][_qp];
200 case Formulation::PENALTY:
201 return _phi_secondary[_j][_qp] * penalty * _test_secondary[_i][_qp];
202 default:
203 mooseError("Invalid formulation");
204 }
205
207 switch (_formulation)
208 {
209 case Formulation::KINEMATIC:
210 return -_phi_primary[_j][_qp] * penalty * _test_secondary[_i][_qp];
211 case Formulation::PENALTY:
212 return -_phi_primary[_j][_qp] * penalty * _test_secondary[_i][_qp];
213 default:
214 mooseError("Invalid formulation");
215 }
216
218 switch (_formulation)
219 {
220 case Formulation::KINEMATIC:
221 secondary_jac = (*_jacobian)(_current_node->dof_number(sys_num, _var.number(), 0),
222 _connected_dof_indices[_j]);
223 return secondary_jac * _test_primary[_i][_qp];
224 case Formulation::PENALTY:
225 return -_phi_secondary[_j][_qp] * penalty * _test_primary[_i][_qp];
226 default:
227 mooseError("Invalid formulation");
228 }
229
231 switch (_formulation)
232 {
233 case Formulation::KINEMATIC:
234 return 0.0;
235 case Formulation::PENALTY:
236 return _test_primary[_i][_qp] * penalty * _phi_primary[_j][_qp];
237 default:
238 mooseError("Invalid formulation");
239 }
240
241 default:
242 mooseError("Unsupported type");
243 break;
244 }
245 return 0.0;
246}
247
248template <bool is_ad>
249Real
251 Moose::ConstraintJacobianType type, unsigned int /*jvar*/)
252{
253 mooseAssert(!is_ad,
254 "In ADEqualValueEmbeddedConstraint, computeQpOffDiagJacobian should not be called. "
255 "Check computeJacobian implementation.");
256
257 Real curr_jac, secondary_jac;
258 unsigned int sys_num = _sys.number();
259
260 switch (type)
261 {
263 curr_jac = (*_jacobian)(_current_node->dof_number(sys_num, _var.number(), 0),
264 _connected_dof_indices[_j]);
265 return -curr_jac;
266
268 return 0.0;
269
271 switch (_formulation)
272 {
273 case Formulation::KINEMATIC:
274 secondary_jac = (*_jacobian)(_current_node->dof_number(sys_num, _var.number(), 0),
275 _connected_dof_indices[_j]);
276 return secondary_jac * _test_primary[_i][_qp];
277 case Formulation::PENALTY:
278 return 0.0;
279 default:
280 mooseError("Invalid formulation");
281 }
282
284 return 0.0;
285
286 default:
287 mooseError("Unsupported type");
288 break;
289 }
290
291 return 0.0;
292}
293
registerMooseObject("MooseApp", EqualValueEmbeddedConstraint)
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application.
Definition MooseError.h:311
Moose::GenericType< Real, is_ad > GenericReal
Definition MooseTypes.h:698
static MooseEnum getNonlinearVariableOrders()
Get the possible variable orders.
A EqualValueEmbeddedConstraint forces the value of a variable to be the same on overlapping portion o...
EqualValueEmbeddedConstraintTempl(const InputParameters &parameters)
virtual Real computeQpOffDiagJacobian(Moose::ConstraintJacobianType type, unsigned int jvar) override
This is the virtual method that derived classes should override for computing the off-diag Jacobian.
virtual Real computeQpSecondaryValue() override
Compute the value the secondary node should have at the beginning of a timestep.
bool shouldApply() override final
Whether or not this constraint should be applied.
virtual void prepareSecondaryToPrimaryMap() override
prepare the _secondary_to_primary_map (see NodeElemConstraintBase)
virtual void reinitConstraint()
Prepare the residual contribution of the current constraint required to enforce it based on the speci...
virtual GenericReal< is_ad > computeQpResidual(Moose::ConstraintType type) override
This is the virtual method that derived classes should override for computing the residual.
virtual Real computeQpJacobian(Moose::ConstraintJacobianType type) override
This is the virtual method that derived classes should override for computing the Jacobian.
Specialization of SubProblem for solving nonlinear equations plus auxiliary equations.
Specialization of SubProblem for solving nonlinear equations plus auxiliary equations.
Definition FEProblem.h:21
static InputParameters validParams()
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.
void addRequiredParam(const std::string &name, const std::string &doc_string)
This method adds a parameter and documentation string to the InputParameters object that will be extr...
void addClassDescription(const std::string &doc_string)
This method adds a description of the class that will be displayed in the input file syntax dump.
T & set(const std::string &name, bool quiet_mode=false)
Returns a writable reference to the named parameters.
void paramError(const std::string &param, Args... args) const
Emits an error prefixed with the file and line number of the given param (from the input file) along ...
Definition MooseBase.h:457
This is a "smart" enum class intended to replace many of the shortcomings in the C++ enum type It sho...
Definition MooseEnum.h:55
bool _overwrite_secondary_residual
Whether or not the secondary's residual should be overwritten.
auto raw_value(const Eigen::Map< T > &in)
ConstraintType
Definition MooseTypes.h:812
@ Primary
Definition MooseTypes.h:814
@ Secondary
Definition MooseTypes.h:813
ConstraintJacobianType
Definition MooseTypes.h:851
@ SecondarySecondary
Definition MooseTypes.h:852
@ SecondaryPrimary
Definition MooseTypes.h:853
@ PrimarySecondary
Definition MooseTypes.h:854
@ PrimaryPrimary
Definition MooseTypes.h:855