5Create the PNG illustrations of the tutorial 11_tsunami.ipynb
7The script builds the tutorial's shallow water setup, runs it and writes
8snapshots of the water height into the directory of this script. It does
9so twice: for the flat sea floor and for the sea floor shaped like the logo
10of Durham University (section "Adding bathymetry and external files", which
11reads the logo from tutorials/exahype2/bathymetry). The tutorial derives
12flux and eigenvalue of the latter with SymPy, whereas we use the handwritten
13versions here. Both give the same results. Finally, it runs the setup of
14section "Letting the bathymetry shape the flow", which uses the surface
15elevation eta as unknown, and plots it at t=0, 0.1, 0.2 and 0.4. Call the
18 python3 tutorials/exahype2/illustrations/11_tsunami.py
20All builds and outputs go into a temporary directory (or --work-directory).
29Here = os.path.dirname(os.path.abspath(__file__))
30PeanoRoot = os.path.abspath(os.path.join(Here,
"..",
"..",
".."))
31sys.path.insert(0, os.path.join(PeanoRoot,
"src"))
36import matplotlib.pyplot
as plt
44 constexpr double g = 9.81;
45 const double h = Q[Variables::h];
46 const double un = Q[Variables::hu + normal] / h;
47 F[Variables::h] = Q[Variables::hu + normal];
48 F[Variables::hu] = Q[Variables::hu] * un;
49 F[Variables::hv] = Q[Variables::hv] * un;
50 F[Variables::hu + normal] += 0.5 * g * h * h;
54 constexpr double g = 9.81;
55 const double h = Q[Variables::h];
56 const double un = Q[Variables::hu + normal] / h;
57 lambdaMax[0] = std::abs(un) + std::sqrt(g * h);
61 Q[Variables::h] = 1.0 + 0.1 * std::exp(-100.0 * (x[0] * x[0] + x[1] * x[1]));
62 Q[Variables::hu] = 0.0;
63 Q[Variables::hv] = 0.0;
64 Q[Variables::b] = 0.0;
67InitPointWiselyWithLogo =
"""
68 const int column = std::clamp(static_cast<int>((x[0] + 1.0) / 2.0 * DurhamLogoSize), 0, DurhamLogoSize - 1);
69 const int row = std::clamp(static_cast<int>((1.0 - x[1]) / 2.0 * DurhamLogoSize), 0, DurhamLogoSize - 1);
70 const double depth = DurhamLogo[row][column] == '1' ? 4.0 : 1.0;
72 Q[Variables::h] = depth + 0.1 * std::exp(-100.0 * (x[0] * x[0] + x[1] * x[1]));
73 Q[Variables::hu] = 0.0;
74 Q[Variables::hv] = 0.0;
75 Q[Variables::b] = -depth;
79 constexpr double g = 9.81;
80 const double h = Q[Variables::eta] - Q[Variables::b];
81 const double un = Q[Variables::hu + normal] / h;
82 F[Variables::eta] = Q[Variables::hu + normal];
83 F[Variables::hu] = Q[Variables::hu] * un;
84 F[Variables::hv] = Q[Variables::hv] * un;
85 F[Variables::hu + normal] += 0.5 * g * h * h;
89 constexpr double g = 9.81;
90 const double h = Q[Variables::eta] - Q[Variables::b];
91 const double un = Q[Variables::hu + normal] / h;
92 lambdaMax[0] = std::abs(un) + std::sqrt(g * h);
95NonconservativeProductEta =
"""
96 constexpr double g = 9.81;
97 const double h = Q[Variables::eta] - Q[Variables::b];
98 BTimesDeltaQ[Variables::eta] = 0.0;
99 BTimesDeltaQ[Variables::hu] = 0.0;
100 BTimesDeltaQ[Variables::hv] = 0.0;
101 BTimesDeltaQ[Variables::hu + normal] = g * h * deltaQ[Variables::b];
104InitPointWiselyEta =
"""
105 const int column = std::clamp(static_cast<int>((x[0] + 1.0) / 2.0 * DurhamLogoSize), 0, DurhamLogoSize - 1);
106 const int row = std::clamp(static_cast<int>((1.0 - x[1]) / 2.0 * DurhamLogoSize), 0, DurhamLogoSize - 1);
107 const double depth = DurhamLogo[row][column] == '1' ? 4.0 : 1.0;
109 Q[Variables::eta] = 0.1 * std::exp(-100.0 * (x[0] * x[0] + x[1] * x[1]));
110 Q[Variables::hu] = 0.0;
111 Q[Variables::hv] = 0.0;
112 Q[Variables::b] = -depth;
115Bathymetry = os.path.join(Here,
"..",
"bathymetry")
117PatchFile =
"solution-SWE.peano-patch-file"
122 init=InitPointWisely,
126 max_eigenvalue=MaxEigenvalue,
127 nonconservative_product=None,
131 Generate, compile and run the tutorial setup within directory
133 with_logo adds the depth map DurhamLogo from Bathymetry to the build.
134 first_unknown is the name of the first unknown, i.e. h or eta.
138 namespace=[
"tutorials",
"exahype2",
"tsunami"],
139 project_name=
"Tsunami",
141 executable=
"tsunami",
144 "SWE", {first_unknown: 1,
"hu": 1,
"hv": 1}, {
"b": 1}
146 solver.add_user_solver_includes(
"#include <cmath>\n#include <algorithm>\n")
148 solver.add_user_solver_includes(
'#include "DurhamLogo.h"\n')
153 if nonconservative_product
is not None:
156 implementation=nonconservative_product, stateless=
False
164 solver, volume_size=0.01
167 solver, first_plot_time_stamp=0.0, time_in_between_plots=0.05
169 project.add_solver(solver)
170 project.set_global_simulation_parameters(
176 periodic_BC=[
True,
True,
True],
178 project.set_Peano4_installation(PeanoRoot, peano4.api.output.CompileMode.RELEASE)
179 peano4_project = project.generate_Peano4_project()
181 makefile = peano4_project.output.makefile
182 makefile.add_cpp_file(os.path.join(Bathymetry,
"DurhamLogo.cpp"))
183 makefile.add_h_file(os.path.join(Bathymetry,
"DurhamLogo.h"))
184 makefile.add_header_search_path(Bathymetry)
185 peano4_project.generate()
186 subprocess.run([
"make",
"-j"], cwd=directory, check=
True, stdout=subprocess.DEVNULL)
187 subprocess.run([
"./tsunami"], cwd=directory, check=
True, stdout=subprocess.DEVNULL)
193 First unknown at the start, half way through and at the end
195 with_early adds the snapshot at a quarter of the simulated time.
198 file_name = os.path.join(directory, PatchFile)
202 ((snapshots - 1) // 2,
"middle"),
203 (snapshots - 1,
"end"),
206 selection.insert(1, ((snapshots - 1) // 4,
"early"))
207 for snapshot, suffix
in selection:
208 fig, ax = plt.subplots(figsize=(6, 5))
210 file_name, snapshot, 0, ax=ax, label=label
213 os.path.join(Here, prefix + suffix +
".png"),
221 """! Sea floor b, which does not change over time"""
222 fig, ax = plt.subplots(figsize=(6, 5))
224 os.path.join(directory, PatchFile), 0, 3, ax=ax, cmap=
"Purples_r", label=
"sea floor b"
226 fig.savefig(os.path.join(Here, prefix +
"b.png"), dpi=100, bbox_inches=
"tight")
230if __name__ ==
"__main__":
231 parser = argparse.ArgumentParser(
232 description=
"Create the PNGs of the tutorial 11_tsunami.ipynb"
237 help=
"Directory for builds and outputs (default: temporary directory)",
239 args = parser.parse_args()
241 work_directory = args.work_directory
or tempfile.mkdtemp(prefix=
"11_tsunami-")
242 print(
"build and run in {}".format(work_directory))
243 flat = os.path.join(work_directory,
"flat")
247 bathymetry = os.path.join(work_directory,
"bathymetry")
252 ncp = os.path.join(work_directory,
"ncp")
259 max_eigenvalue=MaxEigenvalueEta,
260 nonconservative_product=NonconservativeProductEta,
263 ncp,
"11_tsunami-ncp-", label=
"surface elevation eta", with_early=
True
265 print(
"wrote PNGs into {}".format(Here))
The conservative flux F(Q) of a hyperbolic PDE.
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.
The non-conservative product B(Q) applied to a jump deltaQ in a given direction, i....
Abstract base class for all ExaHyPE 2 solvers.
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, init=InitPointWisely, with_logo=False, first_unknown="h", flux=Flux, max_eigenvalue=MaxEigenvalue, nonconservative_product=None)
Generate, compile and run the tutorial setup within directory.
plot_sea_floor(directory, prefix)
Sea floor b, which does not change over time.
plot_snapshots(directory, prefix, label="water height h", with_early=False)
First unknown at the start, half way through and at the end.
Interactive visualisation of Peano patch files within Jupyter notebooks.
plot_snapshot(file_name, snapshot=-1, unknown=0, clim=None, ax=None, cmap="viridis", label=None)
Plot one unknown of one snapshot.
read_snapshots(file_name)
Return list of (time stamp, list of patch files) from a patch meta file.