Canoe
Comprehensive Atmosphere N' Ocean Engine
apply_vapor_limiter.cpp
Go to the documentation of this file.
1 // athena
2 #include <athena/athena.hpp>
3 #include <athena/mesh/mesh.hpp>
4 
5 // canoe
6 #include <impl.hpp>
7 
8 // snap
9 #include "../thermodynamics/thermodynamics.hpp"
10 
11 void apply_vapor_limiter(AthenaArray<Real> *pu, MeshBlock *pmb) {
12  auto pthermo = Thermodynamics::GetInstance();
13  if (NVAPOR == 0) return;
14 
15  int is = pmb->is;
16  int js = pmb->js;
17  int ks = pmb->ks;
18  int ie = pmb->ie;
19  int je = pmb->je;
20  int ke = pmb->ke;
21 
22  AthenaArray<Real> &u = *pu;
23 
24  for (int k = ks; k <= ke; ++k)
25  for (int j = js; j <= je; ++j) {
26  // fix negative vapor from top down
27  for (int i = ie; i > is; --i) {
28  Real density = 0., v1, v2, v3;
29 
30  for (int n = 0; n <= NVAPOR; ++n) density += u(n, k, j, i);
31  v1 = u(IM1, k, j, i) / density, v2 = u(IM2, k, j, i) / density,
32  v3 = u(IM3, k, j, i) / density;
33 
34  // internal energy
35  Real KE = 0.5 * density * (v1 * v1 + v2 * v2 + v3 * v3);
36  Real LE = 0., rhocv = 0.;
37  for (int n = 0; n <= NVAPOR; ++n)
38  rhocv += u(n, k, j, i) * pthermo->GetCvMassRef(n);
39  Real temp = (u(IEN, k, j, i) - KE) / rhocv;
40 
41  for (int n = 1; n <= NVAPOR; ++n) {
42  Real rho = u(n, k, j, i);
43  if (rho < 0.) {
44  u(n, k, j, i - 1) += rho;
45  u(IM1, k, j, i - 1) += v1 * rho;
46  u(IM2, k, j, i - 1) += v2 * rho;
47  u(IM3, k, j, i - 1) += v3 * rho;
48  Real en = pthermo->GetCvMassRef(n) * temp +
49  0.5 * (v1 * v1 + v2 * v2 + v3 * v3);
50  u(IEN, k, j, i - 1) += en * rho;
51 
52  u(n, k, j, i) = 0.;
53  u(IM1, k, j, i) -= v1 * rho;
54  u(IM2, k, j, i) -= v2 * rho;
55  u(IM3, k, j, i) -= v3 * rho;
56  u(IEN, k, j, i) -= en * rho;
57  }
58  }
59  }
60  }
61 }
void apply_vapor_limiter(AthenaArray< Real > *pu, MeshBlock *pmb)
static Thermodynamics const * GetInstance()
Return a pointer to the one and only instance of Thermodynamics.
float temp
Definition: fit_ammonia.py:6