Peano
Loading...
Searching...
No Matches
euler.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 argparse
4
5import peano4
6import exahype2
7
8
9class Euler:
10 _available_solvers = {
13
16
17 "RusanovGlobalFixedADERDG": exahype2.solvers.aderdg.GlobalFixedTimeStep,
18 "RusanovGlobalAdaptiveADERDG": exahype2.solvers.aderdg.GlobalAdaptiveTimeStep,
19 }
20
21 def setup_parser(self):
22 parser = argparse.ArgumentParser(
23 description="ExaHyPE 2 - Euler Application Script"
24 )
25
26 parser.add_argument(
27 "-s",
28 "--solver",
29 choices=self._available_solvers.keys(),
30 help="|".join(self._available_solvers.keys()),
31 )
32 parser.add_argument(
33 "-d",
34 "--dimensions",
35 type=int,
36 help="Number of space dimensions.",
37 )
38 parser.add_argument(
39 "-dt",
40 "--time-step-size",
41 type=float,
42 default=0.01,
43 help="Time step size for fixed time-stepping.",
44 )
45 parser.add_argument(
46 "-cfl",
47 "--time-step-relaxation",
48 type=float,
49 default=0.5,
50 help="Time step relaxation safety factor for adaptive time-stepping.",
51 )
52
53 parser.add_argument(
54 "-width",
55 "--width",
56 type=str,
57 help="Specify size of domain in meters as [x, y] as string (e.g. [10, 10], [7e6, 4e6]).",
58 )
59 parser.add_argument(
60 "-offset",
61 "--offset",
62 type=str,
63 help="Specify offset of domain in meters as [x, y] as string (e.g. [-10, -10], [-7e6, -4e6]).",
64 )
65
66 parser.add_argument(
67 "-stateless",
68 "--stateless",
69 action="store_true",
70 default=False,
71 help="Use stateless PDE terms for GPU offloading (requires a GPU enabled Peano build and an enclave solver).",
72 )
73
74 parser.add_argument(
75 "-o",
76 "--output",
77 type=str,
78 default="solution",
79 help="Output path for project solution output. The project will create a new folder at the given path. Default is 'solution'.",
80 )
81
82 parser.add_argument(
83 "-pbc-x",
84 "--periodic-boundary-conditions-x",
85 action="store_true",
86 help="Use periodic boundary conditions in the x-axis.",
87 )
88 parser.add_argument(
89 "-pbc-y",
90 "--periodic-boundary-conditions-y",
91 action="store_true",
92 help="Use periodic boundary conditions in the y-axis.",
93 )
94 parser.add_argument(
95 "-pbc-z",
96 "--periodic-boundary-conditions-z",
97 action="store_true",
98 help="Use periodic boundary conditions in the z-axis.",
99 )
100
101 parser.add_argument(
102 "-m",
103 "--build-mode",
104 choices=peano4.output.CompileModes,
105 default=peano4.output.CompileModes[0], # Release
106 help="|".join(peano4.output.CompileModes),
107 )
108
109 parser.add_argument(
110 "-et",
111 "--end-time",
112 type=float,
113 default=5.0,
114 help="End time of the simulation.",
115 )
116 parser.add_argument(
117 "-ns",
118 "--number-of-snapshots",
119 type=int,
120 default=10,
121 help="Number of snapshots (plots).",
122 )
123
124 parser.add_argument(
125 "-ps",
126 "--patch-size",
127 type=int,
128 help="Number of finite volumes per axis (dimension) per patch.",
129 )
130 parser.add_argument(
131 "-rk-order",
132 "--rk-order",
133 type=int,
134 help="Order of time discretisation for Runge-Kutta scheme.",
135 )
136 parser.add_argument(
137 "-dg-order",
138 "--dg-order",
139 type=int,
140 help="Order of space discretisation for Discontinuous Galerkin.",
141 )
142
143 parser.add_argument(
144 "-md",
145 "--min-depth",
146 type=float,
147 default=1,
148 help="Determines maximum size of a single cell on each axis.",
149 )
150 parser.add_argument(
151 "-amr",
152 "--amr-levels",
153 type=int,
154 default=0,
155 help="Number of AMR grid levels on top of max. size of a cell.",
156 )
157
158 parser.add_argument(
159 "--storage",
160 type=str,
161 choices=[e.name for e in exahype2.solvers.Storage],
162 default="Heap",
163 help="The storage scheme to use."
164 )
165
166 available_load_balancing_strategies = [
167 "None",
168 "SpreadOut",
169 "SpreadOutHierarchically",
170 "SpreadOutOnceGridStagnates",
171 "RecursiveBipartition",
172 "SplitOversizedTree",
173 "cascade::SpreadOut_RecursiveBipartition",
174 "cascade::SpreadOut_SplitOversizedTree",
175 ]
176 parser.add_argument(
177 "-lbs",
178 "--load-balancing-strategy",
179 choices=available_load_balancing_strategies,
180 default="SpreadOutOnceGridStagnates",
181 help="|".join(available_load_balancing_strategies),
182 )
183 parser.add_argument(
184 "-lbq",
185 "--load-balancing-quality",
186 type=float,
187 default=0.99,
188 help="The quality of the load balancing.",
189 )
190 parser.add_argument(
191 "--trees",
192 type=int,
193 default=-1,
194 help="Number of trees (partitions) per rank after initial decomposition.",
195 )
196 parser.add_argument(
197 "--threads",
198 type=int,
199 default=0,
200 help="Number of threads per rank.",
201 )
202 parser.add_argument(
203 "-f",
204 "--fuse-tasks",
205 type=int,
206 default=131072,
207 help="Number of enclave tasks to fuse into one meta task.",
208 )
209 parser.add_argument(
210 "-timeout",
211 "--timeout",
212 type=int,
213 default=3600,
214 help="MPI timeout in seconds.",
215 )
216 parser.add_argument(
217 "-fpe",
218 "--fpe",
219 action="store_true",
220 help="Enable a floating-point exception handler.",
221 )
222 parser.add_argument(
223 "-no-make",
224 "--no-make",
225 action="store_true",
226 help="Do not compile the code after generation.",
227 )
228
229 parser.add_argument(
230 "--peano-dir",
231 default="../../../",
232 help="Peano directory",
233 )
234
235 return parser
236
237 def setup_solver(self, args):
238 solver_params = {
239 "name": "Euler",
240 "unknowns": {"rho": 1, "u": 1, "v": 1, "w": 1, "e": 1}
241 if args.dimensions == 3
242 else {"rho": 1, "u": 1, "v": 1, "e": 1},
243 "auxiliary_variables": 0,
244 }
245
246 if args.stateless:
247 solver_params.update(
248 {
249 "pde_terms_without_state": True,
250 }
251 )
252
253 if "Fixed" in args.solver:
254 solver_params.update(
255 {
256 "normalised_time_step_size": args.time_step_size,
257 }
258 )
259 elif "Adaptive" in args.solver:
260 solver_params.update(
261 {
262 "time_step_relaxation": args.time_step_relaxation,
263 }
264 )
265
266 max_h = (1.1 * min(args.width[0:args.dimensions]) / (3.0**args.min_depth))
267 min_h = max_h * 3.0 ** (-args.amr_levels)
268
269 if "FV" in args.solver:
270 solver_params.update(
271 {
272 "patch_size": args.patch_size,
273 "max_volume_h": max_h,
274 "min_volume_h": min_h,
275 }
276 )
277 implementation_params = {
278 "initial_conditions": exahype2.solvers.PDETerms.User_Defined_Implementation,
279 "boundary_conditions": exahype2.solvers.PDETerms.User_Defined_Implementation,
280 "refinement_criterion": exahype2.solvers.PDETerms.User_Defined_Implementation,
281 "flux": "applications::exahype2::euler::flux(Q, faceCentre, volumeH, t, dt, normal, F);",
282 "eigenvalues": "return applications::exahype2::euler::maxEigenvalue(Q, faceCentre, volumeH, t, dt, normal);",
283 }
284 elif "RKDG" in args.solver:
285 solver_params.update(
286 {
287 "rk_order": args.rk_order,
288 "polynomials": exahype2.solvers.GaussLegendreBasis(args.dg_order),
289 "max_cell_h": max_h,
290 "min_cell_h": min_h,
291 }
292 )
293 implementation_params = {
294 "initial_conditions": exahype2.solvers.PDETerms.User_Defined_Implementation,
295 "boundary_conditions": exahype2.solvers.PDETerms.User_Defined_Implementation,
296 "refinement_criterion": exahype2.solvers.PDETerms.User_Defined_Implementation,
297 "flux": "applications::exahype2::euler::flux(Q, x, h, t, dt, normal, F);",
298 "eigenvalues": "return applications::exahype2::euler::maxEigenvalue(Q, x, h, t, dt, normal);",
299 }
300 elif "ADERDG" in args.solver:
301 solver_params.update(
302 {
303 "order": args.dg_order,
304 "max_cell_h": max_h,
305 "min_cell_h": min_h,
306 }
307 )
308 implementation_params = {
309 "initial_conditions": exahype2.solvers.PDETerms.User_Defined_Implementation,
310 "boundary_conditions": exahype2.solvers.PDETerms.User_Defined_Implementation,
311 "refinement_criterion": exahype2.solvers.PDETerms.User_Defined_Implementation,
312 "flux": "applications::exahype2::euler::flux(Q, x, h, t, dt, normal, F);",
313 "eigenvalues": "return applications::exahype2::euler::maxEigenvalue(Q, x, h, t, dt, normal);",
314 }
315
316 solver = self._available_solvers[args.solver](**solver_params)
317 solver.plot_description = ", ".join(solver_params["unknowns"].keys()) + ", "
318 if solver_params["auxiliary_variables"] != 0:
319 solver.plot_description += ", ".join(solver_params["auxiliary_variables"].keys())
320 solver.set_implementation(**implementation_params)
321 solver.switch_storage_scheme(exahype2.solvers.Storage[args.storage], exahype2.solvers.Storage[args.storage])
322
323 if "ADERDG" in args.solver:
324 solver.add_kernel_optimisations(is_linear = False, polynomials=exahype2.solvers.aderdg.Polynomials.Gauss_Lobatto)
325
326 return solver
327
328 def setup_project(self, args, solver):
329 project = exahype2.Project(
330 namespace=["applications", "exahype2", "euler"],
331 project_name="Euler",
332 directory=".",
333 executable=f"Euler.{args.build_mode}",
334 )
335
336 project.add_solver(solver)
337
338 if args.number_of_snapshots <= 0:
339 time_in_between_plots = 0.0
340 else:
341 time_in_between_plots = args.end_time / args.number_of_snapshots
342 project.set_output_path(args.output)
343
344 project.set_global_simulation_parameters(
345 dimensions=args.dimensions,
346 size=args.width[0:args.dimensions],
347 offset=args.offset[0:args.dimensions],
348 min_end_time=args.end_time,
349 max_end_time=args.end_time,
350 first_plot_time_stamp=0.0,
351 time_in_between_plots=time_in_between_plots,
352 periodic_BC=[
353 args.periodic_boundary_conditions_x,
354 args.periodic_boundary_conditions_y,
355 args.periodic_boundary_conditions_z,
356 ],
357 )
358
359 if args.load_balancing_strategy != "None":
360 strategy = f"toolbox::loadbalancing::strategies::{args.load_balancing_strategy}"
361 assume_periodic_boundary_conditions = any([
362 args.periodic_boundary_conditions_x,
363 args.periodic_boundary_conditions_y,
364 args.periodic_boundary_conditions_z,
365 ])
366 configuration = (
367 f"new ::exahype2::LoadBalancingConfiguration("
368 f"{args.load_balancing_quality},"
369 f"0,"
370 f"{'true' if assume_periodic_boundary_conditions else 'false'},"
371 f"{args.trees},"
372 f"{args.trees})"
373 )
374 project.set_load_balancing(strategy, configuration)
375
376 project.set_number_of_threads(args.threads)
377
378 project.set_multicore_orchestration(
379 "tarch::multicore::orchestration::Hardcoded::createFuseAll(%s, true, true, 0)"
380 % str(args.fuse_tasks)
381 )
382 project.additional_includes.append("tarch/multicore/orchestration/Hardcoded.h")
383
384 project.set_timeout(args.timeout)
385
386 project.set_Peano4_installation(args.peano_dir, mode=peano4.output.string_to_mode(args.build_mode))
387 project = project.generate_Peano4_project(verbose=True)
388
389 if args.fpe:
390 project.set_fenv_handler("FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW")
391
392 return project
393
394 def build(self, args, project):
395 project.build(
396 make=not args.no_make,
397 make_clean_first=True,
398 throw_away_data_after_build=True,
399 )
setup_project(self, args, solver)
Definition euler.py:328
build(self, args, project)
Definition euler.py:394
setup_solver(self, args)
Definition euler.py:237
setup_parser(self)
Definition euler.py:21
dict _available_solvers
Definition euler.py:10
ExaHyPE 2 project.
Definition Project.py:14
The Gauss-Legendre Basis is by construction the only basis which yields diagonal mass matrices.