23 #include "libmesh/mesh_tools.h" 24 #include "libmesh/mesh_subdivision_support.h" 25 #include "libmesh/boundary_info.h" 32 std::vector<const Node *> & nodes)
38 nodes.resize(valence + 6);
50 unsigned int j, i = 1;
92 const bool mesh_has_boundary_data =
95 std::vector<Elem *> new_boundary_elements;
96 std::vector<short int> new_boundary_sides;
97 std::vector<boundary_id_type> new_boundary_ids;
100 std::vector<boundary_id_type> ids;
102 for (
const auto & elem :
mesh.element_ptr_range())
104 libmesh_assert_equal_to(elem->type(),
TRI3);
107 tri->subdomain_id() = elem->subdomain_id();
108 tri->set_node(0, elem->node_ptr(0));
109 tri->set_node(1, elem->node_ptr(1));
110 tri->set_node(2, elem->node_ptr(2));
112 if (mesh_has_boundary_data)
114 for (
auto side : elem->side_index_range())
118 for (
const auto &
id : ids)
121 new_boundary_ids.push_back(
id);
122 new_boundary_elements.push_back(tri.get());
123 new_boundary_sides.push_back(side);
135 if (mesh_has_boundary_data)
138 libmesh_assert_greater(new_boundary_elements.size(), 0);
142 libmesh_assert_equal_to(new_boundary_sides.size(), new_boundary_elements.size());
143 libmesh_assert_equal_to(new_boundary_sides.size(), new_boundary_ids.size());
148 new_boundary_sides[s],
149 new_boundary_ids[s]);
176 std::unordered_map<dof_id_type, std::vector<const Elem *>> nodes_to_elem_map;
180 for (
auto & node :
mesh.node_ptr_range())
182 std::vector<const Node *> neighbors;
184 const unsigned int valence =
185 cast_int<unsigned int>(neighbors.size());
186 libmesh_assert_greater(valence, 1);
187 node->set_valence(valence);
190 for (
auto & elem :
mesh.element_ptr_range())
202 for (
auto & elem :
mesh.element_ptr_range())
207 for (
auto i : elem->side_index_range())
209 if (elem->neighbor_ptr(i) ==
nullptr)
213 if (elem->neighbor_ptr(
next[i]))
218 if (elem->neighbor_ptr(
prev[i]))
231 static const Real tol = 1e-5;
234 std::vector<Tri3Subdivision *> ghost_elems;
235 std::vector<Node *> ghost_nodes;
237 for (
unsigned int eid = 0; eid <
n_elem; ++eid)
250 libmesh_assert_not_equal_to(elem->
neighbor_ptr(i), elem);
257 for (
unsigned int l=0;l<4;l++)
268 Node * node =
nullptr;
269 for (
auto & ghost_node : ghost_nodes)
270 if ((*ghost_node - point).
norm() < tol * (elem->
point(k) - point).
norm())
280 ghost_nodes.push_back(node);
284 auto newelem = cast_ptr<Tri3Subdivision *>(uelem.get());
288 ghost_elems.push_back(newelem);
291 newelem->set_node(1, nelem->
node_ptr(k));
292 newelem->set_node(2, node);
293 newelem->set_neighbor(0, nelem);
294 newelem->set_ghost(
true);
296 newelem->set_neighbor(2,
nullptr);
310 auto newelem = cast_ptr<Tri3Subdivision *>(uelem.get());
313 newelem->set_node(1, nelem->
node_ptr(2));
315 newelem->set_neighbor(0, nelem);
317 newelem->set_ghost(
true);
318 newelem->set_neighbor(2, elem);
329 libmesh_assert_not_equal_to(elem->
neighbor_ptr(i), elem);
340 Node * node =
nullptr;
341 for (
auto & ghost_node : ghost_nodes)
342 if ((*ghost_node - point).
norm() < tol * (elem->
point(i) - point).
norm())
352 ghost_nodes.push_back(node);
356 auto newelem = cast_ptr<Tri3Subdivision *>(uelem.get());
358 ghost_elems.push_back(newelem);
361 newelem->set_node(1, elem->
node_ptr(i));
362 newelem->set_node(2, node);
363 newelem->set_neighbor(0, elem);
364 newelem->set_ghost(
true);
377 std::vector<std::unique_ptr<Elem>> missing_ghost_elems;
378 for (
auto & elem : ghost_elems)
382 for (
auto i : elem->side_index_range())
384 if (elem->neighbor_ptr(i) ==
nullptr &&
385 elem->neighbor_ptr(
prev[i]) !=
nullptr)
391 unsigned int n_nb = 0;
392 while (nb1 !=
nullptr && nb1->
id() != elem->id())
401 libmesh_assert_not_equal_to(nb2->
id(), elem->id());
421 Node * node =
nullptr;
422 for (
auto & ghost_node : ghost_nodes)
423 if ((*ghost_node - point).
norm() < tol * (nb2->
point(j) - point).
norm())
433 ghost_nodes.push_back(node);
437 auto newelem = cast_ptr<Tri3Subdivision *>(uelem.get());
439 newelem->set_node(0, nb2->
node_ptr(j));
441 newelem->set_node(2, node);
442 newelem->set_neighbor(0, nb2);
443 newelem->set_neighbor(1,
nullptr);
444 newelem->set_ghost(
true);
452 nb2 = cast_ptr<Tri3Subdivision *>(added_elem);
457 auto newelem = cast_ptr<Tri3Subdivision *>(uelem.get());
459 newelem->set_node(0, elem->node_ptr(
next[i]));
460 newelem->set_node(1, elem->node_ptr(i));
462 newelem->set_neighbor(0, elem);
463 newelem->set_neighbor(1, nb2);
464 newelem->set_neighbor(2,
nullptr);
465 newelem->set_ghost(
true);
467 elem->set_neighbor(i, newelem);
470 missing_ghost_elems.push_back(std::move(uelem));
477 for (
auto & elem : missing_ghost_elems)
A Node is like a Point, but with more information.
IntRange< unsigned short > side_index_range() const
void prepare_for_use(const bool skip_renumber_nodes_and_elements, const bool skip_find_neighbors)
Prepare a newly ecreated (or read) mesh for use.
void remove(const Node *node)
Removes the boundary conditions associated with node node, if any exist.
This is the base class from which all geometric element types are derived.
void boundary_ids(const Node *node, std::vector< boundary_id_type > &vec_to_fill) const
Fills a user-provided std::vector with the boundary ids associated with Node node.
The libMesh namespace provides an interface to certain functionality in the library.
const BoundaryInfo & get_boundary_info() const
The information about boundary ids on the mesh.
void prepare_subdivision_properties()
Prepares the element for use by reordering the nodes such that the irregular node (valence != 6)...
virtual Node * add_point(const Point &p, const dof_id_type id=DofObject::invalid_id, const processor_id_type proc_id=DofObject::invalid_processor_id)=0
Add a new Node at Point p to the end of the vertex array, with processor_id procid.
This is the MeshBase class.
std::size_t n_boundary_ids() const
Node * get_ordered_node(unsigned int node_id) const
void add_node(const Node *node, const boundary_id_type id)
Add Node node with boundary id id to the boundary information data structures.
bool is_subdivision_updated() const
virtual Elem * add_elem(Elem *e)=0
Add elem e to the end of the element array.
static std::unique_ptr< Elem > build(const ElemType type, Elem *p=nullptr)
The Tri3Subdivision element is a three-noded subdivision surface shell element used in mechanics calc...
unsigned int local_node_number(unsigned int node_id) const
void set_neighbor(const unsigned int i, Elem *n)
Assigns n as the neighbor.
unsigned int get_ordered_valence(unsigned int node_id) const
virtual const Elem * elem_ptr(const dof_id_type i) const =0
virtual Elem * insert_elem(Elem *e)=0
Insert elem e to the element array, preserving its id and replacing/deleting any existing element wit...
const Elem * neighbor_ptr(unsigned int i) const
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
void set_ghost(bool ghosted)
Sets the boolean flag identifying ghost elements.
const Node * node_ptr(const unsigned int i) const
static std::unique_ptr< Elem > build_with_id(const ElemType type, dof_id_type id)
Calls the build() method above with a nullptr parent, and additionally sets the newly-created Elem's ...
void add_side(const dof_id_type elem, const unsigned short int side, const boundary_id_type id)
Add side side of element number elem with boundary id id to the boundary information data structure...
virtual dof_id_type n_elem() const =0
virtual ElemType type() const =0
A Point defines a location in LIBMESH_DIM dimensional Real space.
const Point & point(const unsigned int i) const
auto index_range(const T &sizable)
Helper function that returns an IntRange<std::size_t> representing all the indices of the passed-in v...