Peano
Loading...
Searching...
No Matches
elastic.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 Elastic:
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 - Elastic 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
60 parser.add_argument(
61 "-offset",
62 "--offset",
63 type=str,
64 help="Specify offset of domain in meters as [x, y] as string (e.g. [-10, -10], [-7e6, -4e6]).",
65 )
66
67 parser.add_argument(
68 "-stateless",
69 "--stateless",
70 action="store_true",
71 default=False,
72 help="Use stateless PDE terms (GPU offloading requires a GPU enabled Peano build and an enclave solver).",
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": "Elastic",
240 "unknowns": {"v": args.dimensions, "sigma": args.dimensions + 1},
241 "auxiliary_variables": 0,
242 }
243
244 if args.stateless:
245 solver_params.update(
246 {
247 "pde_terms_without_state": True,
248 }
249 )
250
251 if "Fixed" in args.solver:
252 solver_params.update(
253 {
254 "normalised_time_step_size": args.time_step_size,
255 }
256 )
257 elif "Adaptive" in args.solver:
258 solver_params.update(
259 {
260 "time_step_relaxation": args.time_step_relaxation,
261 }
262 )
263
264 max_h = (1.1 * min(args.width[0:args.dimensions]) / (3.0**args.min_depth))
265 min_h = max_h * 3.0 ** (-args.amr_levels)
266
267 if "FV" in args.solver:
268 solver_params.update(
269 {
270 "patch_size": args.patch_size,
271 "max_volume_h": max_h,
272 "min_volume_h": min_h,
273 }
274 )
275 implementation_params = {
276 "initial_conditions": exahype2.solvers.PDETerms.User_Defined_Implementation,
277 "boundary_conditions": exahype2.solvers.PDETerms.User_Defined_Implementation,
278 "refinement_criterion": exahype2.solvers.PDETerms.User_Defined_Implementation,
279 "flux": "applications::exahype2::elastic::flux(Q, faceCentre, volumeH, t, dt, normal, F);",
280 "eigenvalues": "return applications::exahype2::elastic::maxEigenvalue(Q, faceCentre, volumeH, t, dt, normal);",
281 "source_term": "applications::exahype2::elastic::sourceTerm(Q, volumeCentre, volumeH, t, dt, S);",
282 }
283 elif "ADERDG" in args.solver:
284 solver_params.update(
285 {
286 "order": args.dg_order,
287 "max_cell_h": max_h,
288 "min_cell_h": min_h,
289 }
290 )
291 implementation_params = {
292 "initial_conditions": exahype2.solvers.PDETerms.User_Defined_Implementation,
293 "boundary_conditions": exahype2.solvers.PDETerms.User_Defined_Implementation,
294 "refinement_criterion": exahype2.solvers.PDETerms.User_Defined_Implementation,
295 "flux": "applications::exahype2::elastic::flux(Q, x, h, t, dt, normal, F);",
296 "eigenvalues": "return applications::exahype2::elastic::maxEigenvalue(Q, x, h, t, dt, normal);",
297 "source_term": "applications::exahype2::elastic::sourceTerm(Q, x, 0.0, t, 0.0, S);",
298 }
299
300 solver = self._available_solvers[args.solver](**solver_params)
301 solver.plot_description = ", ".join(solver_params["unknowns"].keys()) + ", "
302 if solver_params["auxiliary_variables"] != 0:
303 solver.plot_description += ", ".join(solver_params["auxiliary_variables"].keys())
304 solver.set_implementation(**implementation_params)
305 solver.switch_storage_scheme(exahype2.solvers.Storage[args.storage], exahype2.solvers.Storage[args.storage])
306
307 if "ADERDG" in args.solver:
308 solver.add_kernel_optimisations(is_linear = True,)
309
310 return solver
311
312 def setup_project(self, args, solver):
313 project = exahype2.Project(
314 namespace=["applications", "exahype2", "elastic"],
315 project_name="Elastic",
316 directory=".",
317 executable=f"Elastic.{args.build_mode}",
318 )
319
320 project.add_solver(solver)
321
322 if args.number_of_snapshots <= 0:
323 time_in_between_plots = 0.0
324 else:
325 time_in_between_plots = args.end_time / args.number_of_snapshots
326 project.set_output_path(args.output)
327
328 project.set_global_simulation_parameters(
329 dimensions=args.dimensions,
330 size=args.width[0:args.dimensions],
331 offset=args.offset[0:args.dimensions],
332 min_end_time=args.end_time,
333 max_end_time=args.end_time,
334 first_plot_time_stamp=0.0,
335 time_in_between_plots=time_in_between_plots,
336 periodic_BC=[
337 args.periodic_boundary_conditions_x,
338 args.periodic_boundary_conditions_y,
339 args.periodic_boundary_conditions_z,
340 ],
341 )
342
343 if args.load_balancing_strategy != "None":
344 strategy = f"toolbox::loadbalancing::strategies::{args.load_balancing_strategy}"
345 assume_periodic_boundary_conditions = any([
346 args.periodic_boundary_conditions_x,
347 args.periodic_boundary_conditions_y,
348 args.periodic_boundary_conditions_z,
349 ])
350 configuration = (
351 f"new ::exahype2::LoadBalancingConfiguration("
352 f"{args.load_balancing_quality},"
353 f"0,"
354 f"{'true' if assume_periodic_boundary_conditions else 'false'},"
355 f"{args.trees},"
356 f"{args.trees})"
357 )
358 project.set_load_balancing(strategy, configuration)
359
360 project.set_number_of_threads(args.threads)
361
362 project.set_multicore_orchestration(
363 "tarch::multicore::orchestration::Hardcoded::createFuseAll(%s, true, true, 0)"
364 % str(args.fuse_tasks)
365 )
366 project.additional_includes.append("tarch/multicore/orchestration/Hardcoded.h")
367
368 project.set_timeout(args.timeout)
369
370 project.set_Peano4_installation(args.peano_dir, mode=peano4.output.string_to_mode(args.build_mode))
371 project = project.generate_Peano4_project(verbose=True)
372
373 if args.fpe:
374 project.set_fenv_handler("FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW")
375
376 return project
377
378 def build(self, args, project):
379 project.build(
380 make=not args.no_make,
381 make_clean_first=True,
382 throw_away_data_after_build=True,
383 )
dict _available_solvers
Definition elastic.py:10
setup_solver(self, args)
Definition elastic.py:237
build(self, args, project)
Definition elastic.py:378
setup_parser(self)
Definition elastic.py:21
setup_project(self, args, solver)
Definition elastic.py:312
ExaHyPE 2 project.
Definition Project.py:14