Peano
Loading...
Searching...
No Matches
test_plotters.py
Go to the documentation of this file.
1"""Unit tests for multiple plotters per solver (@ref exahype2.api.Solver.Solver.add_plotter())
2and the checkpoints (@ref exahype2.api.fv.WriteCheckpoint, @ref exahype2.api.rkfd4.WriteCheckpoint)."""
3
4import types
5
6import peano4.api
8import exahype2.api
9import pytest
10
11
12def _solver(scheme="fv", dirichlet=False):
13 solver = exahype2.api.Solver("Probe", {"rho": 1, "j": 2, "E": 1}, {"c": 1})
14 solver.add_pde_term(exahype2.api.Flux(implementation=""))
15 solver.add_pde_term(exahype2.api.MaxEigenvalue(implementation=""))
16 solver.add_pde_term(exahype2.api.InitPointWisely(implementation=""))
17 if dirichlet:
18 solver.add_pde_term(exahype2.api.DirichletBoundaryConditions(implementation=""))
19 if scheme == "fv":
20 solver.numerical_scheme = exahype2.api.fv.RusanovWithExplicitEuler(solver, 9)
21 else:
23 solver, patch_size=9, rk_order=2
24 )
25 return solver
26
27
28def _plot_graph(solver, tmp_path, periodic=True):
29 peano_project = peano4.api.Project(["probe"], "probe", directory=str(tmp_path))
30 exahype2_project = types.SimpleNamespace(periodic_BC=[periodic] * 3)
32 for plotter in solver.plotters:
33 plotter.construct_output(exahype2_project, peano_project, graph)
34 return graph
35
36
37def _method_definition(solver, declaration):
38 matches = [
39 generator("probe::AbstractProbe")
40 for existing, generator in solver._abstract_solver_methods
41 if existing == declaration
42 ]
43 assert len(matches) == 1, declaration
44 return matches[0]
45
46
48 solver = _solver()
49 solver.add_plotter(exahype2.api.fv.PlotAsVTKFile(solver))
50 solver.add_plotter(exahype2.api.fv.PlotAsVTKFile(solver, filename="other"))
51 solver.add_plotter(exahype2.api.fv.WriteCheckpoint(solver))
52 assert [p.name for p in solver.plotters] == [
53 "PlotAsVTKFile",
54 "PlotAsVTKFile2",
55 "WriteCheckpoint",
56 ]
57
58
60 solver = _solver()
61 solver.add_plotter(exahype2.api.fv.PlotAsVTKFile(solver, name="Plot"))
62 with pytest.raises(ValueError):
63 solver.add_plotter(
64 exahype2.api.fv.PlotAsVTKFile(solver, filename="b", name="Plot")
65 )
66 with pytest.raises(ValueError):
67 exahype2.api.fv.PlotAsVTKFile(solver, name="not an identifier")
68
69
71 solver = _solver()
72 solver.add_plotter(exahype2.api.fv.PlotAsVTKFile(solver))
73 with pytest.raises(ValueError):
74 solver.add_plotter(exahype2.api.fv.PlotAsVTKFile(solver))
75
76
78 solver = _solver()
79 assert solver.plotter is None
80 solver.add_plotter(exahype2.api.fv.PlotAsVTKFile(solver))
81 solver.add_plotter(exahype2.api.fv.WriteCheckpoint(solver))
82 with pytest.raises(RuntimeError):
83 solver.plotter
84 checkpoint = exahype2.api.fv.WriteCheckpoint(solver)
85 solver.plotter = checkpoint
86 assert solver.plotters == [checkpoint]
87 solver.plotter = None
88 assert solver.plotters == []
89
90
92 solver = _solver()
93 solver.add_plotter(
94 exahype2.api.fv.PlotAsVTKFile(solver, time_in_between_plots=0.25)
95 )
96 solver.add_plotter(
97 exahype2.api.fv.WriteCheckpoint(solver, first_plot_time_stamp=0.5)
98 )
99 _plot_graph(solver, tmp_path)
100 solver._add_wants_to_plot_to_solver()
101 solver._add_wants_to_plot_to_solver()
102
103 assert (
104 "double _nextPlotAsVTKFileTimeStamp = 0.0;"
105 in solver._abstract_solver_attributes
106 )
107 assert (
108 "double _nextWriteCheckpointTimeStamp = 0.5;"
109 in solver._abstract_solver_attributes
110 )
111 assert "_nextPlotAsVTKFileTimeStamp += 0.25;" in _method_definition(
112 solver, "void finishPlotAsVTKFile();"
113 )
114 wants_to_plot = _method_definition(solver, "bool wantsToPlot() const;")
115 assert "isPlotAsVTKFileActive() or isWriteCheckpointActive()" in wants_to_plot
116
117
119 solver = _solver()
120 solver.add_plotter(exahype2.api.fv.PlotAsVTKFile(solver))
121 solver.add_plotter(exahype2.api.fv.WriteCheckpoint(solver))
122 _plot_graph(solver, tmp_path)
123 definition = _method_definition(
124 solver, "std::string toCheckpointMetaData() const override;"
125 )
126 assert definition.count("toCheckpointMetaDataEntry(") == 2
127 assert (
128 'toCheckpointMetaDataEntry("nextWriteCheckpointTimeStamp", _nextWriteCheckpointTimeStamp)'
129 in definition
130 )
131
132
134 solver = _solver()
135 plotter = exahype2.api.fv.PlotAsVTKFile(solver, quantities=["j", 4])
136 plotter.add_plot_filter((0.0, 0.0), (0.5, 0.5))
137 solver.add_plotter(plotter)
138 graph = _plot_graph(solver, tmp_path)
139 (action_set,) = graph.tasks[0].action_sets
140 assert action_set.d["SELECT_DOFS"] == [1, 2, 4]
141 assert action_set.d["PLOTTED_UNKNOWNS"] == "3"
142 assert action_set.d["DESCRIPTION"] == "j[0], j[1], c"
143 assert "marker.overlaps" in action_set.d["GUARD_PREDICATE"]
144 assert action_set.get_guard_of_operation("touchCellFirstTime").startswith(
145 "repositories::instanceOfProbe.isPlotAsVTKFileActive()"
146 )
147
148
150 solver = _solver()
151 checkpoint = exahype2.api.fv.WriteCheckpoint(solver)
152 assert not hasattr(checkpoint, "add_plot_filter")
153 with pytest.raises(TypeError):
154 exahype2.api.fv.WriteCheckpoint(solver, quantities=["rho"])
155
156
157@pytest.mark.parametrize("scheme,halo", [("fv", 1), ("fd4", 2)])
159 solver = _solver(scheme, dirichlet=True)
160 solver.add_plotter(
162 if scheme == "fv"
164 )
165 graph = _plot_graph(solver, tmp_path, periodic=False)
166 names = sorted(task.name for task in graph.tasks)
167 assert names == [
168 "Probe_Apply Dirichlet BCs for WriteCheckpoint",
169 "Probe_WriteCheckpoint_Reconstruct",
170 "Probe_WriteCheckpoint_Write checkpoint",
171 ]
172 active = "repositories::instanceOfProbe.isWriteCheckpointActive()"
173 for task in graph.tasks:
174 for action_set in task.action_sets:
175 for operation in [
176 "touchCellFirstTime",
177 "touchFaceFirstTime",
178 "createHangingFace",
179 ]:
180 guard = action_set.get_guard_of_operation(operation)
181 assert guard == "true" or active in guard, (task.name, operation, guard)
182
183 (write,) = [t for t in graph.tasks if t.name.endswith("Write checkpoint")]
184 (action_set,) = write.action_sets
185 assert action_set.d["DOFS_PER_AXIS"] == str(9 + 2 * halo)
186 assert action_set.d["UNKNOWNS"] == "5"
187 assert action_set.d["SELECT_DOFS"] is None
188 assert action_set.d["PATCH_SCALING"] == (9 + 2 * halo) / 9
189 assert action_set.d["PRECISION"] == 17
190 assert action_set.d["WRITER_PRECISION"] == 17
191 assert action_set.d["METADATA_EVALUATION"] == (
192 "repositories::instanceOfProbe.toCheckpointMetaData()"
193 )
194 assert "finishWriteCheckpoint();" in action_set.get_body_of_unprepareTraversal()
The conservative flux F(Q) of a hyperbolic PDE.
Definition Flux.py:8
Point-wise initial condition: given the physical position of a single degree of freedom,...
The maximum absolute eigenvalue of the flux Jacobian in a given direction, i.e.
Abstract base class for all ExaHyPE 2 solvers.
Definition Solver.py:17
Plotting counterpart to RusanovWithExplicitEuler: maps the patch data of a Finite Volume scheme with ...
Finite Volumes with a Rusanov Riemann solver and explicit Euler time stepping, realised over a block-...
Write checkpoints of a Finite Volume solver.
Fourth-order central Finite Differences with explicit Runge-Kutta time stepping, realised over a bloc...
Write checkpoints of the fourth-order Finite Differences.
Represents a Peano 4 project.
Definition Project.py:23
Holds a sequence of Task instances.
Definition Graph.py:9
The task graph abstraction allows users to formalise their solver steps over small task graphs which ...
Definition __init__.py:1
test_checkpoint_has_neither_filters_nor_quantities()
test_plotter_names_have_to_be_unique_identifiers()
_solver(scheme="fv", dirichlet=False)
test_checkpoint_reconstructs_and_writes_patch_with_halo(tmp_path, scheme, halo)
_method_definition(solver, declaration)
test_vtk_plotter_selects_quantities(tmp_path)
test_plotters_get_names_from_class_and_counter()
_plot_graph(solver, tmp_path, periodic=True)
test_plotters_must_not_share_files()
test_checkpoint_meta_data_lists_added_attributes(tmp_path)
test_each_plotter_gets_own_bookkeeping_and_wants_to_plot_combines_them(tmp_path)
test_plotter_shorthand_replaces_all_plotters()