22#ifndef EXADG_TIME_INTEGRATION_RESTART_H_
23#define EXADG_TIME_INTEGRATION_RESTART_H_
26#include <boost/archive/binary_iarchive.hpp>
27#include <boost/archive/binary_oarchive.hpp>
28#include <boost/archive/text_iarchive.hpp>
29#include <boost/archive/text_oarchive.hpp>
33#include <deal.II/distributed/fully_distributed_tria.h>
34#include <deal.II/distributed/tria.h>
35#include <deal.II/grid/tria.h>
36#include <deal.II/lac/la_parallel_block_vector.h>
37#include <deal.II/lac/la_parallel_vector.h>
38#include <deal.II/numerics/solution_transfer.h>
41#include <exadg/grid/grid_utilities.h>
42#include <exadg/grid/mapping_dof_vector.h>
43#include <exadg/utilities/create_directories.h>
48restart_filename(std::string
const & name, MPI_Comm
const & mpi_comm)
50 std::string
const rank =
51 dealii::Utilities::int_to_string(dealii::Utilities::MPI::this_mpi_process(mpi_comm));
53 std::string
const filename = name +
"." + rank +
".restart";
59rename_restart_files(std::string
const & filename)
62 std::string
const from = filename;
63 std::string
const to = filename +
".old";
65 std::ifstream ifile(from.c_str());
68 int const error = rename(from.c_str(), to.c_str());
70 AssertThrow(error == 0, dealii::ExcMessage(
"Can not rename file: " + from +
" -> " + to));
75write_restart_file(std::ostringstream & oss, std::string
const & filename)
77 std::ofstream stream(filename.c_str());
79 stream << oss.str() << std::endl;
82template<
typename VectorType>
86 MPI_Comm
const & mpi_comm = vector.get_mpi_communicator();
87 double const l2_norm = vector.l2_norm();
88 if(dealii::Utilities::MPI::this_mpi_process(mpi_comm) == 0)
90 std::cout <<
" vector global l2 norm: " << std::scientific << std::setprecision(8)
91 << std::setw(20) << l2_norm <<
"\n";
102template<
typename VectorType,
typename BoostArchiveType>
107 if(std::is_same<BoostArchiveType, boost::archive::text_oarchive>::value or
108 std::is_same<BoostArchiveType, boost::archive::binary_oarchive>::value)
110 print_vector_l2_norm(vector);
115 using Number =
typename VectorType::value_type;
116 if constexpr(std::is_same<std::remove_cv_t<VectorType>,
117 dealii::LinearAlgebra::distributed::Vector<Number>>::value)
119 for(
unsigned int i = 0; i < vector.locally_owned_size(); ++i)
121 archive & vector.local_element(i);
124 else if constexpr(std::is_same<std::remove_cv_t<VectorType>,
125 dealii::LinearAlgebra::distributed::BlockVector<Number>>::value)
127 for(
unsigned int i = 0; i < vector.n_blocks(); ++i)
129 for(
unsigned int j = 0; j < vector.block(i).locally_owned_size(); ++j)
131 archive & vector.block(i).local_element(j);
137 AssertThrow(
false, dealii::ExcMessage(
"Reading into this VectorType not supported."));
141 if(std::is_same<BoostArchiveType, boost::archive::text_iarchive>::value or
142 std::is_same<BoostArchiveType, boost::archive::binary_iarchive>::value)
144 print_vector_l2_norm(vector);
153template<
typename VectorType,
typename BlockVectorType>
154std::vector<std::vector<VectorType *>>
157 unsigned int const n_blocks = block_vectors.at(0)->n_blocks();
158 for(
unsigned int i = 0; i < block_vectors.size(); ++i)
160 AssertThrow(block_vectors[i]->n_blocks() == n_blocks,
161 dealii::ExcMessage(
"Provided number of blocks per "
162 "BlockVector must be equal."));
165 std::vector<std::vector<VectorType *>> vectors_per_block;
166 for(
unsigned int i = 0; i < n_blocks; ++i)
168 std::vector<VectorType *> vectors;
169 for(
unsigned int j = 0; j < block_vectors.size(); ++j)
171 vectors.push_back(&block_vectors[j]->block(i));
173 vectors_per_block.push_back(vectors);
176 return vectors_per_block;
184template<
int dim,
typename BlockVectorType>
185std::vector<BlockVectorType>
187 unsigned int const n_vectors,
188 std::vector<dealii::DoFHandler<dim, dim>
const *>
const & dof_handlers)
190 unsigned int const n_blocks = dof_handlers.size();
193 BlockVectorType block_vector(n_blocks);
194 for(
unsigned int i = 0; i < n_blocks; ++i)
196 block_vector.block(i).reinit(dof_handlers[i]->locally_owned_dofs(),
197 dof_handlers[i]->get_mpi_communicator());
199 block_vector.collect_sizes();
201 std::vector<BlockVectorType> block_vectors(n_vectors, block_vector);
203 return block_vectors;
206template<
typename VectorType>
208get_ghost_state(std::vector<VectorType *>
const & vectors)
210 std::vector<bool> has_ghost_elements(vectors.size());
211 for(
unsigned int i = 0; i < has_ghost_elements.size(); ++i)
213 has_ghost_elements[i] = vectors[i]->has_ghost_elements();
215 return has_ghost_elements;
218template<
typename VectorType>
220set_ghost_state(std::vector<VectorType *>
const & vectors,
221 std::vector<bool>
const & had_ghost_elements)
223 AssertThrow(vectors.size() == had_ghost_elements.size(),
224 dealii::ExcMessage(
"Vector sizes do not match."));
226 for(
unsigned int i = 0; i < had_ghost_elements.size(); ++i)
228 if(had_ghost_elements[i])
230 vectors[i]->update_ghost_values();
234 vectors[i]->zero_out_ghost_values();
244template<
int dim,
typename TriangulationType>
247 std::string
const & filename_base,
248 TriangulationType
const & triangulation)
250 if constexpr(std::is_same<std::remove_cv_t<TriangulationType>,
251 dealii::parallel::distributed::Triangulation<dim, dim>>::value or
252 std::is_same<std::remove_cv_t<TriangulationType>,
253 dealii::parallel::fullydistributed::Triangulation<dim, dim>>::value)
256 dealii::ExcMessage(
"Only TriangulationType::Serial, i.e., "
257 "dealii::Triangulation<dim> supported."));
260 MPI_Comm
const & mpi_comm = triangulation.get_mpi_communicator();
265 std::string
const filename = directory + filename_base +
".coarse_triangulation";
266 if(dealii::Utilities::MPI::this_mpi_process(mpi_comm) == 0)
269 rename_restart_files(filename +
".info");
270 rename_restart_files(filename +
"_triangulation.data");
273 triangulation.save(filename);
286template<
int dim,
typename VectorType>
289 std::string
const & directory,
290 std::string
const & filename_base,
291 std::vector<std::vector<VectorType const *>>
const & vectors_per_dof_handler,
292 std::vector<dealii::DoFHandler<dim, dim>
const *>
const & dof_handlers)
294 AssertThrow(vectors_per_dof_handler.size() > 0,
295 dealii::ExcMessage(
"No vectors to store in triangulation."));
296 AssertThrow(vectors_per_dof_handler.size() == dof_handlers.size(),
297 dealii::ExcMessage(
"Number of vectors of vectors and DoFHandlers do not match."));
298 auto const & triangulation = dof_handlers.at(0)->get_triangulation();
301 for(
unsigned int i = 1; i < dof_handlers.size(); ++i)
303 AssertThrow(&dof_handlers[i]->get_triangulation() == &triangulation,
304 dealii::ExcMessage(
"Triangulations of DoFHandlers are not identical."));
308 std::vector<std::shared_ptr<dealii::SolutionTransfer<dim, VectorType>>> solution_transfers;
309 std::vector<std::vector<bool>> has_ghost_elements_per_dof_handler;
310 for(
unsigned int i = 0; i < dof_handlers.size(); ++i)
313 std::vector<bool> has_ghost_elements = get_ghost_state(vectors_per_dof_handler[i]);
314 has_ghost_elements_per_dof_handler.push_back(has_ghost_elements);
315 for(
unsigned int j = 0; j < vectors_per_dof_handler[i].size(); ++j)
317 vectors_per_dof_handler[i][j]->update_ghost_values();
318 print_vector_l2_norm(*vectors_per_dof_handler[i][j]);
321 solution_transfers.push_back(
322 std::make_shared<dealii::SolutionTransfer<dim, VectorType>>(*dof_handlers[i]));
323 solution_transfers[i]->prepare_for_serialization(vectors_per_dof_handler[i]);
327 std::string
const filename = directory + filename_base +
".triangulation";
328 MPI_Comm
const & mpi_comm = dof_handlers[0]->get_mpi_communicator();
329 if(dealii::Utilities::MPI::this_mpi_process(mpi_comm) == 0)
332 rename_restart_files(filename);
333 rename_restart_files(filename +
".info");
334 rename_restart_files(filename +
"_fixed.data");
335 rename_restart_files(filename +
"_triangulation.data");
339 triangulation.save(filename);
342 for(
unsigned int i = 0; i < dof_handlers.size(); ++i)
344 set_ghost_state(vectors_per_dof_handler[i], has_ghost_elements_per_dof_handler[i]);
353template<
int dim,
typename VectorType>
356 std::string
const & directory,
357 std::string
const & filename_base,
358 std::vector<std::vector<VectorType const *>>
const & vectors_per_dof_handler,
359 std::vector<dealii::DoFHandler<dim, dim>
const *>
const & dof_handlers,
360 dealii::Mapping<dim>
const & mapping,
361 dealii::DoFHandler<dim>
const * dof_handler_mapping,
362 unsigned int const mapping_degree)
364 AssertThrow(vectors_per_dof_handler.size() > 0,
365 dealii::ExcMessage(
"No vectors to store in triangulation."));
366 AssertThrow(vectors_per_dof_handler.size() == dof_handlers.size(),
367 dealii::ExcMessage(
"Number of vectors of vectors and DoFHandlers do not match."));
369 auto const & triangulation = dof_handlers.at(0)->get_triangulation();
372 for(
unsigned int i = 1; i < dof_handlers.size(); ++i)
374 AssertThrow(&dof_handlers[i]->get_triangulation() == &triangulation,
375 dealii::ExcMessage(
"Triangulations of DoFHandlers are not identical."));
378 AssertThrow(triangulation.all_reference_cells_are_hyper_cube(),
379 dealii::ExcMessage(
"Serialization including mapping not "
380 "supported for non-hypercube cell types."));
383 bool vector_initialized =
false;
385 for(
unsigned int i = 0; i < dof_handlers.size(); ++i)
387 if(dof_handlers[i] == dof_handler_mapping and not vector_initialized)
390 vector_grid_coordinates.reinit(*vectors_per_dof_handler[i][0],
392 vector_initialized =
true;
397 if(not vector_initialized)
400 dealii::IndexSet
const & locally_owned_dofs = dof_handler_mapping->locally_owned_dofs();
401 dealii::IndexSet
const locally_relevant_dofs =
402 dealii::DoFTools::extract_locally_relevant_dofs(*dof_handler_mapping);
403 vector_grid_coordinates.reinit(locally_owned_dofs,
404 locally_relevant_dofs,
405 dof_handler_mapping->get_mpi_communicator());
411 vector_grid_coordinates,
412 *dof_handler_mapping);
415 std::vector<std::vector<VectorType const *>> vectors_per_dof_handler_extended =
416 vectors_per_dof_handler;
417 std::vector<VectorType const *> tmp = {&vector_grid_coordinates};
418 vectors_per_dof_handler_extended.push_back(tmp);
420 std::vector<dealii::DoFHandler<dim, dim>
const *> dof_handlers_extended = dof_handlers;
421 dof_handlers_extended.push_back(dof_handler_mapping);
426 vectors_per_dof_handler_extended,
427 dof_handlers_extended);
434inline std::shared_ptr<dealii::Triangulation<dim>>
436 std::string
const & filename_base,
437 TriangulationType
const triangulation_type,
438 MPI_Comm
const & mpi_communicator)
440 std::shared_ptr<dealii::Triangulation<dim>> triangulation_old;
442 std::string
const filename = directory + filename_base;
445 if(triangulation_type == TriangulationType::Serial)
447 triangulation_old = std::make_shared<dealii::Triangulation<dim>>();
448 triangulation_old->load(filename +
".triangulation");
450 else if(triangulation_type == TriangulationType::Distributed)
454 dealii::Triangulation<dim, dim> coarse_triangulation;
457 coarse_triangulation.load(filename +
".coarse_triangulation");
463 "Deserializing coarse triangulation expected in\n" + filename +
464 ".coarse_triangulation\n"
465 "make sure to store the coarse grid during `create_grid`\n"
466 "in the respective application.h using TriangulationType::Serial."));
469 std::shared_ptr<dealii::parallel::distributed::Triangulation<dim>> tmp =
470 std::make_shared<dealii::parallel::distributed::Triangulation<dim>>(mpi_communicator);
472 tmp->copy_triangulation(coarse_triangulation);
473 coarse_triangulation.clear();
477 tmp->reset_all_manifolds();
478 tmp->set_all_manifold_ids(dealii::numbers::flat_manifold_id);
479 tmp->load(filename +
".triangulation");
481 triangulation_old = std::dynamic_pointer_cast<dealii::Triangulation<dim>>(tmp);
483 else if(triangulation_type == TriangulationType::FullyDistributed)
487 std::shared_ptr<dealii::parallel::fullydistributed::Triangulation<dim>> tmp =
488 std::make_shared<dealii::parallel::fullydistributed::Triangulation<dim>>(mpi_communicator);
489 tmp->load(filename +
".triangulation");
491 triangulation_old = std::dynamic_pointer_cast<dealii::Triangulation<dim>>(tmp);
495 AssertThrow(
false, dealii::ExcMessage(
"TriangulationType not supported."));
498 return triangulation_old;
506template<
int dim,
typename VectorType>
508load_vectors(std::vector<std::vector<VectorType *>> & vectors_per_dof_handler,
509 std::vector<dealii::DoFHandler<dim, dim>
const *>
const & dof_handlers)
513 AssertThrow(vectors_per_dof_handler.size() > 0,
514 dealii::ExcMessage(
"No vectors to load into from triangulation."));
515 AssertThrow(vectors_per_dof_handler.size() == dof_handlers.size(),
516 dealii::ExcMessage(
"Number of vectors of vectors and DoFHandlers do not match."));
520 for(
unsigned int i = 0; i < dof_handlers.size(); ++i)
522 dealii::SolutionTransfer<dim, VectorType> solution_transfer(*dof_handlers[i]);
525 bool all_ghosted =
false;
526 for(
unsigned int j = 0; j < vectors_per_dof_handler[i].size(); ++j)
528 if(not vectors_per_dof_handler[i][j]->has_ghost_elements())
536 dealii::IndexSet
const & locally_owned_dofs = dof_handlers[i]->locally_owned_dofs();
537 dealii::IndexSet
const locally_relevant_dofs =
538 dealii::DoFTools::extract_locally_relevant_dofs(*dof_handlers[i]);
539 for(
unsigned int j = 0; j < vectors_per_dof_handler[i].size(); ++j)
541 if(not vectors_per_dof_handler[i][j]->has_ghost_elements())
543 vectors_per_dof_handler[i][j]->reinit(locally_owned_dofs,
544 locally_relevant_dofs,
545 dof_handlers[i]->get_mpi_communicator());
550 solution_transfer.deserialize(vectors_per_dof_handler[i]);
552 for(
unsigned int j = 0; j < vectors_per_dof_handler[i].size(); ++j)
554 print_vector_l2_norm(*vectors_per_dof_handler[i][j]);
563template<
int dim,
typename VectorType>
564inline std::shared_ptr<MappingDoFVector<dim, typename VectorType::value_type>>
565load_vectors(std::vector<std::vector<VectorType *>> & vectors_per_dof_handler,
566 std::vector<dealii::DoFHandler<dim, dim>
const *>
const & dof_handlers,
567 dealii::DoFHandler<dim>
const * dof_handler_mapping,
568 unsigned int const mapping_degree)
572 dealii::IndexSet
const & locally_owned_dofs = dof_handler_mapping->locally_owned_dofs();
573 VectorType vector_grid_coordinates(locally_owned_dofs,
574 dof_handler_mapping->get_mpi_communicator());
577 std::vector<std::vector<VectorType *>> vectors_per_dof_handler_extended = vectors_per_dof_handler;
578 std::vector<VectorType *> tmp = {&vector_grid_coordinates};
579 vectors_per_dof_handler_extended.push_back(tmp);
580 std::vector<dealii::DoFHandler<dim, dim>
const *> dof_handlers_extended = dof_handlers;
581 dof_handlers_extended.push_back(dof_handler_mapping);
583 load_vectors(vectors_per_dof_handler_extended, dof_handlers_extended);
586 std::shared_ptr<MappingDoFVector<dim, typename VectorType::value_type>> mapping_dof_vector =
587 std::make_shared<MappingDoFVector<dim, typename VectorType::value_type>>(mapping_degree);
588 mapping_dof_vector->initialize_mapping_from_dof_vector(
nullptr ,
589 vector_grid_coordinates,
590 *dof_handler_mapping);
591 return mapping_dof_vector;
Definition mapping_dof_vector.h:54
void fill_grid_coordinates_vector(VectorType &grid_coordinates, dealii::DoFHandler< dim > const &dof_handler) const
Definition mapping_dof_vector.h:105
void save_coarse_triangulation(std::string const &directory, std::string const &filename_base, TriangulationType const &triangulation)
Definition restart.h:246
void store_vectors_in_triangulation_and_serialize(std::string const &directory, std::string const &filename_base, std::vector< std::vector< VectorType const * > > const &vectors_per_dof_handler, std::vector< dealii::DoFHandler< dim, dim > const * > const &dof_handlers)
Definition restart.h:288
std::vector< BlockVectorType > get_block_vectors_from_dof_handlers(unsigned int const n_vectors, std::vector< dealii::DoFHandler< dim, dim > const * > const &dof_handlers)
Definition restart.h:186
void read_write_distributed_vector(VectorType &vector, BoostArchiveType &archive)
Definition restart.h:104
std::vector< std::vector< VectorType * > > get_vectors_per_block(std::vector< BlockVectorType * > const &block_vectors)
Definition restart.h:155
std::shared_ptr< dealii::Triangulation< dim > > deserialize_triangulation(std::string const &directory, std::string const &filename_base, TriangulationType const triangulation_type, MPI_Comm const &mpi_communicator)
Definition restart.h:435
void load_vectors(std::vector< std::vector< VectorType * > > &vectors_per_dof_handler, std::vector< dealii::DoFHandler< dim, dim > const * > const &dof_handlers)
Definition restart.h:508
void create_directories(std::string const &directory, MPI_Comm const &mpi_comm)
Definition create_directories.h:35