3#ifdef LIBMESH_HAVE_EXODUS_API
5#include "libmesh/cell_c0polyhedron.h"
6#include "libmesh/enum_to_string.h"
7#include "libmesh/exodusII_io.h"
8#include "libmesh/face_c0polygon.h"
9#include "libmesh/int_range.h"
10#include "libmesh/mesh_communication.h"
11#include "libmesh/mesh_generation.h"
12#include "libmesh/node.h"
20template <ElemType elem_type>
32 exii.
read(
"meshes/exodus_elements/read_exodus_" +
57 exii.
write(
"write_exodus_" +
64 exii_input.
read(
"write_exodus_" +
75 CPPUNIT_TEST(test_read_gold); \
76 CPPUNIT_TEST(test_write);
78#define INSTANTIATE_EXODUSTEST(elemtype) \
79 class ExodusTest_##elemtype : public ExodusTest<elemtype> \
82 ExodusTest_##elemtype() : ExodusTest<elemtype>() \
84 if (unitlog->summarized_logs_enabled()) \
85 this->libmesh_suite_name = "ExodusTest"; \
87 this->libmesh_suite_name = "ExodusTest_" #elemtype; \
89 CPPUNIT_TEST_SUITE(ExodusTest_##elemtype); \
91 CPPUNIT_TEST_SUITE_END(); \
94 CPPUNIT_TEST_SUITE_REGISTRATION(ExodusTest_##elemtype)
124 const std::vector<Point> points =
125 { {0, 0}, {1, 0}, {1.5, 0.5}, {1, 1}, {0, 1} };
130 std::unique_ptr<Elem> polygon =
131 std::make_unique<C0Polygon>(cast_int<unsigned int>(points.size()));
135 polygon->set_id() = 0;
150 exii.
write(
"write_exodus_C0POLYGON.e");
156 exii_input.
read(
"write_exodus_C0POLYGON.e");
161 CPPUNIT_ASSERT_EQUAL(cast_int<dof_id_type>(1), input_mesh.
n_elem());
164 bool found_elem = elem;
165 input_mesh.
comm().
max(found_elem);
166 CPPUNIT_ASSERT(found_elem);
172 CPPUNIT_ASSERT_EQUAL(5u, elem->
n_nodes());
175 CPPUNIT_ASSERT_EQUAL(cast_int<dof_id_type>(i), elem->
node_id(i));
195 const std::string &filename)
199 exii.
write(filename);
210 const std::vector<Point> &points,
211 const std::vector<std::vector<unsigned int>> &nodes_on_side)
216 std::vector<std::shared_ptr<Polygon>> sides(nodes_on_side.size());
219 const auto &nodes_on_s = nodes_on_side[s];
220 sides[s] = std::make_shared<C0Polygon>(nodes_on_s.size());
225 std::unique_ptr<Node> mid_elem_node;
226 std::unique_ptr<Elem> polyhedron =
227 std::make_unique<C0Polyhedron>(sides, mid_elem_node);
250 for (
auto &elem :
mesh.element_ptr_range())
251 elem->subdomain_id() = 1;
257 CPPUNIT_ASSERT_EQUAL(header_info.
num_dim, 3);
258 CPPUNIT_ASSERT_EQUAL(header_info.
num_elem, 8);
260 CPPUNIT_ASSERT_EQUAL(header_info.
num_face, 48);
271 const std::vector<Point> points =
272 { { 0, -2, 0}, {-1, -1, 0}, {-1, 1, 0},
273 { 0, 2, 0}, { 1, 1, 0}, { 1, -1, 0},
274 { 0, -2, 1}, {-1, -1, 1}, {-1, 1, 1},
275 { 0, 2, 1}, { 1, 1, 1}, { 1, -1, 1} };
277 const std::vector<std::vector<unsigned int>> nodes_on_side =
278 { {0, 1, 2, 3, 4, 5},
285 {6, 7, 8, 9, 10, 11} };
292 CPPUNIT_ASSERT_EQUAL(header_info.
num_dim, 3);
293 CPPUNIT_ASSERT_EQUAL(header_info.
num_elem, 1);
295 CPPUNIT_ASSERT_EQUAL(header_info.
num_face, 8);
306 const std::vector<Point> points =
307 { { 0, -2, 0}, {-1, -1, 0}, {-1, 1, 0},
308 { 0, 2, 0}, { 1, 1, 0}, { 1, -1, 0},
309 { 0, -2, 1}, {-1, -1, 1}, {-1, 1, 1},
310 { 0, 2, 1}, { 1, 1, 1}, { 1, -1, 1} };
312 const std::vector<std::vector<unsigned int>> nodes_on_side =
313 { {0, 1, 2, 3, 4, 5},
320 {6, 7, 8, 9, 10, 11} };
324 std::vector<std::vector<dof_id_type>> expected_nodes_on_side;
326 const bool have_output_elem = output_elem;
327 bool found_output_elem = have_output_elem;
329 CPPUNIT_ASSERT(found_output_elem);
333 expected_nodes_on_side.reserve(output_elem->
n_sides());
336 expected_nodes_on_side.emplace_back();
338 expected_nodes_on_side.back().push_back(output_elem->
node_id(n));
344 exii.
write(
"write_exodus_C0POLYHEDRON_HEXPRISM_READ.e");
350 exii_input.
read(
"write_exodus_C0POLYHEDRON_HEXPRISM_READ.e");
355 CPPUNIT_ASSERT_EQUAL(cast_int<dof_id_type>(1), input_mesh.
n_elem());
358 bool found_elem = elem;
359 input_mesh.
comm().
max(found_elem);
360 CPPUNIT_ASSERT(found_elem);
362 const bool can_compare = have_output_elem && elem;
363 bool found_comparable_elem = can_compare;
364 input_mesh.
comm().
max(found_comparable_elem);
365 CPPUNIT_ASSERT(found_comparable_elem);
371 CPPUNIT_ASSERT_EQUAL(12u, elem->
n_vertices());
372 CPPUNIT_ASSERT_EQUAL(8u, elem->
n_sides());
377 CPPUNIT_ASSERT_EQUAL(expected_nodes_on_side[s].size(), side_nodes.size());
378 for (
auto n :
index_range(expected_nodes_on_side[s]))
379 CPPUNIT_ASSERT_EQUAL(expected_nodes_on_side[s][n],
404#ifdef LIBMESH_ENABLE_EXCEPTIONS
LIBMESH_CPPUNIT_TEST_SUITE(ExodusC0PolygonTest)
void build_pentagon(Mesh &mesh)
CPPUNIT_TEST(test_write_and_read_pentagon)
void test_write_and_read_pentagon()
CPPUNIT_TEST(test_write_and_read_hexagonal_prism)
CPPUNIT_TEST(test_write_hexagonal_prism_header)
void test_write_hexagonal_prism_header()
void test_write_and_read_hexagonal_prism()
void test_write_cube_header()
void build_c0polyhedron(Mesh &mesh, const std::vector< Point > &points, const std::vector< std::vector< unsigned int > > &nodes_on_side)
ExodusHeaderInfo write_and_read_header(Mesh &mesh, const std::string &filename)
CPPUNIT_TEST(test_write_cube_header)
LIBMESH_CPPUNIT_TEST_SUITE(ExodusC0PolyhedronTest)
bool meshes_equal_enough(Mesh &other_mesh, bool double_precision)
std::unique_ptr< Mesh > _mesh
void max(const T &r, T &o, Request &req) const
void clear()
Clears the underlying data structures and restores the object to a pristine state with no data stored...
virtual dof_id_type n_elem() const override final
virtual const Elem * query_elem_ptr(const dof_id_type i) const override final
This is the base class from which all geometric element types are derived.
virtual unsigned int n_vertices() const =0
virtual unsigned int n_nodes() const =0
virtual std::vector< unsigned int > nodes_on_side(const unsigned int) const =0
subdomain_id_type subdomain_id() const
virtual ElemType type() const =0
virtual unsigned int n_sides() const =0
dof_id_type node_id(const unsigned int i) const
IntRange< unsigned short > side_index_range() const
The ExodusII_IO class implements reading meshes in the ExodusII file format from Sandia National Labs...
void set_max_name_length(unsigned int max_length)
For backwards compatibility, libMesh currently truncates names in ExodusII output to the old default ...
virtual void write(const std::string &fname) override
This method implements writing a mesh to a specified file.
ExodusHeaderInfo read_header(const std::string &name)
Read only the header information, instead of the entire mesh.
virtual void read(const std::string &name) override
This method implements reading a mesh from a specified file.
const BoundaryInfo & get_boundary_info() const
The information about boundary ids on the mesh.
virtual const Node * node_ptr(const dof_id_type i) const =0
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.
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 const Elem * query_elem_ptr(const dof_id_type i) const =0
virtual Elem * add_elem(Elem *e)=0
Add elem e to the end of the element array.
This is the MeshCommunication class.
void broadcast(MeshBase &) const
This method takes a mesh (which is assumed to reside on processor 0) and broadcasts it to all the oth...
The Mesh class is a thin wrapper, around the ReplicatedMesh class by default.
processor_id_type processor_id() const
const Parallel::Communicator & comm() const
Communicator * TestCommWorld
CPPUNIT_TEST_SUITE_REGISTRATION(ExodusC0PolygonTest)
INSTANTIATE_EXODUSTEST(EDGE2)
std::string enum_to_string(const T e)
The libMesh namespace provides an interface to certain functionality in the library.
auto index_range(const T &sizable)
Helper function that returns an IntRange<std::size_t> representing all the indices of the passed-in v...
IntRange< T > make_range(T beg, T end)
The 2-parameter make_range() helper function returns an IntRange<T> when both input parameters are of...