Peano
Loading...
Searching...
No Matches
RusanovRiemannSolver.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, class Quadrature, int NumberOfUnknowns, int NumberOfAuxiliaryVariables, int Order>
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 // Compute average left and right states
17 constexpr auto N{NumberOfUnknowns + NumberOfAuxiliaryVariables};
18 T QavgL[N] = {};
19 T QavgR[N] = {};
20 for (auto xy = 0; xy < Order + 1; ++xy) {
21 for (auto i = 0; i < N; ++i) {
22 QavgL[i] += Quadrature::weights2[xy] * QL[xy * N + i];
23 QavgR[i] += Quadrature::weights2[xy] * QR[xy * N + i];
24 }
25 }
26
27 // Wave speed estimation based on the flux Jacobian
28 auto sL{0.0};
29 if (QavgL[Shortcuts::h] > hThreshold) {
30 const auto VnL{QavgL[Shortcuts::hu + normal] / QavgL[Shortcuts::h]};
31 const auto cL{std::sqrt(g * QavgL[Shortcuts::h])};
32 sL = std::fmax(std::fabs(VnL - cL), std::fabs(VnL + cL));
33 }
34 auto sR{0.0};
35 if (QavgR[Shortcuts::h] > hThreshold) {
36 const auto VnR{QavgR[Shortcuts::hu + normal] / QavgR[Shortcuts::h]};
37 const auto cR{std::sqrt(g * QavgR[Shortcuts::h])};
38 sR = std::fmax(std::fabs(VnR - cR), std::fabs(VnR + cR));
39 }
40 const auto smax{std::fmax(sR, sL)};
41
42 auto j{0};
43 auto rusanovFlux{0.0};
44 for (auto xy = 0; xy < Order + 1; ++xy) {
45 for (auto i = 0; i < N; ++i) {
46 j = xy * N + i;
47 rusanovFlux = 0.5 * (FL[j] + FR[j] + smax * (QL[j] - QR[j]));
48 FL[j] = rusanovFlux;
49 FR[j] = rusanovFlux;
50 }
51 // Ignore flux for flow topography
52 j = xy * N + Shortcuts::z;
53 FL[j] = 0.0;
54 FR[j] = 0.0;
55 }
56}
57
58template <class T, class Shortcuts, int NumberOfUnknowns, int NumberOfAuxiliaryVariables>
59static inline GPU_CALLABLE_METHOD double applications::exahype2::ShallowWater::rusanovRiemannSolverFV(
60 const T* const NOALIAS QL,
61 const T* const NOALIAS QR,
62 const tarch::la::Vector<DIMENSIONS, double>& x,
63 const tarch::la::Vector<DIMENSIONS, double>& h,
64 const double t,
65 const double dt,
66 const int normal,
67 T* const NOALIAS FL,
68 T* const NOALIAS FR
69) {
70 flux<T, Shortcuts, NumberOfUnknowns>(QL, x, h, t, dt, normal, FL);
71 flux<T, Shortcuts, NumberOfUnknowns>(QR, x, h, t, dt, normal, FR);
72
73 const auto smax{std::fmax(
74 maxEigenvalue<T, Shortcuts>(QL, x, h, t, dt, normal),
75 maxEigenvalue<T, Shortcuts>(QR, x, h, t, dt, normal)
76 )};
77 constexpr auto N{NumberOfAuxiliaryVariables + NumberOfUnknowns};
78
79 T Qavg[N] = {};
80 T DeltaQ[N] = {};
81 for (int i = 0; i < NumberOfUnknowns; ++i) {
82 Qavg[i] = 0.5 * (QL[i] + QR[i]);
83 DeltaQ[i] = QR[i] - QL[i];
84 FL[i] = 0.5 * (FL[i] + FR[i] - smax * DeltaQ[i]);
85 FR[i] = FL[i];
86 }
87
88 for (int i = NumberOfUnknowns; i < N; ++i) {
89 Qavg[i] = 0.5 * (QL[i] + QR[i]);
90 DeltaQ[i] = QR[i] - QL[i];
91 }
92
93 T ncp[NumberOfUnknowns] = {};
94 FrictionLaws::nonconservativeProduct<T, Shortcuts, NumberOfUnknowns>(Qavg, DeltaQ, x, h, t, dt, normal, ncp);
95 for (int i = 0; i < NumberOfUnknowns; ++i) {
96 FL[i] += 0.5 * ncp[i];
97 FR[i] -= 0.5 * ncp[i];
98 }
99
100 auto sL{0.0};
101 if (QL[Shortcuts::h] > hThreshold) {
102 const auto hL{QL[Shortcuts::h] > hThreshold ? QL[Shortcuts::h] : hThreshold};
103 const auto momentumL{std::sqrt(QL[Shortcuts::hu] * QL[Shortcuts::hu] + QL[Shortcuts::hv] * QL[Shortcuts::hv])};
104 sL = 2.0 * g * momentumL * invXi / (hL * hL);
105 }
106
107 auto sR{0.0};
108 if (QL[Shortcuts::h] > hThreshold) {
109 const auto hR{QR[Shortcuts::h] > hThreshold ? QR[Shortcuts::h] : hThreshold};
110 const auto momentumR{std::sqrt(QR[Shortcuts::hu] * QR[Shortcuts::hu] + QR[Shortcuts::hv] * QR[Shortcuts::hv])};
111 sR = 2.0 * g * momentumR * invXi / (hR * hR);
112 }
113
114 return std::fmax(smax, h[normal] * std::fmax(sL, sR));
115}
static GPU_CALLABLE_METHOD void rusanovRiemannSolverADERDG(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)
static GPU_CALLABLE_METHOD double rusanovRiemannSolverFV(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)