4from enum
import IntEnum
5from abc
import abstractmethod
10import peano4.datamodel
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
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.
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",
52 "bfloat16_t":
"std::bfloat16_t",
53 "std::bfloat16_t":
"std::bfloat16_t",
68 plot_grid_properties=False,
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
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
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.
99 if type(unknowns)
is dict:
102 for var
in list(unknowns.values()):
105 elif type(unknowns)
is int:
109 "not a valid type for parameter unknowns, needs to be int or dictionary."
112 if type(auxiliary_variables)
is dict:
115 for var
in list(auxiliary_variables.values()):
118 elif type(auxiliary_variables)
is int:
122 "not a valid type for parameter auxiliary_variables, needs to be int or dictionary."
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.
131 if min_cell_h > max_cell_h:
135 +
") is bigger than max_cell_h ("
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.
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.
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.
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
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.
239 0.008821428571428572,
240 0.005235326086956522,
241 0.0031307249999999996,
242 0.0018842326388888888,
243 0.001140285614224138,
244 0.0006933672202620968,
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.
273 + self.__class__.__module__
296Auxiliary variables: """
305Initial conditions: """
308Boundary conditions: """
311Refinement criterion: """
329Number of point sources:"""
335Material parameters: """
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.
408 assert False,
"Storage variant {} not supported".format(
440 assert False,
"Storage variant {} not supported".format(
450#include "peano4/utils/Loop.h"
451#include "repositories/SolverRepository.h"
458#include "peano4/utils/Loop.h"
459#include "repositories/SolverRepository.h"
462 self.
_current_time_step.generator.load_store_compute_flag =
"::peano4::grid::constructLoadStoreComputeFlag({},{},{})".format(
468 self.
_previous_time_step.generator.load_store_compute_flag =
"::peano4::grid::constructLoadStoreComputeFlag({},{},{})".format(
474 self.
_rhs_estimates_projection.generator.load_store_compute_flag =
"::peano4::grid::constructLoadStoreComputeFlag({},{},{})".format(
484 self.
_flux_estimates_projection.generator.load_store_compute_flag =
"::peano4::grid::constructLoadStoreComputeFlag({},{},{})".format(
494#include "../repositories/SolverRepository.h"
498#include "../repositories/SolverRepository.h"
502#include "../repositories/SolverRepository.h"
506#include "../repositories/SolverRepository.h"
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.
572 +
" and (repositories::"
574 +
".isFirstGridSweepOfTimeStep() or repositories::"
576 +
".getSolverState()=="
578 +
"::SolverState::GridInitialisation)",
579 build_up_new_refinement_instructions=
True,
580 called_by_grid_construction=
False,
581 implement_previous_refinement_instructions=
True
588 build_up_new_refinement_instructions=
False,
589 implement_previous_refinement_instructions=
True,
590 called_by_grid_construction=
False,
597 build_up_new_refinement_instructions=
True,
598 implement_previous_refinement_instructions=
True,
599 called_by_grid_construction=
True,
609 """ ExaHyPE 2 ADER-DG solver of order: """
611 +
""" with a domain size of: """
613 +
""" and a domain offset of: """
625 Add further includes to this property, if your action sets require some additional
626 routines from other header files.
632 Add further includes to this property, if your solver requires some additional
633 routines from other header files.
639 "not marker.willBeRefined() "
640 +
"and repositories::"
642 +
".getSolverState()!="
644 +
"::SolverState::GridConstruction"
649 "not marker.willBeRefined() "
650 +
"and repositories::"
652 +
".getSolverState()!="
654 +
"::SolverState::GridConstruction"
659 "not marker.willBeRefined() "
660 +
"and repositories::"
662 +
".getSolverState()!="
664 +
"::SolverState::GridConstruction"
669 "not marker.hasBeenRefined() "
670 +
"and repositories::"
672 +
".getSolverState()!="
674 +
"::SolverState::GridConstruction "
675 +
"and repositories::"
677 +
".getSolverState()!="
679 +
"::SolverState::GridInitialisation"
684 "not marker.willBeRefined() "
685 +
"and repositories::"
687 +
".getSolverState()!="
689 +
"::SolverState::GridConstruction"
694 "not marker.hasBeenRefined() "
695 +
"and repositories::"
697 +
".getSolverState()!="
699 +
"::SolverState::GridConstruction "
700 +
"and repositories::"
702 +
".getSolverState()!="
704 +
"::SolverState::GridInitialisation"
710 +
" and not repositories::"
712 +
".PeriodicBC[marker.getSelectedFaceNumber()%Dimensions]"
713 +
" and not marker.hasBeenRefined() and fineGridFace"
715 +
"FaceLabel.getBoundary()"
725 +
".getSolverState()!="
727 +
"::SolverState::GridInitialisation"
734 return self.
_name +
"Q"
737 return "instanceOf" + self.
_name
741#include "tarch/la/Vector.h"
743#include "peano4/utils/Globals.h"
744#include "peano4/utils/Loop.h"
746#include "repositories/SolverRepository.h"
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.
759 print(
"Patch overlap data")
789 if evaluate_refinement_criterion:
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))
811 filename=output_path +
"solution-" + self.
_name,
817 guard=
"repositories::plotFilter.plotPatch(marker) and "
819 additional_includes=
"""
820#include "exahype2/PlotFilter.h"
821#include "../repositories/SolverRepository.h"
823 precision=
"PlotterPrecision",
824 time_stamp_evaluation=
"0.5*(repositories::getMinTimeStamp()+repositories::getMaxTimeStamp())",
825 plot_cell_data=
False,
835 filename=output_path +
"grid-" + self.
_name,
837 guard_guard=
"repositories::plotFilter.plotPatch(marker) and "
839 additional_includes=
"""
840#include "exahype2/PlotFilter.h"
841#include "../repositories/SolverRepository.h"
843 plot_cell_data=
False,
871 "Material parameters and point sources are currently only available for linear generated kernels."
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
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/"
885 if not os.path.exists(kernels_output_path):
886 os.makedirs(kernels_output_path)
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 +
".",
896 default_overwrite=
True,
897 apply_iteratively=
True,
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)
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 +
".",
912 default_overwrite=
True,
913 apply_iteratively=
True,
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)
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 +
".",
928 default_overwrite=
True,
929 apply_iteratively=
True,
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)
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 +
".",
945 default_overwrite=
True,
946 apply_iteratively=
True,
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)
954 kernels_namespace, output, subdirectory, kernels_templates_prefix, kernels_output_path
957 kernels_namespace, output, subdirectory, kernels_templates_prefix, kernels_output_path
960 kernels_namespace, output, subdirectory, kernels_templates_prefix, kernels_output_path
963 kernels_namespace, output, subdirectory, kernels_templates_prefix, kernels_output_path
966 kernels_namespace, output, subdirectory, kernels_templates_prefix, kernels_output_path
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 +
".",
978 default_overwrite=
True,
979 apply_iteratively=
True,
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)
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 +
".",
995 default_overwrite=
True,
996 apply_iteratively=
True,
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)
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.
1011 file = open(
"kernels/" + self.
_name +
"/FusedSpaceTimePredictorVolumeIntegral_libxsmm.c",
"r")
1012 content = file.read()
1014 file = open(
"kernels/" + self.
_name +
"/FusedSpaceTimePredictorVolumeIntegral_libxsmm.c",
"w")
1015 content = content.replace(
"__FILE__)\n",
"__FILE__)\n#endif\n")
1019 file = open(
"kernels/" + self.
_name +
"/AMRRoutines_libxsmm.c",
"r")
1020 content = file.read()
1022 file = open(
"kernels/" + self.
_name +
"/AMRRoutines_libxsmm.c",
"w")
1023 content = content.replace(
"__FILE__)\n",
"__FILE__)\n#endif\n")
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.
1039 The ExaHyPE2 project will call this operation when it sets
1040 up the overall environment.
1042 This routine is typically not invoked by a user.
1044 output: peano4.output.Output
1046 templatefile_prefix = os.path.dirname(os.path.realpath(__file__)) +
"/"
1048 if self._solver_template_file_class_name
is None:
1049 templatefile_prefix += self.__class__.__name__
1051 templatefile_prefix += self._solver_template_file_class_name
1056 abstractHeaderDictionary = {}
1057 implementationDictionary = {}
1063 generated_abstract_header_file = (
1065 templatefile_prefix +
"Abstract.template.h",
1066 templatefile_prefix +
"Abstract.template.cpp",
1067 "Abstract" + self.
_name,
1070 abstractHeaderDictionary,
1075 generated_solver_files = (
1077 templatefile_prefix +
".template.h",
1078 templatefile_prefix +
".template.cpp",
1082 implementationDictionary,
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)
1097 os.path.dirname(os.path.realpath(__file__))
1099 +
"../VariableShortcuts.template.h",
1100 "VariableShortcuts",
1103 implementationDictionary,
1107 output.add(generated_shortcut_file)
1108 output.makefile.add_h_file(subdirectory +
"VariableShortcuts.h", generated=
True)
1134 @preprocess_reconstructed_patch.setter
1144 @postprocess_updated_patch.setter
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.
1160 d[
"SOLVER_NAME"] = self.
_name
1163 d[
"ALIGNMENT"] = Architectures.get_alignment(self.
_architecture)
1164 d[
"SIMD_WIDTH"] = Architectures.get_simd_width(self.
_architecture)
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
1180 d[
"LINEARITY"] =
"linear" if self.
_is_linear else "nonlinear"
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" )
1195 d[
"NUMBER_OF_PREDICTOR_PRECISIONS"] = len(d[
"PREDICTOR_COMPUTATION_PRECISIONS"])
1196 d[
"NUMBER_OF_PRECISIONS"] = len(d[
"COMPUTATION_PRECISIONS"])
1199 raise Exception(
"min/max h are inconsistent")
1212 d[
"ABSTRACT_SOLVER_USER_DECLARATIONS"] = jinja2.Template(
1215 d[
"ABSTRACT_SOLVER_USER_DEFINITIONS"] = jinja2.Template(
1218 d[
"SOLVER_USER_DECLARATIONS"] = jinja2.Template(
1221 d[
"SOLVER_USER_DEFINITIONS"] = jinja2.Template(
1225 d[
"START_TIME_STEP_IMPLEMENTATION"] = jinja2.Template(
1228 d[
"FINISH_TIME_STEP_IMPLEMENTATION"] = jinja2.Template(
1232 d[
"CONSTRUCTOR_IMPLEMENTATION"] = jinja2.Template(
1235 d[
"DESTRUCTOR_IMPLEMENTATION"] = jinja2.Template(
1238 d[
"COMPUTE_TIME_STEP_SIZE"] = jinja2.Template(
1241 d[
"COMPUTE_NEW_TIME_STEP_SIZE"] = jinja2.Template(
1245 d[
"PREPROCESS_RECONSTRUCTED_PATCH"] = jinja2.Template(
1248 d[
"POSTPROCESS_UPDATED_PATCH"] = jinja2.Template(
1263 d[
"QUADRATURE_POINTS"] =
", ".join(self.
_basis.quadrature_points())
1275 boundary_conditions,
1276 refinement_criterion,
1279 material_parameters,
1281 additional_action_set_includes,
1282 additional_user_includes,
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.
1291 if boundary_conditions
is not None:
1293 if refinement_criterion
is not None:
1295 if initial_conditions
is not None:
1298 if flux
is not None:
1302 if eigenvalues
is not None:
1304 if source_term
is not None:
1306 if material_parameters
is not None:
1309 if type(point_source) != int:
1311 "point_source needs to be an integer, this determines the number of point sources that will be used."
1314 if point_source > 0:
1327 polynomials = Polynomials.Gauss_Legendre,
1328 use_libxsmm = 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
1339 if polynomials
is Polynomials.Gauss_Legendre:
1341 elif polynomials
is Polynomials.Gauss_Lobatto:
1345 "No proper basis chosen: {}, valid options are Gauss_Legendre and Gauss_Lobatto nodes".format(
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())
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())
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())
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())
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())
1404 if riemann_solver_implementation
is not PDETerms.None_Implementation:
1416 cell_data_storage: Storage,
1417 face_data_storage: Storage,
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.
1423 @see create_data_structures()
1425 assert isinstance(cell_data_storage, Storage)
1426 assert isinstance(face_data_storage, Storage)
1436 "OVERLAP": patch_overlap.dim[0]
1438 "DOFS_PER_AXIS": patch_overlap.dim[1],
1439 "UNKNOWNS": patch_overlap.no_of_unknowns,
1443 constexpr int SpaceFaceSize = {DOFS_PER_AXIS} * {UNKNOWNS}; // Order + 1
1445 constexpr int SpaceFaceSize = {DOFS_PER_AXIS} * {DOFS_PER_AXIS} * {UNKNOWNS}; // (Order + 1)^2
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);
1452 // std::copy_n(from, how_many, to);
1454 &neighbour.value[(1 - faceLR) * SpaceFaceSize],
1456 &value[(1 - faceLR) * SpaceFaceSize]
1459 return Template.format(**d)
Update the cell label within a sweep.
_interpolate_face_data_default_guard(self)
add_actions_to_plot_solution(self, step, output_path)
_restrict_face_data_default_guard(self)
_get_default_includes(self)
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...
_load_cell_data_default_guard(self)
create_readme_descriptor(self, domain_offset, domain_size)
_action_set_prediction_on_hanging_cells
get_user_solver_includes(self)
_store_boundary_data_default_guard(self)
add_user_solver_includes(self, value)
Add further includes to this property, if your solver requires some additional routines from other he...
_action_set_update_face_label
add_implementation_files_to_project(self, namespace, output, dimensions, subdirectory="")
The ExaHyPE2 project will call this operation when it sets up the overall environment.
_point_sources_implementation
add_use_data_statements_to_Peano4_solver_step(self, step)
get_user_action_set_includes(self)
_compute_new_time_step_size
create_data_structures(self)
_load_face_data_default_guard(self)
_delete_face_data_default_guard(self)
_number_of_face_projections
_riemann_solver_implementation
get_name_of_global_instance(self)
_finish_time_step_implementation
__init__(self, name, order, unknowns, auxiliary_variables, min_cell_h, max_cell_h, plot_grid_properties=False)
_action_set_initial_conditions
add_actions_to_create_grid(self, step, evaluate_refinement_criterion)
_store_face_data_default_guard(self)
_unknown_identifier(self)
add_solver_constants(self, datastring)
_rhs_estimates_projection
_refinement_criterion_implementation
add_actions_to_perform_time_step(self, step)
set_solver_constants(self, datastring)
_initial_conditions_implementation
add_user_action_set_includes(self, value)
Add further includes to this property, if your action sets require some additional routines from othe...
auxiliary_variables(self)
_flux_estimates_projection
_destructor_implementation
_action_set_AMR_throughout_grid_construction
_preprocess_reconstructed_patch
add_actions_to_init_grid(self, step)
_generate_kernels(self, namespace, output, subdirectory, dimensions)
_postprocess_updated_patch
switch_storage_scheme(self, Storage cell_data_storage, Storage face_data_storage)
By default, we hold all data on the heap using smart pointers.
_provide_cell_data_to_compute_kernels_default_guard(self)
_init_dictionary_with_default_parameters(self, d)
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)
_precision_criterion_implementation
_solver_user_declarations
_action_set_couple_resolution_transitions_and_handle_dynamic_mesh_refinement
_corrector_computation_precision
_action_set_postprocess_solution
_precompute_picard_precision
preprocess_reconstructed_patch(self)
_eigenvalues_implementation
postprocess_updated_patch(self)
_constructor_implementation
set_plot_description(self, description)
_solution_persistent_storage_precision
_source_term_implementation
_store_cell_data_default_guard(self)
_action_set_handle_boundary
_action_set_initial_conditions_for_grid_construction
_abstract_solver_user_declarations
_action_set_update_cell_label
_predictor_computation_precisions
_abstract_solver_user_definitions
add_entries_to_text_replacement_dictionary(self, d)
_material_param_implementation
_action_set_AMR_commit_without_further_analysis
_provide_face_data_to_compute_kernels_default_guard(self)
add_to_Peano4_datamodel(self, datamodel, verbose)
_start_time_step_implementation
_boundary_conditions_implementation
The action set to realise AMR.
The linear combination of the Runge-Kutta trials has to be projected onto the faces,...
ExaHyPE 2 ADER-DG handling of adaptive meshes.
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,...
Realise patch via smart pointers.
Realise patch via smart pointers.
Very simple converter which maps the patch 1:1 onto a double array.
get_face_overlap_merge_implementation(patch_overlap)