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:
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},
18 publisher={Wiley Online Library}
21 It was first described by William Carlisle Thacker in:
24 title={Some exact solutions to the nonlinear shallow-water wave equations},
25 author={Thacker, William Carlisle},
26 journal={Journal of Fluid Mechanics},
30 publisher={Cambridge University Press}
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;
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;
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];
53 Q[Shortcuts::h] = 0.0;
54 Q[Shortcuts::hu] = 0.0;
55 Q[Shortcuts::hv] = 0.0;
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];
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;
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];
74refinement_criterion =
"""
75 return std::sqrt((x(0) * x(0)) + (x(1) * x(1))) <= 1.0
76 ? ::exahype2::RefinementCommand::Refine
77 : ::exahype2::RefinementCommand::Keep;
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.
84analytical_solution =
"""
85 constexpr double a = 1.0;
86 constexpr double hZero = 0.1;
87 constexpr double eta = 0.5;
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;
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];
105parser = exahype2.ArgumentParser()
108 degrees_of_freedom=16,
111args = parser.parse_args()
114 "g": [9.81,
"double"],
115 "hThreshold": [1e-5,
"double"],
119max_h = 1.1 * min(size) / (3.0**args.min_depth)
120min_h = max_h * 3.0 ** (-args.amr_levels)
122fv_solver = exahype2.solvers.fv.godunov.GlobalAdaptiveTimeStep(
124 patch_size=args.degrees_of_freedom,
125 unknowns={
"h": 1,
"hu": 1,
"hv": 1},
126 auxiliary_variables={
"z": 1},
129 time_step_relaxation=0.5,
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);",
139fv_solver.add_user_solver_includes(
141#include "../AugmentedStateRiemannSolver.h"
145exahype2.solvers.fv.ErrorMeasurement(
147 error_measurement_implementation=analytical_solution,
150project = exahype2.Project(
151 namespace=[
"applications",
"exahype2",
"ShallowWater"],
152 project_name=
"OscillatingLake",
154 executable=
"ExaHyPE",
156project.add_solver(fv_solver)
158if args.number_of_snapshots <= 0:
159 time_in_between_plots = 0.0
161 time_in_between_plots = args.end_time / args.number_of_snapshots
162 project.set_output_path(args.output)
164project.set_global_simulation_parameters(
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,
173 args.periodic_boundary_conditions_x,
174 args.periodic_boundary_conditions_y,
178project.set_load_balancer(
179 f
"new ::exahype2::LoadBalancingConfiguration({args.load_balancing_quality}, 1, {args.trees})"
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)