17 #include "libmesh/elem.h" 18 #include "libmesh/mesh_base.h" 19 #include "libmesh/boundary_info.h" 26 AugmentSparsityOnInterface::validParams()
30 "The name of the primary boundary sideset.");
32 "The name of the secondary boundary sideset.");
34 "The name of the primary lower dimensional subdomain.");
36 "The name of the secondary lower dimensional subdomain.");
38 "ghost_point_neighbors",
40 "Whether we should ghost point neighbors of secondary lower-dimensional elements and " 41 "also their mortar interface couples for applications such as mortar nodal auxiliary " 44 "ghost_higher_d_neighbors",
46 "Whether we should ghost higher-dimensional neighbors. This is necessary when we are doing " 47 "second order mortar with finite volume primal variables, because in order for the method to " 48 "be second order we must use cell gradients, which couples in the neighbor cells.");
56 params.
set<
bool>(
"attach_geometric_early") =
false;
62 _primary_boundary_name(getParam<BoundaryName>(
"primary_boundary")),
63 _secondary_boundary_name(getParam<BoundaryName>(
"secondary_boundary")),
64 _primary_subdomain_name(getParam<SubdomainName>(
"primary_subdomain")),
65 _secondary_subdomain_name(getParam<SubdomainName>(
"secondary_subdomain")),
67 _ghost_point_neighbors(getParam<bool>(
"ghost_point_neighbors")),
68 _ghost_higher_d_neighbors(getParam<bool>(
"ghost_higher_d_neighbors"))
74 _primary_boundary_name(other._primary_boundary_name),
75 _secondary_boundary_name(other._secondary_boundary_name),
76 _primary_subdomain_name(other._primary_subdomain_name),
77 _secondary_subdomain_name(other._secondary_subdomain_name),
78 _is_coupling_functor(other._is_coupling_functor),
79 _ghost_point_neighbors(other._ghost_point_neighbors),
80 _ghost_higher_d_neighbors(other._ghost_higher_d_neighbors)
85 AugmentSparsityOnInterface::internalInitWithMesh(
const MeshBase &)
90 AugmentSparsityOnInterface::getInfo()
const 92 std::ostringstream oss;
93 oss <<
"AugmentSparsityOnInterface";
98 AugmentSparsityOnInterface::ghostMortarInterfaceCouplings(
100 const Elem *
const elem,
101 map_type & coupled_elements,
106 auto find_it = mic.find(elem->
id());
107 if (find_it == mic.end())
110 const auto & coupled_set = find_it->second;
112 for (
const auto coupled_elem_id : coupled_set)
115 mooseAssert(coupled_elem,
116 "The coupled element with id " << coupled_elem_id <<
" doesn't exist!");
119 coupled_elements.emplace(coupled_elem, _null_mat);
124 AugmentSparsityOnInterface::ghostLowerDSecondaryElemPointNeighbors(
126 const Elem *
const query_elem,
127 map_type & coupled_elements,
147 std::set<dof_id_type> secondary_lower_elems_handled;
157 auto find_it = mic.find(query_elem->
id());
158 if (find_it == mic.end())
161 const auto & coupled_set = find_it->second;
162 for (
const auto coupled_elem_id : coupled_set)
164 auto *
const coupled_elem =
_mesh->
elem_ptr(coupled_elem_id);
166 if (coupled_elem->
subdomain_id() != secondary_subdomain_id)
171 mooseAssert(coupled_elem->
dim() == query_elem->
dim(),
"These should be matching dim");
175 auto insert_pr = secondary_lower_elems_handled.insert(coupled_elem_id);
178 if (!insert_pr.second)
185 std::set<const Elem *> secondary_lower_elem_point_neighbors;
188 for (
const Elem *
const neigh : secondary_lower_elem_point_neighbors)
190 if (neigh->processor_id() != p)
191 coupled_elements.emplace(neigh, _null_mat);
193 ghostMortarInterfaceCouplings(p, neigh, coupled_elements, amg);
206 const Elem *
const query_elem,
207 map_type & coupled_elements,
217 if (query_elem->
subdomain_id() != secondary_subdomain_id)
226 auto find_it = mic.find(query_elem->
id());
227 if (find_it == mic.end())
231 const auto & lower_d_coupled_set = find_it->second;
232 for (
const auto coupled_elem_id : lower_d_coupled_set)
234 auto *
const coupled_elem =
_mesh->
elem_ptr(coupled_elem_id);
235 if (coupled_elem->
dim() == query_elem->
dim())
239 std::vector<const Elem *> active_neighbors;
245 if (!neigh || neigh == remote_elem)
252 for (
const auto & neighbor : active_neighbors)
253 if (neighbor->processor_id() != p)
256 neighbor->subdomain_id() != secondary_subdomain_id,
257 "Ensure that we aren't missing potential erasures from the secondary-to-msms map");
258 coupled_elements.emplace(neighbor, _null_mat);
266 const MeshBase::const_element_iterator & range_end,
268 map_type & coupled_elements)
274 const auto primary_boundary_id = generating_mesh
277 const auto secondary_boundary_id = generating_mesh
280 const auto primary_subdomain_id = generating_mesh
283 const auto secondary_subdomain_id = generating_mesh
289 std::make_pair(primary_boundary_id, secondary_boundary_id),
290 std::make_pair(primary_subdomain_id, secondary_subdomain_id),
303 for (
const Elem *
const elem :
_mesh->active_element_ptr_range())
311 coupled_elements.insert(std::make_pair(elem, _null_mat));
314 if (ip->on_boundary())
315 coupled_elements.insert(std::make_pair(elem, _null_mat));
324 "Primary boundary id should exist by now. If you're using a MeshModifier " 325 "please use the corresponding MeshGenerator instead");
327 "Secondary boundary id should exist by now. If you're using a MeshModifier " 328 "please use the corresponding MeshGenerator instead");
330 "Primary subdomain id should exist by now. If you're using a MeshModifier " 331 "please use the corresponding MeshGenerator instead");
333 "Secondary subdomain id should exist by now. If you're using a MeshModifier " 334 "please use the corresponding MeshGenerator instead");
343 coupled_elements.insert(std::make_pair(elem, _null_mat));
349 coupled_elements.insert(std::make_pair(elem, _null_mat));
355 "We should have set interior parents for all of our lower-dimensional mortar " 358 auto bnd_id = elem->
subdomain_id() == primary_subdomain_id ? primary_boundary_id
359 : secondary_boundary_id;
361 "The interior parent for the lower-dimensional element does not lie on the " 372 for (
const Elem *
const elem :
as_range(range_begin, range_end))
374 ghostMortarInterfaceCouplings(p, elem, coupled_elements, *amg);
376 if (_ghost_point_neighbors)
377 ghostLowerDSecondaryElemPointNeighbors(
378 p, elem, coupled_elements, secondary_boundary_id, secondary_subdomain_id, *amg);
379 if (_ghost_higher_d_neighbors)
380 ghostHigherDNeighbors(
381 p, elem, coupled_elements, secondary_boundary_id, secondary_subdomain_id, *amg);
389 if (
auto asoi = dynamic_cast<const AugmentSparsityOnInterface *>(&other))
391 if (_primary_boundary_name == asoi->_primary_boundary_name &&
392 _secondary_boundary_name == asoi->_secondary_boundary_name &&
393 _primary_subdomain_name == asoi->_primary_subdomain_name &&
394 _secondary_subdomain_name == asoi->_secondary_subdomain_name &&
395 _ghost_point_neighbors >= asoi->_ghost_point_neighbors &&
396 _ghost_higher_d_neighbors >= asoi->_ghost_higher_d_neighbors &&
baseGreaterEqual(*asoi))
402 std::unique_ptr<GhostingFunctor>
bool has_boundary_id(const Node *const node, const boundary_id_type id) const
RelationshipManagerType
Main types of Relationship Managers.
const Elem * interior_parent() const
IntRange< unsigned short > side_index_range() const
const BoundaryID INVALID_BOUNDARY_ID
unsigned int which_side_am_i(const Elem *e) const
FEProblemBase & feProblem()
Return a reference to this Executioner's FEProblemBase instance.
MooseMesh * _moose_mesh
Pointer to the MooseMesh object.
The following methods are specializations for using the libMesh::Parallel::packed_range_* routines fo...
const BoundaryInfo & get_boundary_info() const
Factory & getFactory()
Retrieve a writable reference to the Factory associated with this App.
This class is a container/interface for the objects involved in automatic generation of mortar spaces...
const SubdomainID INVALID_BLOCK_ID
const MeshBase * getMeshPtr() const
uint8_t processor_id_type
AugmentSparsityOnInterface(MeshBase &mesh, boundary_id_type crack_boundary_lower, boundary_id_type crack_boundary_upper)
boundary_id_type BoundaryID
SimpleRange< IndexType > as_range(const std::pair< IndexType, IndexType > &p)
void find_point_neighbors(const Point &p, std::set< const Elem * > &neighbor_set) const
const std::unordered_map< dof_id_type, std::unordered_set< dof_id_type > > & mortarInterfaceCoupling() const
MooseApp & _app
The MOOSE application this is associated with.
virtual bool baseGreaterEqual(const RelationshipManager &rhs) const
Whether the base class provides more or the same amount and type of ghosting as the rhs...
Executioner * getExecutioner() const
Retrieve the Executioner for this App.
void active_family_tree_by_neighbor(std::vector< const Elem * > &family, const Elem *neighbor, bool reset=true) const
virtual const Elem * elem_ptr(const dof_id_type i) const=0
const Elem * neighbor_ptr(unsigned int i) const
const bool _use_displaced_mesh
Which system this should go to (undisplaced or displaced)
RelationshipManagers are used for describing what kinds of non-local resources are needed for an obje...
subdomain_id_type subdomain_id() const
virtual unsigned short dim() const=0
const AutomaticMortarGeneration & getMortarInterface(const std::pair< BoundaryID, BoundaryID > &primary_secondary_boundary_pair, const std::pair< SubdomainID, SubdomainID > &primary_secondary_subdomain_pair, bool on_displaced) const
Return the undisplaced or displaced mortar generation object associated with the provided boundaries ...
static InputParameters validParams()
registerMooseObject("MooseApp", AugmentSparsityOnInterface)
virtual void operator()(const MeshBase::const_element_iterator &range_begin, const MeshBase::const_element_iterator &range_end, processor_id_type p, map_type &coupled_elements) override
virtual std::unique_ptr< GhostingFunctor > clone() const
MOOSE now contains C++17 code, so give a reasonable error message stating what the user can do to add...
processor_id_type processor_id() const
BoundaryID getBoundaryID(const BoundaryName &boundary_name) const
Get the associated BoundaryID for the boundary name.
SubdomainID getSubdomainID(const SubdomainName &subdomain_name) const
Get the associated subdomain ID for the subdomain name.