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.api
6import exahype2
7
8
9class Elastic:
10 """!
11
12 Superclass for all elastic solvers
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 - Elastic 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": "Elastic",
245 "unknowns": {"v": args.dimensions, "sigma": args.dimensions + 1},
246 "auxiliary_variables": 0,
247 }
248
249 if args.stateless:
250 solver_params.update(
251 {
252 "pde_terms_without_state": True,
253 }
254 )
255
256 if "Fixed" in args.solver:
257 solver_params.update(
258 {
259 "normalised_time_step_size": args.time_step_size,
260 }
261 )
262 elif "Adaptive" in args.solver:
263 solver_params.update(
264 {
265 "time_step_relaxation": args.time_step_relaxation,
266 }
267 )
268
269 max_h = (1.1 * min(args.width[0:args.dimensions]) / (3.0**args.min_depth))
270 min_h = max_h * 3.0 ** (-args.amr_levels)
271
272 if "FV" in args.solver:
273 solver_params.update(
274 {
275 "patch_size": args.patch_size,
276 "max_volume_h": max_h,
277 "min_volume_h": min_h,
278 }
279 )
280 implementation_params = {
281 "initial_conditions": exahype2.solvers.PDETerms.User_Defined_Implementation,
282 "boundary_conditions": exahype2.solvers.PDETerms.User_Defined_Implementation,
283 "refinement_criterion": exahype2.solvers.PDETerms.User_Defined_Implementation,
284 "flux": "applications::exahype2::elastic::flux(Q, faceCentre, volumeH, t, dt, normal, F);",
285 "eigenvalues": "applications::exahype2::elastic::maxEigenvalue(Q, faceCentre, volumeH, t, dt, normal, maxEigenvalue);",
286 "source_term": "applications::exahype2::elastic::sourceTerm(Q, volumeCentre, volumeH, t, dt, S);",
287 }
288 elif "ADERDG" in args.solver:
289 solver_params.update(
290 {
291 "order": args.dg_order,
292 "max_cell_h": max_h,
293 "min_cell_h": min_h,
294 }
295 )
296 implementation_params = {
297 "initial_conditions": exahype2.solvers.PDETerms.User_Defined_Implementation,
298 "boundary_conditions": exahype2.solvers.PDETerms.User_Defined_Implementation,
299 "refinement_criterion": exahype2.solvers.PDETerms.User_Defined_Implementation,
300 "flux": "applications::exahype2::elastic::flux(Q, x, h, t, dt, normal, F);",
301 "eigenvalues": """
302 double lambda[NumberOfUnknowns] = {0.};
303 applications::exahype2::elastic::maxEigenvalue(Q, x, h, t, dt, normal, lambda);
304 return *std::max_element(lambda, lambda+NumberOfUnknowns);""",
305 "source_term": "applications::exahype2::elastic::sourceTerm(Q, x, 0.0, t, 0.0, S);",
306 }
307
308 solver = self._available_solvers[args.solver](**solver_params)
309 solver.plot_description = ", ".join(solver_params["unknowns"].keys()) + ", "
310 if solver_params["auxiliary_variables"] != 0:
311 solver.plot_description += ", ".join(solver_params["auxiliary_variables"].keys())
312 solver.set_implementation(**implementation_params)
313 solver.switch_storage_scheme(exahype2.solvers.Storage[args.storage], exahype2.solvers.Storage[args.storage])
314
315 if "ADERDG" in args.solver:
316 solver.add_kernel_optimisations(is_linear = True,)
317
318 return solver
319
320 def setup_project(self, args, solver):
321 project = exahype2.Project(
322 namespace=["applications", "exahype2", "elastic"],
323 project_name="Elastic",
324 directory=".",
325 executable=f"Elastic.{args.build_mode}",
326 )
327
328 project.add_solver(solver)
329
330 if args.number_of_snapshots <= 0:
331 time_in_between_plots = 0.0
332 else:
333 time_in_between_plots = args.end_time / args.number_of_snapshots
334 project.set_output_path(args.output)
335
336 project.set_global_simulation_parameters(
337 dimensions=args.dimensions,
338 size=args.width[0:args.dimensions],
339 offset=args.offset[0:args.dimensions],
340 min_end_time=args.end_time,
341 max_end_time=args.end_time,
342 first_plot_time_stamp=0.0,
343 time_in_between_plots=time_in_between_plots,
344 periodic_BC=[
345 args.periodic_boundary_conditions_x,
346 args.periodic_boundary_conditions_y,
347 args.periodic_boundary_conditions_z,
348 ],
349 )
350
351 if args.load_balancing_strategy != "None":
352 strategy = f"toolbox::loadbalancing::strategies::{args.load_balancing_strategy}"
353 assume_periodic_boundary_conditions = any([
354 args.periodic_boundary_conditions_x,
355 args.periodic_boundary_conditions_y,
356 args.periodic_boundary_conditions_z,
357 ])
358 configuration = (
359 f"new ::exahype2::LoadBalancingConfiguration("
360 f"{args.load_balancing_quality},"
361 f"0,"
362 f"{'true' if assume_periodic_boundary_conditions else 'false'},"
363 f"{args.trees},"
364 f"{args.trees})"
365 )
366 project.set_load_balancing(strategy, configuration)
367
368 project.set_number_of_threads(args.threads)
369
370 project.set_multicore_orchestration(
371 "tarch::multicore::orchestration::Hardcoded::createFuseAll(%s, 0)"
372 % str(args.fuse_tasks)
373 )
374 project.additional_includes.append("tarch/multicore/orchestration/Hardcoded.h")
375
376 project.set_timeout(args.timeout)
377
378 project.set_Peano4_installation(args.peano_dir, mode=peano4.api.output.string_to_mode(args.build_mode))
379 project = project.generate_Peano4_project(verbose=True)
380
381 if args.fpe:
382 project.set_fenv_handler("FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW")
383
384 return project
385
386 def build(self, args, project):
387 project.build(
388 make=not args.no_make,
389 make_clean_first=True,
390 throw_away_data_after_build=True,
391 )
Superclass for all elastic solvers.
Definition Elastic.py:9
build(self, args, project)
Definition Elastic.py:386
setup_project(self, args, solver)
Definition Elastic.py:320
setup_solver(self, args)
Definition Elastic.py:242
dict _available_solvers
Definition Elastic.py:15
setup_parser(self)
Definition Elastic.py:26