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,
51 #if defined(OpenMPGPUOffloading)
52 #pragma omp end declare target
57 * Determine max eigenvalue over Jacobian in a given point with solution values
58 * (states) Q. All parameters are in.
60 * @return Max eigenvalue. Result has to be positive, so we are actually speaking
61 * about the maximum absolute eigenvalue.
63 virtual double maxEigenvalue(
64 const double * __restrict__ Q, // Q[{{NUMBER_OF_UNKNOWNS}}+{{NUMBER_OF_AUXILIARY_VARIABLES}}],
65 const tarch::la::Vector<Dimensions,double>& faceCentre,
69 ) {% if EIGENVALUES_IMPLEMENTATION=="<user-defined>" %}= 0{% else %} final{% endif %};
71 {% if FLUX_IMPLEMENTATION!="<user-defined>" and STATELESS_PDE_TERMS %}
73 * Depending on the implementation, this variant might be slow as it
74 * lacks an inline define. Also, if you don't want to use ipo aggressively,
75 * it might be clever to put the implementation into the header.
77 #if defined(OpenMPGPUOffloading)
78 #pragma omp declare target
81 const double * __restrict__ Q, // Q[{{NUMBER_OF_UNKNOWNS}}+{{NUMBER_OF_AUXILIARY_VARIABLES}}],
82 const tarch::la::Vector<Dimensions,double>& faceCentre,
86 double * __restrict__ F, // F[{{NUMBER_OF_UNKNOWNS}}]
89 #if defined(OpenMPGPUOffloading)
90 #pragma omp end declare target
94 {% if FLUX_IMPLEMENTATION!="<none>" %}
96 const double * __restrict__ Q, // Q[{{NUMBER_OF_UNKNOWNS}}+{{NUMBER_OF_AUXILIARY_VARIABLES}}],
97 const tarch::la::Vector<Dimensions,double>& faceCentre,
101 double * __restrict__ F // F[{{NUMBER_OF_UNKNOWNS}}]
102 ) {% if FLUX_IMPLEMENTATION=="<user-defined>" %}=0{% else %} final {% endif %};
105 {% if NCP_IMPLEMENTATION!="<user-defined>" and STATELESS_PDE_TERMS %}
107 * Depending on the implementation, this variant might be slow as it
108 * lacks an inline define. Also, if you don't want to use ipo aggressively,
109 * it might be clever to put the implementation into the header.
111 #if defined(OpenMPGPUOffloading)
112 #pragma omp declare target
114 static void nonconservativeProduct(
115 const double * __restrict__ Q, // Q[{{NUMBER_OF_UNKNOWNS}}+{{NUMBER_OF_AUXILIARY_VARIABLES}}],
116 const double * __restrict__ deltaQ, // deltaQ[{{NUMBER_OF_UNKNOWNS}}+{{NUMBER_OF_AUXILIARY_VARIABLES}}],
117 const tarch::la::Vector<Dimensions,double>& faceCentre,
121 double * __restrict__ BTimesDeltaQ, // BTimesDeltaQ[{{NUMBER_OF_UNKNOWNS}}]
124 #if defined(OpenMPGPUOffloading)
125 #pragma omp end declare target
129 {% if NCP_IMPLEMENTATION!="<none>" %}
130 virtual void nonconservativeProduct(
131 const double * __restrict__ Q, // Q[{{NUMBER_OF_UNKNOWNS}}+{{NUMBER_OF_AUXILIARY_VARIABLES}}],
132 const double * __restrict__ deltaQ, // [{{NUMBER_OF_UNKNOWNS}}+{{NUMBER_OF_AUXILIARY_VARIABLES}}]
133 const tarch::la::Vector<Dimensions,double>& faceCentre,
137 double * __restrict__ BTimesDeltaQ // BTimesDeltaQ[{{NUMBER_OF_UNKNOWNS}}]
138 ) {% if NCP_IMPLEMENTATION=="<user-defined>" %}=0{% endif %};
141 {% if SOURCE_TERM_IMPLEMENTATION!="<user-defined>" and STATELESS_PDE_TERMS %}
143 * Depending on the implementation, this variant might be slow as it
144 * lacks an inline define. Also, if you don't want to use ipo aggressively,
145 * it might be clever to put the implementation into the header.
147 #if defined(OpenMPGPUOffloading)
148 #pragma omp declare target
150 static void sourceTerm(
151 const double * __restrict__ Q,
152 const tarch::la::Vector<Dimensions,double>& volumeCentre,
155 double * __restrict__ S,
158 #if defined(OpenMPGPUOffloading)
159 #pragma omp end declare target
163 {% if SOURCE_TERM_IMPLEMENTATION!="<none>" %}
164 virtual void sourceTerm(
165 const double * __restrict__ Q,
166 const tarch::la::Vector<Dimensions,double>& volumeCentre,
169 double * __restrict__ S
170 ) {% if SOURCE_TERM_IMPLEMENTATION=="<user-defined>" %}= 0{% else %} final {% endif %};
173 {% if POINT_SOURCE_IMPLEMENTATION!="<user-defined>" and STATELESS_PDE_TERMS %}
175 * Depending on the implementation, this variant might be slow as it
176 * lacks an inline define. Also, if you don't want to use ipo aggressively,
177 * it might be clever to put the implementation into the header.
179 #if defined(OpenMPGPUOffloading)
180 #pragma omp declare target
183 const double * __restrict__ Q,
184 const tarch::la::Vector<Dimensions,double>& x,
187 double * __restrict__ S,
190 #if defined(OpenMPGPUOffloading)
191 #pragma omp end declare target
195 {% if POINT_SOURCE_IMPLEMENTATION!="<none>" %}
196 virtual void pointSource(
197 const double * __restrict__ Q,
198 const tarch::la::Vector<Dimensions,double>& x,
201 double * __restrict__ S
202 ) {% if SOURCE_TERM_IMPLEMENTATION=="<user-defined>" %}= 0{% else %} final {% endif %};
205 undefined=jinja2.DebugUndefined,
209 d[
"FLUX_IMPLEMENTATION"] = flux_implementation
210 d[
"NCP_IMPLEMENTATION"] = ncp_implementation
211 d[
"EIGENVALUES_IMPLEMENTATION"] = eigenvalues_implementation
212 d[
"SOURCE_TERM_IMPLEMENTATION"] = source_term_implementation
213 d[
"POINT_SOURCE_IMPLEMENTATION"] = point_source_implementation
214 d[
"STATELESS_PDE_TERMS"] = pde_terms_without_state
215 return Template.render(**d)
221 eigenvalues_implementation,
222 source_term_implementation,
223 point_source_implementation,
224 pde_terms_without_state,
226 Template = jinja2.Template(
228{% if EIGENVALUES_IMPLEMENTATION!="<user-defined>" and EIGENVALUES_IMPLEMENTATION!="<none>" %}
229double {{FULL_QUALIFIED_NAMESPACE}}::{{CLASSNAME}}::maxEigenvalue(
230 const double * __restrict__ Q, // Q[{{NUMBER_OF_UNKNOWNS}}+{{NUMBER_OF_AUXILIARY_VARIABLES}}],
231 const tarch::la::Vector<Dimensions,double>& faceCentre,
236 {{EIGENVALUES_IMPLEMENTATION}}
240{% if FLUX_IMPLEMENTATION!="<none>" and FLUX_IMPLEMENTATION!="<user-defined>" %}
241void {{FULL_QUALIFIED_NAMESPACE}}::{{CLASSNAME}}::flux(
242 const double * __restrict__ Q, // Q[{{NUMBER_OF_UNKNOWNS}}+{{NUMBER_OF_AUXILIARY_VARIABLES}}],
243 const tarch::la::Vector<Dimensions,double>& faceCentre,
247 double * __restrict__ F // F[{{NUMBER_OF_UNKNOWNS}}]
249 {{FLUX_IMPLEMENTATION}}
253{% if NCP_IMPLEMENTATION!="<none>" and NCP_IMPLEMENTATION!="<user-defined>" %}
254void {{FULL_QUALIFIED_NAMESPACE}}::{{CLASSNAME}}::nonconservativeProduct(
255 const double * __restrict__ Q, // Q[{{NUMBER_OF_UNKNOWNS}}+{{NUMBER_OF_AUXILIARY_VARIABLES}}],
256 const double * __restrict__ deltaQ, // deltaQ[{{NUMBER_OF_UNKNOWNS}}+{{NUMBER_OF_AUXILIARY_VARIABLES}}]
257 const tarch::la::Vector<Dimensions,double>& faceCentre,
261 double * __restrict__ BTimesDeltaQ // BTimesDeltaQ[{{NUMBER_OF_UNKNOWNS}}]
263 {{NCP_IMPLEMENTATION}}
267{% if SOURCE_TERM_IMPLEMENTATION!="<user-defined>" and SOURCE_TERM_IMPLEMENTATION!="<none>" %}
268void {{FULL_QUALIFIED_NAMESPACE}}::{{CLASSNAME}}::sourceTerm(
269 const double * __restrict__ Q,
270 const tarch::la::Vector<Dimensions,double>& volumeCentre,
273 double * __restrict__ S
275 {% if SOURCE_TERM_IMPLEMENTATION!="<empty>" %}
276 {{SOURCE_TERM_IMPLEMENTATION}}
278 std::fill_n(S,{{NUMBER_OF_UNKNOWNS}},0.0);
283{% if POINT_SOURCE_IMPLEMENTATION!="<user-defined>" and POINT_SOURCE_IMPLEMENTATION!="<none>" %}
284#error Point sources not yet implemented
285void {{FULL_QUALIFIED_NAMESPACE}}::{{CLASSNAME}}::pointSource(
286 const double * __restrict__ Q,
287 const tarch::la::Vector<Dimensions,double>& x,
290 double * __restrict__ S
292 {% if POINT_SOURCE_IMPLEMENTATION!="<empty>" %}
293 {{POINT_SOURCE_IMPLEMENTATION}}
295 std::fill_n(S,{{NUMBER_OF_UNKNOWNS}},0.0);
300{% if EIGENVALUES_IMPLEMENTATION!="<user-defined>" and STATELESS_PDE_TERMS %}
301#if defined(OpenMPGPUOffloading)
302#pragma omp declare target
304double {{FULL_QUALIFIED_NAMESPACE}}::{{CLASSNAME}}::maxEigenvalue(
305 const double * __restrict__ Q, // Q[{{NUMBER_OF_UNKNOWNS}}+{{NUMBER_OF_AUXILIARY_VARIABLES}}],
306 const tarch::la::Vector<Dimensions,double>& faceCentre,
312 {{EIGENVALUES_IMPLEMENTATION}};
314#if defined(OpenMPGPUOffloading)
315#pragma omp end declare target
319{% if FLUX_IMPLEMENTATION!="<user-defined>" and STATELESS_PDE_TERMS %}
320#if defined(OpenMPGPUOffloading)
321#pragma omp declare target
323void {{FULL_QUALIFIED_NAMESPACE}}::{{CLASSNAME}}::flux(
324 const double * __restrict__ Q, // Q[{{NUMBER_OF_UNKNOWNS}}+{{NUMBER_OF_AUXILIARY_VARIABLES}}],
325 const tarch::la::Vector<Dimensions,double>& faceCentre,
329 double * __restrict__ F, // F[{{NUMBER_OF_UNKNOWNS}}]
332 {% if FLUX_IMPLEMENTATION=="<none>" %}
335 {{FLUX_IMPLEMENTATION}}
338#if defined(OpenMPGPUOffloading)
339#pragma omp end declare target
343{% if NCP_IMPLEMENTATION!="<user-defined>" and STATELESS_PDE_TERMS %}
344#if defined(OpenMPGPUOffloading)
345#pragma omp declare target
347void {{FULL_QUALIFIED_NAMESPACE}}::{{CLASSNAME}}::nonconservativeProduct(
348 const double * __restrict__ Q, // Q[{{NUMBER_OF_UNKNOWNS}}+{{NUMBER_OF_AUXILIARY_VARIABLES}}],
349 const double * __restrict__ deltaQ, // deltaQ[{{NUMBER_OF_UNKNOWNS}}+{{NUMBER_OF_AUXILIARY_VARIABLES}}]
350 const tarch::la::Vector<Dimensions,double>& faceCentre,
354 double * __restrict__ BTimesDeltaQ, // BTimesDeltaQ[{{NUMBER_OF_UNKNOWNS}}]
357 {% if NCP_IMPLEMENTATION=="<none>" %}
360 {{NCP_IMPLEMENTATION}}
363#if defined(OpenMPGPUOffloading)
364#pragma omp end declare target
368{% if SOURCE_TERM_IMPLEMENTATION!="<user-defined>" and STATELESS_PDE_TERMS %}
369#if defined(OpenMPGPUOffloading)
370#pragma omp declare target
372void {{FULL_QUALIFIED_NAMESPACE}}::{{CLASSNAME}}::sourceTerm(
373 const double * __restrict__ Q,
374 const tarch::la::Vector<Dimensions,double>& volumeCentre,
377 double * __restrict__ S,
380 {% if SOURCE_TERM_IMPLEMENTATION=="<none>" %}
383 {{SOURCE_TERM_IMPLEMENTATION}}
386#if defined(OpenMPGPUOffloading)
387#pragma omp end declare target
391{% if POINT_SOURCE_IMPLEMENTATION!="<user-defined>" and STATELESS_PDE_TERMS %}
392#if defined(OpenMPGPUOffloading)
393#pragma omp declare target
395void {{FULL_QUALIFIED_NAMESPACE}}::{{CLASSNAME}}::pointSource(
396 const double * __restrict__ Q,
397 const tarch::la::Vector<Dimensions,double>& x,
400 double * __restrict__ S,
403 assertionMsg( false, "point sources not implemented yet" );
404 {% if POINT_SOURCE_IMPLEMENTATION=="<none>" %}
407 {{POINT_SOURCE_IMPLEMENTATION}}
410#if defined(OpenMPGPUOffloading)
411#pragma omp end declare target
415 undefined=jinja2.DebugUndefined,
419 d[
"FLUX_IMPLEMENTATION"] = flux_implementation
420 d[
"NCP_IMPLEMENTATION"] = ncp_implementation
421 d[
"EIGENVALUES_IMPLEMENTATION"] = eigenvalues_implementation
422 d[
"SOURCE_TERM_IMPLEMENTATION"] = source_term_implementation
423 d[
"POINT_SOURCE_IMPLEMENTATION"] = point_source_implementation
424 d[
"STATELESS_PDE_TERMS"] = pde_terms_without_state
425 return Template.render(**d)
431 eigenvalues_implementation,
432 source_term_implementation,
433 point_source_implementation,
434 pde_terms_without_state,
436 Template = jinja2.Template(
439 {% if SOURCE_TERM_IMPLEMENTATION=="<user-defined>" %}
440 virtual void sourceTerm(
441 const double * __restrict__ Q,
442 const tarch::la::Vector<Dimensions,double>& volumeCentre,
445 double * __restrict__ S
449 {% if POINT_SOURCE_IMPLEMENTATION=="<user-defined>" %}
450 #error point sources not defined yet
451 virtual void pointSource(
452 const double * __restrict__ Q,
453 const tarch::la::Vector<Dimensions,double>& x,
456 double * __restrict__ S
460 {% if EIGENVALUES_IMPLEMENTATION=="<user-defined>" %}
462 * Determine max eigenvalue over Jacobian in a given point with solution values
463 * (states) Q. All parameters are in.
465 * @return Max eigenvalue. Result has to be positive, so we are actually speaking
466 * about the maximum absolute eigenvalue.
468 virtual double maxEigenvalue(
469 const double * __restrict__ Q, // Q[{{NUMBER_OF_UNKNOWNS}}+{{NUMBER_OF_AUXILIARY_VARIABLES}}],
470 const tarch::la::Vector<Dimensions,double>& faceCentre,
477 {% if FLUX_IMPLEMENTATION=="<user-defined>" %}
479 const double * __restrict__ Q, // Q[{{NUMBER_OF_UNKNOWNS}}+{{NUMBER_OF_AUXILIARY_VARIABLES}}],
480 const tarch::la::Vector<Dimensions,double>& faceCentre,
484 double * __restrict__ F // F[{{NUMBER_OF_UNKNOWNS}}]
488 {% if NCP_IMPLEMENTATION=="<user-defined>" %}
489 virtual void nonconservativeProduct(
490 const double * __restrict__ Q, // Q[{{NUMBER_OF_UNKNOWNS}}+{{NUMBER_OF_AUXILIARY_VARIABLES}}],
491 const double * __restrict__ deltaQ, // deltaQ[{{NUMBER_OF_UNKNOWNS}}+{{NUMBER_OF_AUXILIARY_VARIABLES}}]
492 const tarch::la::Vector<Dimensions,double>& faceCentre,
496 double * __restrict__ BTimesDeltaQ // BTimesDeltaQ[{{NUMBER_OF_UNKNOWNS}}]
500 {% if STATELESS_PDE_TERMS and SOURCE_TERM_IMPLEMENTATION=="<user-defined>" %}
502 * To obtain the best performance, I recommend to man inline command to
503 * this signature and to copy the implementation into the header. So it would
506 * static inline void sourceTerm( ... ) {
510 * The GPU offloading requires static functions. As we cannot overload the
511 * original (virtual) function with a static alternative, we do the
512 * TBB trick and overload by adding an additional enum. It has no semantics
513 * but helps the compiler to distinguish the different function variants.
515 #if defined(OpenMPGPUOffloading)
516 #pragma omp declare target
518 static void sourceTerm(
519 const double * __restrict__ Q,
520 const tarch::la::Vector<Dimensions,double>& volumeCentre,
521 const tarch::la::Vector<Dimensions,double>& volumeH,
524 double * __restrict__ S,
527 #if defined(OpenMPGPUOffloading)
528 #pragma omp end declare target
532 {% if STATELESS_PDE_TERMS and POINT_SOURCE_IMPLEMENTATION=="<user-defined>" %}
534 * To obtain the best performance, I recommend to man inline command to
535 * this signature and to copy the implementation into the header. So it would
538 * static inline void pointSource( ... ) {
542 * The GPU offloading requires static functions. As we cannot overload the
543 * original (virtual) function with a static alternative, we do the
544 * TBB trick and overload by adding an additional enum. It has no semantics
545 * but helps the compiler to distinguish the different function variants.
547 #error point sources not implemented yet
548 #if defined(OpenMPGPUOffloading)
549 #pragma omp declare target
551 static void pointSource(
552 const double * __restrict__ Q,
553 const tarch::la::Vector<Dimensions,double>& volumeCentre,
554 const tarch::la::Vector<Dimensions,double>& volumeH,
557 double * __restrict__ S,
560 #if defined(OpenMPGPUOffloading)
561 #pragma omp end declare target
565 {% if EIGENVALUES_IMPLEMENTATION=="<user-defined>" and STATELESS_PDE_TERMS %}
567 * To obtain the best performance, I recommend to man inline command to
568 * this signature and to copy the implementation into the header. So it would
571 * static inline double maxEigenvalue( ... ) {
575 * The GPU offloading requires static functions. As we cannot overload the
576 * original (virtual) function with a static alternative, we do the
577 * TBB trick and overload by adding an additional enum. It has no semantics
578 * but helps the compiler to distinguish the different function variants.
580 #if defined(OpenMPGPUOffloading)
581 #pragma omp declare target
583 static double maxEigenvalue(
584 const double * __restrict__ Q, // Q[{{NUMBER_OF_UNKNOWNS}}+{{NUMBER_OF_AUXILIARY_VARIABLES}}],
585 const tarch::la::Vector<Dimensions,double>& faceCentre,
591 #if defined(OpenMPGPUOffloading)
592 #pragma omp end declare target
596 {% if STATELESS_PDE_TERMS and FLUX_IMPLEMENTATION=="<user-defined>" %}
598 * To obtain the best performance, I recommend to man inline command to
599 * this signature and to copy the implementation into the header. So it would
602 * static inline void flux( ... ) {
606 * The GPU offloading requires static functions. As we cannot overload the
607 * original (virtual) function with a static alternative, we do the
608 * TBB trick and overload by adding an additional enum. It has no semantics
609 * but helps the compiler to distinguish the different function variants.
611 #if defined(OpenMPGPUOffloading)
612 #pragma omp declare target
615 const double * __restrict__ Q, // Q[{{NUMBER_OF_UNKNOWNS}}+{{NUMBER_OF_AUXILIARY_VARIABLES}}],
616 const tarch::la::Vector<Dimensions,double>& faceCentre,
620 double * __restrict__ F, // F[{{NUMBER_OF_UNKNOWNS}}]
623 #if defined(OpenMPGPUOffloading)
624 #pragma omp end declare target
628 {% if STATELESS_PDE_TERMS and NCP_IMPLEMENTATION=="<user-defined>" %}
630 * To obtain the best performance, I recommend to man inline command to
631 * this signature and to copy the implementation into the header. So it would
634 * static inline void nonconservativeProduct( ... ) {
638 * The GPU offloading requires static functions. As we cannot overload the
639 * original (virtual) function with a static alternative, we do the
640 * TBB trick and overload by adding an additional enum. It has no semantics
641 * but helps the compiler to distinguish the different function variants.
643 #if defined(OpenMPGPUOffloading)
644 #pragma omp declare target
646 static void nonconservativeProduct(
647 const double * __restrict__ Q, // Q[5+0],
648 const double * __restrict__ deltaQ, // deltaQ[5+0]
649 const tarch::la::Vector<Dimensions,double>& x,
653 double * __restrict__ BTimesDeltaQ, // BTimesDeltaQ[5]
656 #if defined(OpenMPGPUOffloading)
657 #pragma omp end declare target
661 undefined=jinja2.DebugUndefined,
664 d[
"FLUX_IMPLEMENTATION"] = flux_implementation
665 d[
"NCP_IMPLEMENTATION"] = ncp_implementation
666 d[
"EIGENVALUES_IMPLEMENTATION"] = eigenvalues_implementation
667 d[
"SOURCE_TERM_IMPLEMENTATION"] = source_term_implementation
668 d[
"POINT_SOURCE_IMPLEMENTATION"] = point_source_implementation
669 d[
"STATELESS_PDE_TERMS"] = pde_terms_without_state
670 return Template.render(**d)
676 eigenvalues_implementation,
677 source_term_implementation,
678 point_source_implementation,
679 pde_terms_without_state,
681 Template = jinja2.Template(
683{% if EIGENVALUES_IMPLEMENTATION=="<user-defined>" %}
684double {{FULL_QUALIFIED_NAMESPACE}}::{{CLASSNAME}}::maxEigenvalue(
685 const double * __restrict__ Q, // Q[{{NUMBER_OF_UNKNOWNS}}+{{NUMBER_OF_AUXILIARY_VARIABLES}}],
686 const tarch::la::Vector<Dimensions,double>& faceCentre,
691 logTraceInWith4Arguments( "maxEigenvalue(...)", x, t, dt, normal );
693 logTraceOut( "maxEigenvalue(...)" );
697{% if FLUX_IMPLEMENTATION=="<user-defined>" %}
698void {{FULL_QUALIFIED_NAMESPACE}}::{{CLASSNAME}}::flux(
699 const double * __restrict__ Q, // Q[{{NUMBER_OF_UNKNOWNS}}+{{NUMBER_OF_AUXILIARY_VARIABLES}}],
700 const tarch::la::Vector<Dimensions,double>& faceCentre,
704 double * __restrict__ F // F[{{NUMBER_OF_UNKNOWNS}}]
706 logTraceInWith4Arguments( "flux(...)", faceCentre, t, dt, normal );
708 logTraceOut( "flux(...)" );
712{% if NCP_IMPLEMENTATION=="<user-defined>" %}
713void {{FULL_QUALIFIED_NAMESPACE}}::{{CLASSNAME}}::nonconservativeProduct(
714 const double * __restrict__ Q, // Q[{{NUMBER_OF_UNKNOWNS}}+{{NUMBER_OF_AUXILIARY_VARIABLES}}],
715 const double * __restrict__ deltaQ, // deltaQ[{{NUMBER_OF_UNKNOWNS}}+{{NUMBER_OF_AUXILIARY_VARIABLES}}]
716 const tarch::la::Vector<Dimensions,double>& faceCentre,
720 double * __restrict__ BTimesDeltaQ // BTimesDeltaQ[{{NUMBER_OF_UNKNOWNS}}]
722 logTraceInWith4Arguments( "nonconservativeProduct(...)", faceCentre, t, dt, normal );
724 logTraceOut( "nonconservativeProduct(...)" );
728{% if SOURCE_TERM_IMPLEMENTATION=="<user-defined>" %}
729void {{FULL_QUALIFIED_NAMESPACE}}::{{CLASSNAME}}::sourceTerm(
730 const double * __restrict__ Q, // Q[{{NUMBER_OF_UNKNOWNS}}+{{NUMBER_OF_AUXILIARY_VARIABLES}}]
731 const tarch::la::Vector<Dimensions,double>& volumeCentre,
734 double * __restrict__ S // S[{{NUMBER_OF_UNKNOWNS}}]
736 logTraceInWith3Arguments( "sourceTerm(...)", volumeCentre, t, dt );
738 // @todo implement and ensure that all entries of S are properly set
739 for (int i=0; i<NumberOfUnknowns; i++) {
743 logTraceOut( "sourceTerm(...)" );
747{% if EIGENVALUES_IMPLEMENTATION=="<user-defined>" and STATELESS_PDE_TERMS %}
748 #if defined(OpenMPGPUOffloading)
749 #pragma omp declare target
751double {{FULL_QUALIFIED_NAMESPACE}}::{{CLASSNAME}}::maxEigenvalue(
752 const double * __restrict__ Q, // Q[{{NUMBER_OF_UNKNOWNS}}+{{NUMBER_OF_AUXILIARY_VARIABLES}}],
753 const tarch::la::Vector<Dimensions,double>& faceCentre,
761 #if defined(OpenMPGPUOffloading)
762 #pragma omp end declare target
766{% if FLUX_IMPLEMENTATION=="<user-defined>" and STATELESS_PDE_TERMS %}
767 #if defined(OpenMPGPUOffloading)
768 #pragma omp declare target
770void {{FULL_QUALIFIED_NAMESPACE}}::{{CLASSNAME}}::flux(
771 const double * __restrict__ Q, // Q[{{NUMBER_OF_UNKNOWNS}}+{{NUMBER_OF_AUXILIARY_VARIABLES}}],
772 const tarch::la::Vector<Dimensions,double>& faceCentre,
776 double * __restrict__ F,
781 #if defined(OpenMPGPUOffloading)
782 #pragma omp end declare target
786{% if NCP_IMPLEMENTATION=="<user-defined>" and STATELESS_PDE_TERMS %}
787 #if defined(OpenMPGPUOffloading)
788 #pragma omp declare target
790void {{FULL_QUALIFIED_NAMESPACE}}::{{CLASSNAME}}::nonconservativeProduct(
791 const double * __restrict__ Q, // Q[{{NUMBER_OF_UNKNOWNS}}+{{NUMBER_OF_AUXILIARY_VARIABLES}}],
792 const double * __restrict__ deltaQ, // deltaQ[{{NUMBER_OF_UNKNOWNS}}+{{NUMBER_OF_AUXILIARY_VARIABLES}}]
793 const tarch::la::Vector<Dimensions,double>& faceCentre,
797 double * __restrict__ BTimesDeltaQ,
802 #if defined(OpenMPGPUOffloading)
803 #pragma omp end declare target
807{% if SOURCE_TERM_IMPLEMENTATION=="<user-defined>" and STATELESS_PDE_TERMS %}
808 #if defined(OpenMPGPUOffloading)
809 #pragma omp declare target
811void {{FULL_QUALIFIED_NAMESPACE}}::{{CLASSNAME}}::sourceTerm(
812 const double * __restrict__ Q,
813 const tarch::la::Vector<Dimensions,double>& volumeCentre,
816 double * __restrict__ S,
821 #if defined(OpenMPGPUOffloading)
822 #pragma omp end declare target
826{% if POINT_SOURCE_IMPLEMENTATION=="<user-defined>" and STATELESS_PDE_TERMS %}
827 #if defined(OpenMPGPUOffloading)
828 #pragma omp declare target
830#error point sources not implemented yet
831void {{FULL_QUALIFIED_NAMESPACE}}::{{CLASSNAME}}::sourceTerm(
832 const double * __restrict__ Q,
833 const tarch::la::Vector<Dimensions,double>& volumeCentre,
836 double * __restrict__ S,
841 #if defined(OpenMPGPUOffloading)
842 #pragma omp end declare target
846 undefined=jinja2.DebugUndefined,
849 d[
"FLUX_IMPLEMENTATION"] = flux_implementation
850 d[
"NCP_IMPLEMENTATION"] = ncp_implementation
851 d[
"EIGENVALUES_IMPLEMENTATION"] = eigenvalues_implementation
852 d[
"SOURCE_TERM_IMPLEMENTATION"] = source_term_implementation
853 d[
"POINT_SOURCE_IMPLEMENTATION"] = point_source_implementation
854 d[
"STATELESS_PDE_TERMS"] = pde_terms_without_state
855 return Template.render(**d)
859 assert False,
"I don't think this one is used anymore. @todo Remove"
862 "OVERLAP": patch_overlap.dim[0]
864 "DOFS_PER_AXIS": patch_overlap.dim[1],
865 "UNKNOWNS": patch_overlap.no_of_unknowns,
870 constexpr int nodesPerFace = {DOFS_PER_AXIS};
872 constexpr int nodesPerFace = {DOFS_PER_AXIS}*{DOFS_PER_AXIS};
875 constexpr int strideQ = {UNKNOWNS};
877 const int faceDimension = marker.getSelectedFaceNumber()%Dimensions;
878 //if the outer normal is positive, the normal points to the right so the face is on the right
879 const int faceLR = (marker.outerNormal()[faceDimension]>0.0 ? 1 : 0);
881 for(int i=0; i<nodesPerFace; i++){{
882 for(int j=0; j<strideQ ; j++){{
883 value[(2*i+faceLR)*strideQ+j] = neighbour.value[(2*i+faceLR)*strideQ+j];
889 return template.format(**d)
893 normalised_time_step_size,
896 We roll over all reduced data after the last time step, and we
897 plot status info in the first step.
902 tarch::mpi::Rank::getInstance().isGlobalMaster()
906 isFirstGridSweepOfTimeStep()
908 logInfo( "step()", "Solver {{SOLVER_NAME}}:" );
909 logInfo( "step()", "t = " << _minTimeStampThisTimeStep );
910 logInfo( "step()", "dt = " << getTimeStepSize() );
911 logInfo( "step()", "h_{min} = " << _minCellHThisTimeStep );
912 logInfo( "step()", "h_{max} = " << _maxCellHThisTimeStep );
915 + str(normalised_time_step_size)
923 A set of default volumetric kernel calls. You might want to use different
924 solver calls in your code depending on the context.
926 ## Difference to Finite Volume (FV) implementation
928 In the FV code base, I need the implementation routines as argument: As we work
929 with FV, the generic FV class does not know which implementations are around. If
930 you work with a domain-specific Rusanov solver, e.g., then there is no such
933 For the DG schemes, things are different: Every DG solver in ExaHyPE 2 in principle
934 supports the ncp. So the base Python class already instantiates the corresponding
935 dictionary entries, and we can use them straightaway.
939 solver_variant: SolverVariant
940 Picks different implementation variants
943 isinstance(polynomial_basis, GaussLegendreBasis)
944 and solver_variant == SolverVariant.WithVirtualFunctions
946 return """cellIntegral_patchwise_in_situ_GaussLegendre_functors(
949 {{NUMBER_OF_UNKNOWNS}},
950 {{NUMBER_OF_AUXILIARY_VARIABLES}},
952 const double * __restrict__ Q,
953 const tarch::la::Vector<Dimensions,double>& x,
957 double * __restrict__ F
959 {% if FLUX_IMPLEMENTATION!="<none>" %}
960 repositories::{{SOLVER_INSTANCE}}.flux(Q,x,t,dt,normal,F);
964 const double * __restrict__ Q,
965 const double * __restrict__ deltaQ,
966 const tarch::la::Vector<Dimensions,double>& faceCentre,
970 double * __restrict__ F
972 {% if NCP_IMPLEMENTATION!="<none>" %}
973 repositories::{{SOLVER_INSTANCE}}.nonconservativeProduct(Q, deltaQ, faceCentre, t, dt, normal, F);
977 const double * __restrict__ Q,
978 const tarch::la::Vector<Dimensions,double>& x,
981 double * __restrict__ S
983 {% if SOURCE_TERM_IMPLEMENTATION!="<none>" %}
984 repositories::{{SOLVER_INSTANCE}}.sourceTerm(Q,x,t,dt,S);
988 const double * __restrict__ Q,
989 const tarch::la::Vector<Dimensions,double>& cellCentre,
990 const tarch::la::Vector<Dimensions,double>& cellH,
993 ) -> std::vector<::exahype2::dg::PointSource> {
994 {% if POINT_SOURCES_IMPLEMENTATION!="<none>" %}
995 return repositories::{{SOLVER_INSTANCE}}.pointSources(Q,cellCentre,cellH,t,dt);
997 return std::vector<::exahype2::dg::PointSource>();
1000 repositories::{{SOLVER_INSTANCE}}.QuadraturePoints1d,
1001 repositories::{{SOLVER_INSTANCE}}.MassMatrixDiagonal1d,
1002 repositories::{{SOLVER_INSTANCE}}.StiffnessOperator1d,
1003 repositories::{{SOLVER_INSTANCE}}.DerivativeOperator1d,
1004 {{ "true" if FLUX_IMPLEMENTATION!="<none>" else "false" }}, //useFlux
1005 {{ "true" if NCP_IMPLEMENTATION!="<none>" else "false" }}, //useNCP
1006 {{ "true" if SOURCE_TERM_IMPLEMENTATION!="<none>" else "false" }}, //useSource
1007 {{ "true" if POINT_SOURCES_IMPLEMENTATION!="<none>" else "false" }} //usePointSource
1011 isinstance(polynomial_basis, GaussLegendreBasis)
1012 and solver_variant == SolverVariant.Stateless
1014 return """cellIntegral_patchwise_in_situ_GaussLegendre<{{SOLVER_NAME}},{{ORDER}},{{NUMBER_OF_UNKNOWNS}},{{NUMBER_OF_AUXILIARY_VARIABLES}}>(
1016 {{ "true" if FLUX_IMPLEMENTATION!="<none>" else "false" }}, //useFlux
1017 {{ "true" if NCP_IMPLEMENTATION!="<none>" else "false" }}, //useNCP
1018 {{ "true" if SOURCE_TERM_IMPLEMENTATION!="<none>" else "false" }}, //useSource
1019 {{ "true" if POINT_SOURCES_IMPLEMENTATION!="<none>" else "false" }} //usePointSource
1023 isinstance(polynomial_basis, GaussLegendreBasis)
1024 and solver_variant == SolverVariant.Accelerator
1026 return """cellIntegral_patchwise_in_situ_GaussLegendre<{{SOLVER_NAME}},{{ORDER}},{{NUMBER_OF_UNKNOWNS}},{{NUMBER_OF_AUXILIARY_VARIABLES}}>(
1029 {{ "true" if FLUX_IMPLEMENTATION!="<none>" else "false" }}, //useFlux
1030 {{ "true" if NCP_IMPLEMENTATION!="<none>" else "false" }}, //useNCP
1031 {{ "true" if SOURCE_TERM_IMPLEMENTATION!="<none>" else "false" }}, //useSource
1032 {{ "true" if POINT_SOURCES_IMPLEMENTATION!="<none>" else "false" }} //usePointSource
1036 return "#solver variant not implemented yet"
1040 if isinstance(polynomial_basis, GaussLegendreBasis):
1041 return """integrateOverRiemannSolutionsAndAddToVolume_GaussLegendre(
1043 fineGridFaces{{UNKNOWN_IDENTIFIER}}RiemannSolution(0).value, //left
1044 fineGridFaces{{UNKNOWN_IDENTIFIER}}RiemannSolution(2).value, //right
1045 fineGridFaces{{UNKNOWN_IDENTIFIER}}RiemannSolution(1).value, //down
1046 fineGridFaces{{UNKNOWN_IDENTIFIER}}RiemannSolution(3).value, //up
1048 fineGridFaces{{UNKNOWN_IDENTIFIER}}RiemannSolution(0).value, //left
1049 fineGridFaces{{UNKNOWN_IDENTIFIER}}RiemannSolution(3).value, //right
1050 fineGridFaces{{UNKNOWN_IDENTIFIER}}RiemannSolution(1).value, //down
1051 fineGridFaces{{UNKNOWN_IDENTIFIER}}RiemannSolution(4).value, //up
1052 fineGridFaces{{UNKNOWN_IDENTIFIER}}RiemannSolution(2).value, //front
1053 fineGridFaces{{UNKNOWN_IDENTIFIER}}RiemannSolution(5).value, //back
1056 {{NUMBER_OF_UNKNOWNS}},
1057 {{NUMBER_OF_AUXILIARY_VARIABLES}},
1059 repositories::{{SOLVER_INSTANCE}}.BasisFunctionValuesLeft1d,
1060 repositories::{{SOLVER_INSTANCE}}.MassMatrixDiagonal1d,
1065 return "#error Not supported yet"
1069 if isinstance(polynomial_basis, GaussLegendreBasis):
1070 return """multiplyWithInvertedMassMatrix_GaussLegendre(
1073 {{NUMBER_OF_UNKNOWNS}},
1074 {{NUMBER_OF_AUXILIARY_VARIABLES}},
1075 repositories::{{SOLVER_INSTANCE}}.MassMatrixDiagonal1d
1079 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)