Peano
Loading...
Searching...
No Matches
44_localisation.py
Go to the documentation of this file.
1# This file is part of the Peano project. For conditions of distribution and
2# use, please see the copyright notice at www.peano-framework.org
3"""!
4
5Create the PNG illustrations of the tutorial 44_localisation.ipynb
6
7The script builds the tutorial's setup with the two Euler solvers EulerFV
8and CoarseEuler, runs it, and writes two pictures into the directory of
9this script: the density of both solvers over time at the centre of the
10domain, and the density of both solvers side by side at t=0.1. The
11implementation of EulerFV is taken from the tutorial's %%writefile cell.
12Call the script from anywhere:
13
14 python3 tutorials/exahype2/illustrations/44_localisation.py
15
16All builds and outputs go into a temporary directory (or --work-directory).
17The diagram 44_localisation.png is not created by this script.
18
19"""
20import argparse
21import csv
22import json
23import os
24import subprocess
25import sys
26import tempfile
27
28Here = os.path.dirname(os.path.abspath(__file__))
29PeanoRoot = os.path.abspath(os.path.join(Here, "..", "..", ".."))
30sys.path.insert(0, os.path.join(PeanoRoot, "src"))
31
32import matplotlib
33
34matplotlib.use("Agg")
35import matplotlib.pyplot as plt
36
37import peano4.api
38import exahype2
40
41DomainSize = [0.2, 0.2]
42PatchSize = 9
43Solvers = ["EulerFV", "CoarseEuler"]
44
45
47 """! Body of the tutorial's cell which writes EulerFV.cpp"""
48 with open(os.path.join(Here, "..", "44_localisation.ipynb")) as notebook_file:
49 cells = json.load(notebook_file)["cells"]
50 for cell in cells:
51 source = "".join(cell["source"])
52 if source.startswith("%%writefile 44_localisation/EulerFV.cpp"):
53 return source.split("\n", 1)[1]
54 raise Exception("tutorial has no cell writing EulerFV.cpp")
55
56
57def add_plotter(solver):
58 solver.plotter = exahype2.api.fv.PlotAsVTKFile(
59 solver, first_plot_time_stamp=0.0, time_in_between_plots=0.005
60 )
61
62
63def build_and_run(directory):
64 """! Generate, compile and run the tutorial setup within directory"""
65 project = exahype2.api.Project(
66 namespace=["tutorials", "exahype2", "localisation"],
67 project_name="Euler",
68 directory=directory,
69 executable="euler",
70 )
71
72 fine_solver = exahype2.api.Solver("EulerFV", 4, 0)
73 fine_solver.add_pde_term(exahype2.api.Flux(stateless=False))
74 fine_solver.add_pde_term(exahype2.api.MaxEigenvalue(stateless=False))
75 fine_solver.add_pde_term(exahype2.api.InitPointWisely(stateless=False))
76 fine_solver.numerical_scheme = exahype2.api.fv.RusanovWithExplicitEuler(
77 fine_solver, PatchSize
78 )
79 fine_solver.grid_construction = exahype2.api.fv.SetupSimulationOverRegularGrid(
80 fine_solver, volume_size=0.001
81 )
82 add_plotter(fine_solver)
83
84 coarse_solver = exahype2.api.Solver("CoarseEuler", 4, 0)
85 coarse_solver.add_user_solver_includes(
86 '#include "repositories/SolverRepository.h"\n'
87 )
88 coarse_solver.add_pde_term(
90 implementation="repositories::instanceOfEulerFV.flux(Q, x, normal, F);",
91 stateless=False,
92 )
93 )
94 coarse_solver.add_pde_term(
96 implementation="repositories::instanceOfEulerFV.maxEigenvalue(Q, x, normal, lambdaMax);",
97 stateless=False,
98 )
99 )
100 coarse_solver.add_pde_term(
102 implementation="repositories::instanceOfEulerFV.initPointWisely(x, Q);",
103 stateless=False,
104 )
105 )
106 coarse_solver.grid_selector = peano4.api.toolbox.FixedResolutionGridSelector(
107 2, DomainSize
108 )
109 coarse_solver.numerical_scheme = exahype2.api.fv.RusanovWithExplicitEuler(
110 coarse_solver, PatchSize
111 )
112 coarse_solver.grid_construction = exahype2.api.fv.SetupSimulationOverRegularGrid(
113 coarse_solver, volume_size=0.005
114 )
115 add_plotter(coarse_solver)
116
117 project.add_solver(fine_solver)
118 project.add_solver(coarse_solver)
119 project.set_global_simulation_parameters(
120 dimensions=2,
121 offset=[-0.1, -0.1],
122 size=DomainSize,
123 min_end_time=0.2,
124 max_end_time=0.2,
125 periodic_BC=[True, True, True],
126 )
127 project.set_Peano4_installation(PeanoRoot, peano4.api.output.CompileMode.RELEASE)
128 project.generate_Peano4_project().generate()
129 with open(os.path.join(directory, "EulerFV.cpp"), "w") as implementation_file:
130 implementation_file.write(euler_implementation())
131 subprocess.run(["make", "-j"], cwd=directory, check=True, stdout=subprocess.DEVNULL)
132 subprocess.run(["./euler"], cwd=directory, check=True, stdout=subprocess.DEVNULL)
133
134
135def probe(directory, name, point):
136 """! Time stamps and density of solver name at point"""
137 subprocess.run(
138 [
139 sys.executable,
140 "-m",
141 "tarch.plotter.api.probe",
142 "--point",
143 *[str(c) for c in point],
144 "-o",
145 f"probe-{name}.csv",
146 f"solution-{name}.peano-patch-file",
147 ],
148 cwd=directory,
149 env=dict(os.environ, PYTHONPATH=os.path.join(PeanoRoot, "src")),
150 check=True,
151 stdout=subprocess.DEVNULL,
152 )
153 with open(os.path.join(directory, f"probe-{name}.csv")) as csv_file:
154 rows = list(csv.reader(csv_file))
155 return [float(row[0]) for row in rows[1:]], [float(row[1]) for row in rows[1:]]
156
157
158def closest_snapshot(file_name, time_stamp):
159 snapshots = tarch.plotter.api.notebook.read_snapshots(file_name)
160 return min(range(len(snapshots)), key=lambda i: abs(snapshots[i][0] - time_stamp))
161
162
163def plot_probe(directory):
164 fig, ax = plt.subplots(figsize=(7, 4))
165 for name in Solvers:
166 t, rho = probe(directory, name, (0.0, 0.0))
167 ax.plot(t, rho, label=name)
168 ax.set_xlabel("t")
169 ax.set_ylabel("density at x=(0,0)")
170 ax.legend()
171 fig.savefig(
172 os.path.join(Here, "44_localisation-probe.png"), dpi=100, bbox_inches="tight"
173 )
174 plt.close(fig)
175
176
177def plot_comparison(directory):
178 fig, axes = plt.subplots(1, 2, figsize=(12, 5))
179 for ax, name in zip(axes, Solvers):
180 file_name = os.path.join(directory, f"solution-{name}.peano-patch-file")
182 file_name,
183 closest_snapshot(file_name, 0.1),
184 0,
185 clim=(0.8, 1.2),
186 ax=ax,
187 label=f"{name}: density",
188 )
189 fig.savefig(
190 os.path.join(Here, "44_localisation-comparison.png"),
191 dpi=100,
192 bbox_inches="tight",
193 )
194 plt.close(fig)
195
196
197if __name__ == "__main__":
198 parser = argparse.ArgumentParser(
199 description="Create the PNGs of the tutorial 44_localisation.ipynb"
200 )
201 parser.add_argument(
202 "--work-directory",
203 default=None,
204 help="Directory for builds and outputs (default: temporary directory)",
205 )
206 args = parser.parse_args()
207
208 work_directory = args.work_directory or tempfile.mkdtemp(prefix="44_localisation-")
209 print("build and run in {}".format(work_directory))
210 build_and_run(work_directory)
211 plot_probe(work_directory)
212 plot_comparison(work_directory)
213 print("wrote PNGs into {}".format(Here))
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.
ExaHyPE 2 project.
Definition Project.py:15
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-...
Setup phase counterpart to RusanovWithExplicitEuler: sets the initial condition for a Finite Volume s...
build_and_run(directory)
Generate, compile and run the tutorial setup within directory.
plot_comparison(directory)
plot_probe(directory)
closest_snapshot(file_name, time_stamp)
euler_implementation()
Body of the tutorial's cell which writes EulerFV.cpp.
-single-black-hole
Interactive visualisation of Peano patch files within Jupyter notebooks.
Definition notebook.py:1
plot_snapshot(file_name, snapshot=-1, unknown=0, clim=None, ax=None, cmap="viridis", label=None)
Plot one unknown of one snapshot.
Definition notebook.py:100
read_snapshots(file_name)
Return list of (time stamp, list of patch files) from a patch meta file.
Definition notebook.py:30