Peano
Loading...
Searching...
No Matches
oscillating-lake.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 peano4
4import exahype2
5
6"""!
7 Implementation of the planar surface in a paraboloid Thacker's test.
8 This implementation is mainly based on the Planar surface in a paraboloid case in section 4.2.2 Two dimensional cases of the paper:
9
10 @article{Delestre2013,
11 title={SWASHES: a compilation of shallow water analytic solutions for hydraulic and environmental studies},
12 author={Delestre, Olivier and Lucas, Carine and Ksinant, Pierre-Antoine and Darboux, Fr{\'e}d{\'e}ric and Laguerre, Christian and Vo, T-N-Tuoi and James, Francois and Cordier, St{\'e}phane},
13 journal={International Journal for Numerical Methods in Fluids},
14 volume={72},
15 number={3},
16 pages={269--300},
17 year={2013},
18 publisher={Wiley Online Library}
19 }
20
21 It was first described by William Carlisle Thacker in:
22
23 @article{Thacker1981,
24 title={Some exact solutions to the nonlinear shallow-water wave equations},
25 author={Thacker, William Carlisle},
26 journal={Journal of Fluid Mechanics},
27 volume={107},
28 pages={499--508},
29 year={1981},
30 publisher={Cambridge University Press}
31 }
32"""
33initial_conditions = """
34 // Assumption: square domain is centered at 0.0, L/2 == 0.
35 // Values chosen in accordance to the selected values in the SWASHES-framework paper
36 constexpr double a = 1.0;
37 constexpr double hZero = 0.1;
38 constexpr double eta = 0.5;
39
40 const double r = std::sqrt(std::pow(x[0], 2) + std::pow(x[1], 2));
41 const double omega = std::sqrt(2 * g * hZero) / a;
42
43 // As in the paper, the initial condition is the analytical solution at time stamp zero
44 // Initialise the paraboloid bathymetry
45 Q[Shortcuts::z] = -hZero * (1.0 - (std::pow(r, 2))/(std::pow(a, 2)));
46 // Initialise the material height (The analytical solution at time step zero might contain values below zero, but those
47 // will be set to zero here for physical feasibility)
48 Q[Shortcuts::h] = ((eta * hZero) / std::pow(a, 2)) * (2 * (x[0]) * std::cos(omega * 0) + 2 * (x[1]) * std::sin(omega * 0) - eta) - Q[Shortcuts::z];
49 if (Q[Shortcuts::h] >= 0) {
50 Q[Shortcuts::hu] = (-eta * omega * std::sin(omega * 0)) * Q[Shortcuts::h];
51 Q[Shortcuts::hv] = (eta * omega * std::cos(omega * 0)) * Q[Shortcuts::h];
52 } else {
53 Q[Shortcuts::h] = 0.0;
54 Q[Shortcuts::hu] = 0.0;
55 Q[Shortcuts::hv] = 0.0;
56 }
57
58 //Q[Shortcuts::z] = 0.1 * (std::pow(x[0], 2) + std::pow(x[1], 2));
59 //Q[Shortcuts::h] = std::fmax(0.0, 0.05 * (2 * x[0] * std::cos(omega * 0) + 2 * x[1] * std::sin(omega * 0)) + 0.075 - Q[Shortcuts::z]);
60 //Q[Shortcuts::hu] = 0.5 * omega * std::sin(omega * 0) * Q[Shortcuts::h];
61 //Q[Shortcuts::hv] = 0.5 * omega * std::cos(omega * 0) * Q[Shortcuts::h];
62
63 //Q[Shortcuts::h] = 0.025 * (1.0 - std::sqrt((x(0) * x(0)) + (x(1) * x(1))));
64 //Q[Shortcuts::z] = -0.2 * (1.0 - std::sqrt((x(0) * x(0)) + (x(1) * x(1)))) - 0.1;
65"""
66
67boundary_conditions = """
68 Qoutside[Shortcuts::h] = Qinside[Shortcuts::h];
69 Qoutside[Shortcuts::hu] = -Qinside[Shortcuts::hu];
70 Qoutside[Shortcuts::hv] = -Qinside[Shortcuts::hv];
71 Qoutside[Shortcuts::z] = Qinside[Shortcuts::z];
72"""
73
74refinement_criterion = """
75 return std::sqrt((x(0) * x(0)) + (x(1) * x(1))) <= 1.0
76 ? ::exahype2::RefinementCommand::Refine
77 : ::exahype2::RefinementCommand::Keep;
78"""
79
80"""
81The analytical solution implementation according to Delestre2013, similar to the initial condition but now with
82the value for t substituted into the formula instead of zero.
83"""
84analytical_solution = """
85 constexpr double a = 1.0;
86 constexpr double hZero = 0.1;
87 constexpr double eta = 0.5;
88
89 const double r = std::sqrt(std::pow(x[0], 2) + std::pow(x[1], 2));
90 const double omega = std::sqrt(2 * g * hZero) / a;
91
92 const double currentHeight = ((eta * hZero) / std::pow(a, 2)) * (2 * (x[0]) * std::cos(omega * t) + 2 * (x[1]) * std::sin(omega * t) - eta) - Q[Shortcuts::z];
93 // Again, only values h > 0 will be considered, the rest is assumed to be dry-state.
94 if (currentHeight > 0) {
95 solution[0] = ((eta * hZero) / std::pow(a, 2)) * (2 * (x[0]) * std::cos(omega * t) + 2 * (x[1]) * std::sin(omega * t) - eta) - Q[Shortcuts::z];
96 solution[1] = (-eta * omega * std::sin(omega * t)) * Q[Shortcuts::h];
97 solution[2] = (eta * omega * std::cos(omega * t)) * Q[Shortcuts::h];
98 } else {
99 solution[0] = 0.0;
100 solution[1] = 0.0;
101 solution[2] = 0.0;
102 }
103"""
104
105parser = exahype2.ArgumentParser()
106parser.set_defaults(
107 min_depth=5,
108 degrees_of_freedom=16,
109 end_time=10.0,
110)
111args = parser.parse_args()
112
113constants = {
114 "g": [9.81, "double"],
115 "hThreshold": [1e-5, "double"],
116}
117
118size = [4.0, 4.0]
119max_h = 1.1 * min(size) / (3.0**args.min_depth)
120min_h = max_h * 3.0 ** (-args.amr_levels)
121
122fv_solver = exahype2.solvers.fv.godunov.GlobalAdaptiveTimeStep(
123 name="FVSolver",
124 patch_size=args.degrees_of_freedom,
125 unknowns={"h": 1, "hu": 1, "hv": 1},
126 auxiliary_variables={"z": 1},
127 min_volume_h=min_h,
128 max_volume_h=max_h,
129 time_step_relaxation=0.5,
130)
131
132fv_solver.set_implementation(
133 initial_conditions=initial_conditions,
134 boundary_conditions=boundary_conditions,
135 refinement_criterion=refinement_criterion,
136 riemann_solver="return augmentedStateRiemannSolver<double, Shortcuts>(QL, QR, x, h, t, dt, normal, FL, FR);",
137)
138
139fv_solver.add_user_solver_includes(
140 """
141#include "../AugmentedStateRiemannSolver.h"
142"""
143)
144
145exahype2.solvers.fv.ErrorMeasurement(
146 fv_solver,
147 error_measurement_implementation=analytical_solution,
148)
149
150project = exahype2.Project(
151 namespace=["applications", "exahype2", "ShallowWater"],
152 project_name="OscillatingLake",
153 directory=".",
154 executable="ExaHyPE",
155)
156project.add_solver(fv_solver)
157
158if args.number_of_snapshots <= 0:
159 time_in_between_plots = 0.0
160else:
161 time_in_between_plots = args.end_time / args.number_of_snapshots
162 project.set_output_path(args.output)
163
164project.set_global_simulation_parameters(
165 dimensions=2,
166 size=size,
167 offset=[-2.0, -2.0],
168 min_end_time=args.end_time,
169 max_end_time=args.end_time,
170 first_plot_time_stamp=0.0,
171 time_in_between_plots=time_in_between_plots,
172 periodic_BC=[
173 args.periodic_boundary_conditions_x,
174 args.periodic_boundary_conditions_y,
175 ],
176)
177
178project.set_load_balancer(
179 f"new ::exahype2::LoadBalancingConfiguration({args.load_balancing_quality}, 1, {args.trees})"
180)
181project.set_build_mode(mode=peano4.output.string_to_mode(args.build_mode))
182project = project.generate_Peano4_project(verbose=False)
183for const_name, const_info in constants.items():
184 const_val, const_type = const_info
185 project.constants.export_constexpr_with_type(const_name, str(const_val), const_type)
186project.build(make=True, make_clean_first=True, throw_away_data_after_build=True)