Peano
Loading...
Searching...
No Matches
HLLEM.py
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
4hllem = r"""
5 /**
6 ****
7 **** An new formulation of the HLLEM Riemann solver for the Shallow Water Equation with support for inundation
8 ****
9 * Literature:
10 *
11 * @article{DUMBSER2016275,
12 * title = {A new efficient formulation of the HLLEM Riemann solver for general conservative and non-conservative hyperbolic systems},
13 * journal = {Journal of Computational Physics},
14 * volume = {304},
15 * pages = {275-319},
16 * year = {2016},
17 * issn = {0021-9991},
18 * doi = {https://doi.org/10.1016/j.jcp.2015.10.014},
19 * url = {https://www.sciencedirect.com/science/article/pii/S0021999115006786},
20 * author = {Michael Dumbser and Dinshaw S. Balsara}}
21 *
22 * @article{KURGANOV,
23 * title = {A Second-Order Well-Balanced Positivity Preserving Central-Upwind Scheme for the Saint-Venant System},
24 * year = {2007},
25 * month = {03},
26 * pages = {},
27 * volume = {5},
28 * journal = {Communications in mathematical sciences},
29 * author = {Kurganov, Alexander and Petrova, G.},
30 * doi = {10.4310/CMS.2007.v5.n1.a6}}
31 ****
32 */
33
34 const double hLeft = QL[Shortcuts::h];
35 const double hRight = QR[Shortcuts::h];
36 const double huLeft = QL[Shortcuts::hu];
37 const double huRight = QR[Shortcuts::hu];
38 const double hvLeft = QL[Shortcuts::hv];
39 const double hvRight = QR[Shortcuts::hv];
40 const double bLeft = QL[Shortcuts::z];
41 const double bRight = QR[Shortcuts::z];
42
43 // Compute dry tolerance according to KURGANOV. Does not work!
44 //const double dryTol = std::pow(h[0], 4);
45 const double dryTol = hThreshold;
46
47 const double cLeft = std::sqrt(g * hLeft);
48 const double cRight = std::sqrt(g * hRight);
49
50 // Correction of particle velocities according to KURGANOV (modified version):
51 const double uCorrectedLeft = huLeft * hLeft * std::sqrt(2) / std::sqrt(std::pow(hLeft, 4) + std::pow(std::fmax(hLeft, dryTol), 4));
52 const double uCorrectedRight = huRight * hRight * std::sqrt(2) / std::sqrt(std::pow(hRight, 4) + std::pow(std::fmax(hRight, dryTol), 4));
53
54 const double vCorrectedLeft = hvLeft * hLeft * std::sqrt(2) / std::sqrt(std::pow(hLeft, 4) + std::pow(std::fmax(hLeft, dryTol), 4));
55 const double vCorrectedRight = hvRight * hRight * std::sqrt(2) / std::sqrt(std::pow(hRight, 4) + std::pow(std::fmax(hRight, dryTol), 4));
56
57 // Implementation following Eq. (2.17) in KURGANOV does not work:
58 // const double uCorrectedLeft = huLeft * hLeft * std::sqrt(2) / std::sqrt(std::pow(hLeft, 4) + std::fmax(std::pow(hLeft, 4), dryTol));
59 // const double uCorrectedRight = huRight * hRight * std::sqrt(2) / std::sqrt(std::pow(hRight, 4) + std::fmax(std::pow(hRight, 4), dryTol));
60
61 // const double vCorrectedLeft = hvLeft * hLeft * std::sqrt(2) / std::sqrt(std::pow(hLeft, 4) + std::fmax(std::pow(hLeft, 4), dryTol));
62 // const double vCorrectedRight = hvRight * hRight * std::sqrt(2) / std::sqrt(std::pow(hRight, 4) + std::fmax(std::pow(hRight, 4), dryTol));
63
64 const double eigenvaluesLeft[3] {
65 normal == 0 ? uCorrectedLeft + cLeft : vCorrectedLeft + cLeft,
66 normal == 0 ? uCorrectedLeft - cLeft : vCorrectedLeft - cLeft,
67 normal == 0 ? uCorrectedLeft : vCorrectedLeft
68 };
69 const double eigenvaluesRight[3] {
70 normal == 0 ? uCorrectedRight + cRight : vCorrectedRight + cRight,
71 normal == 0 ? uCorrectedRight - cRight : vCorrectedRight - cRight,
72 normal == 0 ? uCorrectedRight : vCorrectedRight
73 };
74
75 double maxWaveSpeed = 0.0;
76 for (int i = 0; i < 3; i++) {
77 const double absEigenvalueLeft = std::fabs(eigenvaluesLeft[i]);
78 maxWaveSpeed = std::fmax(absEigenvalueLeft, maxWaveSpeed);
79 }
80 for (int i = 0; i < 3; i++) {
81 const double absEigenvalueRight = std::fabs(eigenvaluesRight[i]);
82 maxWaveSpeed = std::fmax(absEigenvalueRight, maxWaveSpeed);
83 }
84
85 const double fluxLeft[3] {
86 normal == 0 ? hLeft * uCorrectedLeft : hLeft * vCorrectedLeft,
87 normal == 0 ? hLeft * uCorrectedLeft * uCorrectedLeft : hLeft * vCorrectedLeft * uCorrectedLeft,
88 normal == 0 ? hLeft * uCorrectedLeft * vCorrectedLeft : hLeft * vCorrectedLeft * vCorrectedLeft
89 };
90
91 const double fluxRight[3] {
92 normal == 0 ? hRight * uCorrectedRight : hRight * vCorrectedRight,
93 normal == 0 ? hRight * uCorrectedRight * uCorrectedRight : hRight * vCorrectedRight * uCorrectedRight,
94 normal == 0 ? hRight * uCorrectedRight * vCorrectedRight : hRight * vCorrectedRight * vCorrectedRight
95 };
96
97 const double bMax = std::fmax(bLeft, bRight);
98 const double deltaEta = std::fmax(hRight + bRight - bMax, 0.0) - std::fmax(hLeft + bLeft - bMax, 0.0);
99 const double hRoe = 0.5 * (hLeft + hRight);
100
101 double dJump[3] = {0.0};
102 dJump[Shortcuts::hu + normal] = 0.5 * g * hRoe * deltaEta;
103
104 const double netUpdates[3] {
105 0.5 * (fluxLeft[Shortcuts::h] + fluxRight[Shortcuts::h]) - 0.5 * maxWaveSpeed * deltaEta,
106 0.5 * (fluxLeft[Shortcuts::hu] + fluxRight[Shortcuts::hu]) - 0.5 * maxWaveSpeed * (huRight - huLeft),
107 0.5 * (fluxLeft[Shortcuts::hv] + fluxRight[Shortcuts::hv]) - 0.5 * maxWaveSpeed * (hvRight - hvLeft)
108 };
109
110 for (int i = 0; i < 3; i++){
111 FL[i] = netUpdates[i] + dJump[i];
112 FR[i] = netUpdates[i] - dJump[i];
113 }
114
115 if (QL[Shortcuts::h] < dryTol) {
116 FL[Shortcuts::hu] = FL[Shortcuts::hv] = 0.0;
117 }
118 if (QR[Shortcuts::h] < dryTol) {
119 FR[Shortcuts::hu] = FR[Shortcuts::hv] = 0.0;
120 }
121
122 return maxWaveSpeed;
123"""