Canoe
Comprehensive Atmosphere N' Ocean Engine
flux_decomposition.hpp
Go to the documentation of this file.
1 #ifndef SRC_SNAP_IMPLICIT_FLUX_DECOMPOSITION_HPP_
2 #define SRC_SNAP_IMPLICIT_FLUX_DECOMPOSITION_HPP_
3 
4 // athena
5 #include <athena/athena.hpp>
6 
7 // climath
8 #include <climath/core.h>
9 
10 // Eigen
11 #include <Eigen/Core>
12 #include <Eigen/Dense>
13 
14 inline void CopyPrimitives(Real wl[], Real wr[], AthenaArray<Real> const& w,
15  int k, int j, int i, CoordinateDirection dir) {
16  if (dir == X1DIR) {
17  for (int n = 0; n < NHYDRO; ++n) {
18  wl[n] = w(n, k, j, i - 1);
19  wr[n] = w(n, k, j, i);
20  }
21  } else if (dir == X2DIR) {
22  for (int n = 0; n < NHYDRO; ++n) {
23  wl[n] = w(n, j, i - 1, k);
24  wr[n] = w(n, j, i, k);
25  }
26  } else { // X3DIR
27  for (int n = 0; n < NHYDRO; ++n) {
28  wl[n] = w(n, i - 1, k, j);
29  wr[n] = w(n, i, k, j);
30  }
31  }
32 }
33 
34 inline void RoeAverage(Real prim[], Real gm1, Real wl[], Real wr[]) {
35  Real sqrtdl = sqrt(wl[IDN]);
36  Real sqrtdr = sqrt(wr[IDN]);
37  Real isdlpdr = 1.0 / (sqrtdl + sqrtdr);
38 
39  // Roe average scheme
40  // Flux in the interface between i-th and i+1-th cells:
41  // A(i+1/2) = [sqrt(rho(i))*A(i) + sqrt(rho(i+1))*A(i+1)]/(sqrt(rho(i)) +
42  // sqrt(rho(i+1)))
43 
44  prim[IDN] = sqrtdl * sqrtdr;
45  prim[IVX] = (sqrtdl * wl[IVX] + sqrtdr * wr[IVX]) * isdlpdr;
46  prim[IVY] = (sqrtdl * wl[IVY] + sqrtdr * wr[IVY]) * isdlpdr;
47  prim[IVZ] = (sqrtdl * wl[IVZ] + sqrtdr * wr[IVZ]) * isdlpdr;
48 
49  for (int i = 1; i <= NVAPOR; ++i)
50  prim[i] = (sqrtdl * wl[i] + sqrtdr * wr[i]) * isdlpdr;
51 
52  // Etot of the left side.
53  Real el = wl[IPR] / gm1 +
54  0.5 * wl[IDN] * (sqr(wl[IVX]) + sqr(wl[IVY]) + sqr(wl[IVZ]));
55 
56  // Etot of the right side.
57  Real er = wr[IPR] / gm1 +
58  0.5 * wr[IDN] * (sqr(wr[IVX]) + sqr(wr[IVY]) + sqr(wr[IVZ]));
59 
60  // Enthalpy divided by the density.
61  Real hbar = ((el + wl[IPR]) / sqrtdl + (er + wr[IPR]) / sqrtdr) * isdlpdr;
62 
63  // Roe averaged pressure
64  prim[IPR] =
65  (hbar - 0.5 * (sqr(prim[IVX]) + sqr(prim[IVY]) + sqr(prim[IVZ]))) * gm1 /
66  (gm1 + 1.) * prim[IDN];
67 }
68 
69 template <typename Derived>
70 inline void Eigenvalue(Eigen::MatrixBase<Derived>& Lambda, Real u, Real cs) {
71  Lambda << u - cs, 0., 0., 0., 0., 0., u, 0., 0., 0., 0., 0., u + cs, 0., 0.,
72  0., 0., 0., u, 0., 0., 0., 0., 0., u;
73 
74  Lambda = Lambda.cwiseAbs();
75 }
76 
77 template <typename Derived1, typename Derived2>
78 inline void Eigenvector(Eigen::DenseBase<Derived1>& Rmat,
79  Eigen::DenseBase<Derived2>& Rimat, Real prim[], Real cs,
80  Real gm1, CoordinateDirection dir) {
81  Real r = prim[IDN];
82  Real u = prim[IVX + dir];
83  Real v = prim[IVX + (IVY - IVX + dir) % 3];
84  Real w = prim[IVX + (IVZ - IVX + dir) % 3];
85  Real p = prim[IPR];
86 
87  Real ke = 0.5 * (u * u + v * v + w * w);
88  Real hp = (gm1 + 1.) / gm1 * p / r;
89  Real h = hp + ke;
90 
91  Rmat << 1., 1., 1., 0., 0., u - cs, u, u + cs, 0., 0., v, v, v, 1., 0., w, w,
92  w, 0., 1., h - u * cs, ke, h + u * cs, v, w;
93 
94  Rimat << (cs * ke + u * hp) / (2. * cs * hp), (-hp - cs * u) / (2. * cs * hp),
95  -v / (2. * hp), -w / (2. * hp), 1. / (2. * hp), (hp - ke) / hp, u / hp,
96  v / hp, w / hp, -1. / hp, (cs * ke - u * hp) / (2. * cs * hp),
97  (hp - cs * u) / (2. * cs * hp), -v / (2. * hp), -w / (2. * hp),
98  1. / (2. * hp), -v, 0., 1., 0., 0., -w, 0., 0., 1., 0.;
99 }
100 
101 template <typename Derived1>
102 inline void FluxJacobian(Eigen::DenseBase<Derived1>& dfdq, Real gm1, Real w[],
103  CoordinateDirection dir) {
104  // flux derivative
105  // Input variables are density, velocity field and energy.
106  // The primitives of cell (n,i)
107  Real v1 = w[IVX + dir];
108  Real v2 = w[IVX + (IVY - IVX + dir) % 3];
109  Real v3 = w[IVX + (IVZ - IVX + dir) % 3];
110  Real rho = w[IDN];
111  Real pres = w[IPR];
112  Real s2 = v1 * v1 + v2 * v2 + v3 * v3;
113 
114  Real c1 = ((gm1 - 1) * s2 / 2 - (gm1 + 1) / gm1 * pres / rho) * v1;
115  Real c2 = (gm1 + 1) / gm1 * pres / rho + s2 / 2 - gm1 * v1 * v1;
116 
117  dfdq << 0, 1., 0., 0., 0., gm1 * s2 / 2 - v1 * v1, (2. - gm1) * v1, -gm1 * v2,
118  -gm1 * v3, gm1, -v1 * v2, v2, v1, 0., 0., -v1 * v3, v3, 0., v1, 0., c1,
119  c2, -gm1 * v2 * v1, -gm1 * v3 * v1, (gm1 + 1) * v1;
120 }
121 
122 #endif // SRC_SNAP_IMPLICIT_FLUX_DECOMPOSITION_HPP_
double sqr(double x)
Definition: core.h:14
void Eigenvector(Eigen::DenseBase< Derived1 > &Rmat, Eigen::DenseBase< Derived2 > &Rimat, Real prim[], Real cs, Real gm1, CoordinateDirection dir)
void CopyPrimitives(Real wl[], Real wr[], AthenaArray< Real > const &w, int k, int j, int i, CoordinateDirection dir)
void FluxJacobian(Eigen::DenseBase< Derived1 > &dfdq, Real gm1, Real w[], CoordinateDirection dir)
void RoeAverage(Real prim[], Real gm1, Real wl[], Real wr[])
void Eigenvalue(Eigen::MatrixBase< Derived > &Lambda, Real u, Real cs)