libMesh
Loading...
Searching...
No Matches
mesh_generation_test.C
Go to the documentation of this file.
1#include <libmesh/libmesh.h>
2#include <libmesh/distributed_mesh.h>
3#include <libmesh/elem.h>
4#include <libmesh/cell_c0polyhedron.h>
5#include <libmesh/face_c0polygon.h>
6#include <libmesh/face_polygon.h>
7#include <libmesh/mesh.h>
8#include <libmesh/mesh_generation.h>
9#include <libmesh/mesh_tools.h>
10#include <libmesh/replicated_mesh.h>
11
12#include <timpi/parallel_implementation.h> // Communicator::sum definition
13
14#include "test_comm.h"
15#include "libmesh_cppunit.h"
16
17#include <memory>
18#include <vector>
19
20
21using namespace libMesh;
22
23class MeshGenerationTest : public CppUnit::TestCase
24{
30public:
32
36# ifdef LIBMESH_ENABLE_AMR
39// CPPUNIT_TEST( buildSphereEdge4 ); Doesn't work with AMR yet
40# endif
41
42#if LIBMESH_DIM > 1
51# ifdef LIBMESH_ENABLE_AMR
54# endif
55#endif
56#if LIBMESH_DIM > 2
70
71 // These tests throw an exception from contains_point() calls, and
72 // this simply aborts() when exceptions are not enabled.
73#ifdef LIBMESH_ENABLE_EXCEPTIONS
77
78#ifdef LIBMESH_ENABLE_AMR
80#endif
81#endif
82
83# ifdef LIBMESH_ENABLE_AMR
85# endif
86#endif
87
89
90protected:
91 std::unique_ptr<UnstructuredMesh> new_mesh (bool is_replicated)
92 {
93 if (is_replicated)
94 return std::make_unique<ReplicatedMesh>(*TestCommWorld);
95 return std::make_unique<DistributedMesh>(*TestCommWorld);
96 }
97
98public:
99 void setUp() {}
100
101 void tearDown() {}
102
103 void testBuildLine(UnstructuredMesh & mesh, unsigned int n, ElemType type)
104 {
105 MeshTools::Generation::build_line (mesh, n, -1.0, 2.0, type);
106 CPPUNIT_ASSERT_EQUAL(mesh.n_elem(), cast_int<dof_id_type>(n));
107 CPPUNIT_ASSERT_EQUAL(mesh.n_nodes(),
108 cast_int<dof_id_type>((Elem::type_to_n_nodes_map[type]-1)*n + 1));
109
111 CPPUNIT_ASSERT_EQUAL(bbox.min()(0), Real(-1.0));
112 CPPUNIT_ASSERT_EQUAL(bbox.max()(0), Real(2.0));
113
114 // Do serial assertions *after* all parallel assertions, so we
115 // stay in sync after failure on only some processor(s)
116 for (auto & elem : mesh.element_ptr_range())
117 CPPUNIT_ASSERT(elem->has_affine_map());
118 }
119
120 void testBuildSquare(UnstructuredMesh & mesh, unsigned int n, ElemType type)
121 {
122 MeshTools::Generation::build_square (mesh, n, n, -2.0, 3.0, -4.0, 5.0, type);
123 if (type == C0POLYGON)
124 CPPUNIT_ASSERT_EQUAL(mesh.n_elem(), cast_int<dof_id_type>(n*n + 4 + 2 * (n - 1) + ((n - 1) / 2)));
125 else if (Elem::type_to_n_sides_map[type] == 4)
126 CPPUNIT_ASSERT_EQUAL(mesh.n_elem(), cast_int<dof_id_type>(n*n));
127 else
128 CPPUNIT_ASSERT_EQUAL(mesh.n_elem(), cast_int<dof_id_type>(n*n*2));
129
130 switch (type)
131 {
132 case TRI3: // First-order elements
133 case QUAD4:
134 CPPUNIT_ASSERT_EQUAL(mesh.n_nodes(),
135 cast_int<dof_id_type>((n+1)*(n+1)));
136 break;
137 case TRI6: // Second-order elements
138 case QUAD9:
139 CPPUNIT_ASSERT_EQUAL(mesh.n_nodes(),
140 cast_int<dof_id_type>((2*n+1)*(2*n+1)));
141 break;
142 case QUAD8: // Not-really-second-order element missing center nodes
143 CPPUNIT_ASSERT_EQUAL(mesh.n_nodes(),
144 cast_int<dof_id_type>((2*n+1)*(2*n+1) - n*n));
145 break;
146 case TRI7: // Not-really-second-order element with extra center nodes
147 CPPUNIT_ASSERT_EQUAL(mesh.n_nodes(),
148 cast_int<dof_id_type>((2*n+1)*(2*n+1) + 2*n*n));
149 break;
150 case C0POLYGON:
151 CPPUNIT_ASSERT_EQUAL(mesh.n_nodes(),
152 cast_int<dof_id_type>(4 + 2*n*n + (n - 1) + 2*n + 2 * (n%2)));
153 break;
154 default: // Wait, what did we try to build?
155 CPPUNIT_ASSERT(false);
156 }
157
158 // Our bounding boxes can be loose on higher order elements, but
159 // we can at least assert that they're not too tight
161 CPPUNIT_ASSERT(bbox.min()(0) <= Real(-2.0));
162 CPPUNIT_ASSERT(bbox.max()(0) >= Real(3.0));
163 CPPUNIT_ASSERT(bbox.min()(1) <= Real(-4.0));
164 CPPUNIT_ASSERT(bbox.max()(1) >= Real(5.0));
165
166 if (type == C0POLYGON)
167 {
169 LIBMESH_ASSERT_FP_EQUAL(nodal_bbox.min()(0),
170 Real(-2.0),
172 LIBMESH_ASSERT_FP_EQUAL(nodal_bbox.max()(0),
173 Real(3.0),
175 LIBMESH_ASSERT_FP_EQUAL(nodal_bbox.min()(1),
176 Real(-4.0),
178 LIBMESH_ASSERT_FP_EQUAL(nodal_bbox.max()(1),
179 Real(5.0),
181 }
182
183 // Do serial assertions *after* all parallel assertions, so we
184 // stay in sync after failure on only some processor(s)
185 if (type != C0POLYGON)
186 for (auto & elem : mesh.element_ptr_range())
187 CPPUNIT_ASSERT(elem->has_affine_map());
188 }
189
190 void testBuildCube(UnstructuredMesh & mesh, unsigned int n, ElemType type)
191 {
192 MeshTools::Generation::build_cube (mesh, n, n, n, -2.0, 3.0, -4.0, 5.0, -6.0, 7.0, type);
193 if (type == C0POLYHEDRON)
194 {
195 const dof_id_type grid_nodes = cast_int<dof_id_type>((n+1)*(n+1)*(n+1));
196
197 CPPUNIT_ASSERT_EQUAL(mesh.n_elem(), cast_int<dof_id_type>(n*n*n));
198 CPPUNIT_ASSERT(mesh.n_nodes() >= grid_nodes);
199 CPPUNIT_ASSERT(mesh.n_nodes() <= grid_nodes + cast_int<dof_id_type>(n*n*n));
200 }
201 else
202 {
203 switch (Elem::type_to_n_sides_map[type])
204 {
205 case 4: // tets
206 CPPUNIT_ASSERT_EQUAL(mesh.n_elem(), cast_int<dof_id_type>(n*n*n*24));
207 break;
208 case 5: // prisms, pyramids
209 if (type == PRISM6 || type == PRISM15 || type == PRISM18 ||
210 type == PRISM20 || type == PRISM21)
211 CPPUNIT_ASSERT_EQUAL(mesh.n_elem(), cast_int<dof_id_type>(n*n*n*2));
212 else
213 CPPUNIT_ASSERT_EQUAL(mesh.n_elem(), cast_int<dof_id_type>(n*n*n*6));
214 break;
215 case 6: // hexes
216 CPPUNIT_ASSERT_EQUAL(mesh.n_elem(), cast_int<dof_id_type>(n*n*n));
217 break;
218 default:
219 libmesh_error();
220 }
221
222
223 switch (Elem::type_to_n_nodes_map[type])
224 {
225 case 4: // First-order tets
226 CPPUNIT_ASSERT_EQUAL(mesh.n_nodes(),
227 cast_int<dof_id_type>((n+1)*(n+1)*(n+1) + n*n*n + 3*(n+1)*n*n));
228 break;
229 case 6: // First-order prisms and hexes use the same nodes
230 case 8:
231 CPPUNIT_ASSERT_EQUAL(mesh.n_nodes(),
232 cast_int<dof_id_type>((n+1)*(n+1)*(n+1)));
233 break;
234 case 10: // Second-order tets
235 CPPUNIT_ASSERT_EQUAL(mesh.n_nodes(),
236 cast_int<dof_id_type>((2*n+1)*(2*n+1)*(2*n+1) + 14*n*n*n + 4*3*(n+1)*n*n));
237 break;
238 case 18:
239 case 27: // Second-order prisms and hexes use the same nodes
240 CPPUNIT_ASSERT_EQUAL(mesh.n_nodes(),
241 cast_int<dof_id_type>((2*n+1)*(2*n+1)*(2*n+1)));
242 break;
243 case 20:
244 if (type == HEX20)
245 CPPUNIT_ASSERT_EQUAL(mesh.n_nodes(),
246 cast_int<dof_id_type>((2*n+1)*(2*n+1)*(2*n+1) - n*n*n - 3*(n+1)*n*n));
247 if (type == PRISM20)
248 CPPUNIT_ASSERT_EQUAL(mesh.n_nodes(),
249 cast_int<dof_id_type>((2*n+1)*(2*n+1)*(2*n+1) + 2*(n+1)*n*n));
250 break;
251 case 21: // Prisms based on full Tri7 cross sections
252 CPPUNIT_ASSERT_EQUAL(mesh.n_nodes(),
253 cast_int<dof_id_type>((2*n+1)*(2*n+1)*(2*n+1) + 2*(2*n+1)*n*n));
254 break;
255 case 15: // weird partial order prism
256 CPPUNIT_ASSERT_EQUAL(mesh.n_nodes(),
257 cast_int<dof_id_type>((2*n+1)*(2*n+1)*(2*n+1) - n*n*n - 2*(n+1)*n*n));
258 break;
259 case 5: // pyramids
260 CPPUNIT_ASSERT_EQUAL(mesh.n_nodes(),
261 cast_int<dof_id_type>((n+1)*(n+1)*(n+1) + n*n*n));
262 break;
263 case 13:
264 CPPUNIT_ASSERT_EQUAL(mesh.n_nodes(),
265 cast_int<dof_id_type>((2*n+1)*(2*n+1)*(2*n+1) + 8*n*n*n - 3*(n+1)*n*n));
266 break;
267 case 14: // pyramids, tets
268 if (type == PYRAMID14)
269 CPPUNIT_ASSERT_EQUAL(mesh.n_nodes(),
270 cast_int<dof_id_type>((2*n+1)*(2*n+1)*(2*n+1) + 8*n*n*n));
271 else // TET14
272 CPPUNIT_ASSERT_EQUAL(mesh.n_nodes(),
273 cast_int<dof_id_type>((2*n+1)*(2*n+1)*(2*n+1) + 14*n*n*n + 4*3*(n+1)*n*n +
274 36*n*n*n + 4*3*(n+1)*n*n));
275 break;
276 default:
277 libmesh_error();
278 }
279 }
280
281 // Our bounding boxes can be loose on higher order elements, but
282 // we can at least assert that they're not too tight
284 CPPUNIT_ASSERT(bbox.min()(0) <= Real(-2.0));
285 CPPUNIT_ASSERT(bbox.max()(0) >= Real(3.0));
286 CPPUNIT_ASSERT(bbox.min()(1) <= Real(-4.0));
287 CPPUNIT_ASSERT(bbox.max()(1) >= Real(5.0));
288 CPPUNIT_ASSERT(bbox.min()(2) <= Real(-6.0));
289 CPPUNIT_ASSERT(bbox.max()(2) >= Real(7.0));
290
291 if (type == C0POLYHEDRON)
292 {
294 const Real expected_volume = Real(5) * Real(9) * Real(13);
295
296 LIBMESH_ASSERT_FP_EQUAL(nodal_bbox.min()(0),
297 Real(-2.0),
299 LIBMESH_ASSERT_FP_EQUAL(nodal_bbox.max()(0),
300 Real(3.0),
302 LIBMESH_ASSERT_FP_EQUAL(nodal_bbox.min()(1),
303 Real(-4.0),
305 LIBMESH_ASSERT_FP_EQUAL(nodal_bbox.max()(1),
306 Real(5.0),
308 LIBMESH_ASSERT_FP_EQUAL(nodal_bbox.min()(2),
309 Real(-6.0),
311 LIBMESH_ASSERT_FP_EQUAL(nodal_bbox.max()(2),
312 Real(7.0),
314 LIBMESH_ASSERT_FP_EQUAL(MeshTools::volume(mesh),
315 expected_volume,
317
318 for (auto & elem : mesh.element_ptr_range())
319 {
320 CPPUNIT_ASSERT_EQUAL(elem->type(), C0POLYHEDRON);
321 CPPUNIT_ASSERT_EQUAL(elem->n_sides(), 6u);
322 CPPUNIT_ASSERT(elem->n_sub_elem() > 0);
323 CPPUNIT_ASSERT(elem->volume() > 0);
324 }
325
326 // Verify that find_neighbors() actually linked the polyhedra to
327 // one another. This is a regression test for a bug where
328 // Polyhedron::low_order_key() hashed a face's nodes in their
329 // stored (winding) order rather than sorted; since two adjacent
330 // cells wind their shared face in opposite orders, the keys
331 // never matched and every interior face was left looking like a
332 // boundary face with no neighbor. For an n x n x n cube there
333 // are 3*(n-1)*n*n interior faces, each shared by two elements,
334 // so 2*3*(n-1)*n*n sides should carry a neighbor link.
335 int n_neighbor_links = 0;
336 for (auto & elem : mesh.active_local_element_ptr_range())
337 for (auto s : elem->side_index_range())
338 {
339 const Elem * neigh = elem->neighbor_ptr(s);
340 if (!neigh)
341 continue;
342 ++n_neighbor_links;
343
344 // Links to a non-remote neighbor must be reciprocal.
345 if (!neigh->is_remote())
346 {
347 const unsigned int ns = neigh->which_neighbor_am_i(elem);
348 CPPUNIT_ASSERT(ns < neigh->n_sides());
349 CPPUNIT_ASSERT(neigh->neighbor_ptr(ns) == elem);
350 }
351 }
352 mesh.comm().sum(n_neighbor_links);
353
354 CPPUNIT_ASSERT_EQUAL(n_neighbor_links,
355 static_cast<int>(2 * 3 * (n-1) * n * n));
356
357 return;
358 }
359
360 // We don't yet try to do affine map optimizations on pyramids
361 if (type == PYRAMID5 ||
362 type == PYRAMID13 ||
363 type == PYRAMID14)
364 return;
365
366 // Do serial assertions *after* all parallel assertions, so we
367 // stay in sync after failure on only some processor(s)
368 for (auto & elem : mesh.element_ptr_range())
369 CPPUNIT_ASSERT(elem->has_affine_map());
370 }
371
372 void testBuildSphere(unsigned int n_ref, ElemType type)
373 {
375 MeshTools::Generation::build_sphere (rmesh, 2.0, n_ref, type);
376
378 dmesh.allow_renumbering(false);
379 MeshTools::Generation::build_sphere (dmesh, 2.0, n_ref, type);
380 }
381
382
384
385 void tester(Builder f, unsigned int n, ElemType type)
386 {
387 for (int is_replicated = 0; is_replicated != 2; ++is_replicated)
388 {
389 for (int skip_renumber = 0 ; skip_renumber != 2; ++skip_renumber)
390 {
391 std::unique_ptr<UnstructuredMesh> mesh =
392 new_mesh(is_replicated);
393 mesh->allow_renumbering(!skip_renumber);
394 (this->*f)(*mesh, n, type);
395 }
396 }
397 }
398
402
403 void buildSphereEdge2 () { LOG_UNIT_TEST; testBuildSphere(2, EDGE2); }
404 void buildSphereEdge3 () { LOG_UNIT_TEST; testBuildSphere(2, EDGE3); }
405 void buildSphereEdge4 () { LOG_UNIT_TEST; testBuildSphere(2, EDGE4); }
406
415
416 void buildSphereTri3 () { LOG_UNIT_TEST; testBuildSphere(2, TRI3); }
417 void buildSphereQuad4 () { LOG_UNIT_TEST; testBuildSphere(2, QUAD4); }
418
427
428 // Verify that find_neighbors() links a C0Polyhedron to an adjacent
429 // standard element (here a TET4) across their shared triangular face.
430 // The polyhedron's side is a C0POLYGON while the tet's side is a TRI3,
431 // so Elem::operator== alone (which requires matching element types)
432 // would not match them; find_neighbors() falls back to a vertex-id
433 // comparison at such a mixed interface.
435 {
436 LOG_UNIT_TEST;
437
438 // Exercise both a replicated and a (genuinely) distributed mesh; on
439 // a DistributedMesh with more ranks than elements this used to be
440 // built in a way that dereferenced elements deleted by
441 // delete_remote_elements(), so we must not hold element pointers
442 // across prepare_for_use() and must reduce counts across ranks.
443 for (int is_replicated = 0; is_replicated != 2; ++is_replicated)
444 {
445 std::unique_ptr<UnstructuredMesh> mesh_ptr = new_mesh(is_replicated);
446 UnstructuredMesh & mesh = *mesh_ptr;
447
448 // Five nodes: {0,1,2,3} form a tet-shaped polyhedron, and the
449 // TET4 is {1,2,3,4} on the far side of the shared face {1,2,3}.
450 mesh.add_point(Point(0,0,0), 0);
451 mesh.add_point(Point(1,0,0), 1);
452 mesh.add_point(Point(0,1,0), 2);
453 mesh.add_point(Point(0,0,1), 3);
454 mesh.add_point(Point(1,1,1), 4);
455
456 auto tri = [&mesh](dof_id_type a, dof_id_type b, dof_id_type c)
457 {
458 auto p = std::make_shared<C0Polygon>(3);
459 p->set_node(0, mesh.node_ptr(a));
460 p->set_node(1, mesh.node_ptr(b));
461 p->set_node(2, mesh.node_ptr(c));
462 return std::shared_ptr<Polygon>(std::move(p));
463 };
464
465 std::vector<std::shared_ptr<Polygon>> faces =
466 { tri(0,1,2), tri(0,1,3), tri(1,2,3), tri(0,2,3) };
467
468 std::unique_ptr<Node> mid_elem_node;
469 std::unique_ptr<Elem> poly =
470 std::make_unique<C0Polyhedron>(faces, mid_elem_node);
471 if (mid_elem_node)
472 mesh.add_node(std::move(mid_elem_node));
473 poly->set_id() = 0;
474 mesh.add_elem(std::move(poly));
475
476 std::unique_ptr<Elem> tet = Elem::build(TET4);
477 tet->set_id() = 1;
478 tet->set_node(0, mesh.node_ptr(1));
479 tet->set_node(1, mesh.node_ptr(2));
480 tet->set_node(2, mesh.node_ptr(3));
481 tet->set_node(3, mesh.node_ptr(4));
482 mesh.add_elem(std::move(tet));
483
485
486 // find_neighbors() must link the polyhedron's C0POLYGON face to
487 // the tet's TRI3 face. Count the interface from each owned
488 // element's side and reduce, so the check is valid however the
489 // two elements are partitioned.
490 int poly_to_tet = 0, tet_to_poly = 0;
491 for (const Elem * elem : mesh.active_local_element_ptr_range())
492 for (auto s : elem->side_index_range())
493 {
494 const Elem * neigh = elem->neighbor_ptr(s);
495 if (!neigh)
496 continue;
497
498 if (elem->type() == C0POLYHEDRON)
499 {
500 ++poly_to_tet;
501 if (!neigh->is_remote())
502 {
503 CPPUNIT_ASSERT_EQUAL(neigh->type(), TET4);
504 CPPUNIT_ASSERT(neigh->neighbor_ptr
505 (neigh->which_neighbor_am_i(elem)) == elem);
506 }
507 }
508 else if (elem->type() == TET4)
509 {
510 ++tet_to_poly;
511 if (!neigh->is_remote())
512 {
513 CPPUNIT_ASSERT_EQUAL(neigh->type(), C0POLYHEDRON);
514 CPPUNIT_ASSERT(neigh->neighbor_ptr
515 (neigh->which_neighbor_am_i(elem)) == elem);
516 }
517 }
518 }
519 mesh.comm().sum(poly_to_tet);
520 mesh.comm().sum(tet_to_poly);
521
522 CPPUNIT_ASSERT_EQUAL(1, poly_to_tet);
523 CPPUNIT_ASSERT_EQUAL(1, tet_to_poly);
524 }
525 }
526
532
533 // These tests throw an exception from contains_point() calls, and
534 // this simply aborts() when exceptions are not enabled.
535#ifdef LIBMESH_ENABLE_EXCEPTIONS
539#endif
540
541 void buildSphereHex8 () { LOG_UNIT_TEST; testBuildSphere(2, HEX8); }
542 void buildSphereHex27 () { LOG_UNIT_TEST; testBuildSphere(2, HEX27); }
543};
544
545
void ErrorVector unsigned int
CPPUNIT_TEST(buildSquareQuad9)
CPPUNIT_TEST(buildLineEdge2)
std::unique_ptr< UnstructuredMesh > new_mesh(bool is_replicated)
void testBuildLine(UnstructuredMesh &mesh, unsigned int n, ElemType type)
CPPUNIT_TEST(buildLineEdge3)
LIBMESH_CPPUNIT_TEST_SUITE(MeshGenerationTest)
The goal of this test is to verify proper operation of MeshGeneration functions, as well as to indire...
CPPUNIT_TEST(buildCubePrism6)
CPPUNIT_TEST(buildCubePyramid13)
CPPUNIT_TEST(buildCubeTet4)
CPPUNIT_TEST(buildCubePrism18)
void testBuildSphere(unsigned int n_ref, ElemType type)
CPPUNIT_TEST(buildCubeHex20)
CPPUNIT_TEST(buildCubePrism15)
CPPUNIT_TEST(buildSphereEdge3)
CPPUNIT_TEST(buildCubeC0Polyhedron)
CPPUNIT_TEST(buildSphereEdge2)
CPPUNIT_TEST(buildLineEdge4)
void testBuildCube(UnstructuredMesh &mesh, unsigned int n, ElemType type)
CPPUNIT_TEST(buildCubeHex8)
CPPUNIT_TEST(buildSquareTri6)
CPPUNIT_TEST(buildSphereHex8)
CPPUNIT_TEST(buildSquareC0PolygonEven)
CPPUNIT_TEST(buildSquareTri3)
CPPUNIT_TEST(buildSquareQuad8)
CPPUNIT_TEST(buildCubeHex27)
CPPUNIT_TEST(buildSphereTri3)
CPPUNIT_TEST(buildCubeTet14)
void testBuildSquare(UnstructuredMesh &mesh, unsigned int n, ElemType type)
void tester(Builder f, unsigned int n, ElemType type)
CPPUNIT_TEST(buildCubePrism21)
CPPUNIT_TEST(buildSphereQuad4)
CPPUNIT_TEST(buildCubePyramid5)
CPPUNIT_TEST(buildSquareTri7)
CPPUNIT_TEST(buildCubePyramid14)
CPPUNIT_TEST(buildCubePrism20)
CPPUNIT_TEST(polyhedronTetNeighbor)
CPPUNIT_TEST(buildCubeTet10)
CPPUNIT_TEST(buildSquareC0PolygonOdd)
CPPUNIT_TEST(buildSphereHex27)
CPPUNIT_TEST(buildSquareQuad4)
void(MeshGenerationTest::* Builder)(UnstructuredMesh &, unsigned int, ElemType)
Defines a Cartesian bounding box by the two corner extremum.
const Point & max() const
const Point & min() const
The DistributedMesh class is derived from the MeshBase class, and is intended to provide identical fu...
dof_id_type & set_id()
Definition dof_object.h:841
This is the base class from which all geometric element types are derived.
Definition elem.h:96
unsigned int which_neighbor_am_i(const Elem *e) const
This function tells you which neighbor e is.
Definition elem.h:3057
static std::unique_ptr< Elem > build(const ElemType type, Elem *p=nullptr)
Definition elem.C:382
static const unsigned int type_to_n_sides_map[INVALID_ELEM]
This array maps the integer representation of the ElemType enum to the number of sides on the element...
Definition elem.h:759
virtual bool is_remote() const
Definition elem.h:617
static constexpr unsigned int type_to_n_nodes_map[INVALID_ELEM]
This array maps the integer representation of the ElemType enum to the number of nodes in the element...
Definition elem.h:664
virtual ElemType type() const =0
const Elem * neighbor_ptr(unsigned int i) const
Definition elem.h:2736
virtual const Node * node_ptr(const dof_id_type i) const =0
virtual dof_id_type n_elem() const =0
void allow_renumbering(bool allow)
If false is passed in then this mesh will no longer be renumbered when being prepared for use.
Definition mesh_base.h:1359
void prepare_for_use(const bool skip_renumber_nodes_and_elements, const bool skip_find_neighbors)
Prepare a newly created (or read) mesh for use.
Definition mesh_base.C:824
virtual dof_id_type n_nodes() const =0
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 Node * add_node(Node *n)=0
Add Node n to the end of the vertex array.
virtual Elem * add_elem(Elem *e)=0
Add elem e to the end of the element array.
const Parallel::Communicator & comm() const
A Point defines a location in LIBMESH_DIM dimensional Real space.
Definition point.h:41
The ReplicatedMesh class is derived from the MeshBase class, and is used to store identical copies of...
The UnstructuredMesh class is derived from the MeshBase class.
static const Real b
Communicator * TestCommWorld
MeshBase & mesh
CPPUNIT_TEST_SUITE_REGISTRATION(MeshGenerationTest)
void build_square(UnstructuredMesh &mesh, const unsigned int nx, const unsigned int ny, const Real xmin=0., const Real xmax=1., const Real ymin=0., const Real ymax=1., const ElemType type=INVALID_ELEM, const bool gauss_lobatto_grid=false)
A specialized build_cube() for 2D meshes.
void build_sphere(UnstructuredMesh &mesh, const Real radius=1, const unsigned int n_refinements=2, const ElemType type=INVALID_ELEM, const unsigned int n_smooth=2, const bool flat=true)
Fills mesh with a mesh discretizing a ball (||x||<= radius) or sphere (||x|| = radius) domain.
void build_line(UnstructuredMesh &mesh, const unsigned int nx, const Real xmin=0., const Real xmax=1., const ElemType type=INVALID_ELEM, const bool gauss_lobatto_grid=false)
A specialized build_cube() for 1D meshes.
void build_cube(UnstructuredMesh &mesh, const unsigned int nx=0, const unsigned int ny=0, const unsigned int nz=0, const Real xmin=0., const Real xmax=1., const Real ymin=0., const Real ymax=1., const Real zmin=0., const Real zmax=1., const ElemType type=INVALID_ELEM, const bool gauss_lobatto_grid=false)
Builds a (elements) cube.
Real volume(const MeshBase &mesh, unsigned int dim=libMesh::invalid_uint)
Find the total volume of a mesh (interpreting that as area for dim = 2, or total arc length for dim =...
libMesh::BoundingBox create_bounding_box(const MeshBase &mesh)
Definition mesh_tools.C:566
libMesh::BoundingBox create_nodal_bounding_box(const MeshBase &mesh)
Definition mesh_tools.C:591
The libMesh namespace provides an interface to certain functionality in the library.
ElemType
Defines an enum for geometric element types.
static constexpr Real TOLERANCE
uint8_t dof_id_type
Definition id_types.h:67
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real