Peano
Loading...
Searching...
No Matches
solitary-wave.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 A solitary wave case implementation based on the papers listed below. the wave shape and initial velocity
8 are taken from the paper "Non-breaking and breaking solitary wave run-up" section 2.5.1.
9 Some more properties, like the characteristic length of the wave, are taken from the paper
10 "Solitary wave runup on plane slopes".
11
12 @article{Li2002,
13 title={Non-breaking and breaking solitary wave run-up},
14 author={Li, Ying and Raichlen, Fredric},
15 journal={Journal of Fluid Mechanics},
16 volume={456},
17 pages={295--318},
18 year={2002},
19 publisher={Cambridge University Press}
20 }
21
22 @article{Li2001,
23 title={Solitary wave runup on plane slopes},
24 author={Li, Ying and Raichlen, Fredric},
25 journal={Journal of Waterway, Port, Coastal, and Ocean Engineering},
26 volume={127},
27 number={1},
28 pages={33--44},
29 year={2001},
30 publisher={American Society of Civil Engineers}
31 }
32
33 Also interesting is one of the original papers which introduced many of such cases:
34
35 @article{Synolakis1987,
36 title={The runup of solitary waves},
37 author={Synolakis, Costas Emmanuel},
38 journal={Journal of Fluid Mechanics},
39 volume={185},
40 pages={523--545},
41 year={1987},
42 publisher={Cambridge University Press}
43 }
44"""
45
46initial_conditions = """
47 for (int i = 0; i < NumberOfUnknowns + NumberOfAuxiliaryVariables; i++) {
48 Q[i] = 0.0;
49 }
50
51 constexpr double Depth = 1.0;
52 constexpr double BeachSlopeAngle = 30 * std::numbers::pi / 180;
53 constexpr double WaveAmplitude = 0.5;
54
55 const double gamma = std::sqrt((3 * WaveAmplitude) / (4 * Depth));
56
57 // The wave crest is located at L/2 away from the foot of the
58 // slope xZero, where L is the characteristic length of the solitary wave.
59 const double wavePos = 0.5 * ((2/gamma) * (std::acosh(std::sqrt(20))));
60
61 const double xZero = Depth / std::tan(BeachSlopeAngle);
62
63 // Set up the bathymetry, extend the beach a bit in negative x direction
64 if (x[0] < 0) { // Beach slope for negative x[0] values
65 Q[Shortcuts::z] = std::fabs(x[0]) * std::tan(BeachSlopeAngle);
66 } else if (x[0] < xZero) { // Initialise the beach slope for x[0] >= 0
67 Q[Shortcuts::z] = -(x[0] * std::tan(BeachSlopeAngle));
68 } else { // Initialise the constant ocean depth
69 Q[Shortcuts::z] = -Depth;
70 }
71
72 // Set up the wave profile
73 const double innerTerm = gamma * ((x[0] - (xZero + wavePos)) / Depth);
74 const double waveProfile = WaveAmplitude * std::pow((1 / (std::cosh(innerTerm))), 2);
75 if (x[0] >= xZero) {
76 Q[Shortcuts::h] = Depth + waveProfile;
77 } else if (x[0] < xZero && x[0] >= 0){
78 Q[Shortcuts::h] = std::fabs(Q[Shortcuts::z]);
79 } else if (x[0] >= (xZero + 2 * wavePos)) { // Coordinate outside the characteristic wave region
80 Q[Shortcuts::h] = Depth;
81 }
82
83 // Set up the velocity
84 // Velocity taken from the paper "Non-breaking and breaking solitary wave run-up"
85 const double waveCelerity = std::sqrt(g * (WaveAmplitude + Depth));
86 Q[Shortcuts::hu] = -((waveCelerity * waveProfile) / (Depth + waveProfile)) * Q[Shortcuts::h];
87"""
88
89boundary_conditions = """
90 Qoutside[Shortcuts::h] = Qinside[Shortcuts::h];
91 Qoutside[Shortcuts::hu] = -Qinside[Shortcuts::hu];
92 Qoutside[Shortcuts::hv] = -Qinside[Shortcuts::hv];
93 Qoutside[Shortcuts::z] = Qinside[Shortcuts::z];
94"""
95
96refinement_criterion = """
97 auto result = ::exahype2::RefinementCommand::Keep;
98 return result;
99"""
100
101parser = exahype2.ArgumentParser()
102parser.set_defaults(
103 min_depth=5,
104 degrees_of_freedom=16,
105 end_time=5.0,
106)
107args = parser.parse_args()
108
109constants = {
110 "g": [9.81, "double"],
111 "hThreshold": [1e-5, "double"],
112}
113
114offset = [-5, 0]
115size = [15.0, 15.0]
116max_h = 1.1 * min(size) / (3.0**args.min_depth)
117min_h = max_h * 3.0 ** (-args.amr_levels)
118
119fv_solver = exahype2.solvers.fv.godunov.GlobalAdaptiveTimeStep(
120 name="FVSolver",
121 patch_size=args.degrees_of_freedom,
122 unknowns={"h": 1, "hu": 1, "hv": 1},
123 auxiliary_variables={"z": 1},
124 min_volume_h=min_h,
125 max_volume_h=max_h,
126 time_step_relaxation=0.5,
127)
128
129fv_solver.set_implementation(
130 initial_conditions=initial_conditions,
131 boundary_conditions=boundary_conditions,
132 refinement_criterion=refinement_criterion,
133 riemann_solver="return llfRiemannSolver<double, Shortcuts>(QL, QR, x, h, t, dt, normal, FL, FR);",
134)
135
136fv_solver.add_user_solver_includes(
137 """
138#include "../LLFRiemannSolver.h"
139"""
140)
141
142project = exahype2.Project(
143 namespace=["applications", "exahype2", "ShallowWater"],
144 project_name="SolitaryWave",
145 directory=".",
146 executable="ExaHyPE",
147)
148project.add_solver(fv_solver)
149
150if args.number_of_snapshots <= 0:
151 time_in_between_plots = 0.0
152else:
153 time_in_between_plots = args.end_time / args.number_of_snapshots
154 project.set_output_path(args.output)
155
156project.set_global_simulation_parameters(
157 dimensions=2,
158 size=size,
159 offset=offset,
160 min_end_time=args.end_time,
161 max_end_time=args.end_time,
162 first_plot_time_stamp=0.0,
163 time_in_between_plots=time_in_between_plots,
164 periodic_BC=[
165 args.periodic_boundary_conditions_x,
166 args.periodic_boundary_conditions_y,
167 ],
168)
169
170project.set_load_balancer(
171 f"new ::exahype2::LoadBalancingConfiguration({args.load_balancing_quality}, 1, {args.trees})"
172)
173project.set_build_mode(mode=peano4.output.string_to_mode(args.build_mode))
174project = project.generate_Peano4_project(verbose=False)
175for const_name, const_info in constants.items():
176 const_val, const_type = const_info
177 project.constants.export_constexpr_with_type(const_name, str(const_val), const_type)
178project.build(make=True, make_clean_first=True, throw_away_data_after_build=True)