5 if (Q[Shortcuts::h] <= hThreshold) {
9 // Wave speed estimation based on the flux Jacobian
10 const auto Vn{Q[Shortcuts::hu + normal] / Q[Shortcuts::h]};
11 const auto c{std::sqrt(g * Q[Shortcuts::h])};
12 const auto sFlux{std::fmax(std::fabs(Vn + c), std::fabs(Vn - c))};
15 stiff_eigenvalue =
r"""
16 // Wave speed estimation based on the stiff source
17 const auto momentum{std::sqrt(Q[Shortcuts::hu] * Q[Shortcuts::hu] + Q[Shortcuts::hv] * Q[Shortcuts::hv])};
18 const auto sSource{2.0 * g * momentum * invXi / (Q[Shortcuts::h] * Q[Shortcuts::h])};
22 for (int n = 0; n < NumberOfUnknowns; n++) {
26 if (Q[Shortcuts::h] <= hThreshold) {
30 const auto Vn{Q[Shortcuts::hu + normal] / Q[Shortcuts::h]};
31 F[Shortcuts::h] = Q[Shortcuts::hu + normal]; // Mass flux
32 F[Shortcuts::hu] = Vn * Q[Shortcuts::hu]; // Momentum-x flux
33 F[Shortcuts::hv] = Vn * Q[Shortcuts::hv]; // Momentum-y flux
34 F[Shortcuts::hu + normal] += 0.5 * g * Q[Shortcuts::h] * Q[Shortcuts::h]; // Hydrostatic pressure
37 nonconservative_product =
r"""
38 for (int n = 0; n < NumberOfUnknowns; n++) {
39 BTimesDeltaQ[n] = 0.0;
42 if (Q[Shortcuts::h] <= hThreshold) {
46 // Bathymetry/topography-related effects
47 BTimesDeltaQ[Shortcuts::hu + normal] = g * Q[Shortcuts::h] * (deltaQ[Shortcuts::h] + deltaQ[Shortcuts::z]);
50 stiff_nonconservative_product =
r"""
51 // Compute stiff turbulent drag on the interface
52 const auto momentumSQR{Q[Shortcuts::hu] * Q[Shortcuts::hu] + Q[Shortcuts::hv] * Q[Shortcuts::hv]};
53 const auto momentum{std::sqrt(momentumSQR)};
54 if (tarch::la::greater(momentum / Q[Shortcuts::h], 0.0)) {
55 const auto turbulentDrag{g * momentumSQR * invXi / (Q[Shortcuts::h] * Q[Shortcuts::h])};
56 const auto directionVect{Q[Shortcuts::hu + normal] / momentum};
57 BTimesDeltaQ[Shortcuts::hu + normal] += h[normal] * turbulentDrag * directionVect;
61 stiff_source_term_aderdg =
r"""
62 for (int n = 0; n < NumberOfUnknowns; n++) {
66 if (Q[Shortcuts::h] <= hThreshold) {
70 // Compute local slope cF
71 const auto dzx{deltaQ[Shortcuts::z]};
72 const auto dzy{deltaQ[Shortcuts::z + NumberOfUnknowns + NumberOfAuxiliaryVariables]};
73 const auto cF{1.0 / std::sqrt(1.0 + dzx * dzx + dzy * dzy)};
75 // Apply friction only if there is some movement
76 const auto momentumSQR{Q[Shortcuts::hu] * Q[Shortcuts::hu] + Q[Shortcuts::hv] * Q[Shortcuts::hv]};
77 const auto momentum{std::sqrt(momentumSQR)};
78 if (tarch::la::greater(momentum / Q[Shortcuts::h], 0.0)) {
79 const auto coulombFriction{mu * cF * Q[Shortcuts::h]};
80 const auto turbulentDrag{momentumSQR * invXi / (Q[Shortcuts::h] * Q[Shortcuts::h])};
81 const auto frictionTerm{-g * (coulombFriction + turbulentDrag) / momentum};
82 S[Shortcuts::hu] = Q[Shortcuts::hu] * frictionTerm;
83 S[Shortcuts::hv] = Q[Shortcuts::hv] * frictionTerm;
87 stiff_source_term_fv =
r"""
88 for (int n = 0; n < NumberOfUnknowns; n++) {
92 if (Q[Shortcuts::h] <= hThreshold) {
96 // Compute local slope cF
97 const auto dzx{deltaQ[Shortcuts::z]};
98 const auto dzy{deltaQ[Shortcuts::z + NumberOfUnknowns + NumberOfAuxiliaryVariables]};
99 const auto cF{1.0 / std::sqrt(1.0 + dzx * dzx + dzy * dzy)};
101 // Apply friction only if there is some movement
102 const auto momentumSQR{Q[Shortcuts::hu] * Q[Shortcuts::hu] + Q[Shortcuts::hv] * Q[Shortcuts::hv]};
103 const auto momentum{std::sqrt(momentumSQR)};
104 if (tarch::la::greater(momentum / Q[Shortcuts::h], 0.0)) {
105 const auto coulombFriction{mu * cF * Q[Shortcuts::h]};
106 const auto frictionTerm{-g * coulombFriction / momentum};
107 S[Shortcuts::hu] = Q[Shortcuts::hu] * frictionTerm;
108 S[Shortcuts::hv] = Q[Shortcuts::hv] * frictionTerm;