14#include "libmesh/null_output_iterator.h"
15#include "libmesh/parallel.h"
16#include "libmesh/parallel_elem.h"
17#include "libmesh/parallel_node.h"
31struct CompareElemsByLevel
33 bool operator()(
const Elem * a,
const Elem * b)
const
37 const unsigned int al = a->level(), bl = b->level();
40 return (al == bl) ? aid < bid : al < bl;
53 "Constraint for enforcing that variables on each side of a boundary are equivalent.");
56 "The ID of the primary node. If no ID is provided, first node of secondary set is chosen.");
57 params.
addParam<Point>(
"primary_node_coord",
"Coordinates of the primary node to locate.");
58 params.
addParam<std::vector<unsigned int>>(
"secondary_node_ids",
"The IDs of the secondary node");
59 params.
addParam<BoundaryName>(
"secondary",
"The boundary ID associated with the secondary side");
60 params.
addRequiredParam<Real>(
"penalty",
"The penalty used for the boundary term");
89 paramError(
"secondary",
"Either secondary or secondary_node_ids must be provided.");
94 "Both 'secondary' and 'secondary_node_ids' parameters are set. They are mutually "
106 const auto & secondary_bnd = getParam<BoundaryName>(
"secondary");
109 for (
const auto & nid : secondary_nodes)
116 const auto & secondary_node_ids = getParam<std::vector<unsigned int>>(
"secondary_node_ids");
117 for (
const auto & nid : secondary_node_ids)
130 "Both 'primary' and 'primary_node_coord' parameters are set. They are mutually exclusive.");
132 dof_id_type primary_node_id = Node::invalid_id;
139 primary_node_id = getParam<unsigned int>(
"primary");
158 mooseAssert(primary_node_id != Node::invalid_id,
"We should have found a primary node");
174 std::unordered_set<dof_id_type> local_primary_node_ids;
175 const auto & primary_node_coord = getParam<Point>(
"primary_node_coord");
180 if ((*(bnd_node->_node) - primary_node_coord).norm() < eps)
190 local_primary_node_ids.insert(bnd_node->_node->id());
195 const std::vector<dof_id_type> local_node_vec(local_primary_node_ids.begin(),
196 local_primary_node_ids.end());
197 std::vector<std::vector<dof_id_type>> gathered_node_vecs;
201 std::unordered_set<dof_id_type> global_primary_node_ids;
202 for (
const auto & vec : gathered_node_vecs)
203 global_primary_node_ids.insert(vec.begin(), vec.end());
206 if (global_primary_node_ids.size() == 0)
207 mooseError(
"Couldn't find a node ID for the specified primary_node_coord.");
208 else if (global_primary_node_ids.size() > 1)
209 mooseError(
"Multiple nodes found for the specified primary_node_coord.");
211 return *global_primary_node_ids.begin();
219 bool found_elems = (node_to_elem_pair != node_to_elem_map.end());
228 bool someone_found_elems = found_elems;
230 mooseAssert(someone_found_elems,
"Missing entry in node to elem map");
233 std::set<Elem *, CompareElemsByLevel> primary_elems_to_ghost;
234 std::set<Node *> nodes_to_ghost;
237 for (dof_id_type
id : node_to_elem_pair->second)
242 primary_elems_to_ghost.insert(elem);
244 const unsigned int n_nodes = elem->n_nodes();
245 for (
unsigned int n = 0; n !=
n_nodes; ++n)
246 nodes_to_ghost.insert(elem->node_ptr(n));
253 nodes_to_ghost.begin(),
254 nodes_to_ghost.end(),
258 primary_elems_to_ghost.begin(),
259 primary_elems_to_ghost.end(),
269 found_elems = (node_to_elem_pair != new_node_to_elem_map.end());
273 mooseError(
"Couldn't find any elements connected to primary node");
275 const std::vector<dof_id_type> & elems = node_to_elem_pair->second;
277 if (elems.size() == 0)
278 mooseError(
"Couldn't find any elements connected to primary node");
registerMooseObject("MooseApp", EqualValueBoundaryConstraint)
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application.
dof_id_type getPrimaryNodeIDByCoord() const
Get the primary node ID by searching for the node with coordinates matching _primary_node_coord on th...
virtual Real computeQpJacobian(Moose::ConstraintJacobianType type) override
Computes the jacobian for the constraint.
void pickPrimaryNode()
Pick the primary node from user input or from the secondary node set.
void populateSecondaryNodes()
Populate the set of secondary nodes from user input.
void ghostPrimary()
Ghost elements and nodes connected to the primary node.
EqualValueBoundaryConstraint(const InputParameters ¶meters)
void updateConstrainedNodes()
Update the sets of nodes with constrained DOFs.
static InputParameters validParams()
Real _penalty
Penalty if constraint is not satisfied.
virtual void meshChanged() override
Called on this object when the mesh changes.
virtual Real computeQpResidual(Moose::ConstraintType type) override
Computes the residual for the current secondary node.
const std::string & type() const
Get the type of this class.
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 ...
bool isParamValid(const std::string &name) const
Test if the supplied parameter is valid.
virtual const Node & nodeRef(const dof_id_type i) const
MeshBase & getMesh()
Accessor for the underlying libMesh Mesh object.
void update()
Calls buildNodeListFromSideList(), buildNodeList(), and buildBndElemList().
const std::unordered_map< dof_id_type, std::vector< dof_id_type > > & nodeToElemMap()
If not already created, creates a map from every node to all elements to which they are connected.
virtual Elem * queryElemPtr(const dof_id_type i)
BoundaryID getBoundaryID(const BoundaryName &boundary_name) const
Get the associated BoundaryID for the boundary name.
const std::vector< dof_id_type > & getNodeList(boundary_id_type nodeset_id) const
Return a writable reference to a vector of node IDs that belong to nodeset_id.
libMesh::StoredRange< MooseMesh::const_bnd_node_iterator, const BndNode * > * getBoundaryNodeRange()
virtual const Node * queryNodePtr(const dof_id_type i) const
unsigned int _i
Counter for primary and secondary nodes.
std::vector< dof_id_type > _primary_node_vector
node IDs of the primary node
std::vector< dof_id_type > _connected_nodes
node IDs connected to the primary node (secondary nodes)
static InputParameters validParams()
const VariableValue & _u_secondary
Value of the unknown variable this BC is action on.
const VariableValue & _u_primary
Holds the current solution at the current quadrature point.
MooseMesh & _mesh
Reference to this Kernel's mesh object.
SubProblem & _subproblem
Reference to this kernel's SubProblem.
virtual void addGhostedElem(dof_id_type elem_id)=0
Will make sure that all dofs connected to elem_id are ghosted to this processor.
void min(const T &r, T &o, Request &req) const
void allgather(const T &send_data, std::vector< T, A > &recv_data) const
processor_id_type processor_id() const
const Parallel::Communicator & comm() const
static constexpr Real TOLERANCE
const dof_id_type n_nodes