libMesh
Loading...
Searching...
No Matches
Public Member Functions | List of all members
CheckpointIOTest Class Reference
Inheritance diagram for CheckpointIOTest:
[legend]

Public Member Functions

 LIBMESH_CPPUNIT_TEST_SUITE (CheckpointIOTest)
 This test verifies that we can write files with the CheckpointIO object.
 
 CPPUNIT_TEST (testAsciiDistRepSplitter)
 
 CPPUNIT_TEST (testBinaryDistRepSplitter)
 
 CPPUNIT_TEST (testAsciiRepDistSplitter)
 
 CPPUNIT_TEST (testBinaryRepDistSplitter)
 
 CPPUNIT_TEST (testAsciiRepRepSplitter)
 
 CPPUNIT_TEST (testBinaryRepRepSplitter)
 
 CPPUNIT_TEST (testAsciiDistDistSplitter)
 
 CPPUNIT_TEST (testBinaryDistDistSplitter)
 
 CPPUNIT_TEST (testAsciiC0Polygon)
 
 CPPUNIT_TEST (testBinaryC0Polygon)
 
 CPPUNIT_TEST (testAsciiC0Polyhedron)
 
 CPPUNIT_TEST (testBinaryC0Polyhedron)
 
 CPPUNIT_TEST_SUITE_END ()
 
void setUp ()
 
void tearDown ()
 
template<typename MeshA , typename MeshB >
void testSplitter (bool binary, bool using_distmesh, bool skip_partition=false)
 
void testC0PolygonCheckpoint (bool binary)
 
void testC0PolyhedronCheckpoint (bool binary)
 
void testAsciiDistRepSplitter ()
 
void testBinaryDistRepSplitter ()
 
void testAsciiRepDistSplitter ()
 
void testBinaryRepDistSplitter ()
 
void testAsciiRepRepSplitter ()
 
void testBinaryRepRepSplitter ()
 
void testAsciiDistDistSplitter ()
 
void testBinaryDistDistSplitter ()
 
void testAsciiC0Polygon ()
 
void testBinaryC0Polygon ()
 
void testAsciiC0Polyhedron ()
 
void testBinaryC0Polyhedron ()
 
void testAsciiDistDistSplitterCache ()
 

Detailed Description

Definition at line 19 of file checkpoint.C.

Member Function Documentation

◆ CPPUNIT_TEST() [1/12]

CheckpointIOTest::CPPUNIT_TEST ( testAsciiC0Polygon  )

◆ CPPUNIT_TEST() [2/12]

CheckpointIOTest::CPPUNIT_TEST ( testAsciiC0Polyhedron  )

◆ CPPUNIT_TEST() [3/12]

CheckpointIOTest::CPPUNIT_TEST ( testAsciiDistDistSplitter  )

◆ CPPUNIT_TEST() [4/12]

CheckpointIOTest::CPPUNIT_TEST ( testAsciiDistRepSplitter  )

◆ CPPUNIT_TEST() [5/12]

CheckpointIOTest::CPPUNIT_TEST ( testAsciiRepDistSplitter  )

◆ CPPUNIT_TEST() [6/12]

CheckpointIOTest::CPPUNIT_TEST ( testAsciiRepRepSplitter  )

◆ CPPUNIT_TEST() [7/12]

CheckpointIOTest::CPPUNIT_TEST ( testBinaryC0Polygon  )

◆ CPPUNIT_TEST() [8/12]

CheckpointIOTest::CPPUNIT_TEST ( testBinaryC0Polyhedron  )

◆ CPPUNIT_TEST() [9/12]

CheckpointIOTest::CPPUNIT_TEST ( testBinaryDistDistSplitter  )

◆ CPPUNIT_TEST() [10/12]

CheckpointIOTest::CPPUNIT_TEST ( testBinaryDistRepSplitter  )

◆ CPPUNIT_TEST() [11/12]

CheckpointIOTest::CPPUNIT_TEST ( testBinaryRepDistSplitter  )

◆ CPPUNIT_TEST() [12/12]

CheckpointIOTest::CPPUNIT_TEST ( testBinaryRepRepSplitter  )

◆ CPPUNIT_TEST_SUITE_END()

