14 #include "libmesh/partitioner.h" 26 params.
addClassDescription(
"Break all element-element interfaces in the specified subdomains.");
27 params.
addRequiredParam<MeshGeneratorName>(
"input",
"The mesh we want to modify");
28 params.
addParam<std::vector<SubdomainID>>(
"subdomains",
"The list of subdomain IDs to explode.");
30 "interface_name",
"The boundary name containing all broken element-element interfaces.");
36 _input(getMesh(
"input")),
38 _interface_name(getParam<BoundaryName>(
"interface_name"))
42 std::unique_ptr<MeshBase>
45 std::unique_ptr<MeshBase>
mesh = std::move(
_input);
50 paramError(
"subdomains",
"The block ID '",
id,
"' was not found in the mesh");
52 BoundaryInfo & boundary_info =
mesh->get_boundary_info();
54 paramError(
"interface_name",
"The specified interface name already exits in the mesh.");
62 Partitioner::set_node_processor_ids(*
mesh);
69 std::unique_ptr<MeshBase> & mesh,
const std::vector<SubdomainID> & subdomains)
const 72 for (
const auto & elem :
mesh->active_element_ptr_range())
75 if (std::find(subdomains.begin(), subdomains.end(), elem->subdomain_id()) == subdomains.end())
78 std::set<const Elem *> neighbors;
79 elem->find_point_neighbors(neighbors);
85 bool should_duplicate =
true;
86 for (
auto neighbor : neighbors)
87 if (neighbor->contains_point(elem->node_ref(n)) &&
88 std::find(subdomains.begin(), subdomains.end(), neighbor->subdomain_id()) ==
91 should_duplicate =
false;
96 node_to_elem_map[elem->node_id(n)].insert(elem->id());
100 return node_to_elem_map;
107 for (
const auto & [node_id, connected_elem_ids] : node_to_elem_map)
108 for (
auto & connected_elem_id : connected_elem_ids)
109 if (connected_elem_id != *connected_elem_ids.begin())
116 const Node * node)
const 118 std::unique_ptr<Node> new_node = Node::build(*node, Node::invalid_id);
119 new_node->processor_id() = elem->processor_id();
120 Node * added_node =
mesh->add_node(std::move(new_node));
121 for (
const auto j : elem->node_index_range())
122 if (elem->node_id(j) == node->id())
124 elem->set_node(j, added_node);
129 BoundaryInfo & boundary_info =
mesh->get_boundary_info();
130 std::vector<boundary_id_type> node_boundary_ids;
131 boundary_info.boundary_ids(node, node_boundary_ids);
132 boundary_info.add_node(added_node, node_boundary_ids);
139 BoundaryInfo & boundary_info =
mesh.get_boundary_info();
140 const auto & existing_boundary_ids = boundary_info.get_boundary_ids();
142 existing_boundary_ids.empty() ? 0 : *existing_boundary_ids.rbegin() + 1;
145 std::set<std::pair<dof_id_type, unsigned int>> sides_to_add;
147 for (
const auto & node_to_elems : node_to_elem_map)
148 for (
const auto & elem_id_i : node_to_elems.second)
150 Elem * elem_i =
mesh.elem_ptr(elem_id_i);
151 for (
const auto & elem_id_j : node_to_elems.second)
153 Elem * elem_j =
mesh.elem_ptr(elem_id_j);
154 if (elem_i != elem_j && elem_id_i < elem_id_j && elem_i->has_neighbor(elem_j))
155 sides_to_add.insert(std::make_pair(elem_id_i, elem_i->which_neighbor_am_i(elem_j)));
159 for (
const auto & [elem_id, side] : sides_to_add)
160 boundary_info.add_side(elem_id, side, interface_id);
std::map< const dof_id_type, std::set< dof_id_type > > NodeToElemMapType
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 ...
NodeToElemMapType buildSubdomainRestrictedNodeToElemMap(std::unique_ptr< MeshBase > &mesh, const std::vector< SubdomainID > &subdomains) const
const BoundaryID INVALID_BOUNDARY_ID
static InputParameters validParams()
std::unique_ptr< T_DEST, T_DELETER > dynamic_pointer_cast(std::unique_ptr< T_SRC, T_DELETER > &src)
These are reworked from https://stackoverflow.com/a/11003103.
registerMooseObject("MooseApp", BreakMeshByElementGenerator)
bool hasSubdomainID(const MeshBase &input_mesh, const SubdomainID &id)
Whether a particular subdomain ID exists in the mesh.
std::unique_ptr< MeshBase > & _input
The mesh to modify.
static InputParameters validParams()
registerMooseObjectRenamed("MooseApp", ExplodeMeshGenerator, "05/18/2024 24:00", BreakMeshByElementGenerator)
void duplicateNode(std::unique_ptr< MeshBase > &mesh, Elem *elem, const Node *node) const
const BoundaryName _interface_name
IntRange< T > make_range(T beg, T end)
void duplicateNodes(std::unique_ptr< MeshBase > &mesh, const NodeToElemMapType &node_to_elem_map) const
std::unique_ptr< MeshBase > generate() override
Generate / modify the mesh.
BreakMeshByElementGenerator(const InputParameters ¶meters)
const std::vector< SubdomainID > & _subdomains
MeshGenerators are objects that can modify or add to an existing mesh.
void createInterface(MeshBase &mesh, const NodeToElemMapType &node_to_elem_map) const