libMesh
checkpoint.C
Go to the documentation of this file.
1 #include "libmesh/distributed_mesh.h"
2 #include "libmesh/replicated_mesh.h"
3 #include "libmesh/checkpoint_io.h"
4 #include "libmesh/mesh_generation.h"
5 #include "libmesh/parallel.h"
6 #include "libmesh/partitioner.h"
7 
8 #include "test_comm.h"
9 #include "libmesh_cppunit.h"
10 
11 
12 using namespace libMesh;
13 
14 class CheckpointIOTest : public CppUnit::TestCase {
18 public:
19  LIBMESH_CPPUNIT_TEST_SUITE( CheckpointIOTest );
20 
21 #if LIBMESH_DIM > 1
22  CPPUNIT_TEST( testAsciiDistRepSplitter );
23  CPPUNIT_TEST( testBinaryDistRepSplitter );
24  CPPUNIT_TEST( testAsciiRepDistSplitter );
25  CPPUNIT_TEST( testBinaryRepDistSplitter );
26  CPPUNIT_TEST( testAsciiRepRepSplitter );
27  CPPUNIT_TEST( testBinaryRepRepSplitter );
28  CPPUNIT_TEST( testAsciiDistDistSplitter );
29  CPPUNIT_TEST( testBinaryDistDistSplitter );
30 #endif
31 
32  CPPUNIT_TEST_SUITE_END();
33 
34 protected:
35 
36 public:
37  void setUp()
38  {
39  }
40 
41  void tearDown()
42  {
43  }
44 
45  // Test that we can write multiple checkpoint files from a single processor.
46  template <typename MeshA, typename MeshB>
47  void testSplitter(bool binary, bool using_distmesh, bool skip_partition = false)
48  {
49  // The CheckpointIO-based splitter requires XDR.
50 #ifdef LIBMESH_HAVE_XDR
51 
52  // In this test, we partition the mesh into n_procs parts. Don't
53  // try to partition a DistributedMesh into more parts than we have
54  // processors, though.
55  const unsigned int n_procs = using_distmesh ?
56  std::min(static_cast<processor_id_type>(2), TestCommWorld->size()) :
57  2;
58 
59  // The number of elements in the original mesh. For verification
60  // later.
61  dof_id_type original_n_elem = 0;
62 
63  const std::string filename =
64  std::string("checkpoint_splitter.cp") + (binary ? "r" : "a");
65 
66  {
67  MeshA mesh(*TestCommWorld);
68 
70  4, 4,
71  0., 1.,
72  0., 1.,
73  QUAD4);
74 
75  // Store the number of elements that were in the original mesh.
76  original_n_elem = mesh.n_elem();
77 
78  // Partition the mesh into n_procs pieces
79  mesh.partition(n_procs);
80 
81  // Write out checkpoint files for each piece. Since on a
82  // ReplicatedMesh we might have more pieces than we do
83  // processors, some processors may have to write out more than
84  // one piece.
85  CheckpointIO cpr(mesh);
86  cpr.current_processor_ids().clear();
87  for (processor_id_type pid = mesh.processor_id(); pid < n_procs; pid += mesh.n_processors())
88  cpr.current_processor_ids().push_back(pid);
89  cpr.current_n_processors() = n_procs;
90  cpr.binary() = binary;
91  cpr.parallel() = true;
92  cpr.write(filename);
93  }
94 
96 
97  // Test that we can read in the files we wrote and sum up to the
98  // same total number of elements.
99  {
100  MeshB mesh(*TestCommWorld);
101  if (skip_partition)
102  mesh.skip_partitioning(true);
103 
104  CheckpointIO cpr(mesh);
105  cpr.current_n_processors() = n_procs;
106  cpr.binary() = binary;
107  cpr.read(filename);
108 
109  // If we decided to skip partitioning, then we shouldn't be
110  // waiting for a partition() call to get our n_partitions()
111  // cache in order
112  if (skip_partition)
113  CPPUNIT_ASSERT_EQUAL(mesh.n_partitions(), n_procs);
114 
115  std::size_t read_in_elements = 0;
116 
117  for (unsigned pid=mesh.processor_id(); pid<n_procs; pid += mesh.n_processors())
118  {
119  read_in_elements += std::distance(mesh.pid_elements_begin(pid),
120  mesh.pid_elements_end(pid));
121  }
122  mesh.comm().sum(read_in_elements);
123 
124  // Verify that we read in exactly as many elements as we started with.
125  CPPUNIT_ASSERT_EQUAL(static_cast<dof_id_type>(read_in_elements), original_n_elem);
126  }
127 #endif // LIBMESH_HAVE_XDR
128  }
129 
131  {
132  LOG_UNIT_TEST;
133 
134  testSplitter<DistributedMesh, ReplicatedMesh>(false, true);
135  }
136 
138  {
139  LOG_UNIT_TEST;
140 
141  testSplitter<DistributedMesh, ReplicatedMesh>(true, true);
142  }
143 
145  {
146  LOG_UNIT_TEST;
147 
148  testSplitter<ReplicatedMesh, DistributedMesh>(false, true);
149  }
150 
152  {
153  LOG_UNIT_TEST;
154 
155  testSplitter<ReplicatedMesh, DistributedMesh>(true, true);
156  }
157 
159  {
160  LOG_UNIT_TEST;
161 
162  testSplitter<ReplicatedMesh, ReplicatedMesh>(false, false);
163  }
164 
166  {
167  LOG_UNIT_TEST;
168 
169  testSplitter<ReplicatedMesh, ReplicatedMesh>(true, false);
170  }
171 
173  {
174  LOG_UNIT_TEST;
175 
176  testSplitter<DistributedMesh, DistributedMesh>(false, true);
177  }
178 
180  {
181  LOG_UNIT_TEST;
182 
183  testSplitter<DistributedMesh, DistributedMesh>(true, true);
184  }
185 
187  {
188  LOG_UNIT_TEST;
189 
190  testSplitter<DistributedMesh, DistributedMesh>(false, true, true);
191  }
192 
193 
194 };
195 
The CheckpointIO class can be used to write simplified restart files that can be used to restart simu...
Definition: checkpoint_io.h:61
virtual void write(const std::string &name) override
This method implements writing a mesh to a specified file.
const processor_id_type & current_n_processors() const
Get/Set the n_processors to use.
void testBinaryRepRepSplitter()
Definition: checkpoint.C:165
void skip_partitioning(bool skip)
If true is passed in then nothing on this mesh will be (re)partitioned.
Definition: mesh_base.h:1254
libMesh::Parallel::Communicator * TestCommWorld
Definition: driver.C:171
virtual void read(const std::string &input_name) override
This method implements reading a mesh from a specified file.
void sum(T &r) const
void testAsciiDistDistSplitterCache()
Definition: checkpoint.C:186
void barrier() const
MeshBase & mesh
const Parallel::Communicator & comm() const
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.
The libMesh namespace provides an interface to certain functionality in the library.
bool parallel() const
Get/Set the flag indicating if we should read/write binary.
Real distance(const Point &p)
void testSplitter(bool binary, bool using_distmesh, bool skip_partition=false)
Definition: checkpoint.C:47
virtual void partition(const unsigned int n_parts)
Call the default partitioner (currently metis_partition()).
Definition: mesh_base.C:1576
void testBinaryDistDistSplitter()
Definition: checkpoint.C:179
const std::vector< processor_id_type > & current_processor_ids() const
Get/Set the processor id or processor ids to use.
processor_id_type size() const
uint8_t processor_id_type
processor_id_type n_processors() const
void testAsciiRepRepSplitter()
Definition: checkpoint.C:158
CPPUNIT_TEST_SUITE_REGISTRATION(CheckpointIOTest)
unsigned int n_partitions() const
Definition: mesh_base.h:1345
void testAsciiDistDistSplitter()
Definition: checkpoint.C:172
void testAsciiDistRepSplitter()
Definition: checkpoint.C:130
bool binary() const
Get/Set the flag indicating if we should read/write binary.
void testBinaryDistRepSplitter()
Definition: checkpoint.C:137
void testBinaryRepDistSplitter()
Definition: checkpoint.C:151
virtual dof_id_type n_elem() const =0
processor_id_type processor_id() const
void testAsciiRepDistSplitter()
Definition: checkpoint.C:144
uint8_t dof_id_type
Definition: id_types.h:67