Loading [MathJax]/extensions/tex2jax.js
libMesh
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Pages
exodus_test.C
Go to the documentation of this file.
1 #include "../geom/elem_test.h"
2 
3 #ifdef LIBMESH_HAVE_EXODUS_API
4 
5 #include "libmesh/enum_to_string.h"
6 #include "libmesh/exodusII_io.h"
7 #include "libmesh/mesh_communication.h"
8 #include "libmesh/mesh_serializer.h"
9 
10 using namespace libMesh;
11 
12 template <ElemType elem_type>
13 class ExodusTest : public PerElemTest<elem_type> {
14 
15 private:
16 
17  bool meshes_equal_enough(Mesh & other_mesh)
18  {
19  // We'll need to fix up processor_id() and unique_id() values
20  // before we can operator== these meshes. But worse: our gold
21  // meshes might have been numbered differently to our generated
22  // meshes. Some of our generated mesh options practically
23  // *require* renumbering (e.g. after interior HEX20 nodes are
24  // deleted, ExodusII still wants to see a contiguous numbering),
25  // but ReplicatedMesh and DistributedMesh renumber differently.
26  //
27  // So, let's renumber too.
28 
29  MeshSerializer serialthis(*this->_mesh);
30  MeshSerializer serialother(other_mesh);
31 
32  const dof_id_type max_elem_id = this->_mesh->max_elem_id();
33  const dof_id_type max_node_id = this->_mesh->max_node_id();
34 
35  CPPUNIT_ASSERT_EQUAL(max_elem_id, other_mesh.max_elem_id());
36  CPPUNIT_ASSERT_EQUAL(max_node_id, other_mesh.max_node_id());
37 
38  auto locator = other_mesh.sub_point_locator();
39 
40  for (Elem * e1 : this->_mesh->element_ptr_range())
41  {
42  const Elem * e2c = (*locator)(e1->vertex_average());
43  CPPUNIT_ASSERT(e2c);
44  Elem & e2 = other_mesh.elem_ref(e2c->id());
45  e1->processor_id() = 0;
46  e2.processor_id() = 0;
47 
48  const dof_id_type e1_id = e1->id();
49  const dof_id_type e2_id = e2.id();
50  // Do a swap if necessary, using a free temporary id
51  if (e1_id != e2_id)
52  {
53  other_mesh.renumber_elem(e1_id, max_elem_id);
54  other_mesh.renumber_elem(e2_id, e1_id);
55  other_mesh.renumber_elem(max_elem_id, e2_id);
56  }
57 
58 #ifdef LIBMESH_ENABLE_UNIQUE_ID
59  e2.set_unique_id(e1->unique_id());
60 #endif
61  }
62 
63  for (Node * n1 : this->_mesh->node_ptr_range())
64  {
65  const Elem * e1c = (*locator)(*n1);
66  Node * n2 = nullptr;
67  for (const Node & n : e1c->node_ref_range())
68  if (Point(*n1) == Point(n))
69  n2 = other_mesh.node_ptr(n.id());
70  CPPUNIT_ASSERT(n2);
71  n1->processor_id() = 0;
72  n2->processor_id() = 0;
73 
74  const dof_id_type n1_id = n1->id();
75  const dof_id_type n2_id = n2->id();
76  // Do a swap if necessary, using a free temporary id
77  if (n1_id != n2_id)
78  {
79  other_mesh.renumber_node(n1_id,max_node_id);
80  other_mesh.renumber_node(n2_id,n1_id);
81  other_mesh.renumber_node(max_node_id, n2_id);
82  }
83 
84 #ifdef LIBMESH_ENABLE_UNIQUE_ID
85  n2->set_unique_id(n1->unique_id());
86 #endif
87  }
88 
89 #ifdef LIBMESH_ENABLE_UNIQUE_ID
90  other_mesh.set_next_unique_id(this->_mesh->parallel_max_unique_id());
91  this->_mesh->set_next_unique_id(this->_mesh->parallel_max_unique_id());
92 #endif
93 
94  return *this->_mesh == other_mesh;
95  }
96 
97 public:
98 
100  {
101  LOG_UNIT_TEST;
102 
103  Mesh input_mesh(*TestCommWorld);
104 
105  ExodusII_IO exii(input_mesh);
106  if (input_mesh.processor_id() == 0)
107  exii.read("meshes/exodus_elements/read_exodus_" +
108  Utility::enum_to_string(elem_type) + ".e");
109 
110  MeshCommunication().broadcast(input_mesh);
111  input_mesh.prepare_for_use();
112 
113  CPPUNIT_ASSERT(this->meshes_equal_enough(input_mesh));
114  }
115 
116  void test_write()
117  {
118  LOG_UNIT_TEST;
119 
120  // This is a *buffered* write; we use scope to make sure the
121  // ExodusII_IO object gets destructed (and thus is guaranteed to
122  // finish writing and close the file) before we try to read what
123  // was written.
124  {
125  ExodusII_IO exii(*this->_mesh);
126  exii.write("write_exodus_" +
127  Utility::enum_to_string(elem_type) + ".e");
128  }
129 
130  Mesh input_mesh(*TestCommWorld);
131  ExodusII_IO exii_input(input_mesh);
132  if (input_mesh.processor_id() == 0)
133  exii_input.read("write_exodus_" +
134  Utility::enum_to_string(elem_type) + ".e");
135 
136  MeshCommunication().broadcast(input_mesh);
137  input_mesh.prepare_for_use();
138 
139  CPPUNIT_ASSERT(this->meshes_equal_enough(input_mesh));
140  }
141 };
142 
143 #define EXODUSTEST \
144  CPPUNIT_TEST( test_read_gold ); \
145  CPPUNIT_TEST( test_write );
146 
147 #define INSTANTIATE_EXODUSTEST(elemtype) \
148  class ExodusTest_##elemtype : public ExodusTest<elemtype> { \
149  public: \
150  ExodusTest_##elemtype() : \
151  ExodusTest<elemtype>() { \
152  if (unitlog->summarized_logs_enabled()) \
153  this->libmesh_suite_name = "ExodusTest"; \
154  else \
155  this->libmesh_suite_name = "ExodusTest_" #elemtype; \
156  } \
157  CPPUNIT_TEST_SUITE( ExodusTest_##elemtype ); \
158  EXODUSTEST; \
159  CPPUNIT_TEST_SUITE_END(); \
160  }; \
161  \
162  CPPUNIT_TEST_SUITE_REGISTRATION( ExodusTest_##elemtype )
163 
167 
168 #if LIBMESH_DIM > 1
173 
180 #endif // LIBMESH_DIM > 1
181 
182 #if LIBMESH_DIM > 2
186 
190 
196 
197 // These tests use PointLocator, which uses contains_point(), which
198 // uses inverse_map(), which doesn't play nicely on Pyramids unless we
199 // have exceptions support
200 #ifdef LIBMESH_ENABLE_EXCEPTIONS
205 #endif
206 #endif // LIBMESH_DIM > 2
207 
208 #endif // LIBMESH_HAVE_EXODUS_API
unique_id_type & set_unique_id()
Definition: dof_object.h:858
A Node is like a Point, but with more information.
Definition: node.h:52
std::unique_ptr< PointLocatorBase > sub_point_locator() const
Definition: mesh_base.C:1620
virtual void renumber_elem(dof_id_type old_id, dof_id_type new_id) override final
Changes the id of element old_id, both by changing elem(old_id)->id() and by moving elem(old_id) in t...
libMesh::Parallel::Communicator * TestCommWorld
Definition: driver.C:171
The ExodusII_IO class implements reading meshes in the ExodusII file format from Sandia National Labs...
Definition: exodusII_io.h:52
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.
Definition: mesh_base.C:741
bool meshes_equal_enough(Mesh &other_mesh)
Definition: exodus_test.C:17
This is the base class from which all geometric element types are derived.
Definition: elem.h:94
The libMesh namespace provides an interface to certain functionality in the library.
This is the MeshCommunication class.
dof_id_type id() const
Definition: dof_object.h:828
void test_read_gold()
Definition: exodus_test.C:99
virtual void set_next_unique_id(unique_id_type id) override
Sets the next available unique id to be used.
virtual void read(const std::string &name) override
This method implements reading a mesh from a specified file.
Definition: exodusII_io.C:224
std::string enum_to_string(const T e)
SimpleRange< NodeRefIter > node_ref_range()
Returns a range with all nodes of an element, usable in range-based for loops.
Definition: elem.h:2587
virtual void renumber_node(dof_id_type old_id, dof_id_type new_id) override final
Changes the id of node old_id, both by changing node(old_id)->id() and by moving node(old_id) in the ...
Temporarily serialize a DistributedMesh for non-distributed-mesh capable code paths.
virtual void write(const std::string &fname) override
This method implements writing a mesh to a specified file.
Definition: exodusII_io.C:2160
virtual dof_id_type max_node_id() const override final
void broadcast(MeshBase &) const
Finds all the processors that may contain elements that neighbor my elements.
INSTANTIATE_EXODUSTEST(EDGE2)
virtual const Elem & elem_ref(const dof_id_type i) const
Definition: mesh_base.h:634
The Mesh class is a thin wrapper, around the ReplicatedMesh class by default.
Definition: mesh.h:50
processor_id_type processor_id() const
virtual dof_id_type max_elem_id() const override final
processor_id_type processor_id() const
Definition: dof_object.h:905
A Point defines a location in LIBMESH_DIM dimensional Real space.
Definition: point.h:39
uint8_t dof_id_type
Definition: id_types.h:67
virtual const Node * node_ptr(const dof_id_type i) const override final
void test_write()
Definition: exodus_test.C:116