Peano
Loading...
Searching...
No Matches
FrictionLaws.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>
5static inline GPU_CALLABLE_METHOD double applications::exahype2::ShallowWater::FrictionLaws::maxEigenvalue(
6 const T* const NOALIAS Q,
7 const tarch::la::Vector<DIMENSIONS, double>& x,
8 const tarch::la::Vector<DIMENSIONS, double>& h,
9 const double t,
10 const double dt,
11 const int normal
12) {
13 if (Q[Shortcuts::h] <= hThreshold) {
14 return 0.0;
15 }
16
17 // Wave speed estimation based on the flux Jacobian
18 const auto Vn{Q[Shortcuts::hu + normal] / Q[Shortcuts::h]};
19 const auto c{std::sqrt(g * Q[Shortcuts::h])};
20 const auto sFlux{std::fmax(std::fabs(Vn + c), std::fabs(Vn - c))};
21
22 // Wave speed estimation based on the stiff source
23 const auto momentum{std::sqrt(Q[Shortcuts::hu] * Q[Shortcuts::hu] + Q[Shortcuts::hv] * Q[Shortcuts::hv])};
24 const auto sSource{2.0 * g * momentum * invXi / (Q[Shortcuts::h] * Q[Shortcuts::h])};
25
26 return std::fmax(sFlux, h[normal] * sSource);
27}
28
29template <class T, class Shortcuts, int NumberOfUnknowns>
31 const T* const NOALIAS Q,
32 const T* const NOALIAS deltaQ,
33 const tarch::la::Vector<DIMENSIONS, double>& x,
34 const tarch::la::Vector<DIMENSIONS, double>& h,
35 const double t,
36 const double dt,
37 const int normal,
38 T* const NOALIAS BTimesDeltaQ
39) {
40 for (int n = 0; n < NumberOfUnknowns; n++) {
41 BTimesDeltaQ[n] = 0.0;
42 }
43
44 if (Q[Shortcuts::h] <= hThreshold) {
45 return;
46 }
47
48 // Bathymetry/topography-related effects
49 BTimesDeltaQ[Shortcuts::hu + normal] = g * Q[Shortcuts::h] * (deltaQ[Shortcuts::h] + deltaQ[Shortcuts::z]);
50
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;
58 }
59}
60
61template <class T, class Shortcuts, int NumberOfUnknowns, int NumberOfAuxiliaryVariables>
63 const T* const NOALIAS Q,
64 const T* const NOALIAS deltaQ,
65 const tarch::la::Vector<DIMENSIONS, double>& x,
66 const tarch::la::Vector<DIMENSIONS, double>& h,
67 const double t,
68 const double dt,
69 T* const NOALIAS S
70) {
71 for (int n = 0; n < NumberOfUnknowns; n++) {
72 S[n] = 0.0;
73 }
74
75 if (Q[Shortcuts::h] <= hThreshold) {
76 return;
77 }
78
79 // Compute local slope cF
80 const auto dzx{deltaQ[Shortcuts::z]};
81 const auto dzy{deltaQ[Shortcuts::z + NumberOfUnknowns + NumberOfAuxiliaryVariables]};
82 const auto cF{1.0 / std::sqrt(1.0 + dzx * dzx + dzy * dzy)};
83
84 // Apply friction only if there is some movement
85 const auto momentumSQR{Q[Shortcuts::hu] * Q[Shortcuts::hu] + Q[Shortcuts::hv] * Q[Shortcuts::hv]};
86 const auto momentum{std::sqrt(momentumSQR)};
87 if (tarch::la::greater(momentum / Q[Shortcuts::h], 0.0)) {
88 const auto coulombFriction{mu * cF * Q[Shortcuts::h]};
89 const auto turbulentDrag{momentumSQR * invXi / (Q[Shortcuts::h] * Q[Shortcuts::h])};
90 const auto frictionTerm{-g * (coulombFriction + turbulentDrag) / momentum};
91 S[Shortcuts::hu] = Q[Shortcuts::hu] * frictionTerm;
92 S[Shortcuts::hv] = Q[Shortcuts::hv] * frictionTerm;
93 }
94}
95
96template <class T, class Shortcuts, int NumberOfUnknowns, int NumberOfAuxiliaryVariables>
98 const T* const NOALIAS Q,
99 const T* const NOALIAS deltaQ,
100 const tarch::la::Vector<DIMENSIONS, double>& x,
101 const tarch::la::Vector<DIMENSIONS, double>& h,
102 const double t,
103 const double dt,
104 T* const NOALIAS S
105) {
106 for (int n = 0; n < NumberOfUnknowns; n++) {
107 S[n] = 0.0;
108 }
109
110 if (Q[Shortcuts::h] <= hThreshold) {
111 return;
112 }
113
114 // Compute local slope cF
115 const auto dzx{deltaQ[Shortcuts::z]};
116 const auto dzy{deltaQ[Shortcuts::z + NumberOfUnknowns + NumberOfAuxiliaryVariables]};
117 const auto cF{1.0 / std::sqrt(1.0 + dzx * dzx + dzy * dzy)};
118
119 // Apply friction only if there is some movement
120 const auto momentumSQR{Q[Shortcuts::hu] * Q[Shortcuts::hu] + Q[Shortcuts::hv] * Q[Shortcuts::hv]};
121 const auto momentum{std::sqrt(momentumSQR)};
122 if (tarch::la::greater(momentum / Q[Shortcuts::h], 0.0)) {
123 const auto coulombFriction{mu * cF * Q[Shortcuts::h]};
124 const auto frictionTerm{-g * coulombFriction / momentum};
125 S[Shortcuts::hu] = Q[Shortcuts::hu] * frictionTerm;
126 S[Shortcuts::hv] = Q[Shortcuts::hv] * frictionTerm;
127 }
128}
static GPU_CALLABLE_METHOD double maxEigenvalue(const T *const NOALIAS Q, const tarch::la::Vector< DIMENSIONS, double > &x, const tarch::la::Vector< DIMENSIONS, double > &h, const double t, const double dt, const int normal)
static GPU_CALLABLE_METHOD void nonconservativeProduct(const T *const NOALIAS Q, const T *const NOALIAS deltaQ, 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 BTimesDeltaQ)
static GPU_CALLABLE_METHOD void sourceTermADERDG(const T *const NOALIAS Q, const T *const NOALIAS deltaQ, const tarch::la::Vector< DIMENSIONS, double > &x, const tarch::la::Vector< DIMENSIONS, double > &h, const double t, const double dt, T *const NOALIAS S)
static GPU_CALLABLE_METHOD void sourceTermFV(const T *const NOALIAS Q, const T *const NOALIAS deltaQ, const tarch::la::Vector< DIMENSIONS, double > &x, const tarch::la::Vector< DIMENSIONS, double > &h, const double t, const double dt, T *const NOALIAS S)