24def create_cell_integral_kernel_definitions(namespace, patch_size, unknowns, auxiliary_variables, flux_implementation, ncp_implementation, source_term_implementation, point_source_implementation):
25 if not os.path.exists(
"kernels"):
26 os.makedirs(
"kernels")
28 file = open(
"kernels/dg.h",
"a")
29 file.write(
"""#if Dimensions == 2
30#include "dg_cellIntegral2d.h"
32#include "dg_cellIntegral3d.h"
36 create_cell_integral_kernel_definitions_for_function(exahype2.solvers.rkdg.cellIntegral2d,
"dg_cellIntegral2d", namespace, patch_size, unknowns, auxiliary_variables, flux_implementation, ncp_implementation, source_term_implementation, point_source_implementation)
37 create_cell_integral_kernel_definitions_for_function(exahype2.solvers.rkdg.cellIntegral3d,
"dg_cellIntegral3d", namespace, patch_size, unknowns, auxiliary_variables, flux_implementation, ncp_implementation, source_term_implementation, point_source_implementation)
40 template_parameters = [DSL.SyntaxTree.Argument(
"DGOrder", DSL.SyntaxTree.TInteger()),
41 DSL.SyntaxTree.Argument(
"NumberOfUnknowns", DSL.SyntaxTree.TInteger()),
42 DSL.SyntaxTree.Argument(
"NumberOfAuxiliaryVariables", DSL.SyntaxTree.TInteger()),
43 DSL.SyntaxTree.Argument(
"EvaluateFlux", DSL.SyntaxTree.TBoolean()),
44 DSL.SyntaxTree.Argument(
"EvaluateNonconservativeProduct", DSL.SyntaxTree.TBoolean()),
45 DSL.SyntaxTree.Argument(
"EvaluateSource", DSL.SyntaxTree.TBoolean()),
46 DSL.SyntaxTree.Argument(
"EvaluatePointSources", DSL.SyntaxTree.TBoolean())]
48 functor_arguments = [DSL.SyntaxTree.Argument(
"flux", DSL.SyntaxTree.TCustom(
"const Flux&"),
"(!llvm.ptr, !llvm.ptr, f64, f64, i32, !llvm.ptr) -> ()", is_function=
True),
49 DSL.SyntaxTree.Argument(
"nonconservativeProduct", DSL.SyntaxTree.TCustom(
"const NonConservativeProduct&"),
"(!llvm.ptr, !llvm.ptr, !llvm.ptr, f64, f64, i32, !llvm.ptr) -> ()", is_function=
True),
50 DSL.SyntaxTree.Argument(
"sourceTerm", DSL.SyntaxTree.TCustom(
"const Source&"),
"(!llvm.ptr, !llvm.ptr, f64, f64, !llvm.ptr) -> ()", is_function=
True),
51 DSL.SyntaxTree.Argument(
"pointSource", DSL.SyntaxTree.TCustom(
"const PointSources&"),
"(!llvm.ptr, !llvm.ptr, !llvm.ptr, f64, f64, !llvm.ptr) -> (!llvm.ptr)", is_function=
True),
52 DSL.SyntaxTree.Argument(
"getQuadraturePoint", DSL.SyntaxTree.TCustom(
"const QuadraturePoint&"),
"(index, index, !llvm.ptr, !llvm.ptr, i32, memref<?xf64>, !llvm.ptr) -> ()", is_function=
True),
53 DSL.SyntaxTree.Argument(
"QuadraturePoints1d", DSL.SyntaxTree.TCustom(
"const double*"),
"!llvm.struct<(ptr, ptr, i64, array<1 x i64>, array<1 x i64>)>"),
54 DSL.SyntaxTree.Argument(
"MassMatrixDiagonal1d", DSL.SyntaxTree.TCustom(
"const double*"),
"!llvm.ptr"),
55 DSL.SyntaxTree.Argument(
"StiffnessOperator1d", DSL.SyntaxTree.TCustom(
"const double*"),
"!llvm.ptr"),
56 DSL.SyntaxTree.Argument(
"DerivativeOperator1d", DSL.SyntaxTree.TCustom(
"const double*"),
"!llvm.ptr")]
58 solver_includes =
"""#pragma once
59#include "exahype2/CellData.h"
60#include "exahype2/VolumeIndex.h"
61#include "exahype2/dg/DGUtils.h"
62#include "exahype2/dg/Functors.h"
63#include "peano4/utils/Loop.h"
64#include "tarch/timing/Measurement.h"
65#include "tarch/timing/Watch.h"
68 d[
"KERNEL_NAMESPACE"] = f
"exahype2::dg::{namespace}"
70 d[
"SOLVER_CLASS"] =
"DG"
71 d[
"KERNEL_NAME"] =
"cellIntegral"
72 d[
"SOLVER_INCLUDES"] = solver_includes
73 d[
"SOLVER_CLASS_NAMESPACE"] =
"benchmarks::exahype2::kernelbenchmarks"
75 d[
"PATCH_SIZE"] = patch_size
76 d[
"NUMBER_OF_UNKNOWNS"] = unknowns
77 d[
"NUMBER_OF_AUXILIARY_VARIABLES"] = auxiliary_variables
78 d[
"FLUX_IMPLEMENTATION"] = flux_implementation
79 d[
"NCP_IMPLEMENTATION"] = ncp_implementation
80 d[
"SOURCE_TERM_IMPLEMENTATION"] = source_term_implementation
81 d[
"POINT_SOURCE_IMPLEMENTATION"] = point_source_implementation
84 template_call_jinja =
"""
85 {{SOLVER_CLASS_NAMESPACE}}::{{SOLVER_CLASS}},
87 {{NUMBER_OF_UNKNOWNS}},
88 {{NUMBER_OF_AUXILIARY_VARIABLES}},
89 {% if FLUX_IMPLEMENTATION=="<none>" %} false {% else %} true {% endif %},
90 {% if NCP_IMPLEMENTATION=="<none>" %} false {% else %} true {% endif %},
91 {% if SOURCE_TERM_IMPLEMENTATION=="<none>" %} false {% else %} true {% endif %},
92 {% if POINT_SOURCE_IMPLEMENTATION=="<none>" %} false {% else %} true {% endif %}
94 d[
"TEMPLATE_CALL"] = jinja2.Template(template_call_jinja).render(**d)
96 template_value_definitions_jinja =
"""
97 int DGOrder = {{PATCH_SIZE}};
98 int NumberOfUnknowns = {{NUMBER_OF_UNKNOWNS}};
99 int NumberOfAuxiliaryVariables = {{NUMBER_OF_AUXILIARY_VARIABLES}};
100 bool EvaluateFlux = {% if FLUX_IMPLEMENTATION=="<none>" %} false {% else %} true {% endif %};
101 bool EvaluateNonconservativeProduct = {% if NCP_IMPLEMENTATION=="<none>" %} false {% else %} true {% endif %};
102 bool EvaluateSource = {% if SOURCE_TERM_IMPLEMENTATION=="<none>" %} false {% else %} true {% endif %};
103 bool EvaluatePointSource = {% if POINT_SOURCE_IMPLEMENTATION==False %} false {% else %} true {% endif %};
105 d[
"TEMPLATE_VALUE_DEFINITIONS"] = jinja2.Template(template_value_definitions_jinja).render(**d)
107 bridge_functions_jinja =
"""
108 void flux_bridge(void* Q_ptr, void* x_ptr, double t, double dt, int normal, void* F_ptr) {
109 double* Q = static_cast<double*>(Q_ptr);
110 tarch::la::Vector<Dimensions, double>* x = static_cast<tarch::la::Vector<Dimensions, double>*>(x_ptr);
111 double* F = static_cast<double*>(F_ptr);
112 {{SOLVER_CLASS_NAMESPACE}}::Abstract{{SOLVER_CLASS}}::flux(Q, *x, t, dt, normal, F, OffloadableType::Yes);
115 void nonconservativeProduct_bridge(void* Q_ptr, void* deltaQ_ptr, void* x_ptr, double t, double dt, int normal, void* result_ptr) {
116 double* Q = static_cast<double*>(Q_ptr);
117 double* deltaQ = static_cast<double*>(deltaQ_ptr);
118 tarch::la::Vector<Dimensions, double>* x = static_cast<tarch::la::Vector<Dimensions, double>*>(x_ptr);
119 double* result = static_cast<double*>(result_ptr);
120 {{SOLVER_CLASS_NAMESPACE}}::Abstract{{SOLVER_CLASS}}::nonconservativeProduct(Q, deltaQ, *x, t, dt, normal, result, OffloadableType::Yes);
123 void sourceTerm_bridge(void* Q_ptr, void* x_ptr, double t, double dt, void* S_ptr) {
124 double* Q = static_cast<double*>(Q_ptr);
125 tarch::la::Vector<Dimensions, double>* x = static_cast<tarch::la::Vector<Dimensions, double>*>(x_ptr);
126 double* S = static_cast<double*>(S_ptr);
127 {{SOLVER_CLASS_NAMESPACE}}::Abstract{{SOLVER_CLASS}}::sourceTerm(Q, *x, t, dt, S, OffloadableType::Yes);
130 void pointSource_bridge(void* Q_ptr, void* x_ptr, void* h_ptr,double t, double dt, void* S_ptr) {
131 double* Q = static_cast<double*>(Q_ptr);
132 tarch::la::Vector<Dimensions, double>* x = static_cast<tarch::la::Vector<Dimensions, double>*>(x_ptr);
133 tarch::la::Vector<Dimensions, double>* h = static_cast<tarch::la::Vector<Dimensions, double>*>(h_ptr);
134 double* S = static_cast<double*>(S_ptr);
135 //{{SOLVER_CLASS_NAMESPACE}}::Abstract{{SOLVER_CLASS}}::pointSource(Q, *x, *h, t, dt, S, OffloadableType::Yes);
138 void getQuadraturePoint_bridge(int i, int j, void* x_ptr, void* h_ptr, int polynomialOrder, void* quadraturePoints1D_ptr, void* result_ptr) {
139 auto index = tarch::la::Vector<Dimensions, int>{i, j};
140 tarch::la::Vector<Dimensions, double>* x = static_cast<tarch::la::Vector<Dimensions, double>*>(x_ptr);
141 tarch::la::Vector<Dimensions, double>* h = static_cast<tarch::la::Vector<Dimensions, double>*>(h_ptr);
142 double* positions = static_cast<double*>(result_ptr);
144 //{{SOLVER_CLASS_NAMESPACE}}::Abstract{{SOLVER_CLASS}}::getQuadraturePoint(index, *x, *h, {{SOLVER_CLASS_NAMESPACE}}::Abstract{{SOLVER_CLASS}}::DGOrder, {{SOLVER_CLASS_NAMESPACE}}::Abstract{{SOLVER_CLASS}}::QuadraturePoints1d, positions, OffloadableType::Yes);
147 d[
"BRIDGE_FUNCTIONS"] = jinja2.Template(bridge_functions_jinja).render(**d)
149 d[
"EXTERN_FUNCTION_ARGUMENT_DEFINITIONS"] =
"""
150 void (*flux_fn)(void*, void*, double, double, int, void*),
151 void (*ncp_fn)(void*, void*, void*, double, double, int, void*),
152 void (*source_fn)(void*, void*, double, double, void*),
153 void (*point_source_fn)(void*, void*, void*, double, double, void*),
154 void (*quadrature_points_fn)(int, int, void*, void*, int, void*, void*),
161 DSL.create_kernel_definitions(
167 [
"exahype2",
"dg", namespace],
173def create_abstract_solver_declarations(
176 eigenvalues_implementation,
177 source_term_implementation,
178 point_source_implementation,
179 pde_terms_without_state,
181 Template = jinja2.Template(
184 {% if EIGENVALUES_IMPLEMENTATION=="<none>" or EIGENVALUES_IMPLEMENTATION=="<empty>" %}
185 #error Eigenvalue implementation cannot be none or empty
188 {% if EIGENVALUES_IMPLEMENTATION!="<user-defined>" and STATELESS_PDE_TERMS %}
190 * Depending on the implementation, this variant might be slow as it
191 * lacks an inline define. Also, if you don't want to use ipo aggressively,
192 * it might be clever to put the implementation into the header.
194 #if defined(GPUOffloadingOMP)
195 #pragma omp declare target
197 static void maxEigenvalue(
198 const double * __restrict__ Q, // Q[{{NUMBER_OF_UNKNOWNS}}+{{NUMBER_OF_AUXILIARY_VARIABLES}}],
199 const tarch::la::Vector<Dimensions,double>& faceCentre,
203 double* maxEigenvalue,
206 #if defined(GPUOffloadingOMP)
207 #pragma omp end declare target
212 * Determine max eigenvalue over Jacobian in a given point with solution values
213 * (states) Q. All parameters are in.
215 * @return Max eigenvalue. Result has to be positive, so we are actually speaking
216 * about the maximum absolute eigenvalue.
218 virtual void maxEigenvalue(
219 const double * __restrict__ Q, // Q[{{NUMBER_OF_UNKNOWNS}}+{{NUMBER_OF_AUXILIARY_VARIABLES}}],
220 const tarch::la::Vector<Dimensions,double>& faceCentre,
224 double* maxEigenvalue
225 ) {% if EIGENVALUES_IMPLEMENTATION=="<user-defined>" %}= 0{% else %} final{% endif %};
227 {% if FLUX_IMPLEMENTATION!="<user-defined>" and STATELESS_PDE_TERMS %}
229 * Depending on the implementation, this variant might be slow as it
230 * lacks an inline define. Also, if you don't want to use ipo aggressively,
231 * it might be clever to put the implementation into the header.
233 #if defined(GPUOffloadingOMP)
234 #pragma omp declare target
237 const double * __restrict__ Q, // Q[{{NUMBER_OF_UNKNOWNS}}+{{NUMBER_OF_AUXILIARY_VARIABLES}}],
238 const tarch::la::Vector<Dimensions,double>& faceCentre,
242 double * __restrict__ F, // F[{{NUMBER_OF_UNKNOWNS}}]
245 #if defined(GPUOffloadingOMP)
246 #pragma omp end declare target
250 {% if FLUX_IMPLEMENTATION!="<none>" %}
252 const double * __restrict__ Q, // Q[{{NUMBER_OF_UNKNOWNS}}+{{NUMBER_OF_AUXILIARY_VARIABLES}}],
253 const tarch::la::Vector<Dimensions,double>& faceCentre,
257 double * __restrict__ F // F[{{NUMBER_OF_UNKNOWNS}}]
258 ) {% if FLUX_IMPLEMENTATION=="<user-defined>" %}=0{% else %} final {% endif %};
261 {% if NCP_IMPLEMENTATION!="<user-defined>" and STATELESS_PDE_TERMS %}
263 * Depending on the implementation, this variant might be slow as it
264 * lacks an inline define. Also, if you don't want to use ipo aggressively,
265 * it might be clever to put the implementation into the header.
267 #if defined(GPUOffloadingOMP)
268 #pragma omp declare target
270 static void nonconservativeProduct(
271 const double * __restrict__ Q, // Q[{{NUMBER_OF_UNKNOWNS}}+{{NUMBER_OF_AUXILIARY_VARIABLES}}],
272 const double * __restrict__ deltaQ, // deltaQ[{{NUMBER_OF_UNKNOWNS}}+{{NUMBER_OF_AUXILIARY_VARIABLES}}],
273 const tarch::la::Vector<Dimensions,double>& faceCentre,
277 double * __restrict__ BTimesDeltaQ, // BTimesDeltaQ[{{NUMBER_OF_UNKNOWNS}}]
280 #if defined(GPUOffloadingOMP)
281 #pragma omp end declare target
285 {% if NCP_IMPLEMENTATION!="<none>" %}
286 virtual void nonconservativeProduct(
287 const double * __restrict__ Q, // Q[{{NUMBER_OF_UNKNOWNS}}+{{NUMBER_OF_AUXILIARY_VARIABLES}}],
288 const double * __restrict__ deltaQ, // [{{NUMBER_OF_UNKNOWNS}}+{{NUMBER_OF_AUXILIARY_VARIABLES}}]
289 const tarch::la::Vector<Dimensions,double>& faceCentre,
293 double * __restrict__ BTimesDeltaQ // BTimesDeltaQ[{{NUMBER_OF_UNKNOWNS}}]
294 ) {% if NCP_IMPLEMENTATION=="<user-defined>" %}=0{% endif %};
297 {% if SOURCE_TERM_IMPLEMENTATION!="<user-defined>" and STATELESS_PDE_TERMS %}
299 * Depending on the implementation, this variant might be slow as it
300 * lacks an inline define. Also, if you don't want to use ipo aggressively,
301 * it might be clever to put the implementation into the header.
303 #if defined(GPUOffloadingOMP)
304 #pragma omp declare target
306 static void sourceTerm(
307 const double * __restrict__ Q,
308 const tarch::la::Vector<Dimensions,double>& volumeCentre,
311 double * __restrict__ S,
314 #if defined(GPUOffloadingOMP)
315 #pragma omp end declare target
319 {% if SOURCE_TERM_IMPLEMENTATION!="<none>" %}
320 virtual void sourceTerm(
321 const double * __restrict__ Q,
322 const tarch::la::Vector<Dimensions,double>& volumeCentre,
325 double * __restrict__ S
326 ) {% if SOURCE_TERM_IMPLEMENTATION=="<user-defined>" %}= 0{% else %} final {% endif %};
329 {% if POINT_SOURCE_IMPLEMENTATION!="<user-defined>" and STATELESS_PDE_TERMS %}
331 * Depending on the implementation, this variant might be slow as it
332 * lacks an inline define. Also, if you don't want to use ipo aggressively,
333 * it might be clever to put the implementation into the header.
335 #if defined(GPUOffloadingOMP)
336 #pragma omp declare target
339 const double * __restrict__ Q,
340 const tarch::la::Vector<Dimensions,double>& x,
343 double * __restrict__ S,
346 #if defined(GPUOffloadingOMP)
347 #pragma omp end declare target
351 {% if POINT_SOURCE_IMPLEMENTATION!="<none>" %}
352 virtual void pointSource(
353 const double * __restrict__ Q,
354 const tarch::la::Vector<Dimensions,double>& x,
357 double * __restrict__ S
358 ) {% if SOURCE_TERM_IMPLEMENTATION=="<user-defined>" %}= 0{% else %} final {% endif %};
361 #if defined(GPUOffloadingOMP)
362 #pragma omp declare target
364 static void getQuadraturePoint(
365 const tarch::la::Vector<Dimensions,int>& index,
366 const tarch::la::Vector<Dimensions,double>& cellCentre,
367 const tarch::la::Vector<Dimensions,double>& cellSize,
369 const double* __restrict__ quadraturePoints,
370 tarch::la::Vector<Dimensions,double>* __restrict__ quadraturePositions,
373 #if defined(GPUOffloadingOMP)
374 #pragma omp end declare target
377 #if defined(GPUOffloadingOMP)
378 #pragma omp declare target
380 static void getQuadraturePointInFace(
381 const tarch::la::Vector<Dimensions,int>& index,
382 const tarch::la::Vector<Dimensions,double>& faceCentre,
383 const tarch::la::Vector<Dimensions,double>& cellSize,
386 const double* __restrict__ quadraturePoints,
387 tarch::la::Vector<Dimensions,double>* __restrict__ quadraturePositions,
390 #if defined(GPUOffloadingOMP)
391 #pragma omp end declare target
394 void getQuadraturePoint(
395 const tarch::la::Vector<Dimensions,int>& index,
396 const tarch::la::Vector<Dimensions,double>& cellCentre,
397 const tarch::la::Vector<Dimensions,double>& cellSize,
399 const double* __restrict__ quadraturePoints,
400 tarch::la::Vector<Dimensions,double>* __restrict__ quadraturePositions
403 void getQuadraturePointInFace(
404 const tarch::la::Vector<Dimensions,int>& index,
405 const tarch::la::Vector<Dimensions,double>& faceCentre,
406 const tarch::la::Vector<Dimensions,double>& cellSize,
409 const double* __restrict__ quadraturePoints,
410 tarch::la::Vector<Dimensions,double>* __restrict__ quadraturePositions
413 undefined=jinja2.DebugUndefined,
417 d[
"FLUX_IMPLEMENTATION"] = flux_implementation
418 d[
"NCP_IMPLEMENTATION"] = ncp_implementation
419 d[
"EIGENVALUES_IMPLEMENTATION"] = eigenvalues_implementation
420 d[
"SOURCE_TERM_IMPLEMENTATION"] = source_term_implementation
421 d[
"POINT_SOURCE_IMPLEMENTATION"] = point_source_implementation
422 d[
"STATELESS_PDE_TERMS"] = pde_terms_without_state
423 return Template.render(**d)
426def create_abstract_solver_definitions(
429 eigenvalues_implementation,
430 source_term_implementation,
431 point_source_implementation,
432 pde_terms_without_state,
434 Template = jinja2.Template(
436{% if EIGENVALUES_IMPLEMENTATION!="<user-defined>" and EIGENVALUES_IMPLEMENTATION!="<none>" %}
437void {{FULL_QUALIFIED_NAMESPACE}}::{{CLASSNAME}}::maxEigenvalue(
438 const double * __restrict__ Q, // Q[{{NUMBER_OF_UNKNOWNS}}+{{NUMBER_OF_AUXILIARY_VARIABLES}}],
439 const tarch::la::Vector<Dimensions,double>& faceCentre,
443 double* maxEigenvalue
445 {{EIGENVALUES_IMPLEMENTATION}}
449{% if FLUX_IMPLEMENTATION!="<none>" and FLUX_IMPLEMENTATION!="<user-defined>" %}
450void {{FULL_QUALIFIED_NAMESPACE}}::{{CLASSNAME}}::flux(
451 const double * __restrict__ Q, // Q[{{NUMBER_OF_UNKNOWNS}}+{{NUMBER_OF_AUXILIARY_VARIABLES}}],
452 const tarch::la::Vector<Dimensions,double>& faceCentre,
456 double * __restrict__ F // F[{{NUMBER_OF_UNKNOWNS}}]
458 {{FLUX_IMPLEMENTATION}}
462{% if NCP_IMPLEMENTATION!="<none>" and NCP_IMPLEMENTATION!="<user-defined>" %}
463void {{FULL_QUALIFIED_NAMESPACE}}::{{CLASSNAME}}::nonconservativeProduct(
464 const double * __restrict__ Q, // Q[{{NUMBER_OF_UNKNOWNS}}+{{NUMBER_OF_AUXILIARY_VARIABLES}}],
465 const double * __restrict__ deltaQ, // deltaQ[{{NUMBER_OF_UNKNOWNS}}+{{NUMBER_OF_AUXILIARY_VARIABLES}}]
466 const tarch::la::Vector<Dimensions,double>& faceCentre,
470 double * __restrict__ BTimesDeltaQ // BTimesDeltaQ[{{NUMBER_OF_UNKNOWNS}}]
472 {{NCP_IMPLEMENTATION}}
476{% if SOURCE_TERM_IMPLEMENTATION!="<user-defined>" and SOURCE_TERM_IMPLEMENTATION!="<none>" %}
477void {{FULL_QUALIFIED_NAMESPACE}}::{{CLASSNAME}}::sourceTerm(
478 const double * __restrict__ Q,
479 const tarch::la::Vector<Dimensions,double>& volumeCentre,
482 double * __restrict__ S
484 {% if SOURCE_TERM_IMPLEMENTATION!="<empty>" %}
485 {{SOURCE_TERM_IMPLEMENTATION}}
487 std::fill_n(S,{{NUMBER_OF_UNKNOWNS}},0.0);
492{% if POINT_SOURCE_IMPLEMENTATION!="<user-defined>" and POINT_SOURCE_IMPLEMENTATION!="<none>" %}
493#error Point sources not yet implemented
494void {{FULL_QUALIFIED_NAMESPACE}}::{{CLASSNAME}}::pointSource(
495 const double * __restrict__ Q,
496 const tarch::la::Vector<Dimensions,double>& x,
499 double * __restrict__ S
501 {% if POINT_SOURCE_IMPLEMENTATION!="<empty>" %}
502 {{POINT_SOURCE_IMPLEMENTATION}}
504 std::fill_n(S,{{NUMBER_OF_UNKNOWNS}},0.0);
509{% if EIGENVALUES_IMPLEMENTATION!="<user-defined>" and STATELESS_PDE_TERMS %}
510#if defined(GPUOffloadingOMP)
511#pragma omp declare target
513void {{FULL_QUALIFIED_NAMESPACE}}::{{CLASSNAME}}::maxEigenvalue(
514 const double * __restrict__ Q, // Q[{{NUMBER_OF_UNKNOWNS}}+{{NUMBER_OF_AUXILIARY_VARIABLES}}],
515 const tarch::la::Vector<Dimensions,double>& faceCentre,
519 double* maxEigenvalue,
522 {{EIGENVALUES_IMPLEMENTATION}};
524#if defined(GPUOffloadingOMP)
525#pragma omp end declare target
529{% if FLUX_IMPLEMENTATION!="<user-defined>" and STATELESS_PDE_TERMS %}
530#if defined(GPUOffloadingOMP)
531#pragma omp declare target
533void {{FULL_QUALIFIED_NAMESPACE}}::{{CLASSNAME}}::flux(
534 const double * __restrict__ Q, // Q[{{NUMBER_OF_UNKNOWNS}}+{{NUMBER_OF_AUXILIARY_VARIABLES}}],
535 const tarch::la::Vector<Dimensions,double>& faceCentre,
539 double * __restrict__ F, // F[{{NUMBER_OF_UNKNOWNS}}]
542 {% if FLUX_IMPLEMENTATION=="<none>" %}
545 {{FLUX_IMPLEMENTATION}}
548#if defined(GPUOffloadingOMP)
549#pragma omp end declare target
553{% if NCP_IMPLEMENTATION!="<user-defined>" and STATELESS_PDE_TERMS %}
554#if defined(GPUOffloadingOMP)
555#pragma omp declare target
557void {{FULL_QUALIFIED_NAMESPACE}}::{{CLASSNAME}}::nonconservativeProduct(
558 const double * __restrict__ Q, // Q[{{NUMBER_OF_UNKNOWNS}}+{{NUMBER_OF_AUXILIARY_VARIABLES}}],
559 const double * __restrict__ deltaQ, // deltaQ[{{NUMBER_OF_UNKNOWNS}}+{{NUMBER_OF_AUXILIARY_VARIABLES}}]
560 const tarch::la::Vector<Dimensions,double>& faceCentre,
564 double * __restrict__ BTimesDeltaQ, // BTimesDeltaQ[{{NUMBER_OF_UNKNOWNS}}]
567 {% if NCP_IMPLEMENTATION=="<none>" %}
570 {{NCP_IMPLEMENTATION}}
573#if defined(GPUOffloadingOMP)
574#pragma omp end declare target
578{% if SOURCE_TERM_IMPLEMENTATION!="<user-defined>" and STATELESS_PDE_TERMS %}
579#if defined(GPUOffloadingOMP)
580#pragma omp declare target
582void {{FULL_QUALIFIED_NAMESPACE}}::{{CLASSNAME}}::sourceTerm(
583 const double * __restrict__ Q,
584 const tarch::la::Vector<Dimensions,double>& volumeCentre,
587 double * __restrict__ S,
590 {% if SOURCE_TERM_IMPLEMENTATION=="<none>" %}
593 {{SOURCE_TERM_IMPLEMENTATION}}
596#if defined(GPUOffloadingOMP)
597#pragma omp end declare target
601{% if POINT_SOURCE_IMPLEMENTATION!="<user-defined>" and STATELESS_PDE_TERMS %}
602#if defined(GPUOffloadingOMP)
603#pragma omp declare target
605void {{FULL_QUALIFIED_NAMESPACE}}::{{CLASSNAME}}::pointSource(
606 const double * __restrict__ Q,
607 const tarch::la::Vector<Dimensions,double>& x,
610 double * __restrict__ S,
613 assertionMsg( false, "point sources not implemented yet" );
614 {% if POINT_SOURCE_IMPLEMENTATION=="<none>" %}
617 {{POINT_SOURCE_IMPLEMENTATION}}
620#if defined(GPUOffloadingOMP)
621#pragma omp end declare target
625void {{FULL_QUALIFIED_NAMESPACE}}::{{CLASSNAME}}::getQuadraturePoint(
626 const tarch::la::Vector<Dimensions,int>& index,
627 const tarch::la::Vector<Dimensions,double>& cellCentre,
628 const tarch::la::Vector<Dimensions,double>& cellSize,
630 const double* __restrict__ quadraturePoints,
631 tarch::la::Vector<Dimensions,double>* __restrict__ quadraturePositions,
634 quadraturePositions[0] = ::exahype2::dg::getQuadraturePoint(cellCentre, cellSize, index, polynomialOrder, quadraturePoints);
637void {{FULL_QUALIFIED_NAMESPACE}}::{{CLASSNAME}}::getQuadraturePointInFace(
638 const tarch::la::Vector<Dimensions,int>& index,
639 const tarch::la::Vector<Dimensions,double>& faceCentre,
640 const tarch::la::Vector<Dimensions,double>& cellSize,
643 const double* __restrict__ quadraturePoints,
644 tarch::la::Vector<Dimensions,double>* __restrict__ quadraturePositions,
647 ::exahype2::dg::getQuadraturePointInFace(faceCentre, cellSize, index, polynomialOrder, faceOrientation, quadraturePoints, quadraturePositions);
650void {{FULL_QUALIFIED_NAMESPACE}}::{{CLASSNAME}}::getQuadraturePoint(
651 const tarch::la::Vector<Dimensions,int>& index,
652 const tarch::la::Vector<Dimensions,double>& cellCentre,
653 const tarch::la::Vector<Dimensions,double>& cellSize,
655 const double* __restrict__ quadraturePoints,
656 tarch::la::Vector<Dimensions,double>* __restrict__ quadraturePositions
658 quadraturePositions[0] = ::exahype2::dg::getQuadraturePoint(cellCentre, cellSize, index, polynomialOrder, quadraturePoints);
661void {{FULL_QUALIFIED_NAMESPACE}}::{{CLASSNAME}}::getQuadraturePointInFace(
662 const tarch::la::Vector<Dimensions,int>& index,
663 const tarch::la::Vector<Dimensions,double>& faceCentre,
664 const tarch::la::Vector<Dimensions,double>& cellSize,
667 const double* __restrict__ quadraturePoints,
668 tarch::la::Vector<Dimensions,double>* __restrict__ quadraturePositions
670 ::exahype2::dg::getQuadraturePointInFace(faceCentre, cellSize, index, polynomialOrder, faceOrientation, quadraturePoints, quadraturePositions);
673 undefined=jinja2.DebugUndefined,
677 d[
"FLUX_IMPLEMENTATION"] = flux_implementation
678 d[
"NCP_IMPLEMENTATION"] = ncp_implementation
679 d[
"EIGENVALUES_IMPLEMENTATION"] = eigenvalues_implementation
680 d[
"SOURCE_TERM_IMPLEMENTATION"] = source_term_implementation
681 d[
"POINT_SOURCE_IMPLEMENTATION"] = point_source_implementation
682 d[
"STATELESS_PDE_TERMS"] = pde_terms_without_state
683 return Template.render(**d)
686def create_solver_declarations(
689 eigenvalues_implementation,
690 source_term_implementation,
691 point_source_implementation,
692 pde_terms_without_state,
694 Template = jinja2.Template(
697 {% if SOURCE_TERM_IMPLEMENTATION=="<user-defined>" %}
698 virtual void sourceTerm(
699 const double * __restrict__ Q,
700 const tarch::la::Vector<Dimensions,double>& volumeCentre,
703 double * __restrict__ S
707 {% if POINT_SOURCE_IMPLEMENTATION=="<user-defined>" %}
708 #error point sources not defined yet
709 virtual void pointSource(
710 const double * __restrict__ Q,
711 const tarch::la::Vector<Dimensions,double>& x,
714 double * __restrict__ S
718 {% if EIGENVALUES_IMPLEMENTATION=="<user-defined>" %}
720 * Determine max eigenvalue over Jacobian in a given point with solution values
721 * (states) Q. All parameters are in.
723 * @return Max eigenvalue. Result has to be positive, so we are actually speaking
724 * about the maximum absolute eigenvalue.
726 virtual void maxEigenvalue(
727 const double * __restrict__ Q, // Q[{{NUMBER_OF_UNKNOWNS}}+{{NUMBER_OF_AUXILIARY_VARIABLES}}],
728 const tarch::la::Vector<Dimensions,double>& faceCentre,
732 double* maxEigenvalue
736 {% if FLUX_IMPLEMENTATION=="<user-defined>" %}
738 const double * __restrict__ Q, // Q[{{NUMBER_OF_UNKNOWNS}}+{{NUMBER_OF_AUXILIARY_VARIABLES}}],
739 const tarch::la::Vector<Dimensions,double>& faceCentre,
743 double * __restrict__ F // F[{{NUMBER_OF_UNKNOWNS}}]
747 {% if NCP_IMPLEMENTATION=="<user-defined>" %}
748 virtual void nonconservativeProduct(
749 const double * __restrict__ Q, // Q[{{NUMBER_OF_UNKNOWNS}}+{{NUMBER_OF_AUXILIARY_VARIABLES}}],
750 const double * __restrict__ deltaQ, // deltaQ[{{NUMBER_OF_UNKNOWNS}}+{{NUMBER_OF_AUXILIARY_VARIABLES}}]
751 const tarch::la::Vector<Dimensions,double>& faceCentre,
755 double * __restrict__ BTimesDeltaQ // BTimesDeltaQ[{{NUMBER_OF_UNKNOWNS}}]
759 {% if STATELESS_PDE_TERMS and SOURCE_TERM_IMPLEMENTATION=="<user-defined>" %}
761 * To obtain the best performance, I recommend to man inline command to
762 * this signature and to copy the implementation into the header. So it would
765 * static inline void sourceTerm( ... ) {
769 * The GPU offloading requires static functions. As we cannot overload the
770 * original (virtual) function with a static alternative, we do the
771 * TBB trick and overload by adding an additional enum. It has no semantics
772 * but helps the compiler to distinguish the different function variants.
774 #if defined(GPUOffloadingOMP)
775 #pragma omp declare target
777 static void sourceTerm(
778 const double * __restrict__ Q,
779 const tarch::la::Vector<Dimensions,double>& volumeCentre,
780 const tarch::la::Vector<Dimensions,double>& volumeH,
783 double * __restrict__ S,
786 #if defined(GPUOffloadingOMP)
787 #pragma omp end declare target
791 {% if STATELESS_PDE_TERMS and POINT_SOURCE_IMPLEMENTATION=="<user-defined>" %}
793 * To obtain the best performance, I recommend to man inline command to
794 * this signature and to copy the implementation into the header. So it would
797 * static inline void pointSource( ... ) {
801 * The GPU offloading requires static functions. As we cannot overload the
802 * original (virtual) function with a static alternative, we do the
803 * TBB trick and overload by adding an additional enum. It has no semantics
804 * but helps the compiler to distinguish the different function variants.
806 #error point sources not implemented yet
807 #if defined(GPUOffloadingOMP)
808 #pragma omp declare target
810 static void pointSource(
811 const double * __restrict__ Q,
812 const tarch::la::Vector<Dimensions,double>& volumeCentre,
813 const tarch::la::Vector<Dimensions,double>& volumeH,
816 double * __restrict__ S,
819 #if defined(GPUOffloadingOMP)
820 #pragma omp end declare target
824 {% if EIGENVALUES_IMPLEMENTATION=="<user-defined>" and STATELESS_PDE_TERMS %}
826 * To obtain the best performance, I recommend to man inline command to
827 * this signature and to copy the implementation into the header. So it would
830 * static inline void maxEigenvalue( ... ) {
834 * The GPU offloading requires static functions. As we cannot overload the
835 * original (virtual) function with a static alternative, we do the
836 * TBB trick and overload by adding an additional enum. It has no semantics
837 * but helps the compiler to distinguish the different function variants.
839 #if defined(GPUOffloadingOMP)
840 #pragma omp declare target
842 static void maxEigenvalue(
843 const double * __restrict__ Q, // Q[{{NUMBER_OF_UNKNOWNS}}+{{NUMBER_OF_AUXILIARY_VARIABLES}}],
844 const tarch::la::Vector<Dimensions,double>& faceCentre,
848 double* maxEigenvalue,
851 #if defined(GPUOffloadingOMP)
852 #pragma omp end declare target
856 {% if STATELESS_PDE_TERMS and FLUX_IMPLEMENTATION=="<user-defined>" %}
858 * To obtain the best performance, I recommend to man inline command to
859 * this signature and to copy the implementation into the header. So it would
862 * static inline void flux( ... ) {
866 * The GPU offloading requires static functions. As we cannot overload the
867 * original (virtual) function with a static alternative, we do the
868 * TBB trick and overload by adding an additional enum. It has no semantics
869 * but helps the compiler to distinguish the different function variants.
871 #if defined(GPUOffloadingOMP)
872 #pragma omp declare target
875 const double * __restrict__ Q, // Q[{{NUMBER_OF_UNKNOWNS}}+{{NUMBER_OF_AUXILIARY_VARIABLES}}],
876 const tarch::la::Vector<Dimensions,double>& faceCentre,
880 double * __restrict__ F, // F[{{NUMBER_OF_UNKNOWNS}}]
883 #if defined(GPUOffloadingOMP)
884 #pragma omp end declare target
888 {% if STATELESS_PDE_TERMS and NCP_IMPLEMENTATION=="<user-defined>" %}
890 * To obtain the best performance, I recommend to man inline command to
891 * this signature and to copy the implementation into the header. So it would
894 * static inline void nonconservativeProduct( ... ) {
898 * The GPU offloading requires static functions. As we cannot overload the
899 * original (virtual) function with a static alternative, we do the
900 * TBB trick and overload by adding an additional enum. It has no semantics
901 * but helps the compiler to distinguish the different function variants.
903 #if defined(GPUOffloadingOMP)
904 #pragma omp declare target
906 static void nonconservativeProduct(
907 const double * __restrict__ Q, // Q[5+0],
908 const double * __restrict__ deltaQ, // deltaQ[5+0]
909 const tarch::la::Vector<Dimensions,double>& x,
913 double * __restrict__ BTimesDeltaQ, // BTimesDeltaQ[5]
916 #if defined(GPUOffloadingOMP)
917 #pragma omp end declare target
921 undefined=jinja2.DebugUndefined,
924 d[
"FLUX_IMPLEMENTATION"] = flux_implementation
925 d[
"NCP_IMPLEMENTATION"] = ncp_implementation
926 d[
"EIGENVALUES_IMPLEMENTATION"] = eigenvalues_implementation
927 d[
"SOURCE_TERM_IMPLEMENTATION"] = source_term_implementation
928 d[
"POINT_SOURCE_IMPLEMENTATION"] = point_source_implementation
929 d[
"STATELESS_PDE_TERMS"] = pde_terms_without_state
930 return Template.render(**d)
933def create_solver_definitions(
936 eigenvalues_implementation,
937 source_term_implementation,
938 point_source_implementation,
939 pde_terms_without_state,
941 Template = jinja2.Template(
943{% if EIGENVALUES_IMPLEMENTATION=="<user-defined>" %}
944void {{FULL_QUALIFIED_NAMESPACE}}::{{CLASSNAME}}::maxEigenvalue(
945 const double * __restrict__ Q, // Q[{{NUMBER_OF_UNKNOWNS}}+{{NUMBER_OF_AUXILIARY_VARIABLES}}],
946 const tarch::la::Vector<Dimensions,double>& faceCentre,
950 double* maxEigenvalue
952 logTraceInWith4Arguments( "maxEigenvalue(...)", x, t, dt, normal );
954 logTraceOut( "maxEigenvalue(...)" );
958{% if FLUX_IMPLEMENTATION=="<user-defined>" %}
959void {{FULL_QUALIFIED_NAMESPACE}}::{{CLASSNAME}}::flux(
960 const double * __restrict__ Q, // Q[{{NUMBER_OF_UNKNOWNS}}+{{NUMBER_OF_AUXILIARY_VARIABLES}}],
961 const tarch::la::Vector<Dimensions,double>& faceCentre,
965 double * __restrict__ F // F[{{NUMBER_OF_UNKNOWNS}}]
967 logTraceInWith4Arguments( "flux(...)", faceCentre, t, dt, normal );
969 logTraceOut( "flux(...)" );
973{% if NCP_IMPLEMENTATION=="<user-defined>" %}
974void {{FULL_QUALIFIED_NAMESPACE}}::{{CLASSNAME}}::nonconservativeProduct(
975 const double * __restrict__ Q, // Q[{{NUMBER_OF_UNKNOWNS}}+{{NUMBER_OF_AUXILIARY_VARIABLES}}],
976 const double * __restrict__ deltaQ, // deltaQ[{{NUMBER_OF_UNKNOWNS}}+{{NUMBER_OF_AUXILIARY_VARIABLES}}]
977 const tarch::la::Vector<Dimensions,double>& faceCentre,
981 double * __restrict__ BTimesDeltaQ // BTimesDeltaQ[{{NUMBER_OF_UNKNOWNS}}]
983 logTraceInWith4Arguments( "nonconservativeProduct(...)", faceCentre, t, dt, normal );
985 logTraceOut( "nonconservativeProduct(...)" );
989{% if SOURCE_TERM_IMPLEMENTATION=="<user-defined>" %}
990void {{FULL_QUALIFIED_NAMESPACE}}::{{CLASSNAME}}::sourceTerm(
991 const double * __restrict__ Q, // Q[{{NUMBER_OF_UNKNOWNS}}+{{NUMBER_OF_AUXILIARY_VARIABLES}}]
992 const tarch::la::Vector<Dimensions,double>& volumeCentre,
995 double * __restrict__ S // S[{{NUMBER_OF_UNKNOWNS}}]
997 logTraceInWith3Arguments( "sourceTerm(...)", volumeCentre, t, dt );
999 // @todo implement and ensure that all entries of S are properly set
1000 for (int i=0; i<NumberOfUnknowns; i++) {
1004 logTraceOut( "sourceTerm(...)" );
1008{% if EIGENVALUES_IMPLEMENTATION=="<user-defined>" and STATELESS_PDE_TERMS %}
1009 #if defined(GPUOffloadingOMP)
1010 #pragma omp declare target
1012void {{FULL_QUALIFIED_NAMESPACE}}::{{CLASSNAME}}::maxEigenvalue(
1013 const double * __restrict__ Q, // Q[{{NUMBER_OF_UNKNOWNS}}+{{NUMBER_OF_AUXILIARY_VARIABLES}}],
1014 const tarch::la::Vector<Dimensions,double>& faceCentre,
1018 double* maxEigenvalue,
1023 #if defined(GPUOffloadingOMP)
1024 #pragma omp end declare target
1028{% if FLUX_IMPLEMENTATION=="<user-defined>" and STATELESS_PDE_TERMS %}
1029 #if defined(GPUOffloadingOMP)
1030 #pragma omp declare target
1032void {{FULL_QUALIFIED_NAMESPACE}}::{{CLASSNAME}}::flux(
1033 const double * __restrict__ Q, // Q[{{NUMBER_OF_UNKNOWNS}}+{{NUMBER_OF_AUXILIARY_VARIABLES}}],
1034 const tarch::la::Vector<Dimensions,double>& faceCentre,
1038 double * __restrict__ F,
1043 #if defined(GPUOffloadingOMP)
1044 #pragma omp end declare target
1048{% if NCP_IMPLEMENTATION=="<user-defined>" and STATELESS_PDE_TERMS %}
1049 #if defined(GPUOffloadingOMP)
1050 #pragma omp declare target
1052void {{FULL_QUALIFIED_NAMESPACE}}::{{CLASSNAME}}::nonconservativeProduct(
1053 const double * __restrict__ Q, // Q[{{NUMBER_OF_UNKNOWNS}}+{{NUMBER_OF_AUXILIARY_VARIABLES}}],
1054 const double * __restrict__ deltaQ, // deltaQ[{{NUMBER_OF_UNKNOWNS}}+{{NUMBER_OF_AUXILIARY_VARIABLES}}]
1055 const tarch::la::Vector<Dimensions,double>& faceCentre,
1059 double * __restrict__ BTimesDeltaQ,
1064 #if defined(GPUOffloadingOMP)
1065 #pragma omp end declare target
1069{% if SOURCE_TERM_IMPLEMENTATION=="<user-defined>" and STATELESS_PDE_TERMS %}
1070 #if defined(GPUOffloadingOMP)
1071 #pragma omp declare target
1073void {{FULL_QUALIFIED_NAMESPACE}}::{{CLASSNAME}}::sourceTerm(
1074 const double * __restrict__ Q,
1075 const tarch::la::Vector<Dimensions,double>& volumeCentre,
1078 double * __restrict__ S,
1083 #if defined(GPUOffloadingOMP)
1084 #pragma omp end declare target
1088{% if POINT_SOURCE_IMPLEMENTATION=="<user-defined>" and STATELESS_PDE_TERMS %}
1089 #if defined(GPUOffloadingOMP)
1090 #pragma omp declare target
1092#error point sources not implemented yet
1093void {{FULL_QUALIFIED_NAMESPACE}}::{{CLASSNAME}}::sourceTerm(
1094 const double * __restrict__ Q,
1095 const tarch::la::Vector<Dimensions,double>& volumeCentre,
1098 double * __restrict__ S,
1103 #if defined(GPUOffloadingOMP)
1104 #pragma omp end declare target
1108 undefined=jinja2.DebugUndefined,
1111 d[
"FLUX_IMPLEMENTATION"] = flux_implementation
1112 d[
"NCP_IMPLEMENTATION"] = ncp_implementation
1113 d[
"EIGENVALUES_IMPLEMENTATION"] = eigenvalues_implementation
1114 d[
"SOURCE_TERM_IMPLEMENTATION"] = source_term_implementation
1115 d[
"POINT_SOURCE_IMPLEMENTATION"] = point_source_implementation
1116 d[
"STATELESS_PDE_TERMS"] = pde_terms_without_state
1117 return Template.render(**d)
1182def create_volumetric_solver_call_dsl(polynomial_basis, solver_variant):
1184 A set of default volumetric kernel calls. You might want to use different
1185 solver calls in your code depending on the context.
1187 ## Difference to Finite Volume (FV) implementation
1189 In the FV code base, I need the implementation routines as argument: As we work
1190 with FV, the generic FV class does not know which implementations are around. If
1191 you work with a domain-specific dg solver, e.g., then there is no such
1194 For the DG schemes, things are different: Every DG solver in ExaHyPE 2 in principle
1195 supports the ncp. So the base Python class already instantiates the corresponding
1196 dictionary entries, and we can use them straightaway.
1200 solver_variant: SolverVariant
1201 Picks different implementation variants
1204 isinstance(polynomial_basis, GaussLegendreBasis)
1205 and solver_variant == SolverVariant.WithVirtualFunctions
1207 return """cellIntegral<{{ORDER}},{{NUMBER_OF_UNKNOWNS}},{{NUMBER_OF_AUXILIARY_VARIABLES}},
1208 {{ "true" if FLUX_IMPLEMENTATION!="<none>" else "false" }}, //useFlux
1209 {{ "true" if NCP_IMPLEMENTATION!="<none>" else "false" }}, //useNCP
1210 {{ "true" if SOURCE_TERM_IMPLEMENTATION!="<none>" else "false" }}, //useSource
1211 {{ "true" if POINT_SOURCES_IMPLEMENTATION!="<none>" else "false" }} //usePointSource
1215 const double * __restrict__ Q,
1216 const tarch::la::Vector<Dimensions,double>& x,
1220 double * __restrict__ F
1222 {% if FLUX_IMPLEMENTATION!="<none>" %}
1223 repositories::{{SOLVER_INSTANCE}}.flux(Q,x,t,dt,normal,F);
1227 const double * __restrict__ Q,
1228 const double * __restrict__ deltaQ,
1229 const tarch::la::Vector<Dimensions,double>& faceCentre,
1233 double * __restrict__ F
1235 {% if NCP_IMPLEMENTATION!="<none>" %}
1236 repositories::{{SOLVER_INSTANCE}}.nonconservativeProduct(Q, deltaQ, faceCentre, t, dt, normal, F);
1240 const double * __restrict__ Q,
1241 const tarch::la::Vector<Dimensions,double>& x,
1244 double * __restrict__ S
1246 {% if SOURCE_TERM_IMPLEMENTATION!="<none>" %}
1247 repositories::{{SOLVER_INSTANCE}}.sourceTerm(Q,x,t,dt,S);
1251 const double * __restrict__ Q,
1252 const tarch::la::Vector<Dimensions,double>& cellCentre,
1253 const tarch::la::Vector<Dimensions,double>& cellH,
1256 ) -> std::vector<::exahype2::dg::PointSource> {
1257 {% if POINT_SOURCES_IMPLEMENTATION!="<none>" %}
1258 return repositories::{{SOLVER_INSTANCE}}.pointSources(Q,cellCentre,cellH,t,dt);
1260 return std::vector<::exahype2::dg::PointSource>();
1264 const tarch::la::Vector<Dimensions,int>& index,
1265 const tarch::la::Vector<Dimensions,double>& cellCentre,
1266 const tarch::la::Vector<Dimensions,double>& cellSize,
1267 int polynomialOrder,
1268 const double* __restrict__ quadraturePoints,
1269 tarch::la::Vector<Dimensions,double>* __restrict__ quadraturePositions
1270 ) -> std::vector<::exahype2::dg::PointSource> {
1271 repositories::{{SOLVER_INSTANCE}}.getQuadraturePoint(index, cellCentre, cellSize, polynomialOrder, quadraturePoints, quadraturePositions);
1272 }, //quadraturePoints
1273 repositories::{{SOLVER_INSTANCE}}.QuadraturePoints1d,
1274 repositories::{{SOLVER_INSTANCE}}.MassMatrixDiagonal1d,
1275 repositories::{{SOLVER_INSTANCE}}.StiffnessOperator1d,
1276 repositories::{{SOLVER_INSTANCE}}.DerivativeOperator1d
1280 isinstance(polynomial_basis, GaussLegendreBasis)
1281 and solver_variant == SolverVariant.Stateless
1283 return """cellIntegralStateless<{{SOLVER_NAME}},{{ORDER}},{{NUMBER_OF_UNKNOWNS}},{{NUMBER_OF_AUXILIARY_VARIABLES}},
1284 {{ "true" if FLUX_IMPLEMENTATION!="<none>" else "false" }}, //useFlux
1285 {{ "true" if NCP_IMPLEMENTATION!="<none>" else "false" }}, //useNCP
1286 {{ "true" if SOURCE_TERM_IMPLEMENTATION!="<none>" else "false" }}, //useSource
1287 {{ "true" if POINT_SOURCES_IMPLEMENTATION!="<none>" else "false" }} //usePointSource
1293 isinstance(polynomial_basis, GaussLegendreBasis)
1294 and solver_variant == SolverVariant.Accelerator
1296 return """cellIntegralStateless<{{SOLVER_NAME}},{{ORDER}},{{NUMBER_OF_UNKNOWNS}},{{NUMBER_OF_AUXILIARY_VARIABLES}},
1297 {{ "true" if FLUX_IMPLEMENTATION!="<none>" else "false" }}, //useFlux
1298 {{ "true" if NCP_IMPLEMENTATION!="<none>" else "false" }}, //useNCP
1299 {{ "true" if SOURCE_TERM_IMPLEMENTATION!="<none>" else "false" }}, //useSource
1300 {{ "true" if POINT_SOURCES_IMPLEMENTATION!="<none>" else "false" }} //usePointSource
1302 gpuCellData.targetDevice,
1307 return "#solver variant not implemented yet"
1309def create_volumetric_solver_call(polynomial_basis, solver_variant):
1311 A set of default volumetric kernel calls. You might want to use different
1312 solver calls in your code depending on the context.
1314 ## Difference to Finite Volume (FV) implementation
1316 In the FV code base, I need the implementation routines as argument: As we work
1317 with FV, the generic FV class does not know which implementations are around. If
1318 you work with a domain-specific dg solver, e.g., then there is no such
1321 For the DG schemes, things are different: Every DG solver in ExaHyPE 2 in principle
1322 supports the ncp. So the base Python class already instantiates the corresponding
1323 dictionary entries, and we can use them straightaway.
1327 solver_variant: SolverVariant
1328 Picks different implementation variants
1331 isinstance(polynomial_basis, GaussLegendreBasis)
1332 and solver_variant == SolverVariant.WithVirtualFunctions
1334 return """cellIntegral_patchwise_in_situ_GaussLegendre_functors(
1337 {{NUMBER_OF_UNKNOWNS}},
1338 {{NUMBER_OF_AUXILIARY_VARIABLES}},
1340 const double * __restrict__ Q,
1341 const tarch::la::Vector<Dimensions,double>& x,
1345 double * __restrict__ F
1347 {% if FLUX_IMPLEMENTATION!="<none>" %}
1348 repositories::{{SOLVER_INSTANCE}}.flux(Q,x,t,dt,normal,F);
1352 const double * __restrict__ Q,
1353 const double * __restrict__ deltaQ,
1354 const tarch::la::Vector<Dimensions,double>& faceCentre,
1358 double * __restrict__ F
1360 {% if NCP_IMPLEMENTATION!="<none>" %}
1361 repositories::{{SOLVER_INSTANCE}}.nonconservativeProduct(Q, deltaQ, faceCentre, t, dt, normal, F);
1365 const double * __restrict__ Q,
1366 const tarch::la::Vector<Dimensions,double>& x,
1369 double * __restrict__ S
1371 {% if SOURCE_TERM_IMPLEMENTATION!="<none>" %}
1372 repositories::{{SOLVER_INSTANCE}}.sourceTerm(Q,x,t,dt,S);
1376 const double * __restrict__ Q,
1377 const tarch::la::Vector<Dimensions,double>& cellCentre,
1378 const tarch::la::Vector<Dimensions,double>& cellH,
1381 ) -> std::vector<::exahype2::dg::PointSource> {
1382 {% if POINT_SOURCES_IMPLEMENTATION!="<none>" %}
1383 return repositories::{{SOLVER_INSTANCE}}.pointSources(Q,cellCentre,cellH,t,dt);
1385 return std::vector<::exahype2::dg::PointSource>();
1388 repositories::{{SOLVER_INSTANCE}}.QuadraturePoints1d,
1389 repositories::{{SOLVER_INSTANCE}}.MassMatrixDiagonal1d,
1390 repositories::{{SOLVER_INSTANCE}}.StiffnessOperator1d,
1391 repositories::{{SOLVER_INSTANCE}}.DerivativeOperator1d,
1392 {{ "true" if FLUX_IMPLEMENTATION!="<none>" else "false" }}, //useFlux
1393 {{ "true" if NCP_IMPLEMENTATION!="<none>" else "false" }}, //useNCP
1394 {{ "true" if SOURCE_TERM_IMPLEMENTATION!="<none>" else "false" }}, //useSource
1395 {{ "true" if POINT_SOURCES_IMPLEMENTATION!="<none>" else "false" }} //usePointSource
1399 isinstance(polynomial_basis, GaussLegendreBasis)
1400 and solver_variant == SolverVariant.Stateless
1402 return """cellIntegral_patchwise_in_situ_GaussLegendre<{{SOLVER_NAME}},{{ORDER}},{{NUMBER_OF_UNKNOWNS}},{{NUMBER_OF_AUXILIARY_VARIABLES}}>(
1404 {{ "true" if FLUX_IMPLEMENTATION!="<none>" else "false" }}, //useFlux
1405 {{ "true" if NCP_IMPLEMENTATION!="<none>" else "false" }}, //useNCP
1406 {{ "true" if SOURCE_TERM_IMPLEMENTATION!="<none>" else "false" }}, //useSource
1407 {{ "true" if POINT_SOURCES_IMPLEMENTATION!="<none>" else "false" }} //usePointSource
1411 isinstance(polynomial_basis, GaussLegendreBasis)
1412 and solver_variant == SolverVariant.Accelerator
1414 return """cellIntegral_patchwise_in_situ_GaussLegendre<{{SOLVER_NAME}},{{ORDER}},{{NUMBER_OF_UNKNOWNS}},{{NUMBER_OF_AUXILIARY_VARIABLES}}>(
1417 {{ "true" if FLUX_IMPLEMENTATION!="<none>" else "false" }}, //useFlux
1418 {{ "true" if NCP_IMPLEMENTATION!="<none>" else "false" }}, //useNCP
1419 {{ "true" if SOURCE_TERM_IMPLEMENTATION!="<none>" else "false" }}, //useSource
1420 {{ "true" if POINT_SOURCES_IMPLEMENTATION!="<none>" else "false" }} //usePointSource
1424 return "#solver variant not implemented yet"
create_cell_integral_kernel_definitions_for_function(function, function_name, namespace, patch_size, unknowns, auxiliary_variables, flux_implementation, ncp_implementation, source_term_implementation, point_source_implementation)