Skip to content

Commit 10cfbdd

Browse files
authored
Merge pull request #4392 from roystgnr/xdr_io_tests
XdrIO unit tests
2 parents 5df892a + 3f41357 commit 10cfbdd

62 files changed

Lines changed: 11000 additions & 142 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

tests/Makefile.am

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ unit_tests_sources = \
7878
mesh/mesh_input.C \
7979
mesh/mesh_smoother_test.C \
8080
mesh/mesh_stitch.C \
81+
mesh/mesh_elem_test.h \
8182
mesh/mesh_tet_test.C \
8283
mesh/mesh_triangulation.C \
8384
mesh/mixed_dim_mesh_test.C \
@@ -95,6 +96,7 @@ unit_tests_sources = \
9596
mesh/write_edgeset_data.C \
9697
mesh/write_vec_and_scalar.C \
9798
mesh/project_solution_test.C \
99+
mesh/xdrio_test.C \
98100
numerics/composite_function_test.C \
99101
numerics/coupling_matrix_test.C \
100102
numerics/distributed_vector_test.C \

tests/Makefile.in

Lines changed: 147 additions & 36 deletions
Large diffs are not rendered by default.

tests/geom/elem_test.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
#ifndef ELEM_TEST_H
2+
#define ELEM_TEST_H
3+
14
#include "test_comm.h"
25

36
#include <libmesh/elem.h>
@@ -296,3 +299,5 @@ class PerElemTest : public CppUnit::TestCase
296299
this->_mesh->sync_subdomain_name_map();
297300
}
298301
};
302+
303+
#endif // ELEM_TEST_H

tests/mesh/exodus_test.C

Lines changed: 5 additions & 106 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#include "../geom/elem_test.h"
1+
#include "mesh_elem_test.h"
22

33
#ifdef LIBMESH_HAVE_EXODUS_API
44

@@ -10,109 +10,8 @@
1010
using namespace libMesh;
1111

1212
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-
{
69-
#ifdef LIBMESH_DEFAULT_QUADRUPLE_PRECISION
70-
const Point diff = Point(*n1)-Point(n);
71-
72-
// We're testing against ExodusII input, and if we're in
73-
// triple or quadruple precision that means our lovely
74-
// higher-precision node coordinates got truncated to double
75-
// to be written. We need to adjust ours or they won't
76-
// satisfy operator== later.
77-
78-
// We're *also* testing against gold files that were
79-
// calculated at double precision, so just casting a higher
80-
// precision calculation to double won't give the exact same
81-
// result, we have to account for error.
82-
if (diff.norm() < 1e-15)
83-
for (auto d : make_range(LIBMESH_DIM))
84-
(*n1)(d) = double(n(d));
85-
#endif
86-
if (Point(*n1) == Point(n))
87-
n2 = other_mesh.node_ptr(n.id());
88-
}
89-
CPPUNIT_ASSERT(n2);
90-
n1->processor_id() = 0;
91-
n2->processor_id() = 0;
92-
93-
const dof_id_type n1_id = n1->id();
94-
const dof_id_type n2_id = n2->id();
95-
// Do a swap if necessary, using a free temporary id
96-
if (n1_id != n2_id)
97-
{
98-
other_mesh.renumber_node(n1_id,max_node_id);
99-
other_mesh.renumber_node(n2_id,n1_id);
100-
other_mesh.renumber_node(max_node_id, n2_id);
101-
}
102-
103-
#ifdef LIBMESH_ENABLE_UNIQUE_ID
104-
n2->set_unique_id(n1->unique_id());
105-
#endif
106-
}
107-
108-
#ifdef LIBMESH_ENABLE_UNIQUE_ID
109-
other_mesh.set_next_unique_id(this->_mesh->parallel_max_unique_id());
110-
this->_mesh->set_next_unique_id(this->_mesh->parallel_max_unique_id());
111-
#endif
112-
113-
return *this->_mesh == other_mesh;
114-
}
115-
13+
class ExodusTest : public MeshPerElemTest<elem_type>
14+
{
11615
public:
11716

11817
void test_read_gold()
@@ -129,7 +28,7 @@ public:
12928
MeshCommunication().broadcast(input_mesh);
13029
input_mesh.prepare_for_use();
13130

132-
CPPUNIT_ASSERT(this->meshes_equal_enough(input_mesh));
31+
CPPUNIT_ASSERT(this->meshes_equal_enough(input_mesh, true));
13332
}
13433

13534
void test_write()
@@ -161,7 +60,7 @@ public:
16160
MeshCommunication().broadcast(input_mesh);
16261
input_mesh.prepare_for_use();
16362

164-
CPPUNIT_ASSERT(this->meshes_equal_enough(input_mesh));
63+
CPPUNIT_ASSERT(this->meshes_equal_enough(input_mesh, true));
16564
}
16665
};
16766

