https://mooseframework.inl.gov
Loading...
Searching...
No Matches
Classes | Public Member Functions | Private Member Functions | Private Attributes | List of all members
RestartableEquationSystems Class Reference

Wrapper class that owns a libMesh EquationSystem and adds advanced restart capability to it. More...

#include <RestartableEquationSystems.h>

Classes

struct  EquationSystemsHeader
 Represents a stored EquationSystems in restart. More...
 
struct  SystemHeader
 Represents a stored system in restart. More...
 
struct  VariableHeader
 Represents a stored variable in restart. More...
 
struct  VectorHeader
 Represents a stored variable in restart. More...
 

Public Member Functions

 RestartableEquationSystems (libMesh::MeshBase &mesh)
 
void store (std::ostream &stream) const
 Stores the EquationSystems to the given stream.
 
void load (std::istream &stream)
 Loads the EquationSystems from the given stream.
 
void setLoadAllVectors (const bool load_all_vectors)
 Sets whether or not all vectors are to be loaded.
 
bool isVariableRestored (const std::string &system_name, const std::string &vector_name, const std::string &variable_name) const
 Checks whether variable was successfully restored from a restart file.
 
const std::set< std::tuple< std::string, std::string, std::string > > & getLoadedVariables () const
 Returns the set of variables that were loaded during the load() function. Each set of variables contain; [system name, vector name, variable name].
 
libMesh::EquationSystemses ()
 
const libMesh::EquationSystemses () const
 

Private Member Functions

EquationSystemsHeader buildHeader (const std::vector< const libMesh::DofObject * > &ordered_objects) const
 Internal method for building the header struct.
 
std::vector< const libMesh::DofObject * > orderDofObjects () const
 Internal method for ordering the DofObjects by ID (elems and the nodes)
 
void restore (const SystemHeader &from_sys_header, const VectorHeader &from_vec_header, const VariableHeader &from_var_header, const libMesh::System &to_sys, libMesh::NumericVector< libMesh::Number > &to_vec, const libMesh::Variable &to_var, std::istream &stream)
 

Private Attributes

libMesh::EquationSystems _es
 The underlying EquationSystems.
 
bool _load_all_vectors
 Whether or not to load all of the vectors, including ones that haven't been added yet.
 
std::size_t _loaded_stream_data_begin
 The starting position for the vector data in the input stream.
 
std::vector< const libMesh::DofObject * > _loaded_ordered_objects
 The object ordering for this data.
 
EquationSystemsHeader _loaded_header
 The loaded header.
 
std::set< std::tuple< std::string, std::string, std::string > > _loaded_variables
 The variables that were loaded in load(); [system name, vector name, variable name].
 

Detailed Description

Wrapper class that owns a libMesh EquationSystem and adds advanced restart capability to it.

Definition at line 32 of file RestartableEquationSystems.h.

Constructor & Destructor Documentation

◆ RestartableEquationSystems()

RestartableEquationSystems::RestartableEquationSystems ( libMesh::MeshBase mesh)

Definition at line 22 of file RestartableEquationSystems.C.

23 : _es(mesh), _load_all_vectors(true)
24{
25}
bool _load_all_vectors
Whether or not to load all of the vectors, including ones that haven't been added yet.
libMesh::EquationSystems _es
The underlying EquationSystems.

Member Function Documentation

◆ buildHeader()

RestartableEquationSystems::EquationSystemsHeader RestartableEquationSystems::buildHeader ( const std::vector< const libMesh::DofObject * > &  ordered_objects) const
private

Internal method for building the header struct.

Definition at line 28 of file RestartableEquationSystems.C.

