14 #include "libmesh/dof_map.h" 15 #include "libmesh/dof_object.h" 16 #include "libmesh/elem.h" 17 #include "libmesh/node.h" 23 : _es(
mesh), _load_all_vectors(true)
29 const std::vector<const libMesh::DofObject *> & ordered_objects)
const 39 sys_header.
name = sys.name();
40 sys_header.
type = sys.system_type();
43 for (
const auto var_num :
make_range(sys.n_vars()))
45 const auto & var = sys.variable(var_num);
48 var_header.
name = var.name();
49 var_header.
type = var.type();
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");
58 if (var.type().family !=
SCALAR)
60 for (
const auto & obj : ordered_objects)
61 var_header.
size +=
sizeof(
Real) * obj->n_comp(sys.number(), var.number());
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();
71 sys_header.
variables.emplace(var.name(), var_header);
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()))
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");
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();
93 mooseAssert(!es_header.
systems.count(sys.name()),
"Already inserted");
94 es_header.
systems.emplace(sys.name(), sys_header);
98 std::size_t offset = 0;
99 for (
auto & sys_name_header_pair : es_header.
systems)
101 auto & sys_header = sys_name_header_pair.second;
102 for (
auto & vec_name_header_pair : sys_header.vectors)
104 auto & vec_header = vec_name_header_pair.second;
105 for (
const auto & var_name_header_pair : sys_header.variables)
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;
120 std::vector<const libMesh::DofObject *>
123 std::vector<const libMesh::DofObject *> objects;
124 auto add = [&objects](
const auto begin,
const auto end)
126 std::set<const libMesh::DofObject *, libMesh::CompareDofObjectsByID> ordered(begin, end);
127 objects.insert(objects.end(), ordered.begin(), ordered.end());
131 add(
mesh.local_elements_begin(),
mesh.local_elements_end());
132 add(
mesh.local_nodes_begin(),
mesh.local_nodes_end());
150 std::vector<dof_id_type> ordered_objects_ids(ordered_objects.size());
152 ordered_objects_ids[i] = ordered_objects[i]->
id();
153 dataStore(stream, ordered_objects_ids,
nullptr);
157 const std::size_t data_initial_position =
static_cast<std::size_t
>(stream.tellp());
161 for (
const auto & sys_name_header_pair : es_header.
systems)
163 const auto & sys_header = sys_name_header_pair.second;
167 for (
const auto & vec_name_header_pair : sys_header.vectors)
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)
173 const auto & var_header = var_name_header_pair.second;
174 const auto & var = *var_header.variable;
177 const std::size_t var_initial_position = stream.tellp();
181 if (var.type().family !=
SCALAR)
184 for (
const auto & obj : ordered_objects)
185 for (
const auto comp :
make_range(obj->n_comp(sys.number(), var.number())))
187 auto val = vec(obj->dof_number(sys.number(), var.number(), comp));
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)
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,
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");
217 mooseAssert((data_initial_position + es_header.
data_size) ==
218 static_cast<std::size_t>(stream.tellp()),
219 "Incorrect assumed size");
236 std::vector<dof_id_type> from_ordered_objects_ids;
237 dataLoad(stream, from_ordered_objects_ids,
nullptr);
239 mooseError(
"RestartableEquationSystems::load(): Number of previously stored elements/nodes (",
242 "match the current number of elements/nodes (",
243 from_ordered_objects_ids.size(),
247 mooseError(
"RestartableEquationSystems::load(): Id of previously stored element/node (",
250 "match the current element/node id (",
251 from_ordered_objects_ids[i],
260 const auto & sys_header = sys_name_header_pair.second;
265 bool modified_sys =
false;
267 for (
const auto & vec_name_header_pair : sys_header.vectors)
269 bool modified_vec =
false;
271 const auto & vec_header = vec_name_header_pair.second;
274 if (!is_solution && !sys.have_vector(vec_header.name))
277 sys.add_vector(vec_header.name, vec_header.projections, vec_header.type);
282 auto & vec = is_solution ? *sys.solution : sys.get_vector(vec_header.name);
284 for (
const auto & var_name_header_pair : sys_header.variables)
286 const auto & var_header = var_name_header_pair.second;
287 if (!sys.has_variable(var_header.name))
289 const auto & var = sys.variable(sys.variable_number(var_header.name));
290 if (var.type() != var_header.type)
293 restore(sys_header, vec_header, var_header, sys, vec, var, stream);
319 std::istream & stream)
324 const auto & sys_header = sys_it->second;
325 mooseAssert(sys_header == from_sys_header,
"Not my system");
326 const auto vec_it = sys_header.vectors.find(from_vec_header.
name);
327 mooseAssert(vec_it != sys_header.vectors.end(),
"Vector does not exist");
328 const auto & vec_header = vec_it->second;
329 mooseAssert(vec_header == from_vec_header,
"Not my vector");
330 const auto var_it = sys_header.variables.find(from_var_header.
name);
331 mooseAssert(var_it != sys_header.variables.end(),
"Variable does not exist");
332 const auto & var_header = var_it->second;
333 mooseAssert(var_header == from_var_header,
"Not my variable");
337 [&from_sys_header, &from_vec_header, &from_var_header, &to_sys, &to_var](
auto... args)
339 mooseError(
"An error occured while restoring a system:\n",
342 from_sys_header.
name,
344 from_vec_header.name,
346 from_var_header.name,
353 if (from_var_header.type != to_var.
type())
354 error(
"Cannot restore to a variable of a different type");
356 const auto offset = from_vec_header.variable_offset.at(from_var_header.name);
363 for (
const auto comp :
make_range(obj->n_comp(to_sys.number(), to_var.
number())))
367 to_vec.
set(obj->dof_number(to_sys.number(), to_var.
number(), comp), val);
373 const auto & dof_map = to_sys.get_dof_map();
374 std::vector<dof_id_type> scalar_dofs;
375 dof_map.SCALAR_dof_indices(scalar_dofs, to_var.
number());
376 for (
const auto dof : scalar_dofs)
380 to_vec.
set(dof, val);
std::string name(const ElemQuality q)
void store(std::ostream &stream) const
Stores the EquationSystems to the given stream.
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)
unsigned int n_systems() const
std::size_t _loaded_stream_data_begin
The starting position for the vector data in the input stream.
bool has_system(std::string_view name) const
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application...
const Parallel::Communicator & comm() const
const T_sys & get_system(std::string_view name) const
libMesh::EquationSystems _es
The underlying EquationSystems.
processor_id_type n_processors() const
RestartableEquationSystems(libMesh::MeshBase &mesh)
void load(std::istream &stream)
Loads the EquationSystems from the given stream.
EquationSystemsHeader _loaded_header
The loaded header.
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
bool _load_all_vectors
Whether or not to load all of the vectors, including ones that haven't been added yet...
timpi_pure bool verify(const T &r) const
void dataLoad(std::istream &stream, RestartableEquationSystems &res, void *)
Wrapper class that owns a libMesh EquationSystem and adds advanced restart capability to it...
std::vector< const libMesh::DofObject * > _loaded_ordered_objects
The object ordering for this data.
const MeshBase & get_mesh() const
IntRange< T > make_range(T beg, T end)
void dataStore(std::ostream &stream, RestartableEquationSystems &res, void *)
std::vector< const libMesh::DofObject * > orderDofObjects() const
Internal method for ordering the DofObjects by ID (elems and the nodes)
virtual void set(const numeric_index_type i, const T value)=0
const std::string & name() const
unsigned int number() const
processor_id_type processor_id() const
EquationSystemsHeader buildHeader(const std::vector< const libMesh::DofObject *> &ordered_objects) const
Internal method for building the header struct.
auto index_range(const T &sizable)
const FEType & type() const