Peano
Loading...
Searching...
No Matches
HLLEMRiemannSolver.cpph
Go to the documentation of this file.
1// This file is part of the ExaHyPE2 project. For conditions of distribution and
2// use, please see the copyright notice at www.peano-framework.org
3
4template <class T, class Shortcuts>
5static inline GPU_CALLABLE_METHOD double applications::exahype2::ShallowWater::hllemRiemannSolver(
6 const T* const NOALIAS QL,
7 const T* const NOALIAS QR,
8 const tarch::la::Vector<DIMENSIONS, double>& x,
9 const tarch::la::Vector<DIMENSIONS, double>& h,
10 const double t,
11 const double dt,
12 const int normal,
13 T* const NOALIAS FL,
14 T* const NOALIAS FR
15) {
16 const T hLeft = QL[Shortcuts::h];
17 const T hRight = QR[Shortcuts::h];
18 const T huLeft = QL[Shortcuts::hu];
19 const T huRight = QR[Shortcuts::hu];
20 const T hvLeft = QL[Shortcuts::hv];
21 const T hvRight = QR[Shortcuts::hv];
22 const T zLeft = QL[Shortcuts::z];
23 const T zRight = QR[Shortcuts::z];
24
25 // Compute dry tolerance according to Kurganov. Does not work!
26 // const T dryTol = std::pow(h[0], 4);
27 const T dryTol = hThreshold;
28
29 const T cLeft = std::sqrt(g * hLeft);
30 const T cRight = std::sqrt(g * hRight);
31
32 // Correction of particle velocities according to Kurganov (modified version):
33 const T uCorrectedLeft = huLeft * hLeft * std::sqrt(2)
34 / std::sqrt(std::pow(hLeft, 4) + std::pow(std::fmax(hLeft, dryTol), 4));
35 const T uCorrectedRight = huRight * hRight * std::sqrt(2)
36 / std::sqrt(std::pow(hRight, 4) + std::pow(std::fmax(hRight, dryTol), 4));
37
38 const T vCorrectedLeft = hvLeft * hLeft * std::sqrt(2)
39 / std::sqrt(std::pow(hLeft, 4) + std::pow(std::fmax(hLeft, dryTol), 4));
40 const T vCorrectedRight = hvRight * hRight * std::sqrt(2)
41 / std::sqrt(std::pow(hRight, 4) + std::pow(std::fmax(hRight, dryTol), 4));
42
43 // Implementation following Eq. (2.17) in Kurganov does not work:
44 // const T uCorrectedLeft = huLeft * hLeft * std::sqrt(2) / std::sqrt(std::pow(hLeft, 4) +
45 // std::fmax(std::pow(hLeft, 4), dryTol)); const T uCorrectedRight = huRight * hRight * std::sqrt(2) /
46 // std::sqrt(std::pow(hRight, 4) + std::fmax(std::pow(hRight, 4), dryTol));
47
48 // const T vCorrectedLeft = hvLeft * hLeft * std::sqrt(2) / std::sqrt(std::pow(hLeft, 4) +
49 // std::fmax(std::pow(hLeft, 4), dryTol)); const T vCorrectedRight = hvRight * hRight * std::sqrt(2) /
50 // std::sqrt(std::pow(hRight, 4) + std::fmax(std::pow(hRight, 4), dryTol));
51
52 const T eigenvaluesLeft[3]{
53 normal == 0 ? uCorrectedLeft + cLeft : vCorrectedLeft + cLeft,
54 normal == 0 ? uCorrectedLeft - cLeft : vCorrectedLeft - cLeft,
55 normal == 0 ? uCorrectedLeft : vCorrectedLeft
56 };
57 const T eigenvaluesRight[3]{
58 normal == 0 ? uCorrectedRight + cRight : vCorrectedRight + cRight,
59 normal == 0 ? uCorrectedRight - cRight : vCorrectedRight - cRight,
60 normal == 0 ? uCorrectedRight : vCorrectedRight
61 };
62
63 T maxWaveSpeed = 0.0;
64 for (int i = 0; i < 3; i++) {
65 const T absEigenvalueLeft = std::fabs(eigenvaluesLeft[i]);
66 maxWaveSpeed = std::fmax(absEigenvalueLeft, maxWaveSpeed);
67 }
68 for (int i = 0; i < 3; i++) {
69 const T absEigenvalueRight = std::fabs(eigenvaluesRight[i]);
70 maxWaveSpeed = std::fmax(absEigenvalueRight, maxWaveSpeed);
71 }
72
73 const T fluxLeft[3]{
74 normal == 0 ? hLeft * uCorrectedLeft : hLeft * vCorrectedLeft,
75 normal == 0 ? hLeft * uCorrectedLeft * uCorrectedLeft : hLeft * vCorrectedLeft * uCorrectedLeft,
76 normal == 0 ? hLeft * uCorrectedLeft * vCorrectedLeft : hLeft * vCorrectedLeft * vCorrectedLeft
77 };
78
79 const T fluxRight[3]{
80 normal == 0 ? hRight * uCorrectedRight : hRight * vCorrectedRight,
81 normal == 0 ? hRight * uCorrectedRight * uCorrectedRight : hRight * vCorrectedRight * uCorrectedRight,
82 normal == 0 ? hRight * uCorrectedRight * vCorrectedRight : hRight * vCorrectedRight * vCorrectedRight
83 };
84
85 const T bMax = std::fmax(zLeft, zRight);
86 const T deltaEta = std::fmax(hRight + zRight - bMax, 0.0) - std::fmax(hLeft + zLeft - bMax, 0.0);
87 const T hRoe = 0.5 * (hLeft + hRight);
88
89 T dJump[3] = {0.0};
90 dJump[Shortcuts::hu + normal] = 0.5 * g * hRoe * deltaEta;
91
92 const T netUpdates[3]{
93 0.5 * (fluxLeft[Shortcuts::h] + fluxRight[Shortcuts::h]) - 0.5 * maxWaveSpeed * deltaEta,
94 0.5 * (fluxLeft[Shortcuts::hu] + fluxRight[Shortcuts::hu]) - 0.5 * maxWaveSpeed * (huRight - huLeft),
95 0.5 * (fluxLeft[Shortcuts::hv] + fluxRight[Shortcuts::hv]) - 0.5 * maxWaveSpeed * (hvRight - hvLeft)
96 };
97
98 for (int i = 0; i < 3; i++) {
99 FL[i] = netUpdates[i] + dJump[i];
100 FR[i] = netUpdates[i] - dJump[i];
101 }
102
103 if (QL[Shortcuts::h] < dryTol) {
104 FL[Shortcuts::hu] = FL[Shortcuts::hv] = 0.0;
105 }
106 if (QR[Shortcuts::h] < dryTol) {
107 FR[Shortcuts::hu] = FR[Shortcuts::hv] = 0.0;
108 }
109
110 return maxWaveSpeed;
111}
static GPU_CALLABLE_METHOD double hllemRiemannSolver(const T *const NOALIAS QL, const T *const NOALIAS QR, const tarch::la::Vector< DIMENSIONS, double > &x, const tarch::la::Vector< DIMENSIONS, double > &h, const double t, const double dt, const int normal, T *const NOALIAS FL, T *const NOALIAS FR)
A new formulation of the HLLEM Riemann solver for the Shallow Water Equation with support for inundat...