 |
Peano
|
Go to the documentation of this file.
7 **** An new formulation of the HLLEM Riemann solver for the Shallow Water Equation with support for inundation
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},
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}}
23 * title = {A Second-Order Well-Balanced Positivity Preserving Central-Upwind Scheme for the Saint-Venant System},
28 * journal = {Communications in mathematical sciences},
29 * author = {Kurganov, Alexander and Petrova, G.},
30 * doi = {10.4310/CMS.2007.v5.n1.a6}}
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];
43 // Compute dry tolerance according to KURGANOV. Does not work!
44 //const double dryTol = std::pow(h[0], 4);
45 const double dryTol = hThreshold;
47 const double cLeft = std::sqrt(g * hLeft);
48 const double cRight = std::sqrt(g * hRight);
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));
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));
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));
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));
64 const double eigenvaluesLeft[3] {
65 normal == 0 ? uCorrectedLeft + cLeft : vCorrectedLeft + cLeft,
66 normal == 0 ? uCorrectedLeft - cLeft : vCorrectedLeft - cLeft,
67 normal == 0 ? uCorrectedLeft : vCorrectedLeft
69 const double eigenvaluesRight[3] {
70 normal == 0 ? uCorrectedRight + cRight : vCorrectedRight + cRight,
71 normal == 0 ? uCorrectedRight - cRight : vCorrectedRight - cRight,
72 normal == 0 ? uCorrectedRight : vCorrectedRight
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);
80 for (int i = 0; i < 3; i++) {
81 const double absEigenvalueRight = std::fabs(eigenvaluesRight[i]);
82 maxWaveSpeed = std::fmax(absEigenvalueRight, maxWaveSpeed);
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
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
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);
101 double dJump[3] = {0.0};
102 dJump[Shortcuts::hu + normal] = 0.5 * g * hRoe * deltaEta;
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)
110 for (int i = 0; i < 3; i++){
111 FL[i] = netUpdates[i] + dJump[i];
112 FR[i] = netUpdates[i] - dJump[i];
115 if (QL[Shortcuts::h] < dryTol) {
116 FL[Shortcuts::hu] = FL[Shortcuts::hv] = 0.0;
118 if (QR[Shortcuts::h] < dryTol) {
119 FR[Shortcuts::hu] = FR[Shortcuts::hv] = 0.0;