ExaDG
Loading...
Searching...
No Matches
restart.h
1/* ______________________________________________________________________
2 *
3 * ExaDG - High-Order Discontinuous Galerkin for the Exa-Scale
4 *
5 * Copyright (C) 2021 by the ExaDG authors
6 *
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <https://www.gnu.org/licenses/>.
19 * ______________________________________________________________________
20 */
21
22#ifndef EXADG_TIME_INTEGRATION_RESTART_H_
23#define EXADG_TIME_INTEGRATION_RESTART_H_
24
25// C/C++
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>
30#include <fstream>
31
32// deal.II
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>
39
40// ExaDG
41#include <exadg/grid/grid_utilities.h>
42#include <exadg/grid/mapping_dof_vector.h>
43#include <exadg/time_integration/restart_data.h>
44#include <exadg/utilities/create_directories.h>
45
46namespace ExaDG
47{
48inline std::string
49generate_restart_filename(std::string const & name)
50{
51 // Filename does not incorporate rank information, files in-/output with single rank only.
52 std::string const filename = name + ".restart";
53
54 return filename;
55}
56
57inline void
58rename_old_restart_files(std::string const & filename, unsigned int const n_snapshots_keep)
59{
60 // Store `n_snapshots_keep` snapshots and rename existing ones from back to front, automatically
61 // overwriting last one.
62 for(int i = n_snapshots_keep - 2; i >= 0; --i)
63 {
64 // From most current to first old snapshop, the naming convention changes.
65 std::string const from = i == 0 ? filename : filename + ".old." + std::to_string(i);
66 std::string const to = filename + ".old." + std::to_string(i + 1);
67
68 std::ifstream ifile(from.c_str());
69 if((bool)ifile) // rename only if file already exists
70 {
71 int const error = rename(from.c_str(), to.c_str());
72
73 AssertThrow(error == 0, dealii::ExcMessage("Can not rename file: " + from + " -> " + to));
74 }
75 }
76}
77
78inline void
79write_restart_file(std::ostringstream & oss, std::string const & filename)
80{
81 std::ofstream stream(filename.c_str());
82
83 stream << oss.str() << std::endl;
84}
85
86template<typename VectorType>
87inline void
88print_vector_l2_norm(VectorType const & vector)
89{
90 MPI_Comm const & mpi_comm = vector.get_mpi_communicator();
91 double const l2_norm = vector.l2_norm();
92 if(dealii::Utilities::MPI::this_mpi_process(mpi_comm) == 0)
93 {
94 std::cout << " vector global l2 norm: " << std::scientific << std::setprecision(8)
95 << std::setw(20) << l2_norm << "\n";
96 }
97}
98
104template<typename VectorType, typename BlockVectorType>
105std::vector<std::vector<VectorType *>>
106get_vectors_per_block(std::vector<BlockVectorType *> const & block_vectors)
107{
108 unsigned int const n_blocks = block_vectors.at(0)->n_blocks();
109 for(unsigned int i = 0; i < block_vectors.size(); ++i)
110 {
111 AssertThrow(block_vectors[i]->n_blocks() == n_blocks,
112 dealii::ExcMessage("Provided number of blocks per "
113 "BlockVector must be equal."));
114 }
115
116 std::vector<std::vector<VectorType *>> vectors_per_block;
117 for(unsigned int i = 0; i < n_blocks; ++i)
118 {
119 std::vector<VectorType *> vectors;
120 for(unsigned int j = 0; j < block_vectors.size(); ++j)
121 {
122 vectors.push_back(&block_vectors[j]->block(i));
123 }
124 vectors_per_block.push_back(vectors);
125 }
126
127 return vectors_per_block;
128}
129
135template<int dim, typename BlockVectorType>
136std::vector<BlockVectorType>
138 unsigned int const n_vectors,
139 std::vector<dealii::DoFHandler<dim, dim> const *> const & dof_handlers)
140{
141 unsigned int const n_blocks = dof_handlers.size();
142
143 // Setup first `BlockVector`
144 BlockVectorType block_vector(n_blocks);
145 for(unsigned int i = 0; i < n_blocks; ++i)
146 {
147 block_vector.block(i).reinit(dof_handlers[i]->locally_owned_dofs(),
148 dof_handlers[i]->get_mpi_communicator());
149 }
150 block_vector.collect_sizes();
151
152 std::vector<BlockVectorType> block_vectors(n_vectors, block_vector);
153
154 return block_vectors;
155}
156
157template<typename VectorType>
158std::vector<bool>
159get_ghost_state(std::vector<VectorType *> const & vectors)
160{
161 std::vector<bool> has_ghost_elements(vectors.size());
162 for(unsigned int i = 0; i < has_ghost_elements.size(); ++i)
163 {
164 has_ghost_elements[i] = vectors[i]->has_ghost_elements();
165 }
166 return has_ghost_elements;
167}
168
169template<typename VectorType>
170void
171set_ghost_state(std::vector<VectorType *> const & vectors,
172 std::vector<bool> const & had_ghost_elements)
173{
174 AssertThrow(vectors.size() == had_ghost_elements.size(),
175 dealii::ExcMessage("Vector sizes do not match."));
176
177 for(unsigned int i = 0; i < had_ghost_elements.size(); ++i)
178 {
179 if(had_ghost_elements[i])
180 {
181 vectors[i]->update_ghost_values();
182 }
183 else
184 {
185 vectors[i]->zero_out_ghost_values();
186 }
187 }
188}
189
194inline void
195write_deserialization_parameters(MPI_Comm const & mpi_comm,
196 RestartData const & restart_data,
197 DeserializationParameters const & parameters)
198{
199 // Create folder if not existent.
200 create_directories(restart_data.directory, mpi_comm);
201
202 // Filename for deserialization parameters has to match `read_deserialization_parameters()`.
203 std::string const filename =
204 restart_data.directory + restart_data.filename + ".deserialization_parameters";
205
206 // Write the parameters with a single processor.
207 if(dealii::Utilities::MPI::this_mpi_process(mpi_comm) == 0)
208 {
209 // Serialization only creates a single file, move with one process only.
210 rename_old_restart_files(filename, restart_data.n_snapshots_keep);
211
212 // Write deserialization parameters.
213 std::ofstream stream(filename);
214 AssertThrow(stream, dealii::ExcMessage("Could not write deserialization parameters to file."));
215
216 // Text archive type for debugging purposes.
217 // boost::archive::text_oarchive output_archive(stream);
218 boost::archive::binary_oarchive output_archive(stream);
219
220 // Sequence has to match `read_deserialization_parameters()`.
221 output_archive & parameters.degree;
222 output_archive & parameters.degree_u;
223 output_archive & parameters.degree_p;
224 output_archive & parameters.mapping_degree;
225 output_archive & parameters.consider_mapping_write;
226 output_archive & parameters.triangulation_type;
227 output_archive & parameters.spatial_discretization;
228 }
229}
230
235inline DeserializationParameters
236read_deserialization_parameters(MPI_Comm const & mpi_comm, RestartData const & restart_data)
237{
238 DeserializationParameters parameters;
239
240 // Filename for deserialization parameters has to match `write_deserialization_parameters()`.
241 std::string const filename =
242 restart_data.directory + restart_data.filename + ".deserialization_parameters";
243
244 // Read the parameters with a single processor.
245 if(dealii::Utilities::MPI::this_mpi_process(mpi_comm) == 0)
246 {
247 // Read deserialization parameters.
248 std::ifstream stream(filename);
249 AssertThrow(stream, dealii::ExcMessage("Could not read deserialization parameters from file."));
250
251 // Text archive type for debugging purposes.
252 // boost::archive::text_iarchive input_archive(stream);
253 boost::archive::binary_iarchive input_archive(stream);
254
255 // Sequence has to match `write_deserialization_parameters()`.
256 input_archive & parameters.degree;
257 input_archive & parameters.degree_u;
258 input_archive & parameters.degree_p;
259 input_archive & parameters.mapping_degree;
260 input_archive & parameters.consider_mapping_write;
261 input_archive & parameters.triangulation_type;
262 input_archive & parameters.spatial_discretization;
263 }
264
265 // Broadcast parameters to all processes.
266 parameters = dealii::Utilities::MPI::broadcast(mpi_comm, parameters, 0);
267
268 return parameters;
269}
270
271/*
272 * Utility function to check if mapping is correctly treated in de-/serialization. This is to
273 * provide easier to interpret error messages on ExaDG level in case the number of DoF vectors
274 * mismatches. This might be due to the mapping being described as a displacement vector, which
275 * might also be de-/serialized, while we have to deserialize exactly what we serialized.
276 */
277inline void
278check_mapping_deserialization(bool const consider_mapping_read_source,
279 bool const consider_mapping_write_as_serialized)
280{
281 if(consider_mapping_read_source)
282 {
283 if(consider_mapping_write_as_serialized == false)
284 {
285 AssertThrow(false,
286 dealii::ExcMessage(
287 "Mapping was not considered when writing the restart data, but shall "
288 "be considered when reading the restart data. This is not supported."));
289 }
290 }
291 else
292 {
293 if(consider_mapping_write_as_serialized == true)
294 {
295 AssertThrow(false,
296 dealii::ExcMessage(
297 "Mapping was considered when writing the restart data, but shall "
298 "not be considered when reading the restart data. This is not supported."));
299 }
300 }
301}
302
308template<int dim, typename TriangulationType>
309inline void
310save_coarse_triangulation(RestartData const & restart_data, TriangulationType const & triangulation)
311{
312 if constexpr(std::is_same<std::remove_cv_t<TriangulationType>,
313 dealii::parallel::distributed::Triangulation<dim, dim>>::value or
314 std::is_same<std::remove_cv_t<TriangulationType>,
315 dealii::parallel::fullydistributed::Triangulation<dim, dim>>::value)
316 {
317 AssertThrow(false,
318 dealii::ExcMessage("Only TriangulationType::Serial, i.e., "
319 "dealii::Triangulation<dim> supported."));
320 }
321
322 MPI_Comm const & mpi_comm = triangulation.get_mpi_communicator();
323
324 // Create folder if not existent.
325 create_directories(restart_data.directory_coarse_triangulation, mpi_comm);
326
327 std::string const filename =
328 restart_data.directory_coarse_triangulation + restart_data.filename + ".coarse_triangulation";
329 if(dealii::Utilities::MPI::this_mpi_process(mpi_comm) == 0)
330 {
331 // Serialization only creates a single file, move with one process only.
332 rename_old_restart_files(filename + ".info", restart_data.n_snapshots_keep);
333 rename_old_restart_files(filename + "_triangulation.data", restart_data.n_snapshots_keep);
334
335 // For `dealii::Triangulation` the triangulation is the same for all processes.
336 triangulation.save(filename);
337 }
338}
339
349template<int dim, typename VectorType>
350inline void
352 RestartData const & restart_data,
353 std::vector<dealii::DoFHandler<dim, dim> const *> const & dof_handlers,
354 std::vector<std::vector<VectorType const *>> const & vectors_per_dof_handler)
355{
356 AssertThrow(vectors_per_dof_handler.size() > 0,
357 dealii::ExcMessage("No vectors to store in triangulation."));
358 AssertThrow(vectors_per_dof_handler.size() == dof_handlers.size(),
359 dealii::ExcMessage("Number of vectors of vectors and DoFHandlers do not match."));
360 auto const & triangulation = dof_handlers.at(0)->get_triangulation();
361
362 // Check if all the `Triangulation(s)` associated with the DoFHandlers point to the same object.
363 for(unsigned int i = 1; i < dof_handlers.size(); ++i)
364 {
365 AssertThrow(&dof_handlers[i]->get_triangulation() == &triangulation,
366 dealii::ExcMessage("Triangulations of DoFHandlers are not identical."));
367 }
368
369 // Loop over the `DoFHandlers` and store the vectors in the triangulation.
370 std::vector<std::shared_ptr<dealii::SolutionTransfer<dim, VectorType>>> solution_transfers;
371 std::vector<std::vector<bool>> has_ghost_elements_per_dof_handler;
372 for(unsigned int i = 0; i < dof_handlers.size(); ++i)
373 {
374 // Store ghost state.
375 std::vector<bool> has_ghost_elements = get_ghost_state(vectors_per_dof_handler[i]);
376 has_ghost_elements_per_dof_handler.push_back(has_ghost_elements);
377 for(unsigned int j = 0; j < vectors_per_dof_handler[i].size(); ++j)
378 {
379 vectors_per_dof_handler[i][j]->update_ghost_values();
380 print_vector_l2_norm(*vectors_per_dof_handler[i][j]);
381 }
382
383 solution_transfers.push_back(
384 std::make_shared<dealii::SolutionTransfer<dim, VectorType>>(*dof_handlers[i]));
385 solution_transfers[i]->prepare_for_serialization(vectors_per_dof_handler[i]);
386 }
387
388 // Serialize the triangulation keeping a maximum of two snapshots.
389 std::string const filename = restart_data.directory + restart_data.filename + ".triangulation";
390 MPI_Comm const & mpi_comm = dof_handlers[0]->get_mpi_communicator();
391 if(dealii::Utilities::MPI::this_mpi_process(mpi_comm) == 0)
392 {
393 // Serialization only creates a single file, move with one process only.
394 rename_old_restart_files(filename, restart_data.n_snapshots_keep);
395 rename_old_restart_files(filename + ".info", restart_data.n_snapshots_keep);
396 rename_old_restart_files(filename + "_fixed.data", restart_data.n_snapshots_keep);
397 rename_old_restart_files(filename + "_triangulation.data", restart_data.n_snapshots_keep);
398 }
399
400 // Collective call for serialization, general case requires ghosted vectors.
401 triangulation.save(filename);
402
403 // Recover ghost state.
404 for(unsigned int i = 0; i < dof_handlers.size(); ++i)
405 {
406 set_ghost_state(vectors_per_dof_handler[i], has_ghost_elements_per_dof_handler[i]);
407 }
408}
409
415template<int dim, typename VectorType>
416inline void
418 RestartData const & restart_data,
419 std::vector<dealii::DoFHandler<dim, dim> const *> const & dof_handlers,
420 std::vector<std::vector<VectorType const *>> const & vectors_per_dof_handler,
421 dealii::Mapping<dim> const & mapping,
422 dealii::DoFHandler<dim> const * dof_handler_mapping,
423 unsigned int const mapping_degree)
424{
425 AssertThrow(vectors_per_dof_handler.size() > 0,
426 dealii::ExcMessage("No vectors to store in triangulation."));
427 AssertThrow(vectors_per_dof_handler.size() == dof_handlers.size(),
428 dealii::ExcMessage("Number of vectors of vectors and DoFHandlers do not match."));
429
430 auto const & triangulation = dof_handlers.at(0)->get_triangulation();
431
432 // Check if all the `Triangulation(s)` associated with the `DoFHandlers` point to the same object.
433 for(unsigned int i = 1; i < dof_handlers.size(); ++i)
434 {
435 AssertThrow(&dof_handlers[i]->get_triangulation() == &triangulation,
436 dealii::ExcMessage("Triangulations of DoFHandlers are not identical."));
437 }
438
439 AssertThrow(triangulation.all_reference_cells_are_hyper_cube(),
440 dealii::ExcMessage("Serialization including mapping not "
441 "supported for non-hypercube cell types."));
442
443 // Initialize vector to hold grid coordinates.
444 bool vector_initialized = false;
445 VectorType vector_grid_coordinates;
446 for(unsigned int i = 0; i < dof_handlers.size(); ++i)
447 {
448 if(dof_handlers[i] == dof_handler_mapping and not vector_initialized)
449 {
450 // Cheaper setup if we already have a vector given in the input arguments.
451 vector_grid_coordinates.reinit(*vectors_per_dof_handler[i][0],
452 true /* omit_zeroing_entries */);
453 vector_initialized = true;
454 break;
455 }
456 }
457
458 if(not vector_initialized)
459 {
460 // More expensive setup extracting the `dealii::IndexSet`.
461 dealii::IndexSet const & locally_owned_dofs = dof_handler_mapping->locally_owned_dofs();
462 dealii::IndexSet const locally_relevant_dofs =
463 dealii::DoFTools::extract_locally_relevant_dofs(*dof_handler_mapping);
464 vector_grid_coordinates.reinit(locally_owned_dofs,
465 locally_relevant_dofs,
466 dof_handler_mapping->get_mpi_communicator());
467 }
468
469 // Fill vector with mapping.
470 MappingDoFVector<dim, typename VectorType::value_type> mapping_dof_vector(mapping_degree);
471 mapping_dof_vector.fill_grid_coordinates_vector(mapping,
472 vector_grid_coordinates,
473 *dof_handler_mapping);
474
475 // Attach vector holding mapping and corresponding `dof_handler_mapping`.
476 std::vector<std::vector<VectorType const *>> vectors_per_dof_handler_extended =
477 vectors_per_dof_handler;
478 std::vector<VectorType const *> tmp = {&vector_grid_coordinates};
479 vectors_per_dof_handler_extended.push_back(tmp);
480
481 std::vector<dealii::DoFHandler<dim, dim> const *> dof_handlers_extended = dof_handlers;
482 dof_handlers_extended.push_back(dof_handler_mapping);
483
484 // Use utility function that ignores the mapping.
486 dof_handlers_extended,
487 vectors_per_dof_handler_extended);
488}
489
493template<int dim>
494inline std::shared_ptr<dealii::Triangulation<dim>>
496 TriangulationType const triangulation_type,
497 MPI_Comm const & mpi_communicator)
498{
499 std::shared_ptr<dealii::Triangulation<dim>> triangulation_old;
500
501 std::string const filename = restart_data.directory + restart_data.filename;
502
503 // Deserialize the checkpointed triangulation,
504 if(triangulation_type == TriangulationType::Serial)
505 {
506 triangulation_old = std::make_shared<dealii::Triangulation<dim>>();
507 triangulation_old->load(filename + ".triangulation");
508 }
509 else if(triangulation_type == TriangulationType::Distributed)
510 {
511 // Deserialize the coarse triangulation to be stored by the user
512 // during `create_grid` in the respective application.
513 dealii::Triangulation<dim, dim> coarse_triangulation;
514 std::string const filename_coarse_triangulation =
515 restart_data.directory_coarse_triangulation + restart_data.filename;
516 try
517 {
518 coarse_triangulation.load(filename_coarse_triangulation + ".coarse_triangulation");
519 }
520 catch(...)
521 {
522 AssertThrow(false,
523 dealii::ExcMessage(
524 "Deserializing coarse triangulation expected in\n" +
525 filename_coarse_triangulation +
526 ".coarse_triangulation\n"
527 "make sure to store the coarse grid during `create_grid`\n"
528 "in the respective application.h using TriangulationType::Serial."));
529 }
530
531 std::shared_ptr<dealii::parallel::distributed::Triangulation<dim>> tmp =
532 std::make_shared<dealii::parallel::distributed::Triangulation<dim>>(mpi_communicator);
533
534 tmp->copy_triangulation(coarse_triangulation);
535 coarse_triangulation.clear();
536
537 // We do not need manifolds when applying the refinements, since we recover the mapping
538 // separately.
539 tmp->reset_all_manifolds();
540 tmp->set_all_manifold_ids(dealii::numbers::flat_manifold_id);
541 tmp->load(filename + ".triangulation");
542
543 triangulation_old = std::dynamic_pointer_cast<dealii::Triangulation<dim>>(tmp);
544 }
545 else if(triangulation_type == TriangulationType::FullyDistributed)
546 {
547 // Note that the number of MPI processes the triangulation was
548 // saved with cannot change and hence autopartitioning is disabled.
549 std::shared_ptr<dealii::parallel::fullydistributed::Triangulation<dim>> tmp =
550 std::make_shared<dealii::parallel::fullydistributed::Triangulation<dim>>(mpi_communicator);
551 tmp->load(filename + ".triangulation");
552
553 triangulation_old = std::dynamic_pointer_cast<dealii::Triangulation<dim>>(tmp);
554 }
555 else
556 {
557 AssertThrow(false, dealii::ExcMessage("TriangulationType not supported."));
558 }
559
560 return triangulation_old;
561}
562
568template<int dim, typename VectorType>
569inline void
570load_vectors(std::vector<std::vector<VectorType *>> & vectors_per_dof_handler,
571 std::vector<dealii::DoFHandler<dim, dim> const *> const & dof_handlers)
572{
573 // The `dof_handlers` and `vectors_per_dof_handler` are already initialized and
574 // `vectors_per_dof_handler` contain only owned DoFs.
575 AssertThrow(vectors_per_dof_handler.size() > 0,
576 dealii::ExcMessage("No vectors to load into from triangulation."));
577 AssertThrow(vectors_per_dof_handler.size() == dof_handlers.size(),
578 dealii::ExcMessage("Number of vectors of vectors and DoFHandlers do not match."));
579
580 // Loop over the DoFHandlers and load the vectors stored in
581 // the triangulation the DoFHandlers were initialized with.
582 for(unsigned int i = 0; i < dof_handlers.size(); ++i)
583 {
584 dealii::SolutionTransfer<dim, VectorType> solution_transfer(*dof_handlers[i]);
585
586 // Reinit vectors that do not already have ghost entries.
587 bool all_ghosted = false;
588 for(unsigned int j = 0; j < vectors_per_dof_handler[i].size(); ++j)
589 {
590 if(not vectors_per_dof_handler[i][j]->has_ghost_elements())
591 {
592 all_ghosted = false;
593 break;
594 }
595 }
596 if(not all_ghosted)
597 {
598 dealii::IndexSet const & locally_owned_dofs = dof_handlers[i]->locally_owned_dofs();
599 dealii::IndexSet const locally_relevant_dofs =
600 dealii::DoFTools::extract_locally_relevant_dofs(*dof_handlers[i]);
601 for(unsigned int j = 0; j < vectors_per_dof_handler[i].size(); ++j)
602 {
603 if(not vectors_per_dof_handler[i][j]->has_ghost_elements())
604 {
605 vectors_per_dof_handler[i][j]->reinit(locally_owned_dofs,
606 locally_relevant_dofs,
607 dof_handlers[i]->get_mpi_communicator());
608 }
609 }
610 }
611
612 solution_transfer.deserialize(vectors_per_dof_handler[i]);
613
614 for(unsigned int j = 0; j < vectors_per_dof_handler[i].size(); ++j)
615 {
616 print_vector_l2_norm(*vectors_per_dof_handler[i][j]);
617 }
618 }
619}
620
625template<int dim, typename VectorType>
626inline std::shared_ptr<MappingDoFVector<dim, typename VectorType::value_type>>
627load_vectors(std::vector<std::vector<VectorType *>> & vectors_per_dof_handler,
628 std::vector<dealii::DoFHandler<dim, dim> const *> const & dof_handlers,
629 dealii::DoFHandler<dim> const * dof_handler_mapping,
630 unsigned int const mapping_degree)
631{
632 // We need a collective call to `SolutionTransfer::deserialize()` with all vectors in a
633 // single container. Hence, create a mapping vector and add a pointer to the input argument.
634 dealii::IndexSet const & locally_owned_dofs = dof_handler_mapping->locally_owned_dofs();
635 VectorType vector_grid_coordinates(locally_owned_dofs,
636 dof_handler_mapping->get_mpi_communicator());
637
638 // Standard utility function, sequence as in `store_vectors_in_triangulation_and_serialize()`.
639 std::vector<std::vector<VectorType *>> vectors_per_dof_handler_extended = vectors_per_dof_handler;
640 std::vector<VectorType *> tmp = {&vector_grid_coordinates};
641 vectors_per_dof_handler_extended.push_back(tmp);
642 std::vector<dealii::DoFHandler<dim, dim> const *> dof_handlers_extended = dof_handlers;
643 dof_handlers_extended.push_back(dof_handler_mapping);
644
645 load_vectors(vectors_per_dof_handler_extended, dof_handlers_extended);
646
647 // Reconstruct the mapping given the deserialized grid coordinate vector.
648 std::shared_ptr<MappingDoFVector<dim, typename VectorType::value_type>> mapping_dof_vector =
649 std::make_shared<MappingDoFVector<dim, typename VectorType::value_type>>(mapping_degree);
650 mapping_dof_vector->initialize_mapping_from_dof_vector(nullptr /* mapping */,
651 vector_grid_coordinates,
652 *dof_handler_mapping);
653 return mapping_dof_vector;
654}
655
656} // namespace ExaDG
657
658#endif /* EXADG_TIME_INTEGRATION_RESTART_H_ */
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
Definition driver.cpp:33
DeserializationParameters read_deserialization_parameters(MPI_Comm const &mpi_comm, RestartData const &restart_data)
Definition restart.h:236
void write_deserialization_parameters(MPI_Comm const &mpi_comm, RestartData const &restart_data, DeserializationParameters const &parameters)
Definition restart.h:195
std::shared_ptr< dealii::Triangulation< dim > > deserialize_triangulation(RestartData const &restart_data, TriangulationType const triangulation_type, MPI_Comm const &mpi_communicator)
Definition restart.h:495
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:137
std::vector< std::vector< VectorType * > > get_vectors_per_block(std::vector< BlockVectorType * > const &block_vectors)
Definition restart.h:106
void store_vectors_in_triangulation_and_serialize(RestartData const &restart_data, std::vector< dealii::DoFHandler< dim, dim > const * > const &dof_handlers, std::vector< std::vector< VectorType const * > > const &vectors_per_dof_handler)
Definition restart.h:351
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:570
void save_coarse_triangulation(RestartData const &restart_data, TriangulationType const &triangulation)
Definition restart.h:310
void create_directories(std::string const &directory, MPI_Comm const &mpi_comm)
Definition create_directories.h:35
Definition restart_data.h:40
Definition restart_data.h:84