Peano
Loading...
Searching...
No Matches
poisson.py
Go to the documentation of this file.
1import os
2import sys
3import argparse
4
5sys.path.insert(0, os.path.abspath('../../../../python'))
6import peano4.api
7import exahype2
8
9import numpy as np
10import mghype
11
12modes = {
13 "release": peano4.api.output.CompileMode.RELEASE,
14 "trace": peano4.api.output.CompileMode.TRACE,
15 "assert": peano4.api.output.CompileMode.ASSERTS,
16 "stats": peano4.api.output.CompileMode.STATS,
17 "debug": peano4.api.output.CompileMode.DEBUG,
18}
19
20# parser = argparse.ArgumentParser(description='ExaHyPE 2 - Euler benchmarking script')
21parser = argparse.ArgumentParser(description='Multigrid - Poisson solver')
22parser.add_argument("-j", "--parallel-builds", dest="j", type=int, default=-1, help="Parallel builds. Set to 0 to disable compile or to -1 (default) to use all cores")
23parser.add_argument("-pt", "--plot-timestep", dest="plot_each_timestep", action="store_true", default=False, help="Plot after each timestep. By default (False) we plot after initialisation and at the end" )
24parser.add_argument("-pd", "--peano-dir", dest="peanodir", default="../../../../../", help="Peano4 directory")
25parser.add_argument("-cd", "--configure-dir", dest="configuredir", default="../../../../../", help="Location of configure" )
26parser.add_argument("-v", "--verbose", dest="verbose", action="store_true", default=True, help="Verbose")
27parser.add_argument("-d", "--dimensions", dest="dimensions", type=int, default=2, help="Dimensions")
28parser.add_argument("-upv","--unknowns_per_vertex_dof", dest="upv", type=int, default=3, help="unknowns per vertex dof")
29parser.add_argument("-et", "--end-time", dest="end_time", type=float, default=1.0, help="Number of timesteps")
30parser.add_argument("-amr", "--adaptive-levels", dest="adaptivity_levels", type=int, default=0, help="Number of AMR grid levels on top of hmax (0 by default)")
31parser.add_argument("-t", "--type", dest="type", choices=["global-fixed", "global-adaptive"], required=True)
32parser.add_argument("-pdt", "--plot-dt", dest="plot_snapshot_interval", default=0, help="Time interval in-between two snapshots (switched off by default")
33parser.add_argument("-cs", "--cell-size", dest="h", type=float, required=True, help="Mesh size")
34parser.add_argument("-ps", "--patch-size", dest="patch_size", type=int, default=17, help="Dimensions")
35parser.add_argument("-m", "--mode", dest="mode", default="release", help="|".join(modes.keys()))
36parser.add_argument("-p", "--poly_degree", dest="poly_degree", type=int, default=1, help="Polynomial Degree")
37parser.add_argument("-meshsize", "--meshsize", dest="meshsize", default=0.3, help="Mesh size")
38parser.add_argument("-omega_c", "--omega_c", dest="omega_c", default=0.5, help="Mesh size")
39parser.add_argument("-omega_f", "--omega_f", dest="omega_f", default=1.0, help="Mesh size")
40args = parser.parse_args()
41
42if args.dimensions not in [2,3]:
43 print("Error, dimension must be 2 or 3, you supplied {}".format(args.dimensions))
44 import sys
45 sys.exit(1)
46
47if args.mode not in modes:
48 print("Error, mode must be {} or {}, you supplied {}".format(", ",join(modes.keys()[:-1]),modes.keys()[-1],args.mode))
49 import sys
50 sys.exit(1)
51
52print("\nConfiguring {}D Euler problem. Buildmode is {}, nbuilds={}.\n".format(args.dimensions, args.mode, args.j))
53
54#
55# Add the Finite Volumes solver
56#
57max_h = args.h / args.patch_size
58min_h = 0.9 * args.h * 3.0**(-args.adaptivity_levels) / args.patch_size
59
60time_step_size = 0.1 * min_h
61
62auxiliary_variables = 0
63
64euler_solver = None
65poisson_solver = None
66
67#! [Construct matrices]
68
69# matrices = mghype.api.matrixgenerators.DLinear(
70# dimensions = args.dimensions,
71# poly_degree = 1,
72# unknowns_per_vertex_dof = 1
73# )
74
75matrices = mghype.api.matrixgenerators.GLMatrixFree(
76 args.dimensions,
77 args.poly_degree,
78 1, #args.upv, # Unknowns per cell dof. Scalar PDE here
79 2, # We use the penalty formulation (see docu in tutorials)
80 2
81)
82assembly_matrix, assembly_matrix_scaling = matrices.get_cell_system_matrix_for_laplacian()
83mass_matrix, mass_matrix_scaling = matrices.get_cell_mass_matrix()
84face_from_cell_projection, \
85face_from_cell_projection_scaling = matrices.get_face_from_cell_matrix()
86cell_from_face_projection, \
87cell_from_face_projection_scaling = matrices.get_cell_from_face_matrix()
88approximate_system_matrix, \
89approximate_system_matrix_scaling = matrices.get_A_tilde()
90
91#! [Construct matrices]
92
93#! [Instantiate solvers]
94
95
96
97# # @note: Trying to think in a modularised way:
98# # there is MG code somewhere which I have to use and
99# # assuming that we need different local stiffness matrices for LHS for different types of solvers
100if args.type=="global-fixed":
101 euler_solver = exahype2.solvers.fv.rusanov.GlobalFixedTimeStep(
102 "Euler",
103 args.patch_size,
104 5, #unknowns,
105 3, #auxiliary_variables,
106 min_h, max_h,
107 0.1*min_h,
108 flux = exahype2.solvers.PDETerms.User_Defined_Implementation,
109 eigenvalues = exahype2.solvers.PDETerms.User_Defined_Implementation,
110 source_term = exahype2.solvers.PDETerms.User_Defined_Implementation
111 )
112if args.type=="global-adaptive":
113 euler_solver = exahype2.solvers.fv.rusanov.GlobalAdaptiveTimeStep(
114 "Euler",
115 args.patch_size,
116 5, #unknowns,
117 3, #auxiliary_variables,
118 min_h, max_h,
119 time_step_relaxation = 1e-2,
120 flux = exahype2.solvers.PDETerms.User_Defined_Implementation,
121 eigenvalues = exahype2.solvers.PDETerms.User_Defined_Implementation,
122 source_term = exahype2.solvers.PDETerms.User_Defined_Implementation
123 )
124
125
126
127# poisson_solver = mghype.matrixfree.solvers.api.CollocatedLowOrderDiscretisation("Poisson",
128# args.upv, #1, # unknowns
129# args.dimensions,
130# args.meshsize,
131# args.meshsize,
132# local_assembly_matrix = assembly_matrix,
133# local_assembly_matrix_scaling=assembly_matrix_scaling,
134# mass_matrix = mass_matrix,
135# mass_matrix_scaling = mass_matrix_scaling,
136# solver_tolerance=0.01
137# )
138
139poisson_solver = mghype.matrixfree.solvers.api.DiscontinuousGalerkinDiscretisationPointWiseRiemannSolver(
140 name = "Poisson",
141 dimensions = args.dimensions,
142 poly_degree = args.poly_degree,
143 unknowns_per_cell_node = 1,
144 solutions_per_face_node = 2,
145 projections_per_face_node = 2,
146 min_h = min_h,
147 max_h = max_h,
148 assembly_matrix= assembly_matrix,
149 assembly_matrix_scaling = assembly_matrix_scaling,
150 mass_matrix = mass_matrix,
151 mass_matrix_scaling = mass_matrix_scaling,
152 face_from_cell_projection = face_from_cell_projection,
153 face_from_cell_projection_scaling = face_from_cell_projection_scaling,
154 cell_from_face_projection = cell_from_face_projection,
155 cell_from_face_projection_scaling = cell_from_face_projection_scaling,
156 riemann_matrix = matrices.get_face_face_riemann_problem_matrix(),
157 boundary_matrix = matrices.get_boundary_matrix(),
158 cell_relaxation = args.omega_c,
159 face_relaxation = args.omega_f, # default here is 1, i.e. we solve exactly. See class docu
160 approximate_system_matrix = approximate_system_matrix,
161 approximate_system_matrix_scaling = approximate_system_matrix_scaling,
162 solver_tolerance = 0.01,
163)
164
165# local_assembly_matrix = np.array([
166# 0.6666666666666667, -0.16666666666666669, -0.16666666666666663, -0.33333333333333337
167
168# ,-0.16666666666666669, 0.6666666666666667, -0.33333333333333337, -0.16666666666666669
169
170# ,-0.16666666666666663, -0.33333333333333337, 0.6666666666666667, -0.16666666666666669
171
172# ,-0.33333333333333337, -0.16666666666666669, -0.16666666666666669, 0.6666666666666667
173# ]).reshape((4,4))
174
175# mass_matrix = np.eye( 2**args.dimensions )
176
177# poisson_solver = mghype.matrixfree.solvers.api.CollocatedLowOrderDiscretisation("Poisson",
178# args.upv,
179# args.dimensions,
180# args.meshsize,
181# args.meshsize,
182# local_assembly_matrix,
183# local_assembly_matrix_scaling=0,
184# mass_matrix = mass_matrix,
185# mass_matrix_scaling = 0
186# )
187#! [Instantiate solvers]
188
189assert (
190 poisson_solver.name != euler_solver.name
191), "names the solvers should not be the same"
192
193euler_solver.set_implementation(refinement_criterion=exahype2.solvers.PDETerms.User_Defined_Implementation)
194
195#
196# Create a project and configure it to end up in a subnamespace (and thus subdirectory).
197#
198
199euler_project = exahype2.Project(
200 namespace = ["applications", "exahype2", "euler", "selfgravitation" ],
201 project_name = "Euler",
202 directory = ".",
203 subdirectory = "euler",
204 executable = "selfgravitation-euler"
205)
206
207# poisson_project = petsc.Project(
208# namespace = ["applications", "exahype2", "euler", "selfgravitation"],
209# # subnamespace = ["poisson"],
210# project_name = "Poisson",
211# # subdirectory = "poisson",
212# executable = "selfgravitation-poisson"
213# )
214
215#! [Create project]
216poisson_project = mghype.matrixfree.api.Project(
217 namespace = [ "applications", "exahype2", "euler", "selfgravitation" ],
218 project_name = "Poisson",
219 directory = ".",
220 subdirectory = "poisson",
221 executable = "selfgravitation-poisson"
222 # abstract_overwrite = False,
223)
224#! [Create project]
225
226euler_project.add_solver(euler_solver)
227poisson_project.add_solver(poisson_solver)
228
229# #
230# # Time step synchronisation. Ensure the Euler solver doesn't run ahead but waits
231# # for the Poisson updates.
232# #
233# euler_solver._action_set_update_cell.guard += " and tarch::la::greaterEquals( fineGridCell" + \
234# poisson_solver.name + "CellLabel.getTimeStamp(), fineGridCell" + euler_solver.name + \
235# "CellLabel.getTimeStamp() )"
236
237# #
238# # Add the coupling terms
239# #
240# euler_solver.add_user_action_set_includes( """
241# #include "toolbox/blockstructured/Copy.h"
242# """)
243
244# euler_solver.postprocess_updated_patch = """
245# ::toolbox::blockstructured::copyUnknown(
246# {}, // no of unknowns per dimension
247# fineGridCell{}Q.value, // source
248# 0, // the first index (0) is rho
249# 5+3, // unknowns in source (incl material parameters)
250# 0, // no overlap/halo here
251# fineGridCell{}PETScData.value, // dest
252# 4, // index four in destination, i.e. fifth entry
253# 4+1, // four unknowns in source (incl material parameters)
254# 0 // no overlap/halo here
255# );
256# """.format(args.patch_size, euler_solver.name, poisson_solver.name)
257
258# poisson_solver.add_user_action_set_includes( """
259# #include "toolbox/blockstructured/Derivative.h"
260# """)
261
262# poisson_solver.postprocess_updated_patch = """
263# double delta =
264# ::toolbox::blockstructured::computeGradientAndReturnMaxDifference(
265# {}, // no of unknowns per dimension
266# fineGridCellPoissonQ.value, // source
267# 0, // take first entry of solution vector, ignore helper entries
268# 4+1, // unknowns in source (incl material parameters)
269# 0, // no overlap/halo here
270# fineGridCellEulerQ.value, // source
271# #if Dimensions==2
272# {{5,6}}, // indices to which we write the gradient. Depends on dimension
273# #else
274# {{5,6,7}}, // and uses two brackets as escape symbol
275# #endif
276# 5+3, // four unknowns in source (incl material parameters)
277# 0, // no overlap/halo here
278# marker.h()
279# );
280# repositories::instanceOf{}.reportGradientDelta( delta );
281# """.format(args.patch_size, poisson_solver.name)
282
283# #
284# # Ensure the Poisson solver does never overtake the Euler
285# #
286# poisson_solver._compute_new_time_step_size += """
287# if (fineGridCell""" + poisson_solver.name + "CellLabel.getTimeStamp() > fineGridCell" + euler_solver.name + """CellLabel.getTimeStamp() ) {
288# timeStamp = fineGridCell""" + euler_solver.name + """CellLabel.getTimeStamp(); // reset time step size
289# timeStepSize = 0.0; // invalidate time step size; the one chosen didn't make sense
290# fineGridCell""" + poisson_solver.name + """CellLabel.setTimeStamp( timeStamp );
291# }
292# else {
293# }
294# """
295
296if args.dimensions == 2:
297 size = [1.0, 1.0]
298 offset = [0.0, 0.0]
299else:
300 size = [1.0, 1.0, 1.0]
301 offset = [0.0, 0.0, 0.0]
302
303#
304# Lets configure some global parameters
305#
306euler_project.set_global_simulation_parameters(
307 dimensions = args.dimensions,
308 offset = offset,
309 size = size,
310 min_end_time = args.end_time,
311 max_end_time = args.end_time,
312 first_plot_time_stamp = 0.0,
313 time_in_between_plots = args.plot_snapshot_interval, # snapshots
314 periodic_BC = [False, False, False]
315)
316poisson_project.set_global_simulation_parameters(
317 dimensions = args.dimensions,
318 offset = offset,
319 domain_size = size,
320 plot_each_timestep = args.plot_each_timestep,
321)
322
323#
324# So here's the parallel stuff. This is new compared to the serial
325# prototype we did start off with.
326#
327#
328# Configure build
329#
330euler_project.set_load_balancing("toolbox::loadbalancing::strategies::RecursiveBipartition", "new ::exahype2::LoadBalancingConfiguration()")
331euler_project.set_Peano4_installation(args.peanodir, modes[args.mode])
332poisson_project.set_load_balancing("toolbox::loadbalancing::strategies::RecursiveSubdivision", "new ::exahype2::LoadBalancingConfiguration()")
333poisson_project.set_Peano4_installation(args.peanodir, modes[args.mode])
334
335#
336# This is the plain variant
337#
338# #
339# # Create an 'empty' Peano4 project
340# #
341# peano4_project = euler_project.generate_Peano4_project(args.verbose)
342# peano4_project = poisson_project.generate_Peano4_project(args.verbose)
343
344peano4_project = peano4.api.Project(
345 namespace = [], # "applications", "exahype2", "euler", "selfgravitation"
346 project_name = "EulerPoisson", #"EulerPoisson",
347 directory = ".",
348 executable = "selfgravitation-new",
349)
350peano4_project.add_subproject(
351 euler_project.generate_Peano4_project(args.verbose),
352)
353peano4_project.add_subproject(
354 poisson_project.generate_Peano4_project(args.verbose),
355)
356
357# peano4_project.add_subproject(
358# poisson_project.generate_Peano4_project(args.verbose),
359# # subnamespace = ["poisson"],
360# )
361
362
363peano4_project.output.makefile.parse_configure_script_outcome(args.configuredir)
364peano4_project.output.makefile.add_header_search_path("euler")
365peano4_project.output.makefile.add_header_search_path("poisson")
366peano4_project.output.makefile.add_h_file("""{}/{}.h""".format(euler_project.subdirectory, euler_solver.name))
367peano4_project.output.makefile.add_cpp_file("""{}/{}.cpp""".format(euler_project.subdirectory, euler_solver.name))
368peano4_project.output.makefile.add_h_file("""{}/{}.h""".format(poisson_project.subdirectory, poisson_solver.name))
369peano4_project.output.makefile.add_cpp_file("""{}/{}.cpp""".format(poisson_project.subdirectory, poisson_solver.name))
370if args.j==0:
371 peano4_project.generate()
372else:
373 peano4_project.build(make_clean_first=True, number_of_parallel_builds=args.j)
374print("EulerPoisson Peano4 Project built successfully")
375
376# print("Poisson Peano4 Project built successfully")
377# print("EulerPoisson Peano4 project built successfully") #
378
379# print("Convert any output via pvpython ~/git/Peano/python/peano4/visualisation/render.py solution-Euler.peano-patch-file")
Represents a Peano 4 project.
Definition Project.py:23