Canoe
Comprehensive Atmosphere N' Ocean Engine
forcing_jacobians.hpp
Go to the documentation of this file.
1 #ifndef SRC_SNAP_IMPLICIT_FORCING_JACOBIANS_HPP_
2 #define SRC_SNAP_IMPLICIT_FORCING_JACOBIANS_HPP_
3 
4 // Athena++ header
5 #include <coordinates/coordinates.hpp>
6 #include <mesh/mesh.hpp>
7 
8 // canoe headers
9 #include "implicit_solver.hpp"
10 
11 inline double cot(double x) { return (1. / tan(x)); }
12 
13 template <typename T>
14 void ImplicitSolver::JacobianGravityCoriolis(T &jac, Real const prim[], int k,
15  int j, int i) {
16  Real omega1 = 0, omega2 = 0, omega3 = 0, theta, phi;
17  Real omegax = pmy_hydro->hsrc.GetOmegaX();
18  Real omegay = pmy_hydro->hsrc.GetOmegaY();
19  Real omegaz = pmy_hydro->hsrc.GetOmegaZ();
20  Real grav = pmy_hydro->hsrc.GetG1();
21  int idn = 0, ivx = 1, ivy = 2, ivz = 3, ien = 4;
22 
23  MeshBlock *pmb = pmy_hydro->pmy_block;
24 
25  jac.setZero();
26  if (strcmp(COORDINATE_SYSTEM, "cartesian") == 0) {
27  omega1 = omegaz;
28  omega2 = omegax;
29  omega3 = omegay;
30  } else if (strcmp(COORDINATE_SYSTEM, "cylindrical") == 0) {
31  theta = pmb->pcoord->x2v(j);
32 
33  omega1 = cos(theta) * omegax + sin(theta) * omegay;
34  omega2 = -sin(theta) * omegax + cos(theta) * omegay;
35  omega3 = omegaz;
36  } else if (strcmp(COORDINATE_SYSTEM, "spherical_polar") == 0) {
37  theta = pmb->pcoord->x2v(j);
38  phi = pmb->pcoord->x3v(k);
39 
40  omega1 = sin(theta) * cos(phi) * omegax + sin(theta) * sin(phi) * omegay +
41  cos(theta) * omegaz;
42  omega2 = cos(theta) * cos(phi) * omegax + cos(theta) * sin(phi) * omegay -
43  sin(theta) * omegaz;
44  omega3 = -sin(phi) * omegax + cos(phi) * omegay;
45 
46  Real v1 = prim[IVX];
47  Real v2 = prim[IVY];
48  Real v3 = prim[IVZ];
49  Real ss = v1 * v1 + v2 * v2 + v3 * v3;
50  Real gm1 = pmb->peos->getGamma() - 1;
51  Real r = pmb->pcoord->x1v(i);
52 
53  jac(ivx, idn) += (v1 * v1 + (gm1 - 1) * ss) / r;
54  jac(ivx, ivx) += -2 * gm1 * v1 / r;
55  jac(ivx, ivy) += 2 * (1 - gm1) * v2 / r;
56  jac(ivx, ivz) += 2 * (1 - gm1) * v3 / r;
57  jac(ivx, ien) += 2 * gm1 / r;
58 
59  jac(ivy, idn) += (v1 * v2 + (gm1 / 2. * ss - v3 * v3) * cot(theta)) / r;
60  jac(ivy, ivx) += -(v2 + gm1 * v1 * cot(theta)) / r;
61  jac(ivy, ivy) += -(v1 + gm1 * v2 * cot(theta)) / r;
62  jac(ivy, ivz) += (2 - gm1) * v3 * cot(theta) / r;
63  jac(ivy, ien) += gm1 * cot(theta) / r;
64 
65  jac(ivz, idn) += v3 * (v1 + v2 * cot(theta)) / r;
66  jac(ivz, ivx) += -v3 / r;
67  jac(ivz, ivy) += -v3 * cot(theta) / r;
68  jac(ivz, ivz) += -(v1 + v2 * cot(theta)) / r;
69  }
70 
71  jac(ivx, idn) += grav;
72  jac(ien, ivx) += grav;
73  jac(ivx, ivy) += 2. * omega3;
74  jac(ivx, ivz) += -2 * omega2;
75  jac(ivy, ivx) += -2 * omega3;
76  jac(ivy, ivz) += 2 * omega1;
77  jac(ivz, ivx) += 2 * omega2;
78  jac(ivz, ivy) += -2 * omega1;
79 
80  if (mydir_ == X2DIR)
81  jac = p2_ * jac * p3_;
82  else if (mydir_ == X3DIR)
83  jac = p3_ * jac * p2_;
84 
85  /*} else if (dir == X2DIR) {
86  jac(ivz,idn) = grav;
87  jac(ien,ivz) = grav;
88  Real tmp = omega1;
89  omega1 = omega2;
90  omega2 = omega3;
91  omega3 = tmp;
92  } else { // X3DIR
93  jac(ivy,idn) = grav;
94  jac(ien,ivy) = grav;
95  Real tmp = omega3;
96  omega3 = omega2;
97  omega2 = omega1;
98  omega1 = tmp;
99  }*/
100 }
101 
102 #endif // SRC_SNAP_IMPLICIT_FORCING_JACOBIANS_HPP_
Eigen::Matrix< Real, 5, 5 > p3_
CoordinateDirection mydir_
void JacobianGravityCoriolis(T &jac, Real const prim[], int k, int j, int i)
Eigen::Matrix< Real, 5, 5 > p2_
double cot(double x)