Peano
Loading...
Searching...
No Matches
WriteCheckpoint.py
Go to the documentation of this file.
1# This file is part of the ExaHyPE2 project. For conditions of distribution and
2# use, please see the copyright notice at www.peano-framework.org
3import os
4
5import peano4.api
7
8from ..Solver import Solver
9from .PlotAsVTKFile import _PlotPatchesIfPlotterIsActive
10from .actionsets import ApplyDirichletBoundaryConditions
11
12
14 """!
15
16 Write checkpoints of a Finite Volume solver
17
18 The checkpoint is configured like PlotAsVTKFile, i.e. it is written in
19 regular time intervals. Different to a plot, it writes the whole state
20 of the solver such that a simulation can continue from it. It hence has
21 neither plot filters nor a selection of quantities: It writes all
22 entries of Q, i.e. the unknowns and the auxiliary variables, of all
23 cells which the solver updates.
24
25 - It writes each patch together with its halo. Before it writes the
26 data, it reconstructs the halo exactly as the time step does: It
27 sets the ghost volumes along the domain boundary (Dirichlet
28 boundary conditions), interpolates the hanging faces on adaptive
29 meshes and gathers patch and face data into solver._patch_with_halo
30 (toolbox.blockstructured.api.ReconstructPatchWithHalo). A patch
31 with N volumes per axis and a halo of M volumes is written as a patch
32 with N+2M volumes per axis. Its box covers the cell plus the halo, so
33 every volume sits at its true position, and neighbouring patches
34 overlap.
35 - It writes all values without loss: values, patch offsets and sizes
36 carry 17 significant digits by default, and the writer does not set
37 small values to zero
38 (@ref tarch::plotter::griddata::blockstructured::PeanoTextPatchFileWriter).
39 - The meta-data block in the header of each file holds the solver's
40 state (@ref exahype2::Solver::toCheckpointMetaData()): its time
41 stamps, time step sizes, admissible time step size and mesh sizes,
42 plus the attributes the Python API adds to the solver's class, e.g.
43 the time stamps of the next outputs of all of its plotters.
44
45 The files are called checkpoint-SolverName by default. A solver can
46 have a checkpoint next to its other plotters
47 (@ref exahype2.api.Solver.Solver.add_plotter()).
48 A simulation continues from a checkpoint with
49 @ref exahype2.api.blockstructured.LoadCheckpoint.LoadCheckpoint instead of
50 its usual grid construction.
51
52 The reconstruction only reads the patch and face data, i.e. a
53 checkpoint does not change the solution. The Dirichlet boundary
54 conditions overwrite the ghost volumes with the values they have at the
55 current time stamp anyway, and the next time step sets them again.
56
57 """
58
60 self,
61 solver: Solver,
62 first_plot_time_stamp=0.0,
63 time_in_between_plots=0.1,
64 plotter_precision=17,
65 output_path=".",
66 filename="checkpoint",
67 name: str = None,
68 binary=True,
69 ):
70 """!
71
72 @param solver: exahype2.api.Solver
73 The solver whose state is written.
74
75 @param first_plot_time_stamp: float
76 Time stamp of the first checkpoint.
77
78 @param time_in_between_plots: float
79 Time in between two checkpoints. Has to be positive.
80
81 @param plotter_precision: int
82 Number of significant digits written per value. The default of 17
83 ensures that the values are read back without loss.
84
85 @param output_path: str
86 Directory the checkpoint files are written into.
87
88 @param filename: str
89 The checkpoint files are called filename-SolverName.
90
91 @param name: str or None
92 Name of the plotter (@ref exahype2.api.Solver.Solver.Plotter).
93
94 @param binary: bool
95 Write the values as raw doubles instead of text
96 (@ref tarch::plotter::griddata::blockstructured::PeanoBinaryPatchFileWriter).
97 The checkpoint reader (@ref exahype2::CheckpointReader) reads both
98 formats. Pass False to get human-readable checkpoints.
99
100 """
101 super().__init__(solver, name)
102
103 if time_in_between_plots <= 0:
104 raise Exception("Time in between checkpoints has to be bigger than 0")
105 if plotter_precision <= 0:
106 raise Exception("Precision has to be bigger than 0")
107 self._first_plot_time_stamp = first_plot_time_stamp
108 self._time_in_between_plots = time_in_between_plots
109 self._plotter_precision = plotter_precision
110 self._output_path = output_path
111 self._filename = filename
112 self._binary = binary
113
115 return os.path.join(self._output_path, self._filename + "-" + self._solver_solver.name)
116
117 def construct_output(self, exahype2_project, peano_project, plot):
118 """!
119
120 Add the reconstruction of the halo and the writing of the checkpoint
121 to the plot graph
122
123 All action sets are guarded by the checkpoint's is<Name>Active(),
124 i.e. the tasks do no work in plot phases without checkpoint. The
125 writing task is the last one, so it moves the checkpoint on to its
126 next time stamp.
127
128 """
129 peano4.api.Logger().log(
130 "Create checkpoint task graph for Finite Volume scheme over block-structured meshes"
131 )
132
133 for attribute in [
134 "_patch",
135 "_patch_with_halo",
136 "_patch_overlap_current_time_step",
137 ]:
138 assert hasattr(self._solver_solver, attribute), (
139 f"Solver {self._solver.name} has no attribute {attribute}. "
140 "WriteCheckpoint assumes the numerical scheme has added this field "
141 "to the solver immediately upon construction."
142 )
143
146 )
147 self._solver_solver._add_checkpoint_meta_data_to_solver()
148
149 Access = peano4.api.taskgraph.Task.DataAccess
150 is_active = self.create_is_active_predicate()
151 cell_guard = (
152 "("
153 + is_active
154 + ") and ("
155 + self._solver_solver.grid_selector.createCellGuard()
156 + ")"
157 )
158 includes = (
159 self._solver_solver._get_default_includes() + self._solver_solver.user_solver_includes
160 )
161
162 reconstruction_task = peano4.api.taskgraph.Task(
163 name=f"{self._solver.name}_{self.name}_Reconstruct",
164 entity=peano4.api.taskgraph.Task.GridEntity.CELL,
165 may_spawn_background_tasks=False,
166 )
167 write_checkpoint_task = peano4.api.taskgraph.Task(
168 name=f"{self._solver.name}_{self.name}_Write checkpoint",
169 entity=peano4.api.taskgraph.Task.GridEntity.CELL,
170 may_spawn_background_tasks=False,
171 )
172 plot.add_task(reconstruction_task)
173 plot.add_task(write_checkpoint_task)
174
175
176 reconstruction_task.use_cell(self._solver_solver._patch, Access.READ_AND_WRITE)
177 reconstruction_task.use_cell(self._solver_solver._patch_with_halo, Access.WRITE)
178 reconstruction_task.use_face(
179 self._solver_solver._patch_overlap_current_time_step, Access.READ_AND_WRITE
180 )
181 reconstruction_task.add_action_set(
182 toolbox.blockstructured.api.ReconstructPatchWithHalo(
183 patch=self._solver_solver._patch,
184 patch_overlap=self._solver_solver._patch_overlap_current_time_step,
185 reconstructed_patch=self._solver_solver._patch_with_halo,
186 guard=cell_guard,
187 add_assertions_to_halo_exchange=False,
188 additional_includes=includes,
189 )
190 )
191
194 interpolation = getattr(self._solver_solver.numerical_scheme, "interpolation", None)
195 if interpolation is not None:
196 reconstruction_task.add_action_set(
197 toolbox.blockstructured.api.InterpolateHangingFaces(
198 self._solver_solver._patch_overlap_current_time_step,
199 scheme=interpolation,
200 guard=is_active,
201 additional_includes=includes,
202 )
203 )
204
205 ApplyDirichletBoundaryConditions.add_task_to_time_step(
206 self._solver_solver,
207 exahype2_project,
208 plot,
209 reconstruction_task,
210 name_suffix=f" for {self.name}",
211 additional_guard=is_active,
212 )
213
214
215 write_checkpoint_task.add_dependency(reconstruction_task)
216 write_checkpoint_task.use_cell(
217 self._solver_solver._patch_with_halo, Access.READ_AND_DISCARD
218 )
219 write_checkpoint_task.add_action_set(
221 is_active_predicate=is_active,
222 finish_call=self.create_finish_call(),
224 patch=self._solver_solver._patch_with_halo,
225 dataset_name=self._solver_solver._patch_with_halo.name,
226 description=", ".join(self._solver_solver.variable_names_per_entry())
227 or self._solver_solver._unknown_identifier(),
228 guard=self._solver_solver.grid_selector.createCellGuard(),
229 additional_includes="""
230#include "../repositories/SolverRepository.h"
231""",
232 precision=self._plotter_precision,
233 binary=self._binary,
234 time_stamp_evaluation="0.5*(repositories::getMinTimeStamp()+repositories::getMaxTimeStamp())",
235 patch_scaling=self._solver_solver._patch_with_halo.dim[0]
236 / self._solver_solver._patch.dim[0],
237 metadata_evaluation="repositories::"
238 + self._solver_solver.get_name_of_global_instance()
239 + ".toCheckpointMetaData()",
240 )
241 )
242
243 if peano4.api.Logger().is_visualisation:
244 plot.visualise(title="Plot task graph for {}".format(self._solver_solver.name))
245 if peano4.api.Logger().is_text:
246 plot.log_as_text(title="Plot task graph for {}".format(self._solver_solver.name))
How a Solver writes out its solution.
Definition Solver.py:124
str output_file_prefix(self)
Prefix of the files the plotter writes, including the path.
Definition Solver.py:199
_add_time_interval_bookkeeping_to_solver(self, float first_time_stamp, float time_in_between)
Make the plotter active in regular time intervals.
Definition Solver.py:245
str create_is_active_predicate(self)
C++ predicate which holds if the plotter is active.
Definition Solver.py:210
str create_finish_call(self)
C++ statement which moves the plotter on to its next output.
Definition Solver.py:226
PlotPatchesInPeanoBlockFormat which only does something if its plotter is active.
Write checkpoints of a Finite Volume solver.
output_file_prefix(self)
Prefix of the files the plotter writes, including the path.
construct_output(self, exahype2_project, peano_project, plot)
Add the reconstruction of the halo and the writing of the checkpoint to the plot graph.
_solver
Set the ghost volumes along the domain boundary.
__init__(self, Solver solver, first_plot_time_stamp=0.0, time_in_between_plots=0.1, plotter_precision=17, output_path=".", filename="checkpoint", str name=None, binary=True)
Singleton logger for the Peano 4 Python API.
Definition Logger.py:37
One task within a peano4.api.taskgraph.Graph.
Definition Task.py:8