Peano
aderSWE.cpp
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 #include "aderSWE.h"
4 #include "exahype2/RefinementControl.h"
5 
6 tarch::logging::Log exahype::limiting::swe::aderSWE::_log( "exahype::limiting::swe::aderSWE" );
7 
8 
10  [[maybe_unused]] const double* NOALIAS Q, // Q[4+0]
11  [[maybe_unused]] const tarch::la::Vector<DIMENSIONS, double>& x,
12  [[maybe_unused]] const tarch::la::Vector<DIMENSIONS, double>& h,
13  [[maybe_unused]] double t,
14  [[maybe_unused]] double dt,
15  [[maybe_unused]] int normal
16 ) {
17 
18  static constexpr double g = 9.81;
19  static constexpr double zeroFlux = 1e-3;
20 
21  if(Q[0] < zeroFlux)
22  {
23  return 0;
24  }
25 
26  double u = Q[normal+1] / Q[0];
27  double c = std::sqrt(g * Q[0]);
28 
29  return std::max(std::abs(u - c), std::abs(u + c));
30 
31 }
32 
34  [[maybe_unused]] const double* NOALIAS Q, // Q[4+0]
35  [[maybe_unused]] const tarch::la::Vector<DIMENSIONS, double>& x,
36  [[maybe_unused]] const tarch::la::Vector<DIMENSIONS, double>& h_,
37  [[maybe_unused]] double t,
38  [[maybe_unused]] double dt,
39  [[maybe_unused]] int normal,
40  [[maybe_unused]] double* NOALIAS F // F[4]
41 ) {
42 
43  static constexpr double g = 9.81;
44  static constexpr double zeroFlux = 1e-3;
45 
46  double h = Q[0];
47 
48  if(h < zeroFlux)
49  {
50  F[0] = 0;
51  F[1] = 0;
52  F[2] = 0;
53  F[3] = 0;
54  return;
55  }
56 
57  double hu = Q[1];
58  double hv = Q[2];
59  double u = Q[1] / h;
60  double v = Q[2] / h;
61 
62  if (normal == 0) {
63  F[0] = hu;
64  F[1] = h * u * u + 0.5 * g * h * h;
65  F[2] = h * u * v;
66  F[3] = 0;
67  } else {
68  F[0] = hv;
69  F[1] = h * u * v;
70  F[2] = h * v * v + 0.5 * g * h * h;
71  F[3] = 0;
72  }
73 
74 }
75 
76 void exahype::limiting::swe::aderSWE::nonconservativeProduct(
77  [[maybe_unused]] const double* NOALIAS Q, // Q[4+0]
78  [[maybe_unused]] const double* NOALIAS deltaQ, // deltaQ[4+0]
79  [[maybe_unused]] const tarch::la::Vector<DIMENSIONS, double>& x,
80  [[maybe_unused]] const tarch::la::Vector<DIMENSIONS, double>& h,
81  [[maybe_unused]] double t,
82  [[maybe_unused]] double dt,
83  [[maybe_unused]] int normal,
84  [[maybe_unused]] double* NOALIAS BTimesDeltaQ // BTimesDeltaQ[4]
85 ) {
86 
87  static constexpr double g = 9.81;
88  static constexpr double zeroFlux = 1e-3;
89 
90  if(Q[0] < zeroFlux)
91  {
92  BTimesDeltaQ[0] = 0.0;
93  BTimesDeltaQ[1] = 0.0;
94  BTimesDeltaQ[2] = 0.0;
95  BTimesDeltaQ[3] = 0.0;
96  return;
97  }
98 
99  switch (normal) {
100  case 0: //x
101  BTimesDeltaQ[0] = 0.0;
102  BTimesDeltaQ[1] = g * Q[0] * (deltaQ[3]);
103  BTimesDeltaQ[2] = 0.0;
104  BTimesDeltaQ[3] = 0.0;
105  break;
106  case 1: //y
107  BTimesDeltaQ[0] = 0.0;
108  BTimesDeltaQ[1] = 0.0;
109  BTimesDeltaQ[2] = g * Q[0] * (deltaQ[3]);
110  BTimesDeltaQ[3] = 0.0;
111  break;
112  }
113 
114 }
115 
117  double* const FL, // FL[4
118  double* const FR, // FR[4
119  const double* const QL, // QL[4+0]
120  const double* const QR, // QR[4+0]
121  const double t,
122  const double dt,
123  const tarch::la::Vector<DIMENSIONS, double>& x,
124  const tarch::la::Vector<DIMENSIONS, double>& h,
125  const int direction,
126  bool isBoundaryFace,
127  int faceIndex
128 ) {
129 
130  //Compute max eigenvalue over face
131  double smax = 0.0;
132  for(int xy=0; xy<Order+1; xy++){
133  smax = std::max(smax, maxEigenvalue(&QL[xy*4], x, h, t, dt, direction));
134  smax = std::max(smax, maxEigenvalue(&QR[xy*4], x, h, t, dt, direction));
135 
136  }
137 
138  for(int xy=0; xy<Order+1; xy++){
139 
140  // h gets added term from bathimetry, u and v are regular Rusanov, b does not change
141  FL[xy*4+0] = 0.5*(FL[xy*4+0]+FR[xy*4+0] + smax*(QL[xy*4+0]+QL[xy*4+3]-QR[xy*4+0]-QR[xy*4+3]) );
142  FL[xy*4+1] = 0.5*(FL[xy*4+1]+FR[xy*4+1] + smax*(QL[xy*4+1]-QR[xy*4+1]) );
143  FL[xy*4+2] = 0.5*(FL[xy*4+2]+FR[xy*4+2] + smax*(QL[xy*4+2]-QR[xy*4+2]) );
144  FL[xy*4+3] = 0.0;
145 
146  FR[xy*4+0] = FL[xy*4+0];
147  FR[xy*4+1] = FL[xy*4+1];
148  FR[xy*4+2] = FL[xy*4+2];
149  FR[xy*4+3] = 0.0;
150 
151  //Contribution from NCP
152  FL[xy*4+direction+1] += 0.5*9.81*0.5*(QL[xy*4+0]+QR[xy*4+0])*(QR[xy*4+3]-QL[xy*4+3]);
153  FR[xy*4+direction+1] -= 0.5*9.81*0.5*(QL[xy*4+0]+QR[xy*4+0])*(QR[xy*4+3]-QL[xy*4+3]);
154 
155  }
156 
157 }
void riemannSolver(double *FL, double *FR, const double *const QL, const double *const QR, const double dt, const int direction, bool isBoundaryFace, int faceIndex)
static double maxEigenvalue(const double *const Q, int normal, const double CCZ4e, const double CCZ4ds, const double CCZ4GLMc, const double CCZ4GLMd)
u
Definition: euler.py:113
flux
Definition: euler.py:29
hu
Definition: swe.py:80
g
Definition: swe.py:85
hv
Definition: swe.py:81
h
Definition: swe.py:79
tarch::logging::Log _log
This is variant 1 of the fused kernels.