Peano
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 
4 hllem = 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 """