1 #include <libmesh/libmesh.h> 2 #include <libmesh/node.h> 3 #include <libmesh/mesh_generation.h> 4 #include <libmesh/mesh_tools.h> 5 #include <libmesh/replicated_mesh.h> 6 #include <libmesh/elem.h> 7 #include <libmesh/utility.h> 8 #include <libmesh/reference_elem.h> 9 #include <unordered_map> 39 CPPUNIT_TEST( testEdge2 );
40 CPPUNIT_TEST( testEdge3 );
41 CPPUNIT_TEST( testEdge4 );
42 CPPUNIT_TEST( testOrientation );
44 CPPUNIT_TEST( testTri3 );
45 CPPUNIT_TEST( testTri6 );
46 CPPUNIT_TEST( testTri7 );
48 CPPUNIT_TEST( testQuad4 );
49 CPPUNIT_TEST( testQuad8 );
50 CPPUNIT_TEST( testQuad9 );
52 CPPUNIT_TEST( testTet4 );
53 CPPUNIT_TEST( testTet10 );
54 CPPUNIT_TEST( testTet14 );
56 CPPUNIT_TEST( testPyramid5 );
57 CPPUNIT_TEST( testPyramid13 );
58 CPPUNIT_TEST( testPyramid14 );
59 CPPUNIT_TEST( testPyramid18 );
61 CPPUNIT_TEST( testPrism6 );
62 CPPUNIT_TEST( testPrism18 );
63 CPPUNIT_TEST( testPrism20 );
64 CPPUNIT_TEST( testPrism21 );
66 CPPUNIT_TEST( testHex8 );
67 CPPUNIT_TEST( testHex20 );
68 CPPUNIT_TEST( testHex27 );
70 CPPUNIT_TEST_SUITE_END();
75 using Map = std::map<ElemType, std::map<dof_id_type, std::set<dof_id_type>>>;
82 m[
EDGE2][0].insert(1);
83 m[
EDGE2][1].insert(0);
85 m[
EDGE3][0].insert(2);
86 m[
EDGE3][1].insert(2);
87 m[
EDGE3][2].insert({0, 1});
89 m[
EDGE4][0].insert(2);
90 m[
EDGE4][1].insert(3);
91 m[
EDGE4][2].insert({0, 3});
92 m[
EDGE4][3].insert({2, 1});
94 m[
TRI3][0].insert({1, 2});
95 m[
TRI3][1].insert({0, 2});
96 m[
TRI3][2].insert({1, 0});
98 m[
TRI6][0].insert({3, 5});
99 m[
TRI6][1].insert({3, 4});
100 m[
TRI6][2].insert({5, 4});
101 m[
TRI6][3].insert({0, 1});
102 m[
TRI6][4].insert({1, 2});
103 m[
TRI6][5].insert({2, 0});
108 m[
QUAD4][0].insert({1, 3});
109 m[
QUAD4][1].insert({0, 2});
110 m[
QUAD4][2].insert({1, 3});
111 m[
QUAD4][3].insert({0, 2});
113 m[
QUAD8][0].insert({4, 7});
114 m[
QUAD8][1].insert({4, 5});
115 m[
QUAD8][2].insert({5, 6});
116 m[
QUAD8][3].insert({6, 7});
117 m[
QUAD8][4].insert({0, 1});
118 m[
QUAD8][5].insert({1, 2});
119 m[
QUAD8][6].insert({2, 3});
120 m[
QUAD8][7].insert({0, 3});
125 m[
TET4][0].insert({1, 2, 3});
126 m[
TET4][1].insert({0, 2, 3});
127 m[
TET4][2].insert({0, 1, 3});
128 m[
TET4][3].insert({0, 1, 2});
130 m[
TET10][0].insert({4, 6, 7});
131 m[
TET10][1].insert({4, 5, 8});
132 m[
TET10][2].insert({5, 6, 9});
133 m[
TET10][3].insert({7, 8, 9});
134 m[
TET10][4].insert({0, 1});
135 m[
TET10][5].insert({1, 2});
136 m[
TET10][6].insert({0, 2});
137 m[
TET10][7].insert({0, 3});
138 m[
TET10][8].insert({1, 3});
139 m[
TET10][9].insert({2, 3});
148 m[
PYRAMID5][4].insert({0, 1, 2, 3});
170 m[
PRISM6][0].insert({1, 2, 3});
171 m[
PRISM6][1].insert({0, 2, 4});
172 m[
PRISM6][2].insert({0, 1, 5});
173 m[
PRISM6][3].insert({0, 4, 5});
174 m[
PRISM6][4].insert({1, 3, 5});
175 m[
PRISM6][5].insert({2, 3, 4});
177 m[
PRISM18][0].insert({6, 8, 9});
178 m[
PRISM18][1].insert({6, 7, 10});
179 m[
PRISM18][2].insert({7, 8, 11});
180 m[
PRISM18][3].insert({9, 12, 14});
181 m[
PRISM18][4].insert({10, 12, 13});
182 m[
PRISM18][5].insert({11, 13, 14});
200 m[
HEX8][0].insert({1, 3, 4});
201 m[
HEX8][1].insert({0, 2, 5});
202 m[
HEX8][2].insert({1, 3, 6});
203 m[
HEX8][3].insert({0, 2, 7});
204 m[
HEX8][4].insert({0, 5, 7});
205 m[
HEX8][5].insert({1, 4, 6});
206 m[
HEX8][6].insert({2, 5, 7});
207 m[
HEX8][7].insert({3, 4, 6});
209 m[
HEX20][0].insert({8, 11, 12});
210 m[
HEX20][1].insert({8, 9, 13});
211 m[
HEX20][2].insert({9, 10, 14});
212 m[
HEX20][3].insert({10, 11, 15});
213 m[
HEX20][4].insert({12, 16, 19});
214 m[
HEX20][5].insert({13, 16, 17});
215 m[
HEX20][6].insert({14, 17, 18});
216 m[
HEX20][7].insert({15, 18, 19});
217 m[
HEX20][8].insert({0, 1});
218 m[
HEX20][9].insert({1, 2});
219 m[
HEX20][10].insert({2, 3});
220 m[
HEX20][11].insert({0, 3});
221 m[
HEX20][12].insert({0, 4});
222 m[
HEX20][13].insert({1, 5});
223 m[
HEX20][14].insert({2, 6});
224 m[
HEX20][15].insert({3, 7});
225 m[
HEX20][16].insert({4, 5});
226 m[
HEX20][17].insert({5, 6});
227 m[
HEX20][18].insert({6, 7});
228 m[
HEX20][19].insert({4, 7});
236 inline static const Map elem_type_to_neighbor_map = build_elem_type_to_neighbor_map();
244 const auto dim = ref_elem->dim();
257 mesh, n_elems_per_side, n_elems_per_side, 0., 1., 0., 1., elem_type);
275 libmesh_error_msg(
"Unsupported dimension " <<
dim);
278 const auto & neighbor_map = libmesh_map_find(elem_type_to_neighbor_map, elem_type);
281 std::unordered_map<dof_id_type, std::vector<const Elem *>> nodes_to_elem_map;
285 std::vector<const Node*> neighbor_nodes;
287 std::set<dof_id_type> node_ids_checked;
288 for (
const auto * elem :
mesh.element_ptr_range())
290 for (
const auto & node : elem->node_ref_range())
293 if (node_ids_checked.find(node.id()) != node_ids_checked.end())
298 for (
const auto * neigh : neighbor_nodes)
301 const auto & elems_containing_node = libmesh_map_find(nodes_to_elem_map, node.id());
302 const auto & elems_containing_neigh = libmesh_map_find(nodes_to_elem_map, neigh->id());
303 const Elem * common_elem =
nullptr;
304 for (
const auto * neigh_elem : elems_containing_neigh)
306 if ((std::find(elems_containing_node.begin(), elems_containing_node.end(), neigh_elem) !=
307 elems_containing_node.end()))
308 common_elem = neigh_elem;
313 unsigned node_id_local = common_elem->
local_node(node.id());
314 unsigned neigh_id_local = common_elem->local_node(neigh->id());
320 const auto & correct_neighbor_ids = libmesh_map_find(neighbor_map, node_id_local);
321 CPPUNIT_ASSERT(correct_neighbor_ids.find(neigh_id_local) != correct_neighbor_ids.end());
326 node_ids_checked.insert(node.id());
506 std::vector<unsigned int> conn =
518 for (
unsigned int e=0; e<7; ++e)
528 for (
const auto & elem :
mesh.element_ptr_range())
530 auto elem_id = elem->id();
533 if (elem_id == 1 || elem_id == 2)
535 CPPUNIT_ASSERT(elem->neighbor_ptr(0) ==
nullptr);
536 CPPUNIT_ASSERT(elem->neighbor_ptr(1) !=
nullptr);
541 CPPUNIT_ASSERT(elem->neighbor_ptr(0) !=
nullptr);
542 CPPUNIT_ASSERT(elem->neighbor_ptr(1) !=
nullptr);
static const Order type_to_default_order_map[INVALID_ELEM]
This array maps the integer representation of the ElemType enum to the default approximation order of...
ElemType
Defines an enum for geometric element types.
The ReplicatedMesh class is derived from the MeshBase class, and is used to store identical copies of...
virtual Node *& set_node(const unsigned int i)
libMesh::Parallel::Communicator * TestCommWorld
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.
This is the base class from which all geometric element types are derived.
The libMesh namespace provides an interface to certain functionality in the library.
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.
virtual Elem * add_elem(Elem *e)=0
Add elem e to the end of the element array.
void do_test(ElemType elem_type)
static Map build_elem_type_to_neighbor_map()
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 ...
CPPUNIT_TEST_SUITE_REGISTRATION(NodalNeighborsTest)
unsigned int local_node(const dof_id_type i) const
virtual const Node * node_ptr(const dof_id_type i) const =0
std::map< ElemType, std::map< dof_id_type, std::set< dof_id_type > >> Map
A Point defines a location in LIBMESH_DIM dimensional Real space.
const Elem & get(const ElemType type_in)