Peano
Loading...
Searching...
No Matches
ADERDG.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 os
4from enum import IntEnum
5from abc import abstractmethod
6
7import jinja2
8
9import peano4.output
10import peano4.datamodel
12
13import exahype2.grid
16
17from exahype2.solvers.Storage import Storage
18from exahype2.solvers.PDETerms import PDETerms
19from exahype2.solvers.aderdg.Architectures import Architectures
20from exahype2.solvers.aderdg.LagrangeBasis import GaussLegendreBasis, GaussLobattoBasis
21
22
23"""
24Used to have a central way for all of this class' descendants to differentiate between Gauss-Legendre
25and Gauss-Lobatto nodes, helps to avoid having to constantly pass a string and ensure that this string is
26the same everywhere.
27"""
28class Polynomials(IntEnum):
29 Gauss_Legendre = 0,
30 Gauss_Lobatto = 1
31
32"""
33Denotes valid precisions for kernels and storage but also is supposed to allow a little more flexibility
34in the naming. If a user wants to name it float because they're more used to C-based languages that's
35fine but if they'd rather use single we allow it as well.
36"""
37PrecisionType = {
38 "SP": "float",
39 "float": "float",
40 "single": "float",
41 "fp32": "float",
42 "DP": "double",
43 "double": "double",
44 "fp64": "double",
45 "quadruple": "long double",
46 "long double": "long double",
47 "fp128": "long double",
48 "float16_t": "std::float16_t",
49 "std::float16_t": "std::float16_t",
50 "_Float16": "_Float16",
51 "fp16": "_Float16",
52 "bfloat16_t": "std::bfloat16_t",
53 "std::bfloat16_t": "std::bfloat16_t",
54 "__bf16": "__bf16",
55 "bfloat": "__bf16",
56 "bf16": "__bf16"
57}
58
59class ADERDG(object):
61 self,
62 name,
63 order,
64 unknowns,
65 auxiliary_variables,
66 min_cell_h,
67 max_cell_h,
68 plot_grid_properties=False,
69 ):
70 self._name = name
71
72 """
73 Polynomial order of the representation of the underlying function in each spatial dimension.
74 The number of support points used to represent this polynomial is always the order + 1
75 """
76 self._order = order
77
78 """
79 self._unknowns and self._auxiliary_variables respectively hold the number of unknowns and
80 auxiliary variables in the equation to be computed. Unknowns are variables that change over
81 time whereas auxiliary variables can be space-dependent but don't vary over time.
82 These can be specified either as simple ints or by a dictionary
83 (e.g.) unknowns = {'a': 1, 'b': 1, 'c': 3}
84 in which the user specifies the multiplicity of the variable (the velocity has one component
85 per dimension for example.)
86 If they are specified by a dictionary then the code generates a "VariableShortcuts" file which
87 allows the user to specify a variable by name and automatically maps this to the right position
88 in an array for better legibility. Otherwise they must manually remember the position of each
89 variable manually.
90
91 use_var_shortcut is used to know whether or not the user passed their variables via a dict
92 variable_names and variable_pos are used internally to remember the names and respective
93 positions of variables if set by a dictionary.
94 """
95 self._use_var_shortcut = False
97 self._variable_pos = [0]
98
99 if type(unknowns) is dict:
100 self._unknowns = sum(unknowns.values())
101 self._variable_names += list(unknowns.keys())
102 for var in list(unknowns.values()):
103 self._variable_pos.append(var + self._variable_pos[-1])
104 self._use_var_shortcut = True
105 elif type(unknowns) is int:
106 self._unknowns = unknowns
107 else:
108 raise Exception(
109 "not a valid type for parameter unknowns, needs to be int or dictionary."
110 )
111
112 if type(auxiliary_variables) is dict:
113 self._auxiliary_variables = sum(auxiliary_variables.values())
114 self._variable_names += list(auxiliary_variables.keys())
115 for var in list(auxiliary_variables.values()):
116 self._variable_pos.append(var + self._variable_pos[-1])
117 self._use_var_shortcut = True
118 elif type(auxiliary_variables) is int:
119 self._auxiliary_variables = auxiliary_variables
120 else:
121 raise Exception(
122 "not a valid type for parameter auxiliary_variables, needs to be int or dictionary."
123 )
124
125 """
126 Minimal and maximal accepted sizes for the cell, domain will be subdivided until the cell size is smaller
127 than the minimal size but will never be subdivided to be smaller than the minimal size.
128 """
129 self._min_cell_h = min_cell_h
130 self._max_cell_h = max_cell_h
131 if min_cell_h > max_cell_h:
132 raise Exception(
133 "min_cell_h ("
134 + str(min_cell_h)
135 + ") is bigger than max_cell_h ("
136 + str(max_cell_h)
137 + ")"
138 )
139
140 self._is_linear = False
141 self._polynomials = Polynomials.Gauss_Legendre
142 self._basis = GaussLegendreBasis(order + 1)
143 self._architecture = "noarch"
144 self._use_libxsmm = False
145
147
148 self._predictor_computation_precisions = [PrecisionType["double"]]
149 self._corrector_computation_precision = PrecisionType["double"]
150 self._solution_persistent_storage_precision = PrecisionType["double"]
153
154 # Whether or not to plot information about the grid as well as information about the content of the patches
155 self._plot_grid_properties = plot_grid_properties
157
160
161 # Used by children classes or setters in order to add constants or includes to the corresponding part
165
166 """
167 These specify the time step, they must be set by child classes in order to advance the timestepping.
168 These are the main difference between child classes as they all use the same underlying routines.
169 """
170 self._compute_time_step_size = "#error Not yet defined"
171 self._compute_new_time_step_size = "#error Not yet defined"
172
173 """
174 These are all the optional and mandatory plugins that can be specified by the user.
175 eigenvalues, boundary conditions, refinement criteria and initial conditions must
176 all be specified, all others are optional but can be added via the set_implementation() function.
177 There are four choices for these, three of which are specified in PDETerms:
178 User_Defined_Implementation creates empty stubs that the user must then manually fill.
179 None_implementation leaves out this optional stub and ensures the kernels don't use this function.
180 Empty_implementation does... the same thing as user_defined I think?
181 The final option is to fill these with a string, in which case this string is directly taken as
182 C++ code and used as the implementation of this function. The user is trusted to provide code that
183 compiles and runs properly, it is never checked.
184 """
185 self._flux_implementation = PDETerms.None_Implementation
186 self._ncp_implementation = PDETerms.None_Implementation
187 self._source_term_implementation = PDETerms.None_Implementation
188 self._point_sources_implementation = PDETerms.None_Implementation
189 self._eigenvalues_implementation = PDETerms.None_Implementation
190 self._material_param_implementation = PDETerms.None_Implementation
191
192 self._refinement_criterion_implementation = PDETerms.None_Implementation
193 self._initial_conditions_implementation = PDETerms.None_Implementation
194 self._boundary_conditions_implementation = PDETerms.None_Implementation
195
196 self._precision_criterion_implementation = PDETerms.None_Implementation
197 self._riemann_solver_implementation = PDETerms.None_Implementation
199
200 """
201 These will be used by children of this class to fill them with the declaration and definition of the
202 above mandatory and optional functions.
203 """
208
209 """
210 Used by child classes; will contain code to be executed at the start and end respectively of the
211 time step. Typically specifies some timestep variable and advances the overall timestamp of the
212 entire solver.
213 """
216
219
220 """
221 These are ADER-DG CFL factors, they help determine the maximal stable timestep size.
222 Up to order 4, computed via von Neumann analysis [1].
223 [1] M. Dumbser, D. S. Balsara, E. F. Toro, and C.-D. Munz,
224 ‘A unified framework for the construction of one-step finite volume and discontinuous Galerkin schemes on unstructured meshes’, Journal of Computational Physics, vol. 227, no. 18, pp. 8209–8253, Sep. 2008.
225 They are necessary to compute stable timestep sizes as dt <= c*dx / (lambda_max*(2N+1)
226 with c the CFL for given order, lambda_max the maximal eigenvalue, N the order and dx the minimal mesh distance.
227 """
228 self._cflAder = [
229 1.0,
230 0.33,
231 0.17,
232 0.1,
233 0.069,
234 0.045,
235 0.038,
236 0.03,
237 0.02,
238 0.015,
239 0.008821428571428572,
240 0.005235326086956522,
241 0.0031307249999999996,
242 0.0018842326388888888,
243 0.001140285614224138,
244 0.0006933672202620968,
245 ]
246
247 # Safety factor for CFL (Courant-Friedrichs-Lewy) condition
249
250 """
251 Used if the user wants to add some function to postprocessing, meaning
252 it should be added after every other computation in ADER-DG is done.
253 """
255
258
259 self.switch_storage_scheme(Storage.SmartPointers, Storage.SmartPointers)
260
261 # Create initial structures and action_sets, these are re-generated essentially anytime something about the solver is modified.
263 self.create_action_sets()
264
265
266 def __str__(self):
267 result = (
268 """
269Name: """
270 + self._name
271 + """
272Type: """
273 + self.__class__.__module__
274 + """
275Storage schemes: """
276 + str(self._cell_data_storage) + ", " + str(self._face_data_storage)
277 + """
278DG order: """
279 + str(self._order)
280 + """
281Polynomials: """
282 + str(self._polynomials.name)
283 + """
284Basis: """
285 + str(self._basis)
286 + """
287Basis size: """
288 + str(self._order + 1)
289 + """
290Linear: """
291 + str(self._is_linear)
292 + """
293Unknowns: """
294 + str(self._unknowns)
295 + """
296Auxiliary variables: """
297 + str(self._auxiliary_variables)
298 + """
299h_cell_min: """
300 + str(self._min_cell_h)
301 + """
302h_cell_max: """
303 + str(self._max_cell_h)
304 + """
305Initial conditions: """
307 + """
308Boundary conditions: """
310 + """
311Refinement criterion: """
313 + """
314Eigenvalues: """
316 + """
317Flux: """
318 + str(self._flux_implementation)
319 + """
320NCP: """
321 + str(self._ncp_implementation)
322 + """
323Source term: """
325 + """
326Point sources: """
328 + """
329Number of point sources:"""
330 + str(self._number_of_point_sources)
331 + """
332Riemann solver: """
334 + """
335Material parameters: """
337 + """
338"""
339 )
340 return result
341
342 __repr__ = __str__
343
344 """
345 Creates all the structures that are attached on the Peano grid either in a cell or on the faces.
346 These are defined as Peano patches which have given sizes to contain persistent data as well as
347 conditions for when they should be merged, sent, received, stored, loaded, etc.
348 """
349 @abstractmethod
352
353 # Current time step contains the solution, projections are respectively the projection
354 # of the solution and of the fluxes on the faces as predicted by the space-time predictor.
356 (self._order + 1, self._order + 1, self._order + 1),
358 self._unknown_identifier(),
360 )
362 (self._order + 1, self._order + 1, self._order + 1),
364 self._unknown_identifier() + "_old",
366 )
368 (2, self._order+1, self._order+1),
370 self._unknown_identifier() + "Estimates",
372 )
374 (2, self._order+1, self._order+1),
375 self._unknowns,
376 self._unknown_identifier() + "FluxEstimates",
378 )
379
380 if self._cell_data_storage == Storage.CallStack:
384 )
388 )
389 elif self._cell_data_storage == Storage.Heap:
393 )
397 )
398 elif self._cell_data_storage == Storage.SmartPointers:
402 )
406 )
407 else:
408 assert False, "Storage variant {} not supported".format(
410 )
411
412 if self._face_data_storage == Storage.CallStack:
416 )
420 )
421 elif self._face_data_storage == Storage.Heap:
425 )
429 )
430 elif self._face_data_storage == Storage.SmartPointers:
434 )
438 )
439 else:
440 assert False, "Storage variant {} not supported".format(
442 )
443
444 # Custom merge implementation takes into account that the faces project such that
445 # the left cell projects to the left half of the face and the right cell projects to the right half.
446 self._rhs_estimates_projection.generator.merge_method_definition = (
447 get_face_overlap_merge_implementation(self._rhs_estimates_projection)
448 )
449 self._rhs_estimates_projection.generator.includes += """
450#include "peano4/utils/Loop.h"
451#include "repositories/SolverRepository.h"
452"""
453
454 self._flux_estimates_projection.generator.merge_method_definition = (
455 get_face_overlap_merge_implementation(self._flux_estimates_projection)
456 )
457 self._flux_estimates_projection.generator.includes += """
458#include "peano4/utils/Loop.h"
459#include "repositories/SolverRepository.h"
460"""
461
462 self._current_time_step.generator.load_store_compute_flag = "::peano4::grid::constructLoadStoreComputeFlag({},{},{})".format(
466 )
467
468 self._previous_time_step.generator.load_store_compute_flag = "::peano4::grid::constructLoadStoreComputeFlag({},{},{})".format(
472 )
473
474 self._rhs_estimates_projection.generator.load_store_compute_flag = "::peano4::grid::constructLoadStoreComputeFlag({},{},{})".format(
478 )
479
480 # Gets overwritten in subclasses to take into account when to send or receive faces
481 self._rhs_estimates_projection.generator.send_condition = "false"
482 self._rhs_estimates_projection.generator.receive_and_merge_condition = "false"
483
484 self._flux_estimates_projection.generator.load_store_compute_flag = "::peano4::grid::constructLoadStoreComputeFlag({},{},{})".format(
488 )
489
490 self._flux_estimates_projection.generator.send_condition = "false"
491 self._flux_estimates_projection.generator.receive_and_merge_condition = "false"
492
493 self._current_time_step.generator.includes += """
494#include "../repositories/SolverRepository.h"
495"""
496
497 self._previous_time_step.generator.includes += """
498#include "../repositories/SolverRepository.h"
499"""
500
501 self._rhs_estimates_projection.generator.includes += """
502#include "../repositories/SolverRepository.h"
503"""
504
505 self._flux_estimates_projection.generator.includes += """
506#include "../repositories/SolverRepository.h"
507"""
508
509 self._cell_label = exahype2.grid.create_cell_label(self._name)
510 self._face_label = exahype2.grid.create_face_label(self._name)
511
512 """
513 Creates the action sets, these are actions tied to the grid that are executed at given points of
514 grid generation, construction or steps of the ADER-DG solver. Peano handles grid structures that
515 contain data as well as operations that are executed on that data. These are the latter.
516 The guard here are the conditions for the execution of the operation, as in they are only executed
517 if the guard evaluates to true.
518 """
519 @abstractmethod
521 # Updates faces and cells (whether at boundary, refined etc.)
524 self._action_set_update_face_label.descend_invocation_order = 0
525 self._action_set_update_cell_label.descend_invocation_order = 0
526
527 # Sets initial conditions for the solution
529 self, self._store_cell_data_default_guard(), "true"
530 )
531 self._action_set_initial_conditions.descend_invocation_order = 1
532
534 self, self._store_cell_data_default_guard(), "false"
535 )
536 self._action_set_initial_conditions_for_grid_construction.descend_invocation_order = 1
537
540 )
541 self._action_set_handle_boundary.descend_invocation_order = 1
542
544 solver=self,
545 delete_guard=self._delete_face_data_default_guard(),
546 interpolate_guard=self._interpolate_face_data_default_guard(),
547 restrict_guard=self._restrict_face_data_default_guard(),
548 )
550
551 # All the actual computation of the solution happens in the prediction and correction action sets.
552 # Predictor extrapolates the solution from time t onto time-nodes, then projects this
553 # extrapolated solution to the faces.
554 # Correction uses the extrapolated face solutions from the predictor and the neighboring
555 # cells to compute a solution at the next timestep.
558 self._action_set_correction.descend_invocation_order = 2 # Needs to happen after handle_boundary
559
561 self, self._store_cell_data_default_guard(), on_hanging_cells=False)
562 self._action_set_prediction.descend_invocation_order = 3
563
565 self, self._store_cell_data_default_guard(), on_hanging_cells=True)
566 self._action_set_prediction_on_hanging_cells.descend_invocation_order = 3
567
568 # Handles adaptive mesh refinement
570 solver=self,
572 + " and (repositories::"
574 + ".isFirstGridSweepOfTimeStep() or repositories::"
576 + ".getSolverState()=="
577 + self._name
578 + "::SolverState::GridInitialisation)",
579 build_up_new_refinement_instructions=True,
580 called_by_grid_construction=False,
581 implement_previous_refinement_instructions=True
582 )
583 self._action_set_AMR.descend_invocation_order = 4
584
586 solver=self,
588 build_up_new_refinement_instructions=False,
589 implement_previous_refinement_instructions=True,
590 called_by_grid_construction=False,
591 )
592 self._action_set_AMR_commit_without_further_analysis.descend_invocation_order = 4
593
595 solver=self,
597 build_up_new_refinement_instructions=True,
598 implement_previous_refinement_instructions=True,
599 called_by_grid_construction=True,
600 )
601 self._action_set_AMR_throughout_grid_construction.descend_invocation_order = 4
602
603 if self._action_set_postprocess_solution == None:
605 self._action_set_postprocess_solution.descend_invocation_order = 4
606
607 def create_readme_descriptor(self, domain_offset, domain_size):
608 return (
609 """ ExaHyPE 2 ADER-DG solver of order: """
610 + str(self._order)
611 + """ with a domain size of: """
612 + str(domain_size)
613 + """ and a domain offset of: """
614 + str(domain_offset)
615 )
616
621 return self.user_solver_includes
622
624 """
625 Add further includes to this property, if your action sets require some additional
626 routines from other header files.
627 """
628 self.user_action_set_includes += value
629
630 def add_user_solver_includes(self, value):
631 """
632 Add further includes to this property, if your solver requires some additional
633 routines from other header files.
634 """
635 self.user_solver_includes += value
636
638 return (
639 "not marker.willBeRefined() "
640 + "and repositories::"
642 + ".getSolverState()!="
643 + self._name
644 + "::SolverState::GridConstruction"
645 )
646
648 return (
649 "not marker.willBeRefined() "
650 + "and repositories::"
652 + ".getSolverState()!="
653 + self._name
654 + "::SolverState::GridConstruction"
655 )
656
658 return (
659 "not marker.willBeRefined() "
660 + "and repositories::"
662 + ".getSolverState()!="
663 + self._name
664 + "::SolverState::GridConstruction"
665 )
666
668 return (
669 "not marker.hasBeenRefined() "
670 + "and repositories::"
672 + ".getSolverState()!="
673 + self._name
674 + "::SolverState::GridConstruction "
675 + "and repositories::"
677 + ".getSolverState()!="
678 + self._name
679 + "::SolverState::GridInitialisation"
680 )
681
683 return (
684 "not marker.willBeRefined() "
685 + "and repositories::"
687 + ".getSolverState()!="
688 + self._name
689 + "::SolverState::GridConstruction"
690 )
691
693 return (
694 "not marker.hasBeenRefined() "
695 + "and repositories::"
697 + ".getSolverState()!="
698 + self._name
699 + "::SolverState::GridConstruction "
700 + "and repositories::"
702 + ".getSolverState()!="
703 + self._name
704 + "::SolverState::GridInitialisation"
705 )
706
708 return (
710 + " and not repositories::"
712 + ".PeriodicBC[marker.getSelectedFaceNumber()%Dimensions]"
713 + " and not marker.hasBeenRefined() and fineGridFace"
714 + self._name
715 + "FaceLabel.getBoundary()"
716 )
717
719 return "true"
720
722 return (
723 "repositories::"
725 + ".getSolverState()!="
726 + self._name
727 + "::SolverState::GridInitialisation"
728 )
729
731 return "true"
732
734 return self._name + "Q"
735
737 return "instanceOf" + self._name
738
740 return """
741#include "tarch/la/Vector.h"
742
743#include "peano4/utils/Globals.h"
744#include "peano4/utils/Loop.h"
745
746#include "repositories/SolverRepository.h"
747""" + "#include <stdfloat>" if self._use_half_precision else ""
748
749 """
750 The following functions will be called by the Peano 4 project,
751 they tell Peano which of our generated data it should attach
752 to each grid element and use.
753 """
754 def add_to_Peano4_datamodel(self, datamodel, verbose):
755 if verbose:
756 print("Patch data")
757 print("----------")
758 print(str(self._current_time_step))
759 print("Patch overlap data")
760 print("----------")
761 print(str(self._rhs_estimates_projection))
762 print(str(self._flux_estimates_projection))
763 datamodel.add_cell(self._cell_label)
764 datamodel.add_cell(self._current_time_step)
765 datamodel.add_cell(self._previous_time_step)
766 datamodel.add_face(self._face_label)
767 datamodel.add_face(self._rhs_estimates_projection)
768 datamodel.add_face(self._flux_estimates_projection)
769
771 step.use_cell(self._cell_label)
772 step.use_cell(self._current_time_step)
773 step.use_cell(self._previous_time_step)
774 step.use_face(self._face_label)
775 step.use_face(self._rhs_estimates_projection)
776 step.use_face(self._flux_estimates_projection)
777
779 step.add_action_set(self._action_set_initial_conditions)
780 step.add_action_set(self._action_set_update_face_label)
781 step.add_action_set(self._action_set_update_cell_label)
782 step.add_action_set(self._action_set_AMR)
783 step.add_action_set(self._action_set_postprocess_solution)
784
785 def add_actions_to_create_grid(self, step, evaluate_refinement_criterion):
787 step.add_action_set(self._action_set_update_face_label)
788 step.add_action_set(self._action_set_update_cell_label)
789 if evaluate_refinement_criterion:
790 step.add_action_set(self._action_set_AMR_throughout_grid_construction)
791 else:
793
794 def add_actions_to_plot_solution(self, step, output_path):
795 d = {}
798
799 step.add_action_set(self._action_set_update_face_label)
800 step.add_action_set(self._action_set_update_cell_label)
801
802 mapping = []
803 for z in self._basis.quadrature_points():
804 for y in self._basis.quadrature_points():
805 for x in self._basis.quadrature_points():
806 mapping.append((x, y, z))
807
808 # Calls a generator which generates a standard plotter that uses the tarch library.
809 step.add_action_set(
811 filename=output_path + "solution-" + self._name,
812 patch=self._previous_time_step,
813 dataset_name=self._unknown_identifier()+"_old",
814 description=self.plot_description,
815 mapping=mapping,
816 select_dofs=self.select_dofs_to_print,
817 guard="repositories::plotFilter.plotPatch(marker) and "
819 additional_includes="""
820#include "exahype2/PlotFilter.h"
821#include "../repositories/SolverRepository.h"
822""",
823 precision="PlotterPrecision",
824 time_stamp_evaluation="0.5*(repositories::getMinTimeStamp()+repositories::getMaxTimeStamp())",
825 plot_cell_data=False,
827 )
828 )
829
831
832 if self._plot_grid_properties:
833 step.add_action_set(
835 filename=output_path + "grid-" + self._name,
836 cell_unknown=None,
837 guard_guard="repositories::plotFilter.plotPatch(marker) and "
839 additional_includes="""
840#include "exahype2/PlotFilter.h"
841#include "../repositories/SolverRepository.h"
842""",
843 plot_cell_data=False,
844 )
845 )
846 pass
847
848 # These actions are executed during each time step
850 step.add_action_set(self._action_set_update_face_label)
851 step.add_action_set(self._action_set_update_cell_label)
853
854 step.add_action_set(self._action_set_handle_boundary)
855 step.add_action_set(self._action_set_correction)
856 step.add_action_set(self._action_set_prediction)
857 step.add_action_set(self._action_set_prediction_on_hanging_cells)
858
859 step.add_action_set(self._action_set_AMR)
860 step.add_action_set(self._action_set_postprocess_solution)
861
862 def set_plot_description(self, description):
863 self.plot_description = description
864
865 def _generate_kernels(self, namespace, output, subdirectory, dimensions):
866 if (not self._is_linear) and (
867 self._material_param_implementation != PDETerms.None_Implementation
868 or self._point_sources_implementation != PDETerms.None_Implementation
869 ):
870 raise Exception(
871 "Material parameters and point sources are currently only available for linear generated kernels."
872 )
873
874 d = {}
877 d["DIMENSIONS"] = dimensions
878 d["NUMBER_OF_DOF_3D"] = 1 if dimensions == 2 else d["NUMBER_OF_DOF"]
879 d["FULL_QUALIFIED_SOLVER_NAME"] = "::".join(namespace) + "::" + self._name
880
881 kernels_namespace = namespace + ["kernels", self._name]
882 kernels_output_path = subdirectory + "kernels/" + self._name
883 kernels_templates_prefix = os.path.dirname(os.path.realpath(__file__)) + "/kernels/"
884
885 if not os.path.exists(kernels_output_path):
886 os.makedirs(kernels_output_path)
887
888 generated_kernels = (
890 headfile_template=kernels_templates_prefix + "CellErrorIntegral.template.h",
891 cppfile_template=kernels_templates_prefix + "CellErrorIntegral.template.cpp",
892 classname=kernels_output_path + "/CellErrorIntegral",
893 namespace=kernels_namespace,
894 subdirectory=subdirectory + ".",
895 dictionary=d,
896 default_overwrite=True,
897 apply_iteratively=True,
898 )
899 )
900 output.add(generated_kernels)
901 output.makefile.add_h_file(kernels_output_path + "/CellErrorIntegral.h", generated=True)
902 output.makefile.add_cpp_file(kernels_output_path + "/CellErrorIntegral.cpp", generated=True)
903
904 generated_kernels = (
906 headfile_template=kernels_templates_prefix + "MaxScaledEigenvalue.template.h",
907 cppfile_template=kernels_templates_prefix + "MaxScaledEigenvalue.template.cpp",
908 classname=kernels_output_path + "/MaxScaledEigenvalue",
909 namespace=kernels_namespace,
910 subdirectory=subdirectory + ".",
911 dictionary=d,
912 default_overwrite=True,
913 apply_iteratively=True,
914 )
915 )
916 output.add(generated_kernels)
917 output.makefile.add_h_file(kernels_output_path + "/MaxScaledEigenvalue.h", generated=True)
918 output.makefile.add_cpp_file(kernels_output_path + "/MaxScaledEigenvalue.cpp", generated=True)
919
920 generated_kernels = (
922 headfile_template=kernels_templates_prefix + "FaceIntegral.template.h",
923 cppfile_template=kernels_templates_prefix + "FaceIntegral.template.cpp",
924 classname=kernels_output_path + "/FaceIntegral",
925 namespace=kernels_namespace,
926 subdirectory=subdirectory + ".",
927 dictionary=d,
928 default_overwrite=True,
929 apply_iteratively=True,
930 )
931 )
932 output.add(generated_kernels)
933 output.makefile.add_h_file(kernels_output_path + "/FaceIntegral.h", generated=True)
934 output.makefile.add_cpp_file(kernels_output_path + "/FaceIntegral.cpp", generated=True)
935
936 generated_kernels = (
938 headfile_template=kernels_templates_prefix + "RiemannSolver.template.h",
939 cppfile_template=kernels_templates_prefix + "RiemannSolverLinear.template.cpp" if self._is_linear
940 else kernels_templates_prefix + "RiemannSolverNonlinear.template.cpp",
941 classname=kernels_output_path + "/RiemannSolver",
942 namespace=kernels_namespace,
943 subdirectory=subdirectory + ".",
944 dictionary=d,
945 default_overwrite=True,
946 apply_iteratively=True,
947 )
948 )
949 output.add(generated_kernels)
950 output.makefile.add_h_file(kernels_output_path + "/RiemannSolver.h", generated=True)
951 output.makefile.add_cpp_file(kernels_output_path + "/RiemannSolver.cpp", generated=True)
952
954 kernels_namespace, output, subdirectory, kernels_templates_prefix, kernels_output_path
955 )
957 kernels_namespace, output, subdirectory, kernels_templates_prefix, kernels_output_path
958 )
960 kernels_namespace, output, subdirectory, kernels_templates_prefix, kernels_output_path
961 )
963 kernels_namespace, output, subdirectory, kernels_templates_prefix, kernels_output_path
964 )
966 kernels_namespace, output, subdirectory, kernels_templates_prefix, kernels_output_path
967 )
968
969 if self._point_sources_implementation != PDETerms.None_Implementation:
970 generated_kernels = (
972 headfile_template=kernels_templates_prefix + "PointSources.template.h",
973 cppfile_template=kernels_templates_prefix + "PointSources.template.cpp",
974 classname=kernels_output_path + "/PointSources",
975 namespace=kernels_namespace,
976 subdirectory=subdirectory + ".",
977 dictionary=d,
978 default_overwrite=True,
979 apply_iteratively=True,
980 )
981 )
982 output.add(generated_kernels)
983 output.makefile.add_h_file(kernels_output_path + "/PointSources.h", generated=True)
984 output.makefile.add_cpp_file(kernels_output_path + "/PointSources.cpp", generated=True)
985
986 if self._use_libxsmm:
987 generated_kernels = (
989 headfile_template=kernels_templates_prefix + "Gemms.template.h",
990 cppfile_template=kernels_templates_prefix + "Gemms.template.cpp",
991 classname=kernels_output_path + "/Gemms",
992 namespace=kernels_namespace,
993 subdirectory=subdirectory + ".",
994 dictionary=d,
995 default_overwrite=True,
996 apply_iteratively=True,
997 )
998 )
999 output.add(generated_kernels)
1000 output.makefile.add_h_file(kernels_output_path + "/Gemms.h", generated=True)
1001 output.makefile.add_cpp_file(kernels_output_path + "/Gemms.cpp", generated=True)
1002
1003 """"
1004 This is a very ugly fix that should be replaced asap.
1005 Essentially, the libxsmm kernel generator generates faulty code if
1006 'noarch' is specified. This code works fine except that it contains a
1007 #ifdef which is missing its corresponding #endif.
1008 This code just inserts that missing #endif.
1009 """
1010 if self._use_libxsmm and self._architecture == "noarch":
1011 file = open("kernels/" + self._name + "/FusedSpaceTimePredictorVolumeIntegral_libxsmm.c", "r")
1012 content = file.read()
1013 file.close()
1014 file = open("kernels/" + self._name + "/FusedSpaceTimePredictorVolumeIntegral_libxsmm.c", "w")
1015 content = content.replace("__FILE__)\n", "__FILE__)\n#endif\n")
1016 file.write(content)
1017 file.close()
1018
1019 file = open("kernels/" + self._name + "/AMRRoutines_libxsmm.c", "r")
1020 content = file.read()
1021 file.close()
1022 file = open("kernels/" + self._name + "/AMRRoutines_libxsmm.c", "w")
1023 content = content.replace("__FILE__)\n", "__FILE__)\n#endif\n")
1024 file.write(content)
1025 file.close()
1026
1027 """
1028 This tells Peano to add the solver files to the project. It generates any files that are not
1029 specifically cell or face data or grid actions such as the actionsets.
1030 Currently it generates solver implementation and header files as well as abstract solver
1031 implementation and header files.
1032 In addition to this if the user has specified that they would like to use shortcuts to refer
1033 to their variable (e.g., specified their unknowns or aux. variables through a dict) it generates
1034 a VariableShortcuts file which is then connected to the solver so that users can specify their
1035 variables through name.
1036 """
1037 def add_implementation_files_to_project(self, namespace, output, dimensions, subdirectory=""):
1038 """
1039 The ExaHyPE2 project will call this operation when it sets
1040 up the overall environment.
1041
1042 This routine is typically not invoked by a user.
1043
1044 output: peano4.output.Output
1045 """
1046 templatefile_prefix = os.path.dirname(os.path.realpath(__file__)) + "/"
1047
1048 if self._solver_template_file_class_name is None:
1049 templatefile_prefix += self.__class__.__name__
1050 else:
1051 templatefile_prefix += self._solver_template_file_class_name
1052
1053 if subdirectory:
1054 subdirectory += "/"
1055
1056 abstractHeaderDictionary = {}
1057 implementationDictionary = {}
1058 self._init_dictionary_with_default_parameters(abstractHeaderDictionary)
1059 self._init_dictionary_with_default_parameters(implementationDictionary)
1060 self.add_entries_to_text_replacement_dictionary(abstractHeaderDictionary)
1061 self.add_entries_to_text_replacement_dictionary(implementationDictionary)
1062
1063 generated_abstract_header_file = (
1065 templatefile_prefix + "Abstract.template.h",
1066 templatefile_prefix + "Abstract.template.cpp",
1067 "Abstract" + self._name,
1068 namespace,
1069 subdirectory + ".",
1070 abstractHeaderDictionary,
1071 True,
1072 True,
1073 )
1074 )
1075 generated_solver_files = (
1077 templatefile_prefix + ".template.h",
1078 templatefile_prefix + ".template.cpp",
1079 self._name,
1080 namespace,
1081 subdirectory + ".",
1082 implementationDictionary,
1083 False,
1084 True,
1085 )
1086 )
1087
1088 output.add(generated_abstract_header_file)
1089 output.add(generated_solver_files)
1090 output.makefile.add_h_file(subdirectory + "Abstract" + self._name + ".h", generated=True)
1091 output.makefile.add_h_file(subdirectory + self._name + ".h", generated=True)
1092 output.makefile.add_cpp_file(subdirectory + "Abstract" + self._name + ".cpp", generated=True)
1093 output.makefile.add_cpp_file(subdirectory + self._name + ".cpp", generated=True)
1094
1095 if self._use_var_shortcut:
1096 generated_shortcut_file = peano4.output.Jinja2TemplatedHeaderFile(
1097 os.path.dirname(os.path.realpath(__file__))
1098 + "/"
1099 + "../VariableShortcuts.template.h",
1100 "VariableShortcuts",
1101 namespace,
1102 subdirectory + ".",
1103 implementationDictionary,
1104 True,
1105 True,
1106 )
1107 output.add(generated_shortcut_file)
1108 output.makefile.add_h_file(subdirectory + "VariableShortcuts.h", generated=True)
1109
1110 self._generate_kernels(namespace, output, subdirectory, dimensions)
1111
1112 def set_solver_constants(self, datastring):
1113 self._solver_constants = datastring
1114
1115 def add_solver_constants(self, datastring):
1116 self._solver_constants += datastring
1117
1118 @property
1119 def order(self):
1120 return self._order
1121
1122 @property
1123 def unknowns(self):
1124 return self._unknowns
1125
1126 @property
1128 return self._auxiliary_variables
1129
1130 @property
1134 @preprocess_reconstructed_patch.setter
1138 self.create_action_sets()
1139
1140 @property
1144 @postprocess_updated_patch.setter
1145 def postprocess_updated_patch(self, kernel):
1146 self._postprocess_updated_patch = kernel
1148 self.create_action_sets()
1149
1150 @abstractmethod
1154 """
1155 Generates a dictionary of "words" that will later be used in various templates to fill these out by adding
1156 information from the solver or which was specified by the user.
1157 """
1159 d["SOLVER_INSTANCE"] = self.get_name_of_global_instance()
1160 d["SOLVER_NAME"] = self._name
1161 d["UNKNOWN_IDENTIFIER"] = self._unknown_identifier()
1162
1163 d["ALIGNMENT"] = Architectures.get_alignment(self._architecture)
1164 d["SIMD_WIDTH"] = Architectures.get_simd_width(self._architecture)
1165 d["ORDER"] = self._order
1166 d["NUMBER_OF_DOF"] = self._order + 1
1167 d["NUMBER_OF_DOF_PADDED"] = Architectures.get_size_with_padding(self._architecture, self._order + 1)
1168 d["NUMBER_OF_UNKNOWNS"] = self._unknowns
1169 d["NUMBER_OF_UNKNOWNS_PADDED"] = Architectures.get_size_with_padding(self._architecture, self._unknowns)
1170 d["NUMBER_OF_AUXILIARY_VARIABLES"] = self._auxiliary_variables
1171 d["NUMBER_OF_AUXILIARY_VARIABLES_PADDED"] = Architectures.get_size_with_padding(self._architecture, self._auxiliary_variables)
1172 d["NUMBER_OF_DATA"] = self._unknowns + self._auxiliary_variables
1173 d["NUMBER_OF_DATA_PADDED"] = Architectures.get_size_with_padding(self._architecture, self._unknowns + self._auxiliary_variables)
1174
1175 d["CFL_SAFETY_FACTOR"] = self._cflSafetyFactor
1176 d["CFL_ADER"] = self._cflAder[self._order] # /(2*(self._order+1)+1)
1177
1178 d["USE_HALF_PRECISION"] = self._use_half_precision
1179 d["IS_LINEAR"] = self._is_linear
1180 d["LINEARITY"] = "linear" if self._is_linear else "nonlinear"
1181
1182 d["USE_GAUSS_LOBATTO"] = ( "true" if self._polynomials is Polynomials.Gauss_Lobatto else "false" )
1183 d["POLYNOMIAL_TYPE"] = ( "lobatto" if self._polynomials is Polynomials.Gauss_Lobatto else "legendre" )
1184
1185 d["SOLUTION_STORAGE_PRECISION"] = self._solution_persistent_storage_precision
1186
1187 d["PREDICTOR_COMPUTATION_PRECISIONS"] = self._predictor_computation_precisions
1188 d["CORRECTOR_COMPUTATION_PRECISION"] = self._corrector_computation_precision
1189
1190 d["COMPUTATION_PRECISIONS"] = self._predictor_computation_precisions[:]
1191 if self._corrector_computation_precision not in d["COMPUTATION_PRECISIONS"]:
1192 d["COMPUTATION_PRECISIONS"].append(self._corrector_computation_precision)
1193 if self._precompute_picard_precision!=False and self._precompute_picard_precision not in d["COMPUTATION_PRECISIONS"]:
1194 d["COMPUTATION_PRECISIONS"].append(self._precompute_picard_precision)
1195 d["NUMBER_OF_PREDICTOR_PRECISIONS"] = len(d["PREDICTOR_COMPUTATION_PRECISIONS"])
1196 d["NUMBER_OF_PRECISIONS"] = len(d["COMPUTATION_PRECISIONS"])
1197
1198 if self._min_cell_h > self._max_cell_h:
1199 raise Exception("min/max h are inconsistent")
1200 d["MAX_CELL_H"] = self._max_cell_h
1201 d["MIN_CELL_H"] = self._min_cell_h
1202
1203 d["SOLVER_CONSTANTS"] = self._solver_constants
1204 d["SOLVER_INCLUDES"] = self.get_user_solver_includes()
1205
1206 d["BOUNDARY_CONDITIONS_IMPLEMENTATION"] = self._boundary_conditions_implementation
1207 d["REFINEMENT_CRITERION_IMPLEMENTATION"] = self._refinement_criterion_implementation
1208 d["INITIAL_CONDITIONS_IMPLEMENTATION"] = self._initial_conditions_implementation
1209 d["ADAPTIVE_PRECISION_IMPLEMENTATION"] = self._precision_criterion_implementation
1210 d["RIEMANN_SOLVER_IMPLEMENTATION"] = self._riemann_solver_implementation
1211
1212 d["ABSTRACT_SOLVER_USER_DECLARATIONS"] = jinja2.Template(
1213 self._abstract_solver_user_declarations, undefined=jinja2.DebugUndefined
1214 ).render(**d)
1215 d["ABSTRACT_SOLVER_USER_DEFINITIONS"] = jinja2.Template(
1216 self._abstract_solver_user_definitions, undefined=jinja2.DebugUndefined
1217 ).render(**d)
1218 d["SOLVER_USER_DECLARATIONS"] = jinja2.Template(
1219 self._solver_user_declarations, undefined=jinja2.DebugUndefined
1220 ).render(**d)
1221 d["SOLVER_USER_DEFINITIONS"] = jinja2.Template(
1222 self._solver_user_definitions, undefined=jinja2.DebugUndefined
1223 ).render(**d)
1224
1225 d["START_TIME_STEP_IMPLEMENTATION"] = jinja2.Template(
1226 self._start_time_step_implementation, undefined=jinja2.DebugUndefined
1227 ).render(**d)
1228 d["FINISH_TIME_STEP_IMPLEMENTATION"] = jinja2.Template(
1229 self._finish_time_step_implementation, undefined=jinja2.DebugUndefined
1230 ).render(**d)
1231
1232 d["CONSTRUCTOR_IMPLEMENTATION"] = jinja2.Template(
1233 self._constructor_implementation, undefined=jinja2.DebugUndefined
1234 ).render(**d)
1235 d["DESTRUCTOR_IMPLEMENTATION"] = jinja2.Template(
1236 self._destructor_implementation, undefined=jinja2.DebugUndefined
1237 ).render(**d)
1238 d["COMPUTE_TIME_STEP_SIZE"] = jinja2.Template(
1239 self._compute_time_step_size, undefined=jinja2.DebugUndefined
1240 ).render(**d)
1241 d["COMPUTE_NEW_TIME_STEP_SIZE"] = jinja2.Template(
1242 self._compute_new_time_step_size, undefined=jinja2.DebugUndefined
1243 ).render(**d)
1244
1245 d["PREPROCESS_RECONSTRUCTED_PATCH"] = jinja2.Template(
1246 self._preprocess_reconstructed_patch, undefined=jinja2.DebugUndefined
1247 ).render(**d)
1248 d["POSTPROCESS_UPDATED_PATCH"] = jinja2.Template(
1249 self._postprocess_updated_patch, undefined=jinja2.DebugUndefined
1250 ).render(**d)
1251
1252 d["USE_FLUX"] = self._flux_implementation != PDETerms.None_Implementation
1253 d["USE_NCP"] = self._ncp_implementation != PDETerms.None_Implementation
1254 d["USE_SOURCE"] = self._source_term_implementation != PDETerms.None_Implementation
1255 d["USE_MATERIAL_PARAMETERS"] = self._material_param_implementation != PDETerms.None_Implementation
1256 d["USE_POINT_SOURCE"] = self._point_sources_implementation != PDETerms.None_Implementation
1257 d["NUMBER_OF_POINT_SOURCES"] = self._number_of_point_sources
1258
1259 d["USE_VARIABLE_SHORTCUT"] = self._use_var_shortcut
1260 d["VARIABLE_NAMES"] = self._variable_names
1261 d["VARIABLE_POSITIONS"] = self._variable_pos
1262
1263 d["QUADRATURE_POINTS"] = ", ".join(self._basis.quadrature_points())
1264
1265 d["USE_LIBXSMM"] = self._use_libxsmm
1266 d["ARCHITECTURE"] = self._architecture
1267
1268 # self._basis.init_dictionary_with_default_parameters(d)
1269
1271 self,
1272 flux,
1273 ncp,
1274 eigenvalues,
1275 boundary_conditions,
1276 refinement_criterion,
1277 initial_conditions,
1278 source_term,
1279 material_parameters,
1280 point_source,
1281 additional_action_set_includes,
1282 additional_user_includes,
1283 ):
1284 """
1285 If you pass in User_Defined, then the generator will create C++ stubs
1286 that you have to befill manually. If you pass in None_Implementation, it
1287 will create nop, i.e., no implementation or defaults. Any other string
1288 is copied 1:1 into the implementation. If you pass in None, then the
1289 set value so far won't be overwritten.
1290 """
1291 if boundary_conditions is not None:
1292 self._boundary_conditions_implementation = boundary_conditions
1293 if refinement_criterion is not None:
1294 self._refinement_criterion_implementation = refinement_criterion
1295 if initial_conditions is not None:
1296 self._initial_conditions_implementation = initial_conditions
1297
1298 if flux is not None:
1299 self._flux_implementation = flux
1300 if ncp is not None:
1301 self._ncp_implementation = ncp
1302 if eigenvalues is not None:
1303 self._eigenvalues_implementation = eigenvalues
1304 if source_term is not None:
1305 self._source_term_implementation = source_term
1306 if material_parameters is not None:
1307 self._material_param_implementation = material_parameters
1308
1309 if type(point_source) != int:
1310 raise Exception(
1311 "point_source needs to be an integer, this determines the number of point sources that will be used."
1312 )
1313
1314 if point_source > 0:
1315 self._point_sources_implementation = PDETerms.User_Defined_Implementation
1316 self._number_of_point_sources = point_source
1317
1318 self.user_action_set_includes += additional_action_set_includes
1319 self.user_solver_includes += additional_user_includes
1320
1322 self.create_action_sets()
1323
1325 self,
1326 is_linear = False,
1327 polynomials = Polynomials.Gauss_Legendre,
1328 use_libxsmm = False,
1329 precision = False,
1330 predictor_computation_precisions = False,
1331 corrector_computation_precision = False,
1332 solution_persistent_storage_precision = False,
1333 precompute_picard_precision = False,
1334 precision_criterion_implementation = PDETerms.User_Defined_Implementation,
1335 riemann_solver_implementation = PDETerms.None_Implementation,
1336 architecture = "noarch",
1337 initialise_patches = False
1338 ):
1339 if polynomials is Polynomials.Gauss_Legendre:
1340 self._basis = GaussLegendreBasis(self._order + 1)
1341 elif polynomials is Polynomials.Gauss_Lobatto:
1342 self._basis = GaussLobattoBasis(self._order + 1)
1343 else:
1344 raise Exception(
1345 "No proper basis chosen: {}, valid options are Gauss_Legendre and Gauss_Lobatto nodes".format(
1346 polynomials
1347 )
1348 )
1349
1350 self._is_linear = is_linear
1351 self._polynomials = polynomials
1352
1353 self._use_libxsmm = use_libxsmm
1354
1355 if precision != False:
1356 if precision not in PrecisionType.keys():
1357 raise AssertionError(
1358 "The chosen precision was not a valid choice. valid choices are: "
1359 + ", ".join(PrecisionType.keys())
1360 )
1361 else:
1362 self._predictor_computation_precisions = [PrecisionType[precision]]
1363 self._precompute_picard_precision = PrecisionType[precision]
1364 self._solution_persistent_storage_precision = PrecisionType[precision]
1365 self._corrector_computation_precision = PrecisionType[precision]
1366
1367 if solution_persistent_storage_precision != False:
1368 if solution_persistent_storage_precision not in PrecisionType.keys():
1369 raise AssertionError(
1370 "The chosen precision was not a valid choice. valid choices are: "
1371 + ", ".join(PrecisionType.keys())
1372 )
1373 self._solution_persistent_storage_precision = PrecisionType[solution_persistent_storage_precision]
1374
1375 if corrector_computation_precision != False:
1376 if corrector_computation_precision not in PrecisionType.keys():
1377 raise AssertionError(
1378 "The chosen precision was not a valid choice. valid choices are: "
1379 + ", ".join(PrecisionType.keys())
1380 )
1381 self._corrector_computation_precision = PrecisionType[corrector_computation_precision]
1382
1383 if precompute_picard_precision != False:
1384 if precompute_picard_precision not in PrecisionType.keys():
1385 raise AssertionError(
1386 "The chosen precision was not a valid choice. valid choices are: "
1387 + ", ".join(PrecisionType.keys())
1388 )
1389 self._precompute_picard_precision = PrecisionType[precompute_picard_precision]
1390
1391 if predictor_computation_precisions != False:
1393 for prec in predictor_computation_precisions:
1394 if prec not in PrecisionType.keys():
1395 raise AssertionError(
1396 "The chosen precision was not a valid choice. valid choices are: "
1397 + ", ".join(PrecisionType.keys())
1398 )
1399 self._predictor_computation_precisions.append(PrecisionType[prec])
1400
1401 if len(self._predictor_computation_precisions) > 1:
1402 self._precision_criterion_implementation = precision_criterion_implementation
1403
1404 if riemann_solver_implementation is not PDETerms.None_Implementation:
1405 self._riemann_solver_implementation = riemann_solver_implementation
1406
1407 self._architecture = architecture
1408
1409 self._initialise_patches = initialise_patches
1410
1412 self.create_action_sets()
1413
1415 self,
1416 cell_data_storage: Storage,
1417 face_data_storage: Storage,
1418 ):
1419 """
1420 By default, we hold all data on the heap using smart pointers. You can explicitly switch
1421 to storage on the call stack or heap using raw pointers.
1422
1423 @see create_data_structures()
1424 """
1425 assert isinstance(cell_data_storage, Storage)
1426 assert isinstance(face_data_storage, Storage)
1427
1428 self._cell_data_storage = cell_data_storage
1429 self._face_data_storage = face_data_storage
1430
1432 self.create_action_sets()
1433
1435 d = {
1436 "OVERLAP": patch_overlap.dim[0]
1437 / 2, # Assumed to always be two, but present here anyway.
1438 "DOFS_PER_AXIS": patch_overlap.dim[1],
1439 "UNKNOWNS": patch_overlap.no_of_unknowns,
1440 }
1441 Template = """
1442 #if Dimensions == 2
1443 constexpr int SpaceFaceSize = {DOFS_PER_AXIS} * {UNKNOWNS}; // Order + 1
1444 #else
1445 constexpr int SpaceFaceSize = {DOFS_PER_AXIS} * {DOFS_PER_AXIS} * {UNKNOWNS}; // (Order + 1)^2
1446 #endif
1447
1448 const int faceDimension = marker.getSelectedFaceNumber() % Dimensions;
1449 // If the outer normal is positive, the normal points to the right so the face is on the right.
1450 const int faceLR = (marker.outerNormal()[faceDimension] > 0.0 ? 0 : 1);
1451
1452 // std::copy_n(from, how_many, to);
1453 std::copy_n(
1454 &neighbour.value[(1 - faceLR) * SpaceFaceSize],
1455 SpaceFaceSize,
1456 &value[(1 - faceLR) * SpaceFaceSize]
1457 );
1458"""
1459 return Template.format(**d)
Update the cell label within a sweep.
Definition CellLabel.py:9
add_actions_to_plot_solution(self, step, output_path)
Definition ADERDG.py:794
set_implementation(self, flux, ncp, eigenvalues, boundary_conditions, refinement_criterion, initial_conditions, source_term, material_parameters, point_source, additional_action_set_includes, additional_user_includes)
If you pass in User_Defined, then the generator will create C++ stubs that you have to befill manuall...
Definition ADERDG.py:1283
create_readme_descriptor(self, domain_offset, domain_size)
Definition ADERDG.py:607
add_user_solver_includes(self, value)
Add further includes to this property, if your solver requires some additional routines from other he...
Definition ADERDG.py:630
add_implementation_files_to_project(self, namespace, output, dimensions, subdirectory="")
The ExaHyPE2 project will call this operation when it sets up the overall environment.
Definition ADERDG.py:1037
add_use_data_statements_to_Peano4_solver_step(self, step)
Definition ADERDG.py:770
__init__(self, name, order, unknowns, auxiliary_variables, min_cell_h, max_cell_h, plot_grid_properties=False)
Definition ADERDG.py:69
add_actions_to_create_grid(self, step, evaluate_refinement_criterion)
Definition ADERDG.py:785
add_solver_constants(self, datastring)
Definition ADERDG.py:1115
set_solver_constants(self, datastring)
Definition ADERDG.py:1112
add_user_action_set_includes(self, value)
Add further includes to this property, if your action sets require some additional routines from othe...
Definition ADERDG.py:623
_generate_kernels(self, namespace, output, subdirectory, dimensions)
Definition ADERDG.py:865
switch_storage_scheme(self, Storage cell_data_storage, Storage face_data_storage)
By default, we hold all data on the heap using smart pointers.
Definition ADERDG.py:1418
_provide_cell_data_to_compute_kernels_default_guard(self)
Definition ADERDG.py:647
add_kernel_optimisations(self, is_linear=False, polynomials=Polynomials.Gauss_Legendre, use_libxsmm=False, precision=False, predictor_computation_precisions=False, corrector_computation_precision=False, solution_persistent_storage_precision=False, precompute_picard_precision=False, precision_criterion_implementation=PDETerms.User_Defined_Implementation, riemann_solver_implementation=PDETerms.None_Implementation, architecture="noarch", initialise_patches=False)
Definition ADERDG.py:1338
_action_set_couple_resolution_transitions_and_handle_dynamic_mesh_refinement
Definition ADERDG.py:543
set_plot_description(self, description)
Definition ADERDG.py:862
_provide_face_data_to_compute_kernels_default_guard(self)
Definition ADERDG.py:657
add_to_Peano4_datamodel(self, datamodel, verbose)
Definition ADERDG.py:754
The linear combination of the Runge-Kutta trials has to be projected onto the faces,...
Definition Correction.py:10
ExaHyPE 2 ADER-DG handling of adaptive meshes.
Definition DynamicAMR.py:9
The linear combination of the Runge-Kutta trials has to be projected onto the faces,...
PostprocessSolution differs from other action sets, as we only create it once.
The extrapolated solution from the space-time predictor has to be projected onto the faces,...
Definition Prediction.py:10
Very simple converter which maps the patch 1:1 onto a double array.
get_face_overlap_merge_implementation(patch_overlap)
Definition ADERDG.py:1434