CheckpointIOTest::CPPUNIT_TEST_SUITE_END ( )

◆ LIBMESH_CPPUNIT_TEST_SUITE()

CheckpointIOTest::LIBMESH_CPPUNIT_TEST_SUITE ( CheckpointIOTest  )

This test verifies that we can write files with the CheckpointIO object.

◆ setUp()

void CheckpointIOTest::setUp ( )
inline

Definition at line 48 of file checkpoint.C.

49 {
50 }

◆ tearDown()

void CheckpointIOTest::tearDown ( )
inline

Definition at line 52 of file checkpoint.C.

53 {
54 }

◆ testAsciiC0Polygon()

void CheckpointIOTest::testAsciiC0Polygon ( )
inline

Definition at line 371 of file checkpoint.C.

372 {
373 LOG_UNIT_TEST;
374
376 }
void testC0PolygonCheckpoint(bool binary)
Definition checkpoint.C:141

References testC0PolygonCheckpoint().

◆ testAsciiC0Polyhedron()

void CheckpointIOTest::testAsciiC0Polyhedron ( )
inline

Definition at line 386 of file checkpoint.C.

387 {
388 LOG_UNIT_TEST;
389
391 }
void testC0PolyhedronCheckpoint(bool binary)
Definition checkpoint.C:213

References testC0PolyhedronCheckpoint().

◆ testAsciiDistDistSplitter()

void CheckpointIOTest::testAsciiDistDistSplitter ( )
inline

Definition at line 357 of file checkpoint.C.

358 {
359 LOG_UNIT_TEST;
360
361 testSplitter<DistributedMesh, DistributedMesh>(false, true);
362 }

◆ testAsciiDistDistSplitterCache()

void CheckpointIOTest::testAsciiDistDistSplitterCache ( )
inline

Definition at line 401 of file checkpoint.C.

402 {
403 LOG_UNIT_TEST;
404
405 testSplitter<DistributedMesh, DistributedMesh>(false, true, true);
406 }

◆ testAsciiDistRepSplitter()

void CheckpointIOTest::testAsciiDistRepSplitter ( )
inline

Definition at line 315 of file checkpoint.C.

316 {
317 LOG_UNIT_TEST;
318
319 testSplitter<DistributedMesh, ReplicatedMesh>(false, true);
320 }

◆ testAsciiRepDistSplitter()

void CheckpointIOTest::testAsciiRepDistSplitter ( )
inline

Definition at line 329 of file checkpoint.C.

330 {
331 LOG_UNIT_TEST;
332
333 testSplitter<ReplicatedMesh, DistributedMesh>(false, true);
334 }

◆ testAsciiRepRepSplitter()

void CheckpointIOTest::testAsciiRepRepSplitter ( )
inline

Definition at line 343 of file checkpoint.C.

344 {
345 LOG_UNIT_TEST;
346
347 testSplitter<ReplicatedMesh, ReplicatedMesh>(false, false);
348 }

◆ testBinaryC0Polygon()

void CheckpointIOTest::testBinaryC0Polygon ( )
inline

Definition at line 378 of file checkpoint.C.

379 {
380 LOG_UNIT_TEST;
381
383 }

References testC0PolygonCheckpoint().

◆ testBinaryC0Polyhedron()

void CheckpointIOTest::testBinaryC0Polyhedron ( )
inline

Definition at line 393 of file checkpoint.C.

394 {
395 LOG_UNIT_TEST;
396
398 }

References testC0PolyhedronCheckpoint().

◆ testBinaryDistDistSplitter()

void CheckpointIOTest::testBinaryDistDistSplitter ( )
inline

Definition at line 364 of file checkpoint.C.

365 {
366 LOG_UNIT_TEST;
367
368 testSplitter<DistributedMesh, DistributedMesh>(true, true);
369 }

◆ testBinaryDistRepSplitter()

void CheckpointIOTest::testBinaryDistRepSplitter ( )
inline

Definition at line 322 of file checkpoint.C.

323 {
324 LOG_UNIT_TEST;
325
326 testSplitter<DistributedMesh, ReplicatedMesh>(true, true);
327 }

◆ testBinaryRepDistSplitter()

void CheckpointIOTest::testBinaryRepDistSplitter ( )
inline

Definition at line 336 of file checkpoint.C.

337 {
338 LOG_UNIT_TEST;
339
340 testSplitter<ReplicatedMesh, DistributedMesh>(true, true);
341 }

◆ testBinaryRepRepSplitter()

void CheckpointIOTest::testBinaryRepRepSplitter ( )
inline

Definition at line 350 of file checkpoint.C.

351 {
352 LOG_UNIT_TEST;
353
354 testSplitter<ReplicatedMesh, ReplicatedMesh>(true, false);
355 }

◆ testC0PolygonCheckpoint()

void CheckpointIOTest::testC0PolygonCheckpoint ( bool  binary)
inline

Definition at line 141 of file checkpoint.C.

142 {
143#ifdef LIBMESH_HAVE_XDR
144 // Parallel element packing does not yet support runtime topology,
145 // so exercise serial CheckpointIO independently on rank 0.
146 if (TestCommWorld->rank() != 0)
147 return;
148
149 Parallel::Communicator comm_self;
150 const std::string filename =
151 std::string("checkpoint_c0polygon.cp") + (binary ? "r" : "a");
152 const std::vector<Point> points =
153 {{0., 0.}, {1., 0.}, {1.5, 0.5}, {1., 1.}, {0., 1.}};
154
155 {
156 Mesh mesh(comm_self, 2);
157 mesh.allow_renumbering(false);
158
159 auto polygon =
160 std::make_unique<C0Polygon>(cast_int<unsigned int>(points.size()));
161 polygon->set_id() = 0;
162 for (auto n : index_range(points))
163 polygon->set_node(n, mesh.add_point(points[n], n));
164
165 mesh.add_elem(std::move(polygon));
167
168 CheckpointIO checkpoint(mesh, binary);
169 checkpoint.write(filename);
170 }
171
172 {
173 Mesh mesh(comm_self);
174 CheckpointIO checkpoint(mesh, binary);
175 checkpoint.read(filename);
176
177 CPPUNIT_ASSERT_EQUAL(dof_id_type(1), mesh.n_elem());
178 CPPUNIT_ASSERT_EQUAL(dof_id_type(5), mesh.n_nodes());
179 CPPUNIT_ASSERT_EQUAL(2u, static_cast<unsigned int>(mesh.mesh_dimension()));
180
181 const Elem * elem = mesh.query_elem_ptr(0);
182 bool found_elem = elem;
183 mesh.comm().max(found_elem);
184 CPPUNIT_ASSERT(found_elem);
185
186 if (elem)
187 {
188 CPPUNIT_ASSERT_EQUAL(C0POLYGON, elem->type());
189 CPPUNIT_ASSERT_EQUAL(5u, elem->n_nodes());
190 CPPUNIT_ASSERT_EQUAL(5u, elem->n_vertices());
191 CPPUNIT_ASSERT_EQUAL(5u, elem->n_sides());
192 CPPUNIT_ASSERT_EQUAL(5u, elem->n_edges());
193
194 for (auto n : index_range(points))
195 {
196 CPPUNIT_ASSERT_EQUAL(cast_int<dof_id_type>(n), elem->node_id(n));
197 CPPUNIT_ASSERT_EQUAL(points[n], elem->point(n));
198
199 const auto side_nodes = elem->nodes_on_side(n);
200 CPPUNIT_ASSERT_EQUAL(std::size_t(2), side_nodes.size());
201 CPPUNIT_ASSERT_EQUAL(cast_int<unsigned int>(n), side_nodes[0]);
202 CPPUNIT_ASSERT_EQUAL
203 (cast_int<unsigned int>((n + 1) % points.size()), side_nodes[1]);
204 }
205 }
206 }
207
208 CheckpointIO::cleanup(filename, 1);
209#endif // LIBMESH_HAVE_XDR
210 }
void max(const T &r, T &o, Request &req) const
The CheckpointIO class can be used to write simplified restart files that can be used to restart simu...
static void cleanup(const std::string &input_name, processor_id_type n_procs)
Used to remove a checkpoint directory and its corresponding files.
This is the base class from which all geometric element types are derived.
Definition elem.h:96
virtual unsigned int n_vertices() const =0
const Point & point(const unsigned int i) const
Definition elem.h:2462
virtual unsigned int n_nodes() const =0
virtual std::vector< unsigned int > nodes_on_side(const unsigned int) const =0
virtual ElemType type() const =0
virtual unsigned int n_edges() const =0
virtual unsigned int n_sides() const =0
dof_id_type node_id(const unsigned int i) const
Definition elem.h:2484
unsigned int mesh_dimension() const
Definition mesh_base.C:430
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:1355
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 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.
The Mesh class is a thin wrapper, around the ReplicatedMesh class by default.
Definition mesh.h:51
const Parallel::Communicator & comm() const
Communicator * TestCommWorld
MeshBase & mesh
auto index_range(const T &sizable)
Helper function that returns an IntRange<std::size_t> representing all the indices of the passed-in v...
Definition int_range.h:153
uint8_t dof_id_type
Definition id_types.h:67

References libMesh::MeshBase::add_elem(), libMesh::MeshBase::add_point(), libMesh::MeshBase::allow_renumbering(), libMesh::C0POLYGON, libMesh::CheckpointIO::cleanup(), libMesh::ParallelObject::comm(), libMesh::index_range(), libMesh::Parallel::Communicator::max(), mesh, libMesh::MeshBase::mesh_dimension(), libMesh::Elem::n_edges(), libMesh::MeshBase::n_elem(), libMesh::Elem::n_nodes(), libMesh::MeshBase::n_nodes(), libMesh::Elem::n_sides(), libMesh::Elem::n_vertices(), libMesh::Elem::node_id(), libMesh::Elem::nodes_on_side(), libMesh::Elem::point(), libMesh::MeshBase::prepare_for_use(), libMesh::MeshBase::query_elem_ptr(), libMesh::CheckpointIO::read(), TestCommWorld, libMesh::Elem::type(), and libMesh::CheckpointIO::write().

Referenced by testAsciiC0Polygon(), and testBinaryC0Polygon().

◆ testC0PolyhedronCheckpoint()

void CheckpointIOTest::testC0PolyhedronCheckpoint ( bool  binary)
inline

Definition at line 213 of file checkpoint.C.

214 {
215#ifdef LIBMESH_HAVE_XDR
216 // Parallel element packing does not yet support runtime topology,
217 // so exercise serial CheckpointIO independently on rank 0.
218 if (TestCommWorld->rank() != 0)
219 return;
220
221 Parallel::Communicator comm_self;
222 const std::string filename =
223 std::string("checkpoint_c0polyhedron.cp") + (binary ? "r" : "a");
224 const std::vector<Point> points =
225 {{0., -2., 0.}, {-1., -1., 0.}, {-1., 1., 0.},
226 {0., 2., 0.}, {1., 1., 0.}, {1., -1., 0.},
227 {0., -2., 1.}, {-1., -1., 1.}, {-1., 1., 1.},
228 {0., 2., 1.}, {1., 1., 1.}, {1., -1., 1.}};
229 const std::vector<std::vector<unsigned int>> nodes_on_sides =
230 {{0, 1, 2, 3, 4, 5},
231 {0, 1, 7, 6},
232 {1, 2, 8, 7},
233 {2, 3, 9, 8},
234 {3, 4, 10, 9},
235 {4, 5, 11, 10},
236 {5, 0, 6, 11},
237 {6, 7, 8, 9, 10, 11}};
238
239 {
240 Mesh mesh(comm_self, 3);
241 mesh.allow_renumbering(false);
242 for (auto n : index_range(points))
243 mesh.add_point(points[n], n);
244
245 std::vector<std::shared_ptr<Polygon>> sides(nodes_on_sides.size());
246 for (auto s : index_range(nodes_on_sides))
247 {
248 const auto & side_nodes = nodes_on_sides[s];
249 auto side =
250 std::make_shared<C0Polygon>
251 (cast_int<unsigned int>(side_nodes.size()));
252 for (auto n : index_range(side_nodes))
253 side->set_node(n, mesh.node_ptr(side_nodes[n]));
254 sides[s] = std::move(side);
255 }
256
257 std::unique_ptr<Node> mid_elem_node;
258 auto polyhedron =
259 std::make_unique<C0Polyhedron>(sides, mid_elem_node);
260 CPPUNIT_ASSERT(mid_elem_node);
261
262 // Explicit id so DistributedMesh matches ReplicatedMesh
263 mid_elem_node->set_id(points.size());
264
265 mesh.add_node(std::move(mid_elem_node));
266 polyhedron->set_id() = 0;
267 mesh.add_elem(std::move(polyhedron));
269
270 CheckpointIO checkpoint(mesh, binary);
271 checkpoint.write(filename);
272 }
273
274 {
275 Mesh mesh(comm_self);
276 CheckpointIO checkpoint(mesh, binary);
277 checkpoint.read(filename);
278
279 CPPUNIT_ASSERT_EQUAL(dof_id_type(1), mesh.n_elem());
280 CPPUNIT_ASSERT_EQUAL(dof_id_type(13), mesh.n_nodes());
281 CPPUNIT_ASSERT_EQUAL(3u, static_cast<unsigned int>(mesh.mesh_dimension()));
282
283 const Elem * elem = mesh.query_elem_ptr(0);
284 bool found_elem = elem;
285 mesh.comm().max(found_elem);
286 CPPUNIT_ASSERT(found_elem);
287
288 if (elem)
289 {
290 CPPUNIT_ASSERT_EQUAL(C0POLYHEDRON, elem->type());
291 CPPUNIT_ASSERT_EQUAL(12u, elem->n_vertices());
292 CPPUNIT_ASSERT_EQUAL(13u, elem->n_nodes());
293 CPPUNIT_ASSERT_EQUAL(8u, elem->n_sides());
294 CPPUNIT_ASSERT_EQUAL(18u, elem->n_edges());
295 CPPUNIT_ASSERT_EQUAL(dof_id_type(12),
296 elem->node_id(elem->n_vertices()));
297
298 for (auto s : index_range(nodes_on_sides))
299 {
300 const auto side_nodes = elem->nodes_on_side(s);
301 CPPUNIT_ASSERT_EQUAL(nodes_on_sides[s].size(), side_nodes.size());
302 for (auto n : index_range(side_nodes))
303 CPPUNIT_ASSERT_EQUAL
304 (cast_int<dof_id_type>(nodes_on_sides[s][n]),
305 elem->node_id(side_nodes[n]));
306 }
307 }
308 }
309
310 CheckpointIO::cleanup(filename, 1);
311#endif // LIBMESH_HAVE_XDR
312 }
dof_id_type & set_id()
Definition dof_object.h:827
virtual Node * add_node(Node *n)=0
Add Node n to the end of the vertex array.
Tnew cast_int(Told oldvar)

References libMesh::MeshBase::add_elem(), libMesh::MeshBase::add_node(), libMesh::MeshBase::add_point(), libMesh::MeshBase::allow_renumbering(), libMesh::C0POLYHEDRON, libMesh::CheckpointIO::cleanup(), libMesh::ParallelObject::comm(), libMesh::index_range(), libMesh::Parallel::Communicator::max(), mesh, libMesh::MeshBase::mesh_dimension(), libMesh::Elem::n_edges(), libMesh::MeshBase::n_elem(), libMesh::Elem::n_nodes(), libMesh::MeshBase::n_nodes(), libMesh::Elem::n_sides(), libMesh::Elem::n_vertices(), libMesh::Elem::node_id(), libMesh::MeshBase::node_ptr(), libMesh::Elem::nodes_on_side(), libMesh::MeshBase::prepare_for_use(), libMesh::MeshBase::query_elem_ptr(), libMesh::CheckpointIO::read(), libMesh::DofObject::set_id(), TestCommWorld, libMesh::Elem::type(), and libMesh::CheckpointIO::write().

Referenced by testAsciiC0Polyhedron(), and testBinaryC0Polyhedron().

◆ testSplitter()

template<typename MeshA , typename MeshB >
void CheckpointIOTest::testSplitter ( bool  binary,
bool  using_distmesh,
bool  skip_partition = false 
)
inline

Definition at line 58 of file checkpoint.C.

59 {
60 // The CheckpointIO-based splitter requires XDR.
61#ifdef LIBMESH_HAVE_XDR
62
63 // In this test, we partition the mesh into n_procs parts. Don't
64 // try to partition a DistributedMesh into more parts than we have
65 // processors, though.
66 const unsigned int n_procs = using_distmesh ?
67 std::min(static_cast<processor_id_type>(2), TestCommWorld->size()) :
68 2;
69
70 // The number of elements in the original mesh. For verification
71 // later.
72 dof_id_type original_n_elem = 0;
73
74 const std::string filename =
75 std::string("checkpoint_splitter.cp") + (binary ? "r" : "a");
76
77 {
78 MeshA mesh(*TestCommWorld);
79
81 4, 4,
82 0., 1.,
83 0., 1.,
84 QUAD4);
85
86 // Store the number of elements that were in the original mesh.
87 original_n_elem = mesh.n_elem();
88
89 // Partition the mesh into n_procs pieces
90 mesh.partition(n_procs);
91
92 // Write out checkpoint files for each piece. Since on a
93 // ReplicatedMesh we might have more pieces than we do
94 // processors, some processors may have to write out more than
95 // one piece.
96 CheckpointIO cpr(mesh);
97 cpr.current_processor_ids().clear();
98 for (processor_id_type pid = mesh.processor_id(); pid < n_procs; pid += mesh.n_processors())
99 cpr.current_processor_ids().push_back(pid);
100 cpr.current_n_processors() = n_procs;
101 cpr.binary() = binary;
102 cpr.parallel() = true;
103 cpr.write(filename);
104 }
105
106 TestCommWorld->barrier();
107
108 // Test that we can read in the files we wrote and sum up to the
109 // same total number of elements.
110 {
111 MeshB mesh(*TestCommWorld);
112 if (skip_partition)
114
115 CheckpointIO cpr(mesh);
116 cpr.current_n_processors() = n_procs;
117 cpr.binary() = binary;
118 cpr.read(filename);
119
120 // If we decided to skip partitioning, then we shouldn't be
121 // waiting for a partition() call to get our n_partitions()
122 // cache in order
123 if (skip_partition)
124 CPPUNIT_ASSERT_EQUAL(mesh.n_partitions(), n_procs);
125
126 std::size_t read_in_elements = 0;
127
128 for (unsigned pid=mesh.processor_id(); pid<n_procs; pid += mesh.n_processors())
129 {
130 read_in_elements += std::distance(mesh.pid_elements_begin(pid),
131 mesh.pid_elements_end(pid));
132 }
133 mesh.comm().sum(read_in_elements);
134
135 // Verify that we read in exactly as many elements as we started with.
136 CPPUNIT_ASSERT_EQUAL(static_cast<dof_id_type>(read_in_elements), original_n_elem);
137 }
138#endif // LIBMESH_HAVE_XDR
139 }
unsigned int n_partitions() const
Definition mesh_base.h:1526
virtual void partition(const unsigned int n_parts)
Call the default partitioner (currently metis_partition()).
Definition mesh_base.C:1769
void skip_partitioning(bool skip)
If true is passed in then nothing on this mesh will be (re)partitioned.
Definition mesh_base.h:1429
processor_id_type processor_id() const
processor_id_type n_processors() 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.
uint8_t processor_id_type
Definition id_types.h:104

References libMesh::CheckpointIO::binary(), libMesh::MeshTools::Generation::build_square(), libMesh::ParallelObject::comm(), libMesh::CheckpointIO::current_n_processors(), libMesh::CheckpointIO::current_processor_ids(), mesh, libMesh::MeshBase::n_elem(), libMesh::MeshBase::n_partitions(), libMesh::ParallelObject::n_processors(), libMesh::CheckpointIO::parallel(), libMesh::MeshBase::partition(), libMesh::ParallelObject::processor_id(), libMesh::QUAD4, libMesh::CheckpointIO::read(), libMesh::MeshBase::skip_partitioning(), libMesh::Parallel::Communicator::sum(), TestCommWorld, and libMesh::CheckpointIO::write().


The documentation for this class was generated from the following file: