Peano
Loading...
Searching...
No Matches
radial-dam-break.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 os
4import re
5import sys
6
7import peano4.api
8import exahype2
9
10sys.path.insert(0, os.path.abspath(".."))
11from sweargs import SWEArgumentParser
12
13define_radial_dam = """
14 constexpr double DAM_RADIUS = 1.0;
15
16 const double domainSizeHalfX = DomainSize[0] / 2.0;
17 const double domainSizeHalfY = DomainSize[1] / 2.0;
18
19 const double distanceFromOrigin = std::sqrt(
20 (x[0] - domainSizeHalfX) * (x[0] - domainSizeHalfX) +
21 (x[1] - domainSizeHalfY) * (x[1] - domainSizeHalfY)
22 );
23
24 const bool isInsideDam = distanceFromOrigin <= DAM_RADIUS;
25 const bool isOutsideDam = distanceFromOrigin > DAM_RADIUS;
26 const bool isDryRing = distanceFromOrigin >= 2 * DAM_RADIUS and distanceFromOrigin <= 3 * DAM_RADIUS;
27"""
28
29initial_conditions = define_radial_dam + """
30 constexpr double INITIAL_WATER_HEIGHT_INSIDE_DAM = 1.1;
31 constexpr double INITIAL_WATER_HEIGHT_OUTSIDE_DAM = 1.0;
32 constexpr double BATHYMETRY_DRY_RING = 1.2;
33
34 for (int i = 0; i < NumberOfUnknowns + NumberOfAuxiliaryVariables; i++) {
35 Q[i] = 0.0;
36 }
37
38 using s = VariableShortcuts;
39
40 Q[s::h] = isInsideDam ? INITIAL_WATER_HEIGHT_INSIDE_DAM : INITIAL_WATER_HEIGHT_OUTSIDE_DAM;
41
42 if (isDryRing) {
43 Q[s::h] = 0.0; // Dry ring
44 }
45
46 Q[s::b] = isDryRing ? BATHYMETRY_DRY_RING : 0.0;
47"""
48
49boundary_conditions = """
50 using s = VariableShortcuts;
51 Qoutside[s::h] = Qinside[s::h];
52 Qoutside[s::hu] = -Qinside[s::hu];
53 Qoutside[s::hv] = -Qinside[s::hv];
54 Qoutside[s::b] = Qinside[s::b];
55"""
56
57refinement_criterion = define_radial_dam + """
58 return isInsideDam ? ::exahype2::RefinementCommand::Refine : ::exahype2::RefinementCommand::Keep;
59"""
60
61limiting_criterion = define_radial_dam + """
62 return distanceFromOrigin < DAM_RADIUS * 2; // Everything outside the dam (includes the dry ring) shall be limited
63"""
64
66parser.set_defaults(
67 end_time=1.0,
68 width=[10.0, 10.0],
69)
70args = parser.parse_args()
71
72max_h = (1.1 * min(args.width) / (3.0**args.min_depth))
73min_h = max_h * 3.0 ** (-args.amr_levels)
74args.patch_size = args.dg_order * 2 + 1
75
76unknowns={"h": 1, "hu": 1, "hv": 1, "b": 1}
77
78aderdg_solver = exahype2.solvers.aderdg.GlobalAdaptiveTimeStep(
79 name="ADERDG" + str(args.dg_order),
80 order=args.dg_order,
81 unknowns=unknowns,
82 auxiliary_variables=0,
83 min_cell_h=min_h,
84 max_cell_h=max_h,
85 time_step_relaxation=args.time_step_relaxation,
86 initial_conditions=initial_conditions,
87 boundary_conditions=boundary_conditions,
88 refinement_criterion=refinement_criterion,
89 flux="applications::exahype2::swe::flux(Q, x, h, t, dt, normal, F);",
90 ncp="applications::exahype2::swe::nonconservativeProduct(Q, deltaQ, x, h, t, dt, normal, BTimesDeltaQ);",
91 eigenvalues="""
92 double lambda[NumberOfUnknowns] = {0.};
93 applications::exahype2::swe::maxEigenvalue(Q, x, h, t, dt, normal, lambda);
94 return *std::max_element(lambda, lambda+NumberOfUnknowns);""",
95)
96aderdg_solver.plot_description = ", ".join(unknowns.keys())
97aderdg_solver.switch_storage_scheme(exahype2.solvers.Storage[args.storage], exahype2.solvers.Storage[args.storage])
98aderdg_solver.add_kernel_optimisations(is_linear=False, polynomials=exahype2.solvers.aderdg.Polynomials.Gauss_Legendre)
99aderdg_solver.add_user_solver_includes(
100 """
101#include "../SWE.h"
102"""
103)
104
105unknowns = {"h": 1, "hu": 1, "hv": 1}
106auxiliary_variables = {"b": 1}
107
108riemann_solver = exahype2.solvers.fv.riemann.GlobalAdaptiveTimeStep(
109 name="HLLEM" + str(args.patch_size),
110 patch_size=args.patch_size,
111 unknowns=unknowns,
112 auxiliary_variables=auxiliary_variables,
113 min_volume_h=min_h,
114 max_volume_h=max_h,
115 time_step_relaxation=args.time_step_relaxation,
116 pde_terms_without_state=args.stateless,
117 initial_conditions=re.sub(r'\bx\b', 'volumeCentre', initial_conditions),
118 boundary_conditions=boundary_conditions,
119 riemann_solver="return applications::exahype2::swe::hllem(QR, QL, FR, FL, LR, LL, xR, xL, h, t, dt, normal, APDQ, AMDQ);",
120)
121riemann_solver.plot_description = ", ".join(unknowns.keys()) + ", "
122riemann_solver.plot_description += ", ".join(auxiliary_variables.keys())
123riemann_solver.switch_storage_scheme(exahype2.solvers.Storage[args.storage], exahype2.solvers.Storage[args.storage])
124riemann_solver.add_user_solver_includes(
125 """
126#include "../HLLEM.h"
127"""
128)
129
130limiting_solver = exahype2.solvers.limiting.StaticLimiting(
131 name="Limiting",
132 regular_solver=aderdg_solver,
133 limiting_solver=riemann_solver,
134 limiting_criterion_implementation=limiting_criterion
135)
136
137project = exahype2.Project(
138 namespace=["applications", "exahype2", "swe"],
139 project_name="RadialDamBreak",
140 directory=".",
141 executable=f"RadialDamBreak.{args.build_mode}",
142)
143project.add_solver(aderdg_solver)
144project.add_solver(riemann_solver)
145project.add_solver(limiting_solver)
146
147if args.number_of_snapshots <= 0:
148 time_in_between_plots = 0.0
149else:
150 time_in_between_plots = args.end_time / args.number_of_snapshots
151 project.set_output_path(args.output)
152
153project.set_global_simulation_parameters(
154 dimensions=2,
155 size=args.width,
156 offset=args.offset,
157 min_end_time=args.end_time,
158 max_end_time=args.end_time,
159 first_plot_time_stamp=0.0,
160 time_in_between_plots=time_in_between_plots,
161 periodic_BC=[
162 args.periodic_boundary_conditions_x,
163 args.periodic_boundary_conditions_y,
164 ],
165)
166
167if args.load_balancing_strategy != "None":
168 strategy = f"toolbox::loadbalancing::strategies::{args.load_balancing_strategy}"
169 assume_periodic_boundary_conditions = any([
170 args.periodic_boundary_conditions_x,
171 args.periodic_boundary_conditions_y,
172 ])
173 configuration = (
174 f"new ::exahype2::LoadBalancingConfiguration("
175 f"{args.load_balancing_quality},"
176 f"0,"
177 f"{'true' if assume_periodic_boundary_conditions else 'false'},"
178 f"{args.trees},"
179 f"{args.trees})"
180 )
181 project.set_load_balancing(strategy, configuration)
182
183project.set_number_of_threads(args.threads)
184project.set_timeout(3600)
185project.set_Peano4_installation("../../../../", mode=peano4.api.output.string_to_mode(args.build_mode))
186project = project.generate_Peano4_project(verbose=True)
187if args.fpe:
188 project.set_fenv_handler("FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW")
189
190project.output.makefile.add_CXX_flag("-DGRAV=9.81")
191project.build(make=True, make_clean_first=True, throw_away_data_after_build=True)
192
193print(args)
194print(project)
195print(aderdg_solver)
196print(riemann_solver)
197print(limiting_solver)