tests/mesh/mesh_elem_test.h

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
#ifndef MESH_ELEM_TEST_H
2+
#define MESH_ELEM_TEST_H
3+
4+
#include "../geom/elem_test.h"
5+
6+
#include "libmesh/mesh_serializer.h"
7+
8+
using namespace libMesh;
9+
10+
template <ElemType elem_type>
11+
class MeshPerElemTest : public PerElemTest<elem_type>
12+
{
13+
protected:
14+
15+
bool meshes_equal_enough(Mesh & other_mesh, bool double_precision)
16+
{
17+
// We'll need to fix up processor_id() and unique_id() values
18+
// before we can operator== these meshes. But worse: our gold
19+
// meshes might have been numbered differently to our generated
20+
// meshes. Some of our generated mesh options practically
21+
// *require* renumbering (e.g. after interior HEX20 nodes are
22+
// deleted, ExodusII still wants to see a contiguous numbering),
23+
// but ReplicatedMesh and DistributedMesh renumber differently.
24+
//
25+
// So, let's renumber too.
26+
27+
MeshSerializer serialthis(*this->_mesh);
28+
MeshSerializer serialother(other_mesh);
29+
30+
const dof_id_type max_elem_id = this->_mesh->max_elem_id();
31+
const dof_id_type max_node_id = this->_mesh->max_node_id();
32+
33+
CPPUNIT_ASSERT_EQUAL(max_elem_id, other_mesh.max_elem_id());
34+
CPPUNIT_ASSERT_EQUAL(max_node_id, other_mesh.max_node_id());
35+
36+
auto locator = other_mesh.sub_point_locator();
37+
38+
for (Elem * e1 : this->_mesh->element_ptr_range())
39+
{
40+
const Elem * e2c = (*locator)(e1->vertex_average());
41+
CPPUNIT_ASSERT(e2c);
42+
Elem & e2 = other_mesh.elem_ref(e2c->id());
43+
e1->processor_id() = 0;
44+
e2.processor_id() = 0;
45+
46+
const dof_id_type e1_id = e1->id();
47+
const dof_id_type e2_id = e2.id();
48+
// Do a swap if necessary, using a free temporary id
49+
if (e1_id != e2_id)
50+
{
51+
other_mesh.renumber_elem(e1_id, max_elem_id);
52+
other_mesh.renumber_elem(e2_id, e1_id);
53+
other_mesh.renumber_elem(max_elem_id, e2_id);
54+
}
55+
56+
#ifdef LIBMESH_ENABLE_UNIQUE_ID
57+
e2.set_unique_id(e1->unique_id());
58+
#endif
59+
}
60+
61+
for (Node * n1 : this->_mesh->node_ptr_range())
62+
{
63+
const Elem * e1c = (*locator)(*n1);
64+
Node * n2 = nullptr;
65+
for (const Node & n : e1c->node_ref_range())
66+
{
67+
#if defined(LIBMESH_DEFAULT_QUADRUPLE_PRECISION) || defined(LIBMESH_DEFAULT_TRIPLE_PRECISION)
68+
if (double_precision)
69+
{
70+
const Point diff = Point(*n1)-Point(n);
71+
72+
// We may be testing against ExodusII input, and if
73+
// we're in triple or quadruple precision that means our
74+
// lovely higher-precision node coordinates got
75+
// truncated to double to be written. We need to adjust
76+
// ours or they won't satisfy operator== later.
77+
78+
// We're *also* testing against gold files that were
79+
// calculated at double precision, so just casting a
80+
// higher precision calculation to double won't give the
81+
// exact same result, we have to account for error.
82+
if (diff.norm() < 1e-15)
83+
for (auto d : make_range(LIBMESH_DIM))
84+
(*n1)(d) = double(n(d));
85+
}
86+
#endif
87+
if (Point(*n1) == Point(n))
88+
n2 = other_mesh.node_ptr(n.id());
89+
}
90+
CPPUNIT_ASSERT(n2);
91+
n1->processor_id() = 0;
92+
n2->processor_id() = 0;
93+
94+
const dof_id_type n1_id = n1->id();
95+
const dof_id_type n2_id = n2->id();
96+
// Do a swap if necessary, using a free temporary id
97+
if (n1_id != n2_id)
98+
{
99+
other_mesh.renumber_node(n1_id,max_node_id);
100+
other_mesh.renumber_node(n2_id,n1_id);
101+
other_mesh.renumber_node(max_node_id, n2_id);
102+
}
103+
104+
#ifdef LIBMESH_ENABLE_UNIQUE_ID
105+
n2->set_unique_id(n1->unique_id());
106+
#endif
107+
}
108+
109+
#ifdef LIBMESH_ENABLE_UNIQUE_ID
110+
other_mesh.set_next_unique_id(this->_mesh->parallel_max_unique_id());
111+
this->_mesh->set_next_unique_id(this->_mesh->parallel_max_unique_id());
112+
#endif
113+
114+
return *this->_mesh == other_mesh;
115+
}
116+
};
117+
118+
#endif // MESH_ELEM_TEST_H

0 commit comments

Comments
 (0)