Peano
Loading...
Searching...
No Matches
LoopBody.cpph
Go to the documentation of this file.
2#include "exahype2/Solver.h"
4#include <cmath>
5
6#if defined(GPUOffloadingOMP)
7#pragma omp declare target
8#endif
9template <class QInEnumeratorType, class QOutEnumeratorType>
11 const double* __restrict__ QIn,
12 const QInEnumeratorType& QInEnumerator,
13 int patchIndex,
14 const tarch::la::Vector<Dimensions,int>& volumeIndex,
15 int unknown,
16 double* __restrict__ QOut,
17 const QOutEnumeratorType& QOutEnumerator
18) {
19 QOut[ QOutEnumerator(patchIndex,volumeIndex,unknown) ] = QIn[QInEnumerator(patchIndex,volumeIndex,unknown)];
20}
21#if defined(GPUOffloadingOMP)
22#pragma omp end declare target
23#endif
24
25template <class QInEnumeratorType, class QInterEnumeratorType>
27 const double* __restrict__ QIn,
28 const QInEnumeratorType QInEnumerator,
32 const tarch::la::Vector<Dimensions,double>& patchCentre,
34 int patchIndex,
35 const tarch::la::Vector<Dimensions,int>& volumeIndex,
36 double t,
37 double dt,
38 double* __restrict__ timederivative,
39 QInterEnumeratorType QInterEnumerator
40) {
41 double QInGathered[QInEnumerator._unknowns+QInEnumerator._numberOfAuxiliaryVariables];
42 double temp[QInEnumerator._unknowns], shiftQ[QInEnumerator._unknowns];
43 double gradientQ[QInEnumerator._unknowns*3];
44
45
46 // gather
47 #if defined(SharedOMP)
48 #pragma omp simd
49 #endif
50 for (int unknown=0; unknown<QInEnumerator._unknowns+QInEnumerator._numberOfAuxiliaryVariables; unknown++) {
51 QInGathered[unknown] = QIn[ QInEnumerator(patchIndex,volumeIndex,unknown) ];
52 }
53
54 //first, initialize time derivative with source term
55 source(
56 QInGathered,
57 ::exahype2::fv::getVolumeCentre( patchCentre, patchSize, QInEnumerator._numberOfDoFsPerAxisInCell, volumeIndex ),
58 ::exahype2::fv::getVolumeSize( patchSize, QInEnumerator._numberOfDoFsPerAxisInCell ),
59 t,
60 dt,
61 temp
62 );
63 for (int unknown=0; unknown<QInEnumerator._unknowns; unknown++) {
64 timederivative[QInterEnumerator(patchIndex,volumeIndex,unknown)] = temp[ unknown ];
65 }
66
67 //second, add the -B(Q)*\nabla Q, it ask users to define B on the left of the PDE.
68 for (int unknown=0; unknown<QInEnumerator._unknowns; unknown++) {
69 gradientQ[QInEnumerator._unknowns*0+unknown]=QInGathered[ QInEnumerator._unknowns*1+unknown ]; //\partial_x Q_i
70 gradientQ[QInEnumerator._unknowns*1+unknown]=QInGathered[ QInEnumerator._unknowns*2+unknown ]; //\partial_y Q_i
71 gradientQ[QInEnumerator._unknowns*2+unknown]=QInGathered[ QInEnumerator._unknowns*3+unknown ]; //\partial_z Q_i
72 }
73 for (int normal=0; normal<3; normal++){
74 ncp(
75 QInGathered, gradientQ+QInEnumerator._unknowns*normal,
76 ::exahype2::fv::getVolumeCentre( patchCentre, patchSize, QInEnumerator._numberOfDoFsPerAxisInCell, volumeIndex ),
77 ::exahype2::fv::getVolumeSize( patchSize, QInEnumerator._numberOfDoFsPerAxisInCell ),
78 t,
79 dt,
80 normal,
81 temp
82 );
83 for (int unknown=0; unknown<QInEnumerator._unknowns; unknown++) {
84 timederivative[QInterEnumerator(patchIndex,volumeIndex,unknown)] -=temp[ unknown ];
85 }
86 }
87
88 //third, add flux contribution
89 for (int normal=0; normal<3; normal++){
90
91 for (int unknown=0; unknown<QInEnumerator._unknowns; unknown++) {
92 shiftQ[unknown]=QInGathered[unknown]-0.5*gradientQ[QInEnumerator._unknowns*normal+unknown]*::exahype2::fv::getVolumeSize( patchSize, QInEnumerator._numberOfDoFsPerAxisInCell )(normal);
93 }
94 flux(
95 shiftQ,
96 ::exahype2::fv::getVolumeCentre( patchCentre, patchSize, QInEnumerator._numberOfDoFsPerAxisInCell, volumeIndex ),
97 ::exahype2::fv::getVolumeSize( patchSize, QInEnumerator._numberOfDoFsPerAxisInCell ),
98 t, dt, normal, temp
99 );
100 for (int unknown=0; unknown<QInEnumerator._unknowns; unknown++) {
101 timederivative[QInterEnumerator(patchIndex,volumeIndex,unknown)] +=temp[ unknown ]/::exahype2::fv::getVolumeSize( patchSize, QInEnumerator._numberOfDoFsPerAxisInCell )(normal);
102 }
103
104 for (int unknown=0; unknown<QInEnumerator._unknowns; unknown++) {
105 shiftQ[unknown]=QInGathered[unknown]+0.5*gradientQ[QInEnumerator._unknowns*normal+unknown]*::exahype2::fv::getVolumeSize( patchSize, QInEnumerator._numberOfDoFsPerAxisInCell )(normal);
106 }
107 flux(
108 shiftQ,
109 ::exahype2::fv::getVolumeCentre( patchCentre, patchSize, QInEnumerator._numberOfDoFsPerAxisInCell, volumeIndex ),
110 ::exahype2::fv::getVolumeSize( patchSize, QInEnumerator._numberOfDoFsPerAxisInCell ),
111 t, dt, normal, temp
112 );
113 for (int unknown=0; unknown<QInEnumerator._unknowns; unknown++) {
114 timederivative[QInterEnumerator(patchIndex,volumeIndex,unknown)] -=temp[ unknown ]/::exahype2::fv::getVolumeSize( patchSize, QInEnumerator._numberOfDoFsPerAxisInCell )(normal);
115 }
116
117 }
118
119}
120
121template <class QInEnumeratorType, class QInterEnumeratorType>
123 const double* __restrict__ QIn,
124 const QInEnumeratorType QInEnumerator,
125 const tarch::la::Vector<Dimensions,double>& patchCentre,
127 int patchIndex,
128 const tarch::la::Vector<Dimensions,int>& volumeIndex,
129 double t,
130 double dt,
131 double* __restrict__ timederivative,
132 double* __restrict__ QfaceXneg,
133 double* __restrict__ QfaceXpos,
134 double* __restrict__ QfaceYneg,
135 double* __restrict__ QfaceYpos,
136 double* __restrict__ QfaceZneg,
137 double* __restrict__ QfaceZpos,
138 QInterEnumeratorType QInterEnumerator
139) {
140 double QInGathered[QInEnumerator._unknowns+QInEnumerator._numberOfAuxiliaryVariables];
141 //double gradientQ[QInEnumerator._unknowns*3];
142 //double deriTGathered[QInEnumerator._unknowns];
143 const tarch::la::Vector<Dimensions,double> VolumeSize=::exahype2::fv::getVolumeSize( patchSize, QInEnumerator._numberOfDoFsPerAxisInCell );
144
145 //VolumeSize=::exahype2::fv::getVolumeSize( patchSize, QInEnumerator._numberOfDoFsPerAxisInCell );
146 // gather
147 #if defined(SharedOMP)
148 #pragma omp simd
149 #endif
150 for (int unknown=0; unknown<QInEnumerator._unknowns+QInEnumerator._numberOfAuxiliaryVariables; unknown++) {
151 QInGathered[unknown] = QIn[ QInEnumerator(patchIndex,volumeIndex,unknown) ];
152 }
153 for (int unknown=0; unknown<QInEnumerator._unknowns; unknown++) {
154 //Q^{n+1/2}_{i-1/2}
155 QfaceXneg[QInterEnumerator(patchIndex,volumeIndex,unknown)]=QInGathered[unknown]
156 +0.5*dt*timederivative[ QInterEnumerator(patchIndex,volumeIndex,unknown) ]
157 -0.5*VolumeSize(0)*QInGathered[ QInEnumerator._unknowns*1+unknown ];
158 QfaceYneg[QInterEnumerator(patchIndex,volumeIndex,unknown)]=QInGathered[unknown]
159 +0.5*dt*timederivative[ QInterEnumerator(patchIndex,volumeIndex,unknown) ]
160 -0.5*VolumeSize(1)*QInGathered[ QInEnumerator._unknowns*2+unknown ];
161 QfaceZneg[QInterEnumerator(patchIndex,volumeIndex,unknown)]=QInGathered[unknown]
162 +0.5*dt*timederivative[ QInterEnumerator(patchIndex,volumeIndex,unknown) ]
163 -0.5*VolumeSize(2)*QInGathered[ QInEnumerator._unknowns*3+unknown ];
164 //Q^{n+1/2}_{i+1/2}
165 QfaceXpos[QInterEnumerator(patchIndex,volumeIndex,unknown)]=QInGathered[unknown]
166 +0.5*dt*timederivative[ QInterEnumerator(patchIndex,volumeIndex,unknown) ]
167 +0.5*VolumeSize(0)*QInGathered[ QInEnumerator._unknowns*1+unknown ];
168 QfaceYpos[QInterEnumerator(patchIndex,volumeIndex,unknown)]=QInGathered[unknown]
169 +0.5*dt*timederivative[ QInterEnumerator(patchIndex,volumeIndex,unknown) ]
170 +0.5*VolumeSize(0)*QInGathered[ QInEnumerator._unknowns*2+unknown ];
171 QfaceZpos[QInterEnumerator(patchIndex,volumeIndex,unknown)]=QInGathered[unknown]
172 +0.5*dt*timederivative[ QInterEnumerator(patchIndex,volumeIndex,unknown) ]
173 +0.5*VolumeSize(0)*QInGathered[ QInEnumerator._unknowns*3+unknown ];
174 }
175
176}
177
178template <class QInEnumeratorType, class QMaxEigenvalueEnumeratorType>
180 const double* __restrict__ QIn,
181 QInEnumeratorType QInEnumerator,
183 const tarch::la::Vector<Dimensions,double>& patchCentre,
185 int patchIndex,
186 const tarch::la::Vector<Dimensions,int>& volumeIndex,
187 double t,
188 double dt,
189 int normal,
190 double* __restrict__ QMaxEigenvalue,
191 QMaxEigenvalueEnumeratorType QMaxEigenvalueEnumerator
192) {
193 double QInGathered[QInEnumerator._unknowns+QInEnumerator._numberOfAuxiliaryVariables];
194
195 // gather
196 #if defined(SharedOMP)
197 #pragma omp simd
198 #endif
199 for (int unknown=0; unknown<QInEnumerator._unknowns+QInEnumerator._numberOfAuxiliaryVariables; unknown++) {
200 QInGathered[unknown] = QIn[ QInEnumerator(patchIndex,volumeIndex,unknown) ];
201 }
202
203 // actual computation via user's functor
204 QMaxEigenvalue[ QMaxEigenvalueEnumerator(patchIndex,volumeIndex,0) ] =
205 maxEigenvalue(
206 QInGathered,
207 ::exahype2::fv::getVolumeCentre( patchCentre, patchSize, QInEnumerator._numberOfDoFsPerAxisInCell, volumeIndex ),
208 ::exahype2::fv::getVolumeSize( patchSize, QInEnumerator._numberOfDoFsPerAxisInCell ),
209 t,
210 dt,
211 normal
212 );
213}
214
215#if defined(GPUOffloadingOMP)
216#pragma omp declare target
217#endif
218template <typename QInEnumeratorType, typename QInterEnumeratorType, typename QMaxEigenvalueEnumeratorType, typename QOutEnumeratorType>
220 const double* __restrict__ QIn,
221 const QInEnumeratorType QInEnumerator,
222 const double* __restrict__ tempMaxEigenvalueX,
223 const double* __restrict__ tempMaxEigenvalueY,
224 const double* __restrict__ tempMaxEigenvalueZ,
225 const QMaxEigenvalueEnumeratorType & eigenvalueEnumerator,
226 const tarch::la::Vector<Dimensions,double>& patchCentre,
228 int patchIndex,
229 const tarch::la::Vector<Dimensions,int>& volumeIndex,
230 int unknown,
231 double dt,
232 double* __restrict__ QOut,
233 const QOutEnumeratorType & QOutEnumerator,
234 double* __restrict__ QfaceXneg,
235 double* __restrict__ QfaceXpos,
236 double* __restrict__ QfaceYneg,
237 double* __restrict__ QfaceYpos,
238 double* __restrict__ QfaceZneg,
239 double* __restrict__ QfaceZpos,
240 QInterEnumeratorType QInterEnumerator
241) {
242 auto updateAlongOneDirection = [=](const double* __restrict__ tempMaxEigenvalue, const double* __restrict__ QfaceNLeft, const double* __restrict__ QfaceNRight, int normal) {
245 leftVolume(normal)--;
246 rightVolume(normal)++;
247
248 double leftVolumeValue = tempMaxEigenvalue[eigenvalueEnumerator(patchIndex, leftVolume, 0)];
249 double centerVolumeValue = tempMaxEigenvalue[eigenvalueEnumerator(patchIndex, volumeIndex, 0)];
250 double rightVolumeValue = tempMaxEigenvalue[eigenvalueEnumerator(patchIndex, rightVolume, 0)];
251
252 const double lambdaLeft = tempMaxEigenvalue[eigenvalueEnumerator(patchIndex, leftVolume,0)] > tempMaxEigenvalue[eigenvalueEnumerator(patchIndex, volumeIndex,0)]
253 ? tempMaxEigenvalue[eigenvalueEnumerator(patchIndex, leftVolume,0)]
254 : tempMaxEigenvalue[eigenvalueEnumerator(patchIndex, volumeIndex,0)];
255 const double lambdaRight = tempMaxEigenvalue[eigenvalueEnumerator(patchIndex, rightVolume,0)] > tempMaxEigenvalue[eigenvalueEnumerator(patchIndex, volumeIndex,0)]
256 ? tempMaxEigenvalue[eigenvalueEnumerator(patchIndex, rightVolume,0)]
257 : tempMaxEigenvalue[eigenvalueEnumerator(patchIndex, volumeIndex,0)];
258 double fluxLeft = - lambdaLeft * (QfaceNLeft[QInterEnumerator(patchIndex, volumeIndex,unknown)] - QfaceNRight[QInterEnumerator(patchIndex, leftVolume,unknown)]);
259 double fluxRight = - lambdaRight * (QfaceNLeft[QInterEnumerator(patchIndex, rightVolume,unknown)] - QfaceNRight[QInterEnumerator(patchIndex, volumeIndex,unknown)]);
260
261 QOut[ QOutEnumerator(patchIndex, volumeIndex,unknown) ] += dt / patchSize(normal) * QOutEnumerator._numberOfDoFsPerAxisInCell * (fluxLeft - fluxRight)*0.5;
262 };
263 updateAlongOneDirection(tempMaxEigenvalueX, QfaceXneg, QfaceXpos, 0);
264 updateAlongOneDirection(tempMaxEigenvalueY, QfaceYneg, QfaceYpos, 1);
265 if (Dimensions==3) updateAlongOneDirection(tempMaxEigenvalueZ, QfaceZneg, QfaceZpos, 2);
266}
267#if defined(GPUOffloadingOMP)
268#pragma omp end declare target
269#endif
270
271template <class QInEnumeratorType, class QInterEnumeratorType, class QFluxEnumeratorType>
273 double* __restrict__ QfaceNLeft,
274 double* __restrict__ QfaceNRight,
275 QInterEnumeratorType QInterEnumerator,
276 QInEnumeratorType QInEnumerator,
278 const tarch::la::Vector<Dimensions,double>& patchCentre,
280 int patchIndex,
281 const tarch::la::Vector<Dimensions,int>& volumeIndex,
282 double t,
283 double dt,
284 int normal,
285 double* __restrict__ QFluxL,
286 double* __restrict__ QFluxR,
287 QFluxEnumeratorType QFluxEnumerator
288) {
289 double QLeft[QInEnumerator._unknowns], QRight[QInEnumerator._unknowns];
290 double tempFlux[QInEnumerator._unknowns];
291
292 for (int unknown=0; unknown<QInEnumerator._unknowns; unknown++) {
293 QLeft[unknown] = QfaceNLeft[ QInterEnumerator(patchIndex,volumeIndex,unknown) ];
294 QRight[unknown] = QfaceNRight[ QInterEnumerator(patchIndex,volumeIndex,unknown) ];
295 }
296
297 flux(
298 QLeft,
299 ::exahype2::fv::getVolumeCentre( patchCentre, patchSize, QInEnumerator._numberOfDoFsPerAxisInCell, volumeIndex ),
300 ::exahype2::fv::getVolumeSize( patchSize, QInEnumerator._numberOfDoFsPerAxisInCell ),
301 t,
302 dt,
303 normal,
304 tempFlux
305 );
306 for (int unknown=0; unknown<QInEnumerator._unknowns; unknown++) {
307 QFluxL[ QFluxEnumerator(patchIndex,volumeIndex,unknown) ] = tempFlux[unknown];
308 }
309
310 flux(
311 QRight,
312 ::exahype2::fv::getVolumeCentre( patchCentre, patchSize, QInEnumerator._numberOfDoFsPerAxisInCell, volumeIndex ),
313 ::exahype2::fv::getVolumeSize( patchSize, QInEnumerator._numberOfDoFsPerAxisInCell ),
314 t,
315 dt,
316 normal,
317 tempFlux
318 );
319 for (int unknown=0; unknown<QInEnumerator._unknowns; unknown++) {
320 QFluxR[ QFluxEnumerator(patchIndex,volumeIndex,unknown) ] = tempFlux[unknown];
321 }
322}
323
324template <typename QFluxEnumeratorType, typename QOutEnumeratorType>
326 const double* __restrict__ tempFluxXL,
327 const double* __restrict__ tempFluxYL,
328 const double* __restrict__ tempFluxZL,
329 const double* __restrict__ tempFluxXR,
330 const double* __restrict__ tempFluxYR,
331 const double* __restrict__ tempFluxZR,
332 const QFluxEnumeratorType fluxEnumerator,
333 const tarch::la::Vector<Dimensions,double>& patchCentre,
335 int patchIndex,
336 const tarch::la::Vector<Dimensions,int>& volumeIndex,
337 int unknown,
338 double dt,
339 double* __restrict__ QOut,
340 const QOutEnumeratorType& QOutEnumerator
341) {
342 auto updateAlongOneDirection = [=](const double* __restrict__ tempFluxNL, const double* __restrict__ tempFluxNR, int normal) {
345 leftVolume(normal)--;
346 rightVolume(normal)++;
347
348 double fluxLeft = 0.5 * tempFluxNR[fluxEnumerator(patchIndex, leftVolume,unknown)]
349 + 0.5 * tempFluxNL[fluxEnumerator(patchIndex, volumeIndex,unknown)];
350 double fluxRight = 0.5 * tempFluxNR[fluxEnumerator(patchIndex, volumeIndex,unknown)]
351 + 0.5 * tempFluxNL[fluxEnumerator(patchIndex, rightVolume,unknown)];
352 if ( std::isnan(fluxLeft - fluxRight) )
353 {std::cout<<"fluxLeft: "<<std::to_string(fluxLeft)<<" fluxRight: "<<std::to_string(fluxRight)<<" flux result: "<<dt / patchSize(normal) * QOutEnumerator._numberOfDoFsPerAxisInCell*(fluxLeft - fluxRight)<<std::endl;}
354
355 //QOut[ QOutEnumerator(patchIndex, volumeIndex,unknown) ] += 1e-12*(fluxLeft-fluxRight);
356 QOut[ QOutEnumerator(patchIndex, volumeIndex,unknown) ] += dt / patchSize(normal) * QOutEnumerator._numberOfDoFsPerAxisInCell
357 *(fluxLeft - fluxRight);
358 };
359 updateAlongOneDirection(tempFluxXL, tempFluxXR, 0);
360 updateAlongOneDirection(tempFluxYL, tempFluxYR, 1);
361 if (Dimensions==3) updateAlongOneDirection(tempFluxZL, tempFluxZR, 2);
362}
363
364
365template <class QInEnumeratorType, class QInterEnumeratorType, class QNCPFaceEnumeratorType>
367 double* __restrict__ QfaceNLeft,
368 double* __restrict__ QfaceNRight,
369 QInterEnumeratorType QInterEnumerator,
370 QInEnumeratorType QInEnumerator,
372 const tarch::la::Vector<Dimensions,double>& patchCentre,
374 int patchIndex,
375 const tarch::la::Vector<Dimensions,int>& volumeIndex,
376 double t,
377 double dt,
378 int normal,
379 double* __restrict__ QD,
380 const QNCPFaceEnumeratorType QNcpEnumerator
381) {
382 double QAverage[QInEnumerator._unknowns];
383 double DeltaQ[QInEnumerator._unknowns];
384 double QFluxGathered[QInEnumerator._unknowns];
385
388 rightAdjacentVolume(normal)++;
389
390 // gather
391 for (int unknown=0; unknown<QInEnumerator._unknowns; unknown++) {
392 QAverage[unknown] = 0.5 * QfaceNRight[ QInterEnumerator(patchIndex,leftAdjacentVolume,unknown) ]
393 + 0.5 * QfaceNLeft[ QInterEnumerator(patchIndex,rightAdjacentVolume,unknown) ];
394 DeltaQ[unknown] = QfaceNLeft[ QInterEnumerator(patchIndex,rightAdjacentVolume,unknown) ]
395 - QfaceNRight[ QInterEnumerator(patchIndex,leftAdjacentVolume,unknown) ];
396 }
397
398 ncp(
399 QAverage, DeltaQ,
400 ::exahype2::fv::getVolumeCentre( patchCentre, patchSize, QInEnumerator._numberOfDoFsPerAxisInCell, volumeIndex ),
401 ::exahype2::fv::getVolumeSize( patchSize, QInEnumerator._numberOfDoFsPerAxisInCell ),
402 t,
403 dt,
404 normal,
405 QFluxGathered
406 );
407
408 for (int unknown=0; unknown<QInEnumerator._unknowns; unknown++) {
409 QD[ QNcpEnumerator(patchIndex,volumeIndex,unknown) ] = QFluxGathered[unknown];
410 }
411}
412
413template <typename QNCPFaceEnumeratorType, typename QOutEnumeratorType>
415 const double* __restrict__ QDX,
416 const double* __restrict__ QDY,
417 const double* __restrict__ QDZ,
418 const QNCPFaceEnumeratorType ncpEnumerator,
419 const tarch::la::Vector<Dimensions,double>& patchCentre,
421 int patchIndex,
422 const tarch::la::Vector<Dimensions,int>& volumeIndex,
423 int unknown,
424 double dt,
425 double* __restrict__ QOut,
426 const QOutEnumeratorType& QOutEnumerator
427) {
428 auto updateAlongOneCoordinateDirection = [=](const double* __restrict__ QD, int normal) {
431 leftFace(normal)--;
432
433 double fluxLeft = QD[ncpEnumerator(patchIndex, leftFace, unknown)];
434 double fluxRight = QD[ncpEnumerator(patchIndex, rightFace, unknown)];
435
436 //contribution from D term is negative
437 QOut[ QOutEnumerator(patchIndex, volumeIndex,unknown) ] += dt / patchSize(normal) * QOutEnumerator._numberOfDoFsPerAxisInCell *
438 (fluxLeft + fluxRight)*(-0.5);
439 };
440 updateAlongOneCoordinateDirection( QDX, 0 );
441 updateAlongOneCoordinateDirection( QDY, 1 );
442 if (Dimensions==3) updateAlongOneCoordinateDirection( QDZ, 2 );
443}
444
445
446//function on working
447template <class QInEnumeratorType, class QInterEnumeratorType, class QOutEnumeratorType>
449 const double* __restrict__ QIn,
450 const QInterEnumeratorType QInterEnumerator,
451 const QInEnumeratorType QInEnumerator,
454 const tarch::la::Vector<Dimensions,double>& patchCentre,
456 int patchIndex,
457 const tarch::la::Vector<Dimensions,int>& volumeIndex,
458 double t,
459 double dt,
460 double* timeDerivative,
461 double* __restrict__ QOut,
462 const QOutEnumeratorType& QOutEnumerator,
463 bool evalNCP,
464 bool evalSRC
465) {
466 double QInGathered[QInEnumerator._unknowns+QInEnumerator._numberOfAuxiliaryVariables];
467 double QSourceGathered[QInEnumerator._unknowns];
468 double QNCPGathered[QInEnumerator._unknowns];
469 double gradientQ[QInEnumerator._unknowns*3];
470
471 // gather
472 for (int unknown=0; unknown<QInEnumerator._unknowns+QInEnumerator._numberOfAuxiliaryVariables; unknown++) {
473 QInGathered[unknown] = QIn[ QInEnumerator(patchIndex,volumeIndex,unknown) ];
474 }
475 for (int unknown=0; unknown<QInEnumerator._unknowns; unknown++) {
476 gradientQ[QInEnumerator._unknowns*0+unknown]=QInGathered[ QInEnumerator._unknowns*1+unknown ];
477 gradientQ[QInEnumerator._unknowns*1+unknown]=QInGathered[ QInEnumerator._unknowns*2+unknown ];
478 gradientQ[QInEnumerator._unknowns*2+unknown]=QInGathered[ QInEnumerator._unknowns*3+unknown ];
479 }
480 for (int unknown=0; unknown<QInEnumerator._unknowns; unknown++) {
481 QInGathered[unknown] += 0.5*dt*timeDerivative[ QInterEnumerator(patchIndex,volumeIndex,unknown) ]; //Q^n+1/2_i
482 }
483 //
484
485 if (evalSRC){
486 //add source contribution
487 source(
488 QInGathered,
489 ::exahype2::fv::getVolumeCentre( patchCentre, patchSize, QInEnumerator._numberOfDoFsPerAxisInCell, volumeIndex ),
490 ::exahype2::fv::getVolumeSize( patchSize, QInEnumerator._numberOfDoFsPerAxisInCell ),
491 t,
492 dt,
493 QSourceGathered
494 );
495 for (int unknown=0; unknown<QInEnumerator._unknowns; unknown++) {
496 QOut[ QOutEnumerator(patchIndex,volumeIndex,unknown) ] += dt * QSourceGathered[unknown];
497 }
498 }
499
500 if (evalNCP){
501 //add ncp contribution
502 for (int normal=0; normal<3; normal++){
503 ncp(
504 QInGathered, gradientQ+QInEnumerator._unknowns*normal,
505 ::exahype2::fv::getVolumeCentre( patchCentre, patchSize, QInEnumerator._numberOfDoFsPerAxisInCell, volumeIndex ),
506 ::exahype2::fv::getVolumeSize( patchSize, QInEnumerator._numberOfDoFsPerAxisInCell ),
507 t,
508 dt,
509 normal,
510 QNCPGathered
511 );
512 for (int unknown=0; unknown<QInEnumerator._unknowns; unknown++) {
513 QOut[ QOutEnumerator(patchIndex,volumeIndex,unknown) ] -= dt * QNCPGathered[unknown];
514 }
515 }
516 }
517}
518
519//function on working
520template <class QInEnumeratorType>
522 const double* __restrict__ QIn,
523 QInEnumeratorType QInEnumerator,
525 const tarch::la::Vector<Dimensions,double>& patchCentre,
527 int patchIndex,
528 const tarch::la::Vector<Dimensions,int>& volumeIndex,
529 double t,
530 double dt
531) {
532 double QInGathered[QInEnumerator._unknowns+QInEnumerator._numberOfAuxiliaryVariables];
533
534 // gather
535 #if defined(SharedOMP)
536 #pragma omp simd
537 #endif
538 for (int unknown=0; unknown<QInEnumerator._unknowns+QInEnumerator._numberOfAuxiliaryVariables; unknown++) {
539 QInGathered[unknown] = QIn[ QInEnumerator(patchIndex,volumeIndex,unknown) ];
540 }
541
542 double result = 0.0;
543 for (int normal=0; normal<Dimensions; normal++) {
544 // actual computation via user's functor
545 result = std::max(
546 result,
547 maxEigenvalue(
548 QInGathered,
549 ::exahype2::fv::getVolumeCentre( patchCentre, patchSize, QInEnumerator._numberOfDoFsPerAxisInCell, volumeIndex ),
550 ::exahype2::fv::getVolumeSize( patchSize, QInEnumerator._numberOfDoFsPerAxisInCell ),
551 t,
552 dt,
553 normal
554 )
555 );
556 }
557
558 return result;
559}
560
562//old stuff below
564
565
566
567
568
const int temp
float dt
Definition DSL_test.py:5
static void updateSolutionWithEigenvalueDamping_LoopBody(const double *__restrict__ QIn, const QInEnumeratorType QInEnumerator, const double *__restrict__ tempMaxEigenvalueX, const double *__restrict__ tempMaxEigenvalueY, const double *__restrict__ tempMaxEigenvalueZ, const QMaxEigenvalueEnumeratorType &eigenvalueEnumerator, const tarch::la::Vector< Dimensions, double > &patchCentre, const tarch::la::Vector< Dimensions, double > &patchSize, int patchIndex, const tarch::la::Vector< Dimensions, int > &volumeIndex, int unknown, double dt, double *__restrict__ QOut, const QOutEnumeratorType &QOutEnumerator, double *__restrict__ QfaceXneg, double *__restrict__ QfaceXpos, double *__restrict__ QfaceYneg, double *__restrict__ QfaceYpos, double *__restrict__ QfaceZneg, double *__restrict__ QfaceZpos, QInterEnumeratorType QInterEnumerator) InlineMethod
void computeQonFace_LoopBody(const double *__restrict__ QIn, const QInEnumeratorType QInEnumerator, const tarch::la::Vector< Dimensions, double > &patchCentre, const tarch::la::Vector< Dimensions, double > &patchSize, int patchIndex, const tarch::la::Vector< Dimensions, int > &volumeIndex, double t, double dt, double *__restrict__ timederivative, double *__restrict__ QfaceXneg, double *__restrict__ QfaceXpos, double *__restrict__ QfaceYneg, double *__restrict__ QfaceYpos, double *__restrict__ QfaceZneg, double *__restrict__ QfaceZpos, QInterEnumeratorType QInterEnumerator) InlineMethod
static void updateSolutionWithDTerm_LoopBody(const double *__restrict__ QDX, const double *__restrict__ QDY, const double *__restrict__ QDZ, const QNCPFaceEnumeratorType ncpEnumerator, const tarch::la::Vector< Dimensions, double > &patchCentre, const tarch::la::Vector< Dimensions, double > &patchSize, int patchIndex, const tarch::la::Vector< Dimensions, int > &volumeIndex, int unknown, double dt, double *__restrict__ QOut, const QOutEnumeratorType &QOutEnumerator) InlineMethod
static void copySolution_LoopBody(const double *__restrict__ QIn, const QInEnumeratorType &QInEnumerator, int patchIndex, const tarch::la::Vector< Dimensions, int > &volumeIndex, int unknown, double *__restrict__ QOut, const QOutEnumeratorType &QOutEnumerator) InlineMethod
static void computeFlux_LoopBody(double *__restrict__ QfaceNLeft, double *__restrict__ QfaceNRight, QInterEnumeratorType QInterEnumerator, QInEnumeratorType QInEnumerator, exahype2::fv::musclhancock::Flux flux, const tarch::la::Vector< Dimensions, double > &patchCentre, const tarch::la::Vector< Dimensions, double > &patchSize, int patchIndex, const tarch::la::Vector< Dimensions, int > &volumeIndex, double t, double dt, int normal, double *__restrict__ QFluxL, double *__restrict__ QFluxR, QFluxEnumeratorType QFluxEnumerator) InlineMethod
void computeTimeDerivative_LoopBody(const double *__restrict__ QIn, const QInEnumeratorType QInEnumerator, exahype2::fv::musclhancock::Flux flux, exahype2::fv::musclhancock::NonconservativeProduct ncp, exahype2::fv::musclhancock::Source source, const tarch::la::Vector< Dimensions, double > &patchCentre, const tarch::la::Vector< Dimensions, double > &patchSize, int patchIndex, const tarch::la::Vector< Dimensions, int > &volumeIndex, double t, double dt, double *__restrict__ timederivative, QInterEnumeratorType QInterEnumerator) InlineMethod
Definition LoopBody.cpph:26
void updateSolutionwithNCPandSource_LoopBody(const double *__restrict__ QIn, const QInterEnumeratorType QInterEnumerator, const QInEnumeratorType QInEnumerator, exahype2::fv::musclhancock::NonconservativeProduct ncp, exahype2::fv::musclhancock::Source source, const tarch::la::Vector< Dimensions, double > &patchCentre, const tarch::la::Vector< Dimensions, double > &patchSize, int patchIndex, const tarch::la::Vector< Dimensions, int > &volumeIndex, double t, double dt, double *timeDerivative, double *__restrict__ QOut, const QOutEnumeratorType &QOutEnumerator, bool evalNCP, bool evalSRC) InlineMethod
static void computeDTerm_LoopBody(double *__restrict__ QfaceNLeft, double *__restrict__ QfaceNRight, QInterEnumeratorType QInterEnumerator, QInEnumeratorType QInEnumerator, exahype2::fv::musclhancock::NonconservativeProduct ncp, const tarch::la::Vector< Dimensions, double > &patchCentre, const tarch::la::Vector< Dimensions, double > &patchSize, int patchIndex, const tarch::la::Vector< Dimensions, int > &volumeIndex, double t, double dt, int normal, double *__restrict__ QD, const QNCPFaceEnumeratorType QNcpEnumerator) InlineMethod
static void updateSolutionWithFlux_LoopBody(const double *__restrict__ tempFluxXL, const double *__restrict__ tempFluxYL, const double *__restrict__ tempFluxZL, const double *__restrict__ tempFluxXR, const double *__restrict__ tempFluxYR, const double *__restrict__ tempFluxZR, const QFluxEnumeratorType fluxEnumerator, const tarch::la::Vector< Dimensions, double > &patchCentre, const tarch::la::Vector< Dimensions, double > &patchSize, int patchIndex, const tarch::la::Vector< Dimensions, int > &volumeIndex, int unknown, double dt, double *__restrict__ QOut, const QOutEnumeratorType &QOutEnumerator) InlineMethod
static void computeMaxEigenvalue_LoopBody(const double *__restrict__ QIn, QInEnumeratorType QInEnumerator, exahype2::fv::musclhancock::MaxEigenvalue maxEigenvalue, const tarch::la::Vector< Dimensions, double > &patchCentre, const tarch::la::Vector< Dimensions, double > &patchSize, int patchIndex, const tarch::la::Vector< Dimensions, int > &volumeIndex, double t, double dt, int normal, double *__restrict__ QMaxEigenvalue, QMaxEigenvalueEnumeratorType QMaxEigenvalueEnumerator) InlineMethod
static double reduceMaxEigenvalue_LoopBody(const double *__restrict__ QIn, QInEnumeratorType QInEnumerator, exahype2::fv::musclhancock::MaxEigenvalue maxEigenvalue, const tarch::la::Vector< Dimensions, double > &patchCentre, const tarch::la::Vector< Dimensions, double > &patchSize, int patchIndex, const tarch::la::Vector< Dimensions, int > &volumeIndex, double t, double dt) InlineMethod
std::function< void(const double *__restrict__ Q, const double *__restrict__ deltaQ, const tarch::la::Vector< Dimensions, double > &faceCentre, const tarch::la::Vector< Dimensions, double > &volumeH, double t, double dt, int normal, double *__restrict__ BTimesDeltaQ) NonconservativeProduct)
Definition Functors.h:45
std::function< void(const double *__restrict__ Q, const tarch::la::Vector< Dimensions, double > &volumeX, const tarch::la::Vector< Dimensions, double > &volumeH, double t, double dt, double *__restrict__ S) Source)
Definition Functors.h:24
std::function< void(const double *__restrict__ Q, const tarch::la::Vector< Dimensions, double > &faceCentre, const tarch::la::Vector< Dimensions, double > &volumeH, double t, double dt, int normal, double *__restrict__ F) Flux)
Definition Functors.h:34
std::function< double(const double *__restrict__ Q, const tarch::la::Vector< Dimensions, double > &faceCentre, const tarch::la::Vector< Dimensions, double > &volumeH, double t, double dt, int normal) MaxEigenvalue)
Definition Functors.h:54
static tarch::la::Vector< 2, double > getVolumeCentre(const tarch::la::Vector< 2, double > &x, const tarch::la::Vector< 2, double > &h, int numberOfVolumesPerAxisInPatch, const tarch::la::Vector< 2, int > &index)
In ExaHyPE's Finite Volume setup, a cell hosts a patch of Finite Volumes.
Definition PatchUtils.h:94
static tarch::la::Vector< 2, double > getVolumeSize(const tarch::la::Vector< 2, double > &h, int numberOfVolumesPerAxisInPatch)
We need this routine within vectorised and GPUised code.
Definition PatchUtils.h:24
auto volumeIndex(Args... args)
Definition VolumeIndex.h:54
ncp
Definition swe.py:172
Simple vector class.
Definition Vector.h:134