21 #include "libmesh/sparse_matrix.h" 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");
37 "formulation", formulation,
"Formulation used to enforce the constraint");
40 "Penalty parameter used in constraint enforcement for kinematic and penalty formulations.");
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())
59 if (_formulation == Formulation::KINEMATIC)
60 this->
paramError(
"formulation",
"AD constraints cannot be used with KINEMATIC formulation.");
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};
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)))
82 for (
auto & sn : elem->node_ref_range())
85 if (_secondary_to_primary_map.find(sid) == _secondary_to_primary_map.end())
88 const Elem * me = pointLocator->operator()(sn, &allowed_subdomains);
92 _secondary_to_primary_map.insert(std::pair<dof_id_type, dof_id_type>(sid, mid));
93 _subproblem.addGhostedElem(mid);
100 template <
bool is_ad>
105 auto it = _secondary_to_primary_map.find(_current_node->id());
107 if (it != _secondary_to_primary_map.end())
109 const Elem * primary_elem = _mesh.elemPtr(it->second);
110 std::vector<Point> points = {*_current_node};
113 _fe_problem.setNeighborSubdomainID(primary_elem, 0);
114 _fe_problem.reinitNeighborPhys(primary_elem, points, 0);
123 template <
bool is_ad>
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);
131 switch (_formulation)
133 case Formulation::KINEMATIC:
134 _constraint_residual = -_residual_copy(dof_number);
137 case Formulation::PENALTY:
138 _constraint_residual = _penalty * (_u_secondary[0] - _u_primary[0]);
147 template <
bool is_ad>
154 template <
bool is_ad>
164 if (_formulation == Formulation::KINEMATIC)
169 return _test_secondary[_i][_qp] * resid;
173 return _test_primary[_i][_qp] * -resid;
179 template <
bool is_ad>
184 "In ADEqualValueEmbeddedConstraint, computeQpJacobian should not be called. " 185 "Check computeJacobian implementation.");
187 unsigned int sys_num = _sys.number();
189 Real curr_jac, secondary_jac;
194 switch (_formulation)
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];
207 switch (_formulation)
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];
218 switch (_formulation)
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];
231 switch (_formulation)
233 case Formulation::KINEMATIC:
235 case Formulation::PENALTY:
236 return _test_primary[_i][_qp] * penalty * _phi_primary[_j][_qp];
248 template <
bool is_ad>
254 "In ADEqualValueEmbeddedConstraint, computeQpOffDiagJacobian should not be called. " 255 "Check computeJacobian implementation.");
257 Real curr_jac, secondary_jac;
258 unsigned int sys_num = _sys.number();
263 curr_jac = (*_jacobian)(_current_node->dof_number(sys_num, _var.number(), 0),
264 _connected_dof_indices[_j]);
271 switch (_formulation)
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:
static InputParameters validParams()
virtual GenericReal< is_ad > computeQpResidual(Moose::ConstraintType type) override
This is the virtual method that derived classes should override for computing the residual...
Moose::GenericType< Real, is_ad > GenericReal
virtual Real computeQpJacobian(Moose::ConstraintJacobianType type) override
This is the virtual method that derived classes should override for computing the Jacobian...
A EqualValueEmbeddedConstraint forces the value of a variable to be the same on overlapping portion o...
virtual void reinitConstraint()
Prepare the residual contribution of the current constraint required to enforce it based on the speci...
void paramError(const std::string ¶m, Args... args) const
Emits an error prefixed with the file and line number of the given param (from the input file) along ...
Specialization of SubProblem for solving nonlinear equations plus auxiliary equations.
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application...
virtual void prepareSecondaryToPrimaryMap() override
prepare the _secondary_to_primary_map (see NodeElemConstraintBase)
bool _overwrite_secondary_residual
Whether or not the secondary's residual should be overwritten.
Specialization of SubProblem for solving nonlinear equations plus auxiliary equations.
static MooseEnum getNonlinearVariableOrders()
Get the possible variable orders.
registerMooseObject("MooseApp", EqualValueEmbeddedConstraint)
bool shouldApply() override final
Whether or not this constraint should be applied.
SimpleRange< IndexType > as_range(const std::pair< IndexType, IndexType > &p)
This is a "smart" enum class intended to replace many of the shortcomings in the C++ enum type It sho...
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.
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
EqualValueEmbeddedConstraintTempl(const InputParameters ¶meters)
static InputParameters validParams()
const Elem & get(const ElemType type_in)