14 WithVirtualFunctions = 0
22 eigenvalues_implementation,
23 source_term_implementation,
24 point_source_implementation,
25 pde_terms_without_state,
27 Template = jinja2.Template(
30 {% if EIGENVALUES_IMPLEMENTATION=="<none>" or EIGENVALUES_IMPLEMENTATION=="<empty>" %}
31 #error Eigenvalue implementation cannot be none or empty
34 {% if EIGENVALUES_IMPLEMENTATION!="<user-defined>" and STATELESS_PDE_TERMS %}
36 * Depending on the implementation, this variant might be slow as it
37 * lacks an inline define. Also, if you don't want to use ipo aggressively,
38 * it might be clever to put the implementation into the header.
40 #if defined(OpenMPGPUOffloading)
41 #pragma omp declare target
43 static double maxEigenvalue(
44 const double * __restrict__ Q, // Q[{{NUMBER_OF_UNKNOWNS}}+{{NUMBER_OF_AUXILIARY_VARIABLES}}],
45 const tarch::la::Vector<Dimensions,double>& faceCentre,
49 double* maxEigenvalue,
52 #if defined(OpenMPGPUOffloading)
53 #pragma omp end declare target
58 * Determine max eigenvalue over Jacobian in a given point with solution values
59 * (states) Q. All parameters are in.
61 * @return Max eigenvalue. Result has to be positive, so we are actually speaking
62 * about the maximum absolute eigenvalue.
64 virtual double maxEigenvalue(
65 const double * __restrict__ Q, // Q[{{NUMBER_OF_UNKNOWNS}}+{{NUMBER_OF_AUXILIARY_VARIABLES}}],
66 const tarch::la::Vector<Dimensions,double>& faceCentre,
71 ) {% if EIGENVALUES_IMPLEMENTATION=="<user-defined>" %}= 0{% else %} final{% endif %};
73 {% if FLUX_IMPLEMENTATION!="<user-defined>" and STATELESS_PDE_TERMS %}
75 * Depending on the implementation, this variant might be slow as it
76 * lacks an inline define. Also, if you don't want to use ipo aggressively,
77 * it might be clever to put the implementation into the header.
79 #if defined(OpenMPGPUOffloading)
80 #pragma omp declare target
83 const double * __restrict__ Q, // Q[{{NUMBER_OF_UNKNOWNS}}+{{NUMBER_OF_AUXILIARY_VARIABLES}}],
84 const tarch::la::Vector<Dimensions,double>& faceCentre,
88 double * __restrict__ F, // F[{{NUMBER_OF_UNKNOWNS}}]
91 #if defined(OpenMPGPUOffloading)
92 #pragma omp end declare target
96 {% if FLUX_IMPLEMENTATION!="<none>" %}
98 const double * __restrict__ Q, // Q[{{NUMBER_OF_UNKNOWNS}}+{{NUMBER_OF_AUXILIARY_VARIABLES}}],
99 const tarch::la::Vector<Dimensions,double>& faceCentre,
103 double * __restrict__ F // F[{{NUMBER_OF_UNKNOWNS}}]
104 ) {% if FLUX_IMPLEMENTATION=="<user-defined>" %}=0{% else %} final {% endif %};
107 {% if NCP_IMPLEMENTATION!="<user-defined>" and STATELESS_PDE_TERMS %}
109 * Depending on the implementation, this variant might be slow as it
110 * lacks an inline define. Also, if you don't want to use ipo aggressively,
111 * it might be clever to put the implementation into the header.
113 #if defined(OpenMPGPUOffloading)
114 #pragma omp declare target
116 static void nonconservativeProduct(
117 const double * __restrict__ Q, // Q[{{NUMBER_OF_UNKNOWNS}}+{{NUMBER_OF_AUXILIARY_VARIABLES}}],
118 const double * __restrict__ deltaQ, // deltaQ[{{NUMBER_OF_UNKNOWNS}}+{{NUMBER_OF_AUXILIARY_VARIABLES}}],
119 const tarch::la::Vector<Dimensions,double>& faceCentre,
123 double * __restrict__ BTimesDeltaQ, // BTimesDeltaQ[{{NUMBER_OF_UNKNOWNS}}]
126 #if defined(OpenMPGPUOffloading)
127 #pragma omp end declare target
131 {% if NCP_IMPLEMENTATION!="<none>" %}
132 virtual void nonconservativeProduct(
133 const double * __restrict__ Q, // Q[{{NUMBER_OF_UNKNOWNS}}+{{NUMBER_OF_AUXILIARY_VARIABLES}}],
134 const double * __restrict__ deltaQ, // [{{NUMBER_OF_UNKNOWNS}}+{{NUMBER_OF_AUXILIARY_VARIABLES}}]
135 const tarch::la::Vector<Dimensions,double>& faceCentre,
139 double * __restrict__ BTimesDeltaQ // BTimesDeltaQ[{{NUMBER_OF_UNKNOWNS}}]
140 ) {% if NCP_IMPLEMENTATION=="<user-defined>" %}=0{% endif %};
143 {% if SOURCE_TERM_IMPLEMENTATION!="<user-defined>" and STATELESS_PDE_TERMS %}
145 * Depending on the implementation, this variant might be slow as it
146 * lacks an inline define. Also, if you don't want to use ipo aggressively,
147 * it might be clever to put the implementation into the header.
149 #if defined(OpenMPGPUOffloading)
150 #pragma omp declare target
152 static void sourceTerm(
153 const double * __restrict__ Q,
154 const tarch::la::Vector<Dimensions,double>& volumeCentre,
157 double * __restrict__ S,
160 #if defined(OpenMPGPUOffloading)
161 #pragma omp end declare target
165 {% if SOURCE_TERM_IMPLEMENTATION!="<none>" %}
166 virtual void sourceTerm(
167 const double * __restrict__ Q,
168 const tarch::la::Vector<Dimensions,double>& volumeCentre,
171 double * __restrict__ S
172 ) {% if SOURCE_TERM_IMPLEMENTATION=="<user-defined>" %}= 0{% else %} final {% endif %};
175 {% if POINT_SOURCE_IMPLEMENTATION!="<user-defined>" and STATELESS_PDE_TERMS %}
177 * Depending on the implementation, this variant might be slow as it
178 * lacks an inline define. Also, if you don't want to use ipo aggressively,
179 * it might be clever to put the implementation into the header.
181 #if defined(OpenMPGPUOffloading)
182 #pragma omp declare target
185 const double * __restrict__ Q,
186 const tarch::la::Vector<Dimensions,double>& x,
189 double * __restrict__ S,
192 #if defined(OpenMPGPUOffloading)
193 #pragma omp end declare target
197 {% if POINT_SOURCE_IMPLEMENTATION!="<none>" %}
198 virtual void pointSource(
199 const double * __restrict__ Q,
200 const tarch::la::Vector<Dimensions,double>& x,
203 double * __restrict__ S
204 ) {% if SOURCE_TERM_IMPLEMENTATION=="<user-defined>" %}= 0{% else %} final {% endif %};
207 undefined=jinja2.DebugUndefined,
211 d[
"FLUX_IMPLEMENTATION"] = flux_implementation
212 d[
"NCP_IMPLEMENTATION"] = ncp_implementation
213 d[
"EIGENVALUES_IMPLEMENTATION"] = eigenvalues_implementation
214 d[
"SOURCE_TERM_IMPLEMENTATION"] = source_term_implementation
215 d[
"POINT_SOURCE_IMPLEMENTATION"] = point_source_implementation
216 d[
"STATELESS_PDE_TERMS"] = pde_terms_without_state
217 return Template.render(**d)
223 eigenvalues_implementation,
224 source_term_implementation,
225 point_source_implementation,
226 pde_terms_without_state,
228 Template = jinja2.Template(
230{% if EIGENVALUES_IMPLEMENTATION!="<user-defined>" and EIGENVALUES_IMPLEMENTATION!="<none>" %}
231double {{FULL_QUALIFIED_NAMESPACE}}::{{CLASSNAME}}::maxEigenvalue(
232 const double * __restrict__ Q, // Q[{{NUMBER_OF_UNKNOWNS}}+{{NUMBER_OF_AUXILIARY_VARIABLES}}],
233 const tarch::la::Vector<Dimensions,double>& faceCentre,
237 double* maxEigenvalue
239 {{EIGENVALUES_IMPLEMENTATION}}
243{% if FLUX_IMPLEMENTATION!="<none>" and FLUX_IMPLEMENTATION!="<user-defined>" %}
244void {{FULL_QUALIFIED_NAMESPACE}}::{{CLASSNAME}}::flux(
245 const double * __restrict__ Q, // Q[{{NUMBER_OF_UNKNOWNS}}+{{NUMBER_OF_AUXILIARY_VARIABLES}}],
246 const tarch::la::Vector<Dimensions,double>& faceCentre,
250 double * __restrict__ F // F[{{NUMBER_OF_UNKNOWNS}}]
252 {{FLUX_IMPLEMENTATION}}
256{% if NCP_IMPLEMENTATION!="<none>" and NCP_IMPLEMENTATION!="<user-defined>" %}
257void {{FULL_QUALIFIED_NAMESPACE}}::{{CLASSNAME}}::nonconservativeProduct(
258 const double * __restrict__ Q, // Q[{{NUMBER_OF_UNKNOWNS}}+{{NUMBER_OF_AUXILIARY_VARIABLES}}],
259 const double * __restrict__ deltaQ, // deltaQ[{{NUMBER_OF_UNKNOWNS}}+{{NUMBER_OF_AUXILIARY_VARIABLES}}]
260 const tarch::la::Vector<Dimensions,double>& faceCentre,
264 double * __restrict__ BTimesDeltaQ // BTimesDeltaQ[{{NUMBER_OF_UNKNOWNS}}]
266 {{NCP_IMPLEMENTATION}}
270{% if SOURCE_TERM_IMPLEMENTATION!="<user-defined>" and SOURCE_TERM_IMPLEMENTATION!="<none>" %}
271void {{FULL_QUALIFIED_NAMESPACE}}::{{CLASSNAME}}::sourceTerm(
272 const double * __restrict__ Q,
273 const tarch::la::Vector<Dimensions,double>& volumeCentre,
276 double * __restrict__ S
278 {% if SOURCE_TERM_IMPLEMENTATION!="<empty>" %}
279 {{SOURCE_TERM_IMPLEMENTATION}}
281 std::fill_n(S,{{NUMBER_OF_UNKNOWNS}},0.0);
286{% if POINT_SOURCE_IMPLEMENTATION!="<user-defined>" and POINT_SOURCE_IMPLEMENTATION!="<none>" %}
287#error Point sources not yet implemented
288void {{FULL_QUALIFIED_NAMESPACE}}::{{CLASSNAME}}::pointSource(
289 const double * __restrict__ Q,
290 const tarch::la::Vector<Dimensions,double>& x,
293 double * __restrict__ S
295 {% if POINT_SOURCE_IMPLEMENTATION!="<empty>" %}
296 {{POINT_SOURCE_IMPLEMENTATION}}
298 std::fill_n(S,{{NUMBER_OF_UNKNOWNS}},0.0);
303{% if EIGENVALUES_IMPLEMENTATION!="<user-defined>" and STATELESS_PDE_TERMS %}
304#if defined(OpenMPGPUOffloading)
305#pragma omp declare target
307double {{FULL_QUALIFIED_NAMESPACE}}::{{CLASSNAME}}::maxEigenvalue(
308 const double * __restrict__ Q, // Q[{{NUMBER_OF_UNKNOWNS}}+{{NUMBER_OF_AUXILIARY_VARIABLES}}],
309 const tarch::la::Vector<Dimensions,double>& faceCentre,
313 double* maxEigenvalue,
316 {{EIGENVALUES_IMPLEMENTATION}};
318#if defined(OpenMPGPUOffloading)
319#pragma omp end declare target
323{% if FLUX_IMPLEMENTATION!="<user-defined>" and STATELESS_PDE_TERMS %}
324#if defined(OpenMPGPUOffloading)
325#pragma omp declare target
327void {{FULL_QUALIFIED_NAMESPACE}}::{{CLASSNAME}}::flux(
328 const double * __restrict__ Q, // Q[{{NUMBER_OF_UNKNOWNS}}+{{NUMBER_OF_AUXILIARY_VARIABLES}}],
329 const tarch::la::Vector<Dimensions,double>& faceCentre,
333 double * __restrict__ F, // F[{{NUMBER_OF_UNKNOWNS}}]
336 {% if FLUX_IMPLEMENTATION=="<none>" %}
339 {{FLUX_IMPLEMENTATION}}
342#if defined(OpenMPGPUOffloading)
343#pragma omp end declare target
347{% if NCP_IMPLEMENTATION!="<user-defined>" and STATELESS_PDE_TERMS %}
348#if defined(OpenMPGPUOffloading)
349#pragma omp declare target
351void {{FULL_QUALIFIED_NAMESPACE}}::{{CLASSNAME}}::nonconservativeProduct(
352 const double * __restrict__ Q, // Q[{{NUMBER_OF_UNKNOWNS}}+{{NUMBER_OF_AUXILIARY_VARIABLES}}],
353 const double * __restrict__ deltaQ, // deltaQ[{{NUMBER_OF_UNKNOWNS}}+{{NUMBER_OF_AUXILIARY_VARIABLES}}]
354 const tarch::la::Vector<Dimensions,double>& faceCentre,
358 double * __restrict__ BTimesDeltaQ, // BTimesDeltaQ[{{NUMBER_OF_UNKNOWNS}}]
361 {% if NCP_IMPLEMENTATION=="<none>" %}
364 {{NCP_IMPLEMENTATION}}
367#if defined(OpenMPGPUOffloading)
368#pragma omp end declare target
372{% if SOURCE_TERM_IMPLEMENTATION!="<user-defined>" and STATELESS_PDE_TERMS %}
373#if defined(OpenMPGPUOffloading)
374#pragma omp declare target
376void {{FULL_QUALIFIED_NAMESPACE}}::{{CLASSNAME}}::sourceTerm(
377 const double * __restrict__ Q,
378 const tarch::la::Vector<Dimensions,double>& volumeCentre,
381 double * __restrict__ S,
384 {% if SOURCE_TERM_IMPLEMENTATION=="<none>" %}
387 {{SOURCE_TERM_IMPLEMENTATION}}
390#if defined(OpenMPGPUOffloading)
391#pragma omp end declare target
395{% if POINT_SOURCE_IMPLEMENTATION!="<user-defined>" and STATELESS_PDE_TERMS %}
396#if defined(OpenMPGPUOffloading)
397#pragma omp declare target
399void {{FULL_QUALIFIED_NAMESPACE}}::{{CLASSNAME}}::pointSource(
400 const double * __restrict__ Q,
401 const tarch::la::Vector<Dimensions,double>& x,
404 double * __restrict__ S,
407 assertionMsg( false, "point sources not implemented yet" );
408 {% if POINT_SOURCE_IMPLEMENTATION=="<none>" %}
411 {{POINT_SOURCE_IMPLEMENTATION}}
414#if defined(OpenMPGPUOffloading)
415#pragma omp end declare target
419 undefined=jinja2.DebugUndefined,
423 d[
"FLUX_IMPLEMENTATION"] = flux_implementation
424 d[
"NCP_IMPLEMENTATION"] = ncp_implementation
425 d[
"EIGENVALUES_IMPLEMENTATION"] = eigenvalues_implementation
426 d[
"SOURCE_TERM_IMPLEMENTATION"] = source_term_implementation
427 d[
"POINT_SOURCE_IMPLEMENTATION"] = point_source_implementation
428 d[
"STATELESS_PDE_TERMS"] = pde_terms_without_state
429 return Template.render(**d)
435 eigenvalues_implementation,
436 source_term_implementation,
437 point_source_implementation,
438 pde_terms_without_state,
440 Template = jinja2.Template(
443 {% if SOURCE_TERM_IMPLEMENTATION=="<user-defined>" %}
444 virtual void sourceTerm(
445 const double * __restrict__ Q,
446 const tarch::la::Vector<Dimensions,double>& volumeCentre,
449 double * __restrict__ S
453 {% if POINT_SOURCE_IMPLEMENTATION=="<user-defined>" %}
454 #error point sources not defined yet
455 virtual void pointSource(
456 const double * __restrict__ Q,
457 const tarch::la::Vector<Dimensions,double>& x,
460 double * __restrict__ S
464 {% if EIGENVALUES_IMPLEMENTATION=="<user-defined>" %}
466 * Determine max eigenvalue over Jacobian in a given point with solution values
467 * (states) Q. All parameters are in.
469 * @return Max eigenvalue. Result has to be positive, so we are actually speaking
470 * about the maximum absolute eigenvalue.
472 virtual double maxEigenvalue(
473 const double * __restrict__ Q, // Q[{{NUMBER_OF_UNKNOWNS}}+{{NUMBER_OF_AUXILIARY_VARIABLES}}],
474 const tarch::la::Vector<Dimensions,double>& faceCentre,
478 double* maxEigenvalue
482 {% if FLUX_IMPLEMENTATION=="<user-defined>" %}
484 const double * __restrict__ Q, // Q[{{NUMBER_OF_UNKNOWNS}}+{{NUMBER_OF_AUXILIARY_VARIABLES}}],
485 const tarch::la::Vector<Dimensions,double>& faceCentre,
489 double * __restrict__ F // F[{{NUMBER_OF_UNKNOWNS}}]
493 {% if NCP_IMPLEMENTATION=="<user-defined>" %}
494 virtual void nonconservativeProduct(
495 const double * __restrict__ Q, // Q[{{NUMBER_OF_UNKNOWNS}}+{{NUMBER_OF_AUXILIARY_VARIABLES}}],
496 const double * __restrict__ deltaQ, // deltaQ[{{NUMBER_OF_UNKNOWNS}}+{{NUMBER_OF_AUXILIARY_VARIABLES}}]
497 const tarch::la::Vector<Dimensions,double>& faceCentre,
501 double * __restrict__ BTimesDeltaQ // BTimesDeltaQ[{{NUMBER_OF_UNKNOWNS}}]
505 {% if STATELESS_PDE_TERMS and SOURCE_TERM_IMPLEMENTATION=="<user-defined>" %}
507 * To obtain the best performance, I recommend to man inline command to
508 * this signature and to copy the implementation into the header. So it would
511 * static inline void sourceTerm( ... ) {
515 * The GPU offloading requires static functions. As we cannot overload the
516 * original (virtual) function with a static alternative, we do the
517 * TBB trick and overload by adding an additional enum. It has no semantics
518 * but helps the compiler to distinguish the different function variants.
520 #if defined(OpenMPGPUOffloading)
521 #pragma omp declare target
523 static void sourceTerm(
524 const double * __restrict__ Q,
525 const tarch::la::Vector<Dimensions,double>& volumeCentre,
526 const tarch::la::Vector<Dimensions,double>& volumeH,
529 double * __restrict__ S,
532 #if defined(OpenMPGPUOffloading)
533 #pragma omp end declare target
537 {% if STATELESS_PDE_TERMS and POINT_SOURCE_IMPLEMENTATION=="<user-defined>" %}
539 * To obtain the best performance, I recommend to man inline command to
540 * this signature and to copy the implementation into the header. So it would
543 * static inline void pointSource( ... ) {
547 * The GPU offloading requires static functions. As we cannot overload the
548 * original (virtual) function with a static alternative, we do the
549 * TBB trick and overload by adding an additional enum. It has no semantics
550 * but helps the compiler to distinguish the different function variants.
552 #error point sources not implemented yet
553 #if defined(OpenMPGPUOffloading)
554 #pragma omp declare target
556 static void pointSource(
557 const double * __restrict__ Q,
558 const tarch::la::Vector<Dimensions,double>& volumeCentre,
559 const tarch::la::Vector<Dimensions,double>& volumeH,
562 double * __restrict__ S,
565 #if defined(OpenMPGPUOffloading)
566 #pragma omp end declare target
570 {% if EIGENVALUES_IMPLEMENTATION=="<user-defined>" and STATELESS_PDE_TERMS %}
572 * To obtain the best performance, I recommend to man inline command to
573 * this signature and to copy the implementation into the header. So it would
576 * static inline double maxEigenvalue( ... ) {
580 * The GPU offloading requires static functions. As we cannot overload the
581 * original (virtual) function with a static alternative, we do the
582 * TBB trick and overload by adding an additional enum. It has no semantics
583 * but helps the compiler to distinguish the different function variants.
585 #if defined(OpenMPGPUOffloading)
586 #pragma omp declare target
588 static double maxEigenvalue(
589 const double * __restrict__ Q, // Q[{{NUMBER_OF_UNKNOWNS}}+{{NUMBER_OF_AUXILIARY_VARIABLES}}],
590 const tarch::la::Vector<Dimensions,double>& faceCentre,
594 double* maxEigenvalue,
597 #if defined(OpenMPGPUOffloading)
598 #pragma omp end declare target
602 {% if STATELESS_PDE_TERMS and FLUX_IMPLEMENTATION=="<user-defined>" %}
604 * To obtain the best performance, I recommend to man inline command to
605 * this signature and to copy the implementation into the header. So it would
608 * static inline void flux( ... ) {
612 * The GPU offloading requires static functions. As we cannot overload the
613 * original (virtual) function with a static alternative, we do the
614 * TBB trick and overload by adding an additional enum. It has no semantics
615 * but helps the compiler to distinguish the different function variants.
617 #if defined(OpenMPGPUOffloading)
618 #pragma omp declare target
621 const double * __restrict__ Q, // Q[{{NUMBER_OF_UNKNOWNS}}+{{NUMBER_OF_AUXILIARY_VARIABLES}}],
622 const tarch::la::Vector<Dimensions,double>& faceCentre,
626 double * __restrict__ F, // F[{{NUMBER_OF_UNKNOWNS}}]
629 #if defined(OpenMPGPUOffloading)
630 #pragma omp end declare target
634 {% if STATELESS_PDE_TERMS and NCP_IMPLEMENTATION=="<user-defined>" %}
636 * To obtain the best performance, I recommend to man inline command to
637 * this signature and to copy the implementation into the header. So it would
640 * static inline void nonconservativeProduct( ... ) {
644 * The GPU offloading requires static functions. As we cannot overload the
645 * original (virtual) function with a static alternative, we do the
646 * TBB trick and overload by adding an additional enum. It has no semantics
647 * but helps the compiler to distinguish the different function variants.
649 #if defined(OpenMPGPUOffloading)
650 #pragma omp declare target
652 static void nonconservativeProduct(
653 const double * __restrict__ Q, // Q[5+0],
654 const double * __restrict__ deltaQ, // deltaQ[5+0]
655 const tarch::la::Vector<Dimensions,double>& x,
659 double * __restrict__ BTimesDeltaQ, // BTimesDeltaQ[5]
662 #if defined(OpenMPGPUOffloading)
663 #pragma omp end declare target
667 undefined=jinja2.DebugUndefined,
670 d[
"FLUX_IMPLEMENTATION"] = flux_implementation
671 d[
"NCP_IMPLEMENTATION"] = ncp_implementation
672 d[
"EIGENVALUES_IMPLEMENTATION"] = eigenvalues_implementation
673 d[
"SOURCE_TERM_IMPLEMENTATION"] = source_term_implementation
674 d[
"POINT_SOURCE_IMPLEMENTATION"] = point_source_implementation
675 d[
"STATELESS_PDE_TERMS"] = pde_terms_without_state
676 return Template.render(**d)
682 eigenvalues_implementation,
683 source_term_implementation,
684 point_source_implementation,
685 pde_terms_without_state,
687 Template = jinja2.Template(
689{% if EIGENVALUES_IMPLEMENTATION=="<user-defined>" %}
690double {{FULL_QUALIFIED_NAMESPACE}}::{{CLASSNAME}}::maxEigenvalue(
691 const double * __restrict__ Q, // Q[{{NUMBER_OF_UNKNOWNS}}+{{NUMBER_OF_AUXILIARY_VARIABLES}}],
692 const tarch::la::Vector<Dimensions,double>& faceCentre,
696 double* maxEigenvalue
698 logTraceInWith4Arguments( "maxEigenvalue(...)", x, t, dt, normal );
700 logTraceOut( "maxEigenvalue(...)" );
704{% if FLUX_IMPLEMENTATION=="<user-defined>" %}
705void {{FULL_QUALIFIED_NAMESPACE}}::{{CLASSNAME}}::flux(
706 const double * __restrict__ Q, // Q[{{NUMBER_OF_UNKNOWNS}}+{{NUMBER_OF_AUXILIARY_VARIABLES}}],
707 const tarch::la::Vector<Dimensions,double>& faceCentre,
711 double * __restrict__ F // F[{{NUMBER_OF_UNKNOWNS}}]
713 logTraceInWith4Arguments( "flux(...)", faceCentre, t, dt, normal );
715 logTraceOut( "flux(...)" );
719{% if NCP_IMPLEMENTATION=="<user-defined>" %}
720void {{FULL_QUALIFIED_NAMESPACE}}::{{CLASSNAME}}::nonconservativeProduct(
721 const double * __restrict__ Q, // Q[{{NUMBER_OF_UNKNOWNS}}+{{NUMBER_OF_AUXILIARY_VARIABLES}}],
722 const double * __restrict__ deltaQ, // deltaQ[{{NUMBER_OF_UNKNOWNS}}+{{NUMBER_OF_AUXILIARY_VARIABLES}}]
723 const tarch::la::Vector<Dimensions,double>& faceCentre,
727 double * __restrict__ BTimesDeltaQ // BTimesDeltaQ[{{NUMBER_OF_UNKNOWNS}}]
729 logTraceInWith4Arguments( "nonconservativeProduct(...)", faceCentre, t, dt, normal );
731 logTraceOut( "nonconservativeProduct(...)" );
735{% if SOURCE_TERM_IMPLEMENTATION=="<user-defined>" %}
736void {{FULL_QUALIFIED_NAMESPACE}}::{{CLASSNAME}}::sourceTerm(
737 const double * __restrict__ Q, // Q[{{NUMBER_OF_UNKNOWNS}}+{{NUMBER_OF_AUXILIARY_VARIABLES}}]
738 const tarch::la::Vector<Dimensions,double>& volumeCentre,
741 double * __restrict__ S // S[{{NUMBER_OF_UNKNOWNS}}]
743 logTraceInWith3Arguments( "sourceTerm(...)", volumeCentre, t, dt );
745 // @todo implement and ensure that all entries of S are properly set
746 for (int i=0; i<NumberOfUnknowns; i++) {
750 logTraceOut( "sourceTerm(...)" );
754{% if EIGENVALUES_IMPLEMENTATION=="<user-defined>" and STATELESS_PDE_TERMS %}
755 #if defined(OpenMPGPUOffloading)
756 #pragma omp declare target
758double {{FULL_QUALIFIED_NAMESPACE}}::{{CLASSNAME}}::maxEigenvalue(
759 const double * __restrict__ Q, // Q[{{NUMBER_OF_UNKNOWNS}}+{{NUMBER_OF_AUXILIARY_VARIABLES}}],
760 const tarch::la::Vector<Dimensions,double>& faceCentre,
764 double* maxEigenvalue,
769 #if defined(OpenMPGPUOffloading)
770 #pragma omp end declare target
774{% if FLUX_IMPLEMENTATION=="<user-defined>" and STATELESS_PDE_TERMS %}
775 #if defined(OpenMPGPUOffloading)
776 #pragma omp declare target
778void {{FULL_QUALIFIED_NAMESPACE}}::{{CLASSNAME}}::flux(
779 const double * __restrict__ Q, // Q[{{NUMBER_OF_UNKNOWNS}}+{{NUMBER_OF_AUXILIARY_VARIABLES}}],
780 const tarch::la::Vector<Dimensions,double>& faceCentre,
784 double * __restrict__ F,
789 #if defined(OpenMPGPUOffloading)
790 #pragma omp end declare target
794{% if NCP_IMPLEMENTATION=="<user-defined>" and STATELESS_PDE_TERMS %}
795 #if defined(OpenMPGPUOffloading)
796 #pragma omp declare target
798void {{FULL_QUALIFIED_NAMESPACE}}::{{CLASSNAME}}::nonconservativeProduct(
799 const double * __restrict__ Q, // Q[{{NUMBER_OF_UNKNOWNS}}+{{NUMBER_OF_AUXILIARY_VARIABLES}}],
800 const double * __restrict__ deltaQ, // deltaQ[{{NUMBER_OF_UNKNOWNS}}+{{NUMBER_OF_AUXILIARY_VARIABLES}}]
801 const tarch::la::Vector<Dimensions,double>& faceCentre,
805 double * __restrict__ BTimesDeltaQ,
810 #if defined(OpenMPGPUOffloading)
811 #pragma omp end declare target
815{% if SOURCE_TERM_IMPLEMENTATION=="<user-defined>" and STATELESS_PDE_TERMS %}
816 #if defined(OpenMPGPUOffloading)
817 #pragma omp declare target
819void {{FULL_QUALIFIED_NAMESPACE}}::{{CLASSNAME}}::sourceTerm(
820 const double * __restrict__ Q,
821 const tarch::la::Vector<Dimensions,double>& volumeCentre,
824 double * __restrict__ S,
829 #if defined(OpenMPGPUOffloading)
830 #pragma omp end declare target
834{% if POINT_SOURCE_IMPLEMENTATION=="<user-defined>" and STATELESS_PDE_TERMS %}
835 #if defined(OpenMPGPUOffloading)
836 #pragma omp declare target
838#error point sources not implemented yet
839void {{FULL_QUALIFIED_NAMESPACE}}::{{CLASSNAME}}::sourceTerm(
840 const double * __restrict__ Q,
841 const tarch::la::Vector<Dimensions,double>& volumeCentre,
844 double * __restrict__ S,
849 #if defined(OpenMPGPUOffloading)
850 #pragma omp end declare target
854 undefined=jinja2.DebugUndefined,
857 d[
"FLUX_IMPLEMENTATION"] = flux_implementation
858 d[
"NCP_IMPLEMENTATION"] = ncp_implementation
859 d[
"EIGENVALUES_IMPLEMENTATION"] = eigenvalues_implementation
860 d[
"SOURCE_TERM_IMPLEMENTATION"] = source_term_implementation
861 d[
"POINT_SOURCE_IMPLEMENTATION"] = point_source_implementation
862 d[
"STATELESS_PDE_TERMS"] = pde_terms_without_state
863 return Template.render(**d)
867 assert False,
"I don't think this one is used anymore. @todo Remove"
870 "OVERLAP": patch_overlap.dim[0]
872 "DOFS_PER_AXIS": patch_overlap.dim[1],
873 "UNKNOWNS": patch_overlap.no_of_unknowns,
878 constexpr int nodesPerFace = {DOFS_PER_AXIS};
880 constexpr int nodesPerFace = {DOFS_PER_AXIS}*{DOFS_PER_AXIS};
883 constexpr int strideQ = {UNKNOWNS};
885 const int faceDimension = marker.getSelectedFaceNumber()%Dimensions;
886 //if the outer normal is positive, the normal points to the right so the face is on the right
887 const int faceLR = (marker.outerNormal()[faceDimension]>0.0 ? 1 : 0);
889 for(int i=0; i<nodesPerFace; i++){{
890 for(int j=0; j<strideQ ; j++){{
891 value[(2*i+faceLR)*strideQ+j] = neighbour.value[(2*i+faceLR)*strideQ+j];
897 return template.format(**d)
901 normalised_time_step_size,
904 We roll over all reduced data after the last time step, and we
905 plot status info in the first step.
910 tarch::mpi::Rank::getInstance().isGlobalMaster()
914 isFirstGridSweepOfTimeStep()
916 logInfo( "step()", "Solver {{SOLVER_NAME}}:" );
917 logInfo( "step()", "t = " << _minTimeStampThisTimeStep );
918 logInfo( "step()", "dt = " << getTimeStepSize() );
919 logInfo( "step()", "h_{min} = " << _minCellHThisTimeStep );
920 logInfo( "step()", "h_{max} = " << _maxCellHThisTimeStep );
923 + str(normalised_time_step_size)
931 A set of default volumetric kernel calls. You might want to use different
932 solver calls in your code depending on the context.
934 ## Difference to Finite Volume (FV) implementation
936 In the FV code base, I need the implementation routines as argument: As we work
937 with FV, the generic FV class does not know which implementations are around. If
938 you work with a domain-specific Rusanov solver, e.g., then there is no such
941 For the DG schemes, things are different: Every DG solver in ExaHyPE 2 in principle
942 supports the ncp. So the base Python class already instantiates the corresponding
943 dictionary entries, and we can use them straightaway.
947 solver_variant: SolverVariant
948 Picks different implementation variants
951 isinstance(polynomial_basis, GaussLegendreBasis)
952 and solver_variant == SolverVariant.WithVirtualFunctions
954 return """cellIntegral_patchwise_in_situ_GaussLegendre_functors(
957 {{NUMBER_OF_UNKNOWNS}},
958 {{NUMBER_OF_AUXILIARY_VARIABLES}},
960 const double * __restrict__ Q,
961 const tarch::la::Vector<Dimensions,double>& x,
965 double * __restrict__ F
967 {% if FLUX_IMPLEMENTATION!="<none>" %}
968 repositories::{{SOLVER_INSTANCE}}.flux(Q,x,t,dt,normal,F);
972 const double * __restrict__ Q,
973 const double * __restrict__ deltaQ,
974 const tarch::la::Vector<Dimensions,double>& faceCentre,
978 double * __restrict__ F
980 {% if NCP_IMPLEMENTATION!="<none>" %}
981 repositories::{{SOLVER_INSTANCE}}.nonconservativeProduct(Q, deltaQ, faceCentre, t, dt, normal, F);
985 const double * __restrict__ Q,
986 const tarch::la::Vector<Dimensions,double>& x,
989 double * __restrict__ S
991 {% if SOURCE_TERM_IMPLEMENTATION!="<none>" %}
992 repositories::{{SOLVER_INSTANCE}}.sourceTerm(Q,x,t,dt,S);
996 const double * __restrict__ Q,
997 const tarch::la::Vector<Dimensions,double>& cellCentre,
998 const tarch::la::Vector<Dimensions,double>& cellH,
1001 ) -> std::vector<::exahype2::dg::PointSource> {
1002 {% if POINT_SOURCES_IMPLEMENTATION!="<none>" %}
1003 return repositories::{{SOLVER_INSTANCE}}.pointSources(Q,cellCentre,cellH,t,dt);
1005 return std::vector<::exahype2::dg::PointSource>();
1008 repositories::{{SOLVER_INSTANCE}}.QuadraturePoints1d,
1009 repositories::{{SOLVER_INSTANCE}}.MassMatrixDiagonal1d,
1010 repositories::{{SOLVER_INSTANCE}}.StiffnessOperator1d,
1011 repositories::{{SOLVER_INSTANCE}}.DerivativeOperator1d,
1012 {{ "true" if FLUX_IMPLEMENTATION!="<none>" else "false" }}, //useFlux
1013 {{ "true" if NCP_IMPLEMENTATION!="<none>" else "false" }}, //useNCP
1014 {{ "true" if SOURCE_TERM_IMPLEMENTATION!="<none>" else "false" }}, //useSource
1015 {{ "true" if POINT_SOURCES_IMPLEMENTATION!="<none>" else "false" }} //usePointSource
1019 isinstance(polynomial_basis, GaussLegendreBasis)
1020 and solver_variant == SolverVariant.Stateless
1022 return """cellIntegral_patchwise_in_situ_GaussLegendre<{{SOLVER_NAME}},{{ORDER}},{{NUMBER_OF_UNKNOWNS}},{{NUMBER_OF_AUXILIARY_VARIABLES}}>(
1024 {{ "true" if FLUX_IMPLEMENTATION!="<none>" else "false" }}, //useFlux
1025 {{ "true" if NCP_IMPLEMENTATION!="<none>" else "false" }}, //useNCP
1026 {{ "true" if SOURCE_TERM_IMPLEMENTATION!="<none>" else "false" }}, //useSource
1027 {{ "true" if POINT_SOURCES_IMPLEMENTATION!="<none>" else "false" }} //usePointSource
1031 isinstance(polynomial_basis, GaussLegendreBasis)
1032 and solver_variant == SolverVariant.Accelerator
1034 return """cellIntegral_patchwise_in_situ_GaussLegendre<{{SOLVER_NAME}},{{ORDER}},{{NUMBER_OF_UNKNOWNS}},{{NUMBER_OF_AUXILIARY_VARIABLES}}>(
1037 {{ "true" if FLUX_IMPLEMENTATION!="<none>" else "false" }}, //useFlux
1038 {{ "true" if NCP_IMPLEMENTATION!="<none>" else "false" }}, //useNCP
1039 {{ "true" if SOURCE_TERM_IMPLEMENTATION!="<none>" else "false" }}, //useSource
1040 {{ "true" if POINT_SOURCES_IMPLEMENTATION!="<none>" else "false" }} //usePointSource
1044 return "#solver variant not implemented yet"
1048 if isinstance(polynomial_basis, GaussLegendreBasis):
1049 return """integrateOverRiemannSolutionsAndAddToVolume_GaussLegendre(
1051 fineGridFaces{{UNKNOWN_IDENTIFIER}}RiemannSolution(0).value, //left
1052 fineGridFaces{{UNKNOWN_IDENTIFIER}}RiemannSolution(2).value, //right
1053 fineGridFaces{{UNKNOWN_IDENTIFIER}}RiemannSolution(1).value, //down
1054 fineGridFaces{{UNKNOWN_IDENTIFIER}}RiemannSolution(3).value, //up
1056 fineGridFaces{{UNKNOWN_IDENTIFIER}}RiemannSolution(0).value, //left
1057 fineGridFaces{{UNKNOWN_IDENTIFIER}}RiemannSolution(3).value, //right
1058 fineGridFaces{{UNKNOWN_IDENTIFIER}}RiemannSolution(1).value, //down
1059 fineGridFaces{{UNKNOWN_IDENTIFIER}}RiemannSolution(4).value, //up
1060 fineGridFaces{{UNKNOWN_IDENTIFIER}}RiemannSolution(2).value, //front
1061 fineGridFaces{{UNKNOWN_IDENTIFIER}}RiemannSolution(5).value, //back
1064 {{NUMBER_OF_UNKNOWNS}},
1065 {{NUMBER_OF_AUXILIARY_VARIABLES}},
1067 repositories::{{SOLVER_INSTANCE}}.BasisFunctionValuesLeft1d,
1068 repositories::{{SOLVER_INSTANCE}}.MassMatrixDiagonal1d,
1073 return "#error Not supported yet"
1077 if isinstance(polynomial_basis, GaussLegendreBasis):
1078 return """multiplyWithInvertedMassMatrix_GaussLegendre(
1081 {{NUMBER_OF_UNKNOWNS}},
1082 {{NUMBER_OF_AUXILIARY_VARIABLES}},
1083 repositories::{{SOLVER_INSTANCE}}.MassMatrixDiagonal1d
1087 return "#error Not supported yet"
create_abstract_solver_definitions(flux_implementation, ncp_implementation, eigenvalues_implementation, source_term_implementation, point_source_implementation, pde_terms_without_state)
create_volumetric_solver_call(polynomial_basis, solver_variant)
A set of default volumetric kernel calls.
create_multiply_with_inverted_mass_matrix_call(polynomial_basis)
create_solver_declarations(flux_implementation, ncp_implementation, eigenvalues_implementation, source_term_implementation, point_source_implementation, pde_terms_without_state)
create_abstract_solver_declarations(flux_implementation, ncp_implementation, eigenvalues_implementation, source_term_implementation, point_source_implementation, pde_terms_without_state)
create_solver_definitions(flux_implementation, ncp_implementation, eigenvalues_implementation, source_term_implementation, point_source_implementation, pde_terms_without_state)
create_start_time_step_implementation_for_fixed_time_stepping(normalised_time_step_size)
We roll over all reduced data after the last time step, and we plot status info in the first step.
create_add_solver_contributions_call(polynomial_basis)
get_face_merge_implementation(patch_overlap)