30{
31 EquationSystemsHeader es_header;
32
33 // Systems
34 for (const auto sys_num : make_range(_es.n_systems()))
35 {
36 const auto & sys = _es.get_system(sys_num);
37
38 SystemHeader sys_header;
39 sys_header.name = sys.name();
40 sys_header.type = sys.system_type();
41
42 // Variables in the system
43 for (const auto var_num : make_range(sys.n_vars()))
44 {
45 const auto & var = sys.variable(var_num);
46
47 VariableHeader var_header;
48 var_header.name = var.name();
49 var_header.type = var.type();
50 var_header.size = 0;
51 var_header.variable = &var;
52
53 mooseAssert(_es.comm().verify("sys_" + sys.name() + "_var_" + var.name()),
54 "Out of order in parallel");
55 mooseAssert(!sys_header.variables.count(var.name()), "Already inserted");
56
57 // Non-SCALAR variable
58 if (var.type().family != SCALAR)
59 {
60 for (const auto & obj : ordered_objects)
61 var_header.size += sizeof(Real) * obj->n_comp(sys.number(), var.number());
62 }
63 // SCALAR variable on the last rank
64 else if (_es.processor_id() == _es.n_processors() - 1)
65 {
66 std::vector<dof_id_type> scalar_dofs;
67 sys.get_dof_map().SCALAR_dof_indices(scalar_dofs, var.number());
68 var_header.size += sizeof(Real) * scalar_dofs.size();
69 }
70
71 sys_header.variables.emplace(var.name(), var_header);
72 }
73
74 // System vector
75 auto & sys_vec_header = sys_header.vectors[SystemHeader::system_solution_name];
76 sys_vec_header.name = SystemHeader::system_solution_name;
77 sys_vec_header.vector = sys.solution.get();
78 sys_vec_header.type = sys_vec_header.vector->type();
79 for (const auto vec_num : make_range(sys.n_vectors()))
80 {
81 mooseAssert(_es.comm().verify("sys_" + sys.name() + "_vec_" + sys.vector_name(vec_num)),
82 "Out of order in parallel");
83 const auto & name = sys.vector_name(vec_num);
84 mooseAssert(!sys_header.vectors.count(name), "Already inserted");
85 auto & vec_header = sys_header.vectors[name];
86 vec_header.name = sys.vector_name(vec_num);
87 vec_header.projections = sys.vector_preservation(vec_header.name);
88 vec_header.vector = &sys.get_vector(vec_header.name);
89 vec_header.type = vec_header.vector->type();
90 }
91
92 // System in this EquationSystems
93 mooseAssert(!es_header.systems.count(sys.name()), "Already inserted");
94 es_header.systems.emplace(sys.name(), sys_header);
95 }
96
97 // Setup the positions in each vector for easy access later
98 std::size_t offset = 0;
99 for (auto & sys_name_header_pair : es_header.systems)
100 {
101 auto & sys_header = sys_name_header_pair.second;
102 for (auto & vec_name_header_pair : sys_header.vectors)
103 {
104 auto & vec_header = vec_name_header_pair.second;
105 for (const auto & var_name_header_pair : sys_header.variables)
106 {
107 const auto & var_header = var_name_header_pair.second;
108 mooseAssert(!vec_header.variable_offset.count(var_header.name), "Already inserted");
109 vec_header.variable_offset[var_header.name] = offset;
110 offset += var_header.size;
111 }
112 }
113 }
114
115 es_header.data_size = offset;
116
117 return es_header;
118}
unsigned int n_vars
timpi_pure bool verify(const T &r) const
const T_sys & get_system(std::string_view name) const
processor_id_type processor_id() const
const Parallel::Communicator & comm() const
processor_id_type n_processors() const
std::string name(const ElemQuality q)
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
IntRange< T > make_range(T beg, T end)
static const std::string system_solution_name
Special name for a vector that is the system solution vector.

Referenced by store().

◆ es() [1/2]

libMesh::EquationSystems & RestartableEquationSystems::es ( )
inline
Returns
The underyling EquationSystems

Definition at line 130 of file RestartableEquationSystems.h.

130{ return _es; }

Referenced by FEProblemBase::es().

◆ es() [2/2]

const libMesh::EquationSystems & RestartableEquationSystems::es ( ) const
inline

Definition at line 131 of file RestartableEquationSystems.h.

131{ return _es; }

◆ getLoadedVariables()

const std::set< std::tuple< std::string, std::string, std::string > > & RestartableEquationSystems::getLoadedVariables ( ) const
inline

Returns the set of variables that were loaded during the load() function. Each set of variables contain; [system name, vector name, variable name].

Definition at line 152 of file RestartableEquationSystems.h.

153 {
154 return _loaded_variables;
155 }
std::set< std::tuple< std::string, std::string, std::string > > _loaded_variables
The variables that were loaded in load(); [system name, vector name, variable name].

Referenced by to_json().

◆ isVariableRestored()

bool RestartableEquationSystems::isVariableRestored ( const std::string &  system_name,
const std::string &  vector_name,
const std::string &  variable_name 
) const

Checks whether variable was successfully restored from a restart file.

Definition at line 322 of file RestartableEquationSystems.C.

325{
326 std::tuple<std::string, std::string, std::string> key(system_name, vector_name, variable_name);
327 return _loaded_variables.count(key);
328}

Referenced by restore().

◆ load()

void RestartableEquationSystems::load ( std::istream &  stream)

Loads the EquationSystems from the given stream.

Definition at line 223 of file RestartableEquationSystems.C.

224{
225 // Load the header (systems, variables, vectors)
226 // We do this first so that the loader can make informed decisions
227 // on what to put where based on everything that is available
228 _loaded_header.systems.clear();
229 dataLoad(stream, _loaded_header, nullptr);
230
231 // Order objects (elements and then node) by ID for storing
233
234 // Clear previously loaded variables to ensure a clean state
235 _loaded_variables.clear();
236
237 // Sanity check on if we're loading the same thing
238 {
239 const std::string mesh_mismatch_message =
240 ". This means that equation-system data is being restored onto a different mesh topology. "
241 "If this occurs while restoring a MultiApp sub-application that uses mesh adaptivity, the "
242 "backup may not contain mesh checkpoint data for the restored topology, or the "
243 "sub-application mesh may have changed after the backup was made. Use clone_parent_mesh = "
244 "true when the sub-application should share the parent application's mesh topology, or "
245 "avoid changing the sub-application mesh between backup and restore.";
246
247 std::vector<dof_id_type> from_ordered_objects_ids;
248 dataLoad(stream, from_ordered_objects_ids, nullptr);
249 if (_loaded_ordered_objects.size() != from_ordered_objects_ids.size())
250 mooseError("RestartableEquationSystems::load(): Number of previously stored elements/nodes (",
251 from_ordered_objects_ids.size(),
252 ") does not match the current number of elements/nodes (",
254 mesh_mismatch_message);
255 for (const auto i : index_range(_loaded_ordered_objects))
256 if (_loaded_ordered_objects[i]->id() != from_ordered_objects_ids[i])
257 mooseError("RestartableEquationSystems::load(): Id of previously stored element/node (",
258 from_ordered_objects_ids[i],
259 ") does not match the current element/node id (",
261 mesh_mismatch_message);
262 }
263
264 _loaded_stream_data_begin = static_cast<std::size_t>(stream.tellg());
265
266 // Load everything that we have available at the moment
267 for (const auto & sys_name_header_pair : _loaded_header.systems)
268 {
269 const auto & sys_header = sys_name_header_pair.second;
270 if (!_es.has_system(sys_header.name))
271 continue;
272 auto & sys = _es.get_system(sys_header.name);
273
274 bool modified_sys = false;
275
276 for (const auto & vec_name_header_pair : sys_header.vectors)
277 {
278 bool modified_vec = false;
279
280 const auto & vec_header = vec_name_header_pair.second;
281 const bool is_solution = vec_header.name == SystemHeader::system_solution_name;
282
283 if (!is_solution && !sys.have_vector(vec_header.name))
284 {
286 sys.add_vector(vec_header.name, vec_header.projections, vec_header.type);
287 else
288 continue;
289 }
290
291 auto & vec = is_solution ? *sys.solution : sys.get_vector(vec_header.name);
292
293 for (const auto & var_name_header_pair : sys_header.variables)
294 {
295 const auto & var_header = var_name_header_pair.second;
296 if (!sys.has_variable(var_header.name))
297 continue;
298 const auto & var = sys.variable(sys.variable_number(var_header.name));
299 if (var.type() != var_header.type)
300 continue;
301
302 restore(sys_header, vec_header, var_header, sys, vec, var, stream);
303 modified_vec = true;
304 }
305
306 if (modified_vec)
307 {
308 vec.close();
309 modified_sys = true;
310 }
311 }
312
313 if (modified_sys)
314 sys.update();
315 }
316
317 // Move the stream to the end of our data so that we make RestartableDataReader happy
319}
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application.
Definition MooseError.h:311
if(!dmm->_nl) SETERRQ(PETSC_COMM_WORLD
void dataLoad(std::istream &stream, RestartableEquationSystems &res, void *)
std::vector< const libMesh::DofObject * > orderDofObjects() const
Internal method for ordering the DofObjects by ID (elems and the nodes)
void restore(const SystemHeader &from_sys_header, const VectorHeader &from_vec_header, const VariableHeader &from_var_header, const libMesh::System &to_sys, libMesh::NumericVector< libMesh::Number > &to_vec, const libMesh::Variable &to_var, std::istream &stream)
std::size_t _loaded_stream_data_begin
The starting position for the vector data in the input stream.
EquationSystemsHeader _loaded_header
The loaded header.
std::vector< const libMesh::DofObject * > _loaded_ordered_objects
The object ordering for this data.
bool has_system(std::string_view name) const
auto index_range(const T &sizable)
std::map< std::string, RestartableEquationSystems::SystemHeader > systems
The stored systems in the equation systems.
std::size_t data_size
The total size of data for this EquationSystems.

Referenced by dataLoad().

◆ orderDofObjects()

std::vector< const libMesh::DofObject * > RestartableEquationSystems::orderDofObjects ( ) const
private

Internal method for ordering the DofObjects by ID (elems and the nodes)

Definition at line 121 of file RestartableEquationSystems.C.

122{
123 std::vector<const libMesh::DofObject *> objects;
124 auto add = [&objects](const auto begin, const auto end)
125 {
126 std::set<const libMesh::DofObject *, libMesh::CompareDofObjectsByID> ordered(begin, end);
127 objects.insert(objects.end(), ordered.begin(), ordered.end());
128 };
129
130 const auto & mesh = _es.get_mesh();
131 add(mesh.local_elements_begin(), mesh.local_elements_end());
132 add(mesh.local_nodes_begin(), mesh.local_nodes_end());
133
134 return objects;
135}
const MeshBase & get_mesh() const
MeshBase & mesh

Referenced by load(), and store().

◆ restore()

void RestartableEquationSystems::restore ( const SystemHeader from_sys_header,
const VectorHeader from_vec_header,
const VariableHeader from_var_header,
const libMesh::System to_sys,
libMesh::NumericVector< libMesh::Number > &  to_vec,
const libMesh::Variable to_var,
std::istream &  stream 
)
private

Definition at line 331 of file RestartableEquationSystems.C.

338{
339#ifndef NDEBUG
340 const auto sys_it = _loaded_header.systems.find(from_sys_header.name);
341 mooseAssert(sys_it != _loaded_header.systems.end(), "System does not exist");
342 const auto & sys_header = sys_it->second;
343 mooseAssert(sys_header == from_sys_header, "Not my system");
344 const auto vec_it = sys_header.vectors.find(from_vec_header.name);
345 mooseAssert(vec_it != sys_header.vectors.end(), "Vector does not exist");
346 const auto & vec_header = vec_it->second;
347 mooseAssert(vec_header == from_vec_header, "Not my vector");
348 const auto var_it = sys_header.variables.find(from_var_header.name);
349 mooseAssert(var_it != sys_header.variables.end(), "Variable does not exist");
350 const auto & var_header = var_it->second;
351 mooseAssert(var_header == from_var_header, "Not my variable");
352 mooseAssert(!isVariableRestored(from_sys_header.name, from_vec_header.name, from_var_header.name),
353 "Variable already restored");
354#endif
355
356 const auto error =
357 [&from_sys_header, &from_vec_header, &from_var_header, &to_sys, &to_var](auto... args)
358 {
359 mooseError("An error occured while restoring a system:\n",
360 args...,
361 "\n\nFrom system: ",
362 from_sys_header.name,
363 "\nFrom vector: ",
364 from_vec_header.name,
365 "\nFrom variable: ",
366 from_var_header.name,
367 "\nTo system: ",
368 to_sys.name(),
369 "\nTo variable: ",
370 to_var.name());
371 };
372
373 if (from_var_header.type != to_var.type())
374 error("Cannot restore to a variable of a different type");
375
376 const auto offset = from_vec_header.variable_offset.at(from_var_header.name);
377 stream.seekg(_loaded_stream_data_begin + offset);
378
379 // Non-SCALAR variable
380 if (to_var.type().family != SCALAR)
381 {
382 for (const auto & obj : _loaded_ordered_objects)
383 for (const auto comp : make_range(obj->n_comp(to_sys.number(), to_var.number())))
384 {
385 Real val;
386 dataLoad(stream, val, nullptr);
387 to_vec.set(obj->dof_number(to_sys.number(), to_var.number(), comp), val);
388 }
389 }
390 // SCALAR variable on the last rank
391 else if (_es.processor_id() == _es.n_processors() - 1)
392 {
393 const auto & dof_map = to_sys.get_dof_map();
394 std::vector<dof_id_type> scalar_dofs;
395 dof_map.SCALAR_dof_indices(scalar_dofs, to_var.number());
396 for (const auto dof : scalar_dofs)
397 {
398 Real val;
399 dataLoad(stream, val, nullptr);
400 to_vec.set(dof, val);
401 }
402 }
403
404 // insert into the member variable
405 std::tuple<std::string, std::string, std::string> _loaded_variable = {
406 from_sys_header.name, from_vec_header.name, from_var_header.name};
407
408 _loaded_variables.insert(_loaded_variable);
409
410 mooseAssert(isVariableRestored(from_sys_header.name, from_vec_header.name, from_var_header.name),
411 "Variable not marked as restored");
412}
for(PetscInt i=0;i< nvars;++i)
bool isVariableRestored(const std::string &system_name, const std::string &vector_name, const std::string &variable_name) const
Checks whether variable was successfully restored from a restart file.
virtual void set(const numeric_index_type i, const T value)=0
const std::string & name() const
unsigned int number() const
const FEType & type() const

Referenced by load().

◆ setLoadAllVectors()

void RestartableEquationSystems::setLoadAllVectors ( const bool  load_all_vectors)
inline

Sets whether or not all vectors are to be loaded.

By default, this is true. This means that all vectors that do not currently exist in the system will be added and loaded.

Typically, we would want this to be false in the case of restart.

Definition at line 144 of file RestartableEquationSystems.h.

144{ _load_all_vectors = load_all_vectors; }

◆ store()

void RestartableEquationSystems::store ( std::ostream &  stream) const

Stores the EquationSystems to the given stream.

Definition at line 138 of file RestartableEquationSystems.C.

139{
140 // Order objects (elements and then nodes) by ID for storing
141 const auto ordered_objects = orderDofObjects();
142
143 // Store the header (systems, variables, vectors)
144 EquationSystemsHeader es_header = buildHeader(ordered_objects);
145 dataStore(stream, es_header, nullptr);
146
147 // Store the ordered objects so we can do a sanity check on if we're
148 // loading the same thing
149 {
150 std::vector<dof_id_type> ordered_objects_ids(ordered_objects.size());
151 for (const auto i : index_range(ordered_objects))
152 ordered_objects_ids[i] = ordered_objects[i]->id();
153 dataStore(stream, ordered_objects_ids, nullptr);
154 }
155
156#ifndef NDEBUG
157 const std::size_t data_initial_position = static_cast<std::size_t>(stream.tellp());
158#endif
159
160 // Store each system
161 for (const auto & sys_name_header_pair : es_header.systems)
162 {
163 const auto & sys_header = sys_name_header_pair.second;
164 const auto & sys = _es.get_system(sys_header.name);
165
166 // Store each vector and variable
167 for (const auto & vec_name_header_pair : sys_header.vectors)
168 {
169 const auto & vec_header = vec_name_header_pair.second;
170 const auto & vec = *vec_header.vector;
171 for (const auto & var_name_header_pair : sys_header.variables)
172 {
173 const auto & var_header = var_name_header_pair.second;
174 const auto & var = *var_header.variable;
175
176#ifndef NDEBUG
177 const std::size_t var_initial_position = stream.tellp();
178#endif
179
180 // Non-SCALAR variable
181 if (var.type().family != SCALAR)
182 {
183 // Store for each component of each element and node
184 for (const auto & obj : ordered_objects)
185 for (const auto comp : make_range(obj->n_comp(sys.number(), var.number())))
186 {
187 auto val = vec(obj->dof_number(sys.number(), var.number(), comp));
188 dataStore(stream, val, nullptr);
189 }
190 }
191 // SCALAR variable on the last rank
192 else if (_es.processor_id() == _es.n_processors() - 1)
193 {
194 const auto & dof_map = sys.get_dof_map();
195 std::vector<dof_id_type> scalar_dofs;
196 dof_map.SCALAR_dof_indices(scalar_dofs, var.number());
197 for (const auto dof : scalar_dofs)
198 {
199 auto val = vec(dof);
200 dataStore(stream, val, nullptr);
201 }
202 }
203
204#ifndef NDEBUG
205 const std::size_t data_offset = var_initial_position - data_initial_position;
206 mooseAssert(vec_header.variable_offset.at(var_header.name) == data_offset,
207 "Invalid offset");
208
209 const std::size_t current_position = static_cast<std::size_t>(stream.tellp());
210 const std::size_t var_size = current_position - var_initial_position;
211 mooseAssert(var_size == sys_header.variables.at(var.name()).size, "Incorrect assumed size");
212#endif
213 }
214 }
215 }
216
217 mooseAssert((data_initial_position + es_header.data_size) ==
218 static_cast<std::size_t>(stream.tellp()),
219 "Incorrect assumed size");
220}
void dataStore(std::ostream &stream, RestartableEquationSystems &res, void *)
EquationSystemsHeader buildHeader(const std::vector< const libMesh::DofObject * > &ordered_objects) const
Internal method for building the header struct.

Referenced by dataStore().

Member Data Documentation

◆ _es

libMesh::EquationSystems RestartableEquationSystems::_es
private

The underlying EquationSystems.

Definition at line 174 of file RestartableEquationSystems.h.

Referenced by buildHeader(), es(), es(), load(), orderDofObjects(), restore(), and store().

◆ _load_all_vectors

bool RestartableEquationSystems::_load_all_vectors
private

Whether or not to load all of the vectors, including ones that haven't been added yet.

Definition at line 177 of file RestartableEquationSystems.h.

Referenced by load(), and setLoadAllVectors().

◆ _loaded_header

EquationSystemsHeader RestartableEquationSystems::_loaded_header
private

The loaded header.

Definition at line 183 of file RestartableEquationSystems.h.

Referenced by load(), and restore().

◆ _loaded_ordered_objects

std::vector<const libMesh::DofObject *> RestartableEquationSystems::_loaded_ordered_objects
private

The object ordering for this data.

Definition at line 181 of file RestartableEquationSystems.h.

Referenced by load(), and restore().

◆ _loaded_stream_data_begin

std::size_t RestartableEquationSystems::_loaded_stream_data_begin
private

The starting position for the vector data in the input stream.

Definition at line 179 of file RestartableEquationSystems.h.

Referenced by load(), and restore().

◆ _loaded_variables

std::set<std::tuple<std::string, std::string, std::string> > RestartableEquationSystems::_loaded_variables
private

The variables that were loaded in load(); [system name, vector name, variable name].

Definition at line 186 of file RestartableEquationSystems.h.

Referenced by getLoadedVariables(), isVariableRestored(), load(), and restore().


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