Line data Source code
1 : // The libMesh Finite Element Library.
2 : // Copyright (C) 2002-2025 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner
3 :
4 : // This library is free software; you can redistribute it and/or
5 : // modify it under the terms of the GNU Lesser General Public
6 : // License as published by the Free Software Foundation; either
7 : // version 2.1 of the License, or (at your option) any later version.
8 :
9 : // This library is distributed in the hope that it will be useful,
10 : // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 : // Lesser General Public License for more details.
13 :
14 : // You should have received a copy of the GNU Lesser General Public
15 : // License along with this library; if not, write to the Free Software
16 : // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 :
18 :
19 :
20 : #ifndef LIBMESH_CHECKPOINT_IO_H
21 : #define LIBMESH_CHECKPOINT_IO_H
22 :
23 :
24 : // Local includes
25 : #include "libmesh/compare_elems_by_level.h"
26 : #include "libmesh/mesh_input.h"
27 : #include "libmesh/mesh_output.h"
28 : #include "libmesh/mesh_communication.h"
29 : #include "libmesh/parallel_object.h"
30 :
31 : // C++ includes
32 : #include <string>
33 : #include <vector>
34 :
35 : namespace libMesh
36 : {
37 : // Forward declarations
38 : class Xdr;
39 : class CheckpointIO;
40 :
41 : /**
42 : * split_mesh takes the given initialized/opened mesh and partitions it into nsplits pieces or
43 : * chunks. It returns a CheckpointIO object that can be used to write the mesh chunks into
44 : * individual files (e.g. by calling checkpoint_obj.write(out_file_name)) - the number of files is
45 : * equal to the number of chunks. This function supports MPI parallelism and can be used with
46 : * several MPI procs to speed up splitting.
47 : */
48 : std::unique_ptr<CheckpointIO> split_mesh(MeshBase & mesh, processor_id_type nsplits);
49 :
50 : /**
51 : * The CheckpointIO class can be used to write simplified restart
52 : * files that can be used to restart simulations that have
53 : * crashed.
54 : *
55 : * \author Benjamin Kirk
56 : * \author John Peterson
57 : * \author Derek Gaston
58 : * \author Roy Stogner
59 : * \date 2017
60 : */
61 80 : class CheckpointIO : public MeshInput<MeshBase>,
62 : public MeshOutput<MeshBase>,
63 : public ParallelObject
64 : {
65 : public:
66 : // The size used for encoding all id types in this file
67 : typedef largest_id_type xdr_id_type;
68 :
69 : // The size type used to read header sizes (meta data information)
70 : typedef uint64_t header_id_type;
71 :
72 : /**
73 : * Constructor. Takes a writable reference to a mesh object.
74 : * This is the constructor required to read a mesh.
75 : * The optional parameter \p binary can be used to switch
76 : * between ASCII (\p false, the default) or binary (\p true)
77 : * files.
78 : */
79 : explicit
80 : CheckpointIO (MeshBase &, const bool=false);
81 :
82 : /**
83 : * Constructor. Takes a reference to a constant mesh object.
84 : * This constructor will only allow us to write the mesh.
85 : * The optional parameter \p binary can be used to switch
86 : * between ASCII (\p false, the default) or binary (\p true)
87 : * files.
88 : */
89 : explicit
90 : CheckpointIO (const MeshBase &, const bool=false);
91 :
92 : /**
93 : * Destructor.
94 : */
95 : virtual ~CheckpointIO ();
96 :
97 : /**
98 : * This method implements reading a mesh from a specified file. If the mesh has been split for
99 : * running on several processors, input_name should simply be the name of the mesh split
100 : * directory without the "-split[n]" suffix. The number of splits will be determined
101 : * automatically by the number of processes being used for the mesh at the time of reading.
102 : */
103 : virtual void read (const std::string & input_name) override;
104 :
105 : /**
106 : * This method implements writing a mesh to a specified file. If the mesh has been split
107 : * for running on several processors, this will create a subdirectory named
108 : * "[name]-split[n]" where name is the given name argument and n is the number of
109 : * processors the mesh is split for running on. For example:
110 : *
111 : * unsigned int n_splits = 42;
112 : * std::unique_ptr<CheckpointIO> cp = split_mesh(my_mesh, n_splits);
113 : * // ...
114 : * cp->write("foo.cpr");
115 : *
116 : * would create a directory named "foo.cpr-split42".
117 : */
118 : virtual void write (const std::string & name) override;
119 :
120 : /**
121 : * Used to remove a checkpoint directory and its corresponding files. This effectively undoes
122 : * all the work done be calls to write(...). For example, if a checkpoint configuration was
123 : * written via:
124 : *
125 : * unsigned int n_splits = 42;
126 : * std::unique_ptr<CheckpointIO> cp = split_mesh(my_mesh, n_splits);
127 : * // ...
128 : * cp->write("foo.cpr");
129 : *
130 : * then you could remove all the corresponding created files/dirs by:
131 : *
132 : * CheckpointIO::cleanup(my_mesh, n_splits);
133 : *
134 : * Or for cases where the split configuration was determined automatically (e.g. via number of
135 : * running procs with distributed/parallel mesh), then you could:
136 : *
137 : * CheckpointIO::cleanup(your_mesh, your_mesh.comm().size());
138 : *
139 : * Other remaining checkpoint split configurations for the mesh are left unmodified.
140 : */
141 : static void cleanup(const std::string & input_name, processor_id_type n_procs);
142 :
143 : /**
144 : * Get/Set the flag indicating if we should read/write binary.
145 : */
146 : bool binary() const { return _binary; }
147 0 : bool & binary() { return _binary; }
148 :
149 : /**
150 : * Get/Set the flag indicating if we should read/write binary.
151 : */
152 : bool parallel() const { return _parallel; }
153 0 : bool & parallel() { return _parallel; }
154 :
155 : /**
156 : * Get/Set the version string.
157 : */
158 1504 : const std::string & version () const { return _version; }
159 130 : std::string & version () { return _version; }
160 :
161 : /**
162 : * \returns \p true if the current file has an XDR/XDA version that
163 : * matches or exceeds 1.5
164 : *
165 : * As of this version we encode any extra integer data that has been
166 : * attached to a mesh.
167 : */
168 : bool version_at_least_1_5() const;
169 :
170 : /**
171 : * Get/Set the processor id or processor ids to use.
172 : *
173 : * The default processor_id to use is the processor_id() of the
174 : * mesh.
175 : *
176 : * This is used for m->n parallel checkpoint file writing:
177 : * You can force CheckpointIO to write out different partitions of a
178 : * mesh by setting which partitions to write from each processor here.
179 : */
180 : const std::vector<processor_id_type> & current_processor_ids() const { return _my_processor_ids; }
181 0 : std::vector<processor_id_type> & current_processor_ids() { return _my_processor_ids; }
182 :
183 : /**
184 : * Get/Set the n_processors to use
185 : *
186 : * The default n_processors to use is the n_processors() of the
187 : * mesh.
188 : *
189 : * This is used for m->n parallel checkpoint file writing:
190 : * You can force CheckpointIO to view the world as if it contains this number of
191 : * processors by setting it here
192 : */
193 : const processor_id_type & current_n_processors() const { return _my_n_processors; }
194 0 : processor_id_type & current_n_processors() { return _my_n_processors; }
195 :
196 : private:
197 : //---------------------------------------------------------------------------
198 : // Write Implementation
199 :
200 : /**
201 : * Write subdomain name information
202 : */
203 : void write_subdomain_names(Xdr & io) const;
204 :
205 : /**
206 : * Write the connectivity for part of a mesh
207 : */
208 : void write_connectivity (Xdr & io,
209 : const std::set<const Elem *, CompareElemIdsByLevel> & elements) const;
210 :
211 : /**
212 : * Write the remote_elem neighbor and child links for part of a mesh
213 : */
214 : void write_remote_elem (Xdr & io,
215 : const std::set<const Elem *, CompareElemIdsByLevel> & elements) const;
216 :
217 : /**
218 : * Write the nodal locations for part of a mesh
219 : */
220 : void write_nodes (Xdr & io,
221 : const connected_node_set_type & nodeset) const;
222 :
223 : /**
224 : * Write the side boundary conditions for part of a mesh
225 : */
226 : void write_bcs (Xdr & io,
227 : const std::set<const Elem *, CompareElemIdsByLevel> & elements,
228 : const std::vector<std::tuple<dof_id_type, unsigned short int, boundary_id_type>> & bc_triples) const;
229 :
230 : /**
231 : * Write the nodal boundary conditions for part of a mesh
232 : */
233 : void write_nodesets (Xdr & io,
234 : const connected_node_set_type & nodeset,
235 : const std::vector<std::tuple<dof_id_type, boundary_id_type>> & bc_tuples) const;
236 :
237 : /**
238 : * Write boundary names information (sideset and nodeset)
239 : */
240 : void write_bc_names (Xdr & io, const BoundaryInfo & info, bool is_sideset) const;
241 :
242 :
243 : //---------------------------------------------------------------------------
244 : // Read Implementation
245 :
246 : /**
247 : * Read header data on processor 0, then broadcast. Returns the
248 : * number of processors for which parallel non-header files have
249 : * been written, or 0 if files were written in serial.
250 : */
251 : template <typename file_id_type>
252 : file_id_type read_header(const std::string & name);
253 :
254 : /**
255 : * Read a non-header file
256 : */
257 : template <typename file_id_type>
258 : void read_subfile(Xdr & io, bool expect_all_remote);
259 :
260 : /**
261 : * Read subdomain name information
262 : */
263 : template <typename file_id_type>
264 : void read_subdomain_names(Xdr & io);
265 :
266 : /**
267 : * Read the connectivity for a parallel, distributed mesh
268 : */
269 : template <typename file_id_type>
270 : void read_connectivity (Xdr & io);
271 :
272 : /**
273 : * Read the remote_elem neighbor and child links for a parallel, distributed mesh
274 : *
275 : * If we expect all these remote_elem links to truly be remote,
276 : * because we aren't doing an N -> M restart with M < N, then we set
277 : * \p expect_all_remote to true and test more assertions.
278 : */
279 : template <typename file_id_type>
280 : void read_remote_elem (Xdr & io, bool expect_all_remote);
281 :
282 : /**
283 : * Read the nodal locations for a parallel, distributed mesh
284 : */
285 : template <typename file_id_type>
286 : void read_nodes (Xdr & io);
287 :
288 : /**
289 : * Read the boundary conditions for a parallel, distributed mesh
290 : */
291 : template <typename file_id_type>
292 : void read_bcs (Xdr & io);
293 :
294 : /**
295 : * Read the nodeset conditions for a parallel, distributed mesh
296 : */
297 : template <typename file_id_type>
298 : void read_nodesets (Xdr & io);
299 :
300 : /**
301 : * Read boundary names information (sideset and nodeset)
302 : */
303 : template <typename file_id_type>
304 : void read_bc_names(Xdr & io, BoundaryInfo & info, bool is_sideset);
305 :
306 : /**
307 : * Read extra integers names information
308 : */
309 : template <typename file_id_type>
310 : void read_integers_names
311 : (Xdr & io,
312 : std::vector<std::string> & node_integer_names,
313 : std::vector<std::string> & elem_integer_names);
314 :
315 : /**
316 : * \returns The number of levels of refinement in the active mesh on
317 : * this processor.
318 : *
319 : * \note This includes _all_ elements on this processor even those
320 : * not owned by this processor! Implemented by looping over all the
321 : * active elements and finding the maximum level.
322 : */
323 : unsigned int n_active_levels_in(MeshBase::const_element_iterator begin,
324 : MeshBase::const_element_iterator end) const;
325 :
326 : processor_id_type select_split_config(const std::string & input_name, header_id_type & data_size);
327 :
328 : bool _binary;
329 : bool _parallel;
330 : std::string _version;
331 :
332 : // The processor ids to write
333 : std::vector<processor_id_type> _my_processor_ids;
334 :
335 : // The largest processor id to write
336 : processor_id_type _my_n_processors;
337 : };
338 :
339 :
340 : } // namespace libMesh
341 :
342 : #endif // LIBMESH_CHECKPOINT_IO_H
|