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