7 #include <application/exceptions.hpp>
10 #include <athena/athena.hpp>
11 #include <athena/athena_arrays.hpp>
12 #include <athena/eos/eos.hpp>
13 #include <athena/field/field.hpp>
14 #include <athena/globals.hpp>
15 #include <athena/hydro/hydro.hpp>
16 #include <athena/mesh/mesh.hpp>
17 #include <athena/parameter_input.hpp>
20 #include <configure.hpp>
24 #include "../thermodynamics/thermodynamics.hpp"
28 #include <glog/logging.h>
32 int i,
int il,
int iu,
int jl,
int ju) {
33 std::stringstream msg;
35 msg <<
"i = " << ii <<
" ";
37 msg << var(n, k, jj, ii) <<
" ";
46 EquationOfState::EquationOfState(MeshBlock* pmb, ParameterInput* pin)
48 gamma_{pin->GetReal(
"hydro",
"gamma")},
50 pin->GetOrAddReal(
"hydro",
"dfloor", std::sqrt(1024 * float_min))},
52 pin->GetOrAddReal(
"hydro",
"pfloor", std::sqrt(1024 * float_min))},
54 pin->GetOrAddReal(
"hydro",
"sfloor", std::sqrt(1024 * float_min))} {}
63 void EquationOfState::ConservedToPrimitive(
66 Coordinates* pco,
int il,
int iu,
int jl,
int ju,
int kl,
int ku) {
67 Real gm1 = GetGamma() - 1.0;
68 std::stringstream msg;
73 for (
int k = kl; k <= ku; ++k) {
74 for (
int j = jl;
j <= ju; ++
j) {
75 for (
int i = il; i <= iu; ++i) {
76 Real& u_d = cons(IDN, k,
j, i);
77 Real& u_m1 = cons(IM1, k,
j, i);
78 Real& u_m2 = cons(IM2, k,
j, i);
79 Real& u_m3 = cons(IM3, k,
j, i);
80 Real& u_e = cons(IEN, k,
j, i);
83 throw RuntimeError(
"ideal_moist_hydro",
"negative energy");
86 Real& w_d = prim(IDN, k,
j, i);
87 Real& w_vx = prim(IVX, k,
j, i);
88 Real& w_vy = prim(IVY, k,
j, i);
89 Real& w_vz = prim(IVZ, k,
j, i);
90 Real& w_p = prim(IPR, k,
j, i);
93 u_d = (u_d > density_floor_) ? u_d : density_floor_;
96 for (
int n = 0; n <= NVAPOR; ++n) density += cons(n, k,
j, i);
98 Real di = 1. / density;
101 for (
int n = 1; n <= NVAPOR; ++n)
102 prim(n, k,
j, i) = cons(n, k,
j, i) * di;
105 LOG_IF(ERROR, std::isnan(w_d) || (w_d < density_floor_))
106 <<
"rank = " << Globals::my_rank <<
", (k,j,i) = "
107 <<
"(" << k <<
"," <<
j <<
"," << i <<
")"
108 <<
", w_d = " << w_d << std::endl;
110 LOG_IF(INFO, std::isnan(w_d) || (w_d < density_floor_))
114 Real KE, fsig = 1., feps = 1.;
116 for (
int n = 1; n <= NVAPOR; ++n) {
117 fsig += prim(n, k,
j, i) * (pthermo->GetCvRatioMass(n) - 1.);
118 feps += prim(n, k,
j, i) * (pthermo->GetInvMuRatio(n) - 1.);
121 int decay_factor = 1;
123 u_m1 /= decay_factor;
124 u_m2 /= decay_factor;
125 u_m3 /= decay_factor;
133 KE = 0.5 * di * (u_m1 * u_m1 + u_m2 * u_m2 + u_m3 * u_m3);
134 w_p = gm1 * (u_e - KE) * feps / fsig;
137 LOG_IF(ERROR, w_p < 0.)
138 <<
"rank = " << Globals::my_rank <<
", (k,j,i) = "
139 <<
"(" << k <<
"," <<
j <<
"," << i <<
")"
140 <<
", w_p = " << w_p << std::endl;
146 u_e = (w_p > pressure_floor_)
148 : ((pressure_floor_ / gm1) * fsig / feps + KE);
149 w_p = (w_p > pressure_floor_) ? w_p : pressure_floor_;
175 int jl,
int ju,
int kl,
int ku) {
176 Real igm1 = 1.0 / (GetGamma() - 1.0);
179 for (
int k = kl; k <= ku; ++k) {
180 for (
int j = jl;
j <= ju; ++
j) {
181 for (
int i = il; i <= iu; ++i) {
182 Real& u_d = cons(IDN, k,
j, i);
183 Real& u_m1 = cons(IM1, k,
j, i);
184 Real& u_m2 = cons(IM2, k,
j, i);
185 Real& u_m3 = cons(IM3, k,
j, i);
186 Real& u_e = cons(IEN, k,
j, i);
188 const Real& w_d = prim(IDN, k,
j, i);
189 const Real& w_vx = prim(IVX, k,
j, i);
190 const Real& w_vy = prim(IVY, k,
j, i);
191 const Real& w_vz = prim(IVZ, k,
j, i);
192 const Real& w_p = prim(IPR, k,
j, i);
196 for (
int n = 1; n <= NVAPOR; ++n) {
197 cons(n, k,
j, i) = prim(n, k,
j, i) * w_d;
198 cons(IDN, k,
j, i) -= cons(n, k,
j, i);
207 Real KE = 0.5 * w_d * (w_vx * w_vx + w_vy * w_vy + w_vz * w_vz);
208 Real fsig = 1., feps = 1.;
210 for (
int n = 1; n <= NVAPOR; ++n) {
211 fsig += prim(n, k,
j, i) * (pthermo->GetCvRatioMass(n) - 1.);
212 feps += prim(n, k,
j, i) * (pthermo->GetInvMuRatio(n) - 1.);
214 u_e = igm1 * w_p * fsig / feps + KE;
225 Real EquationOfState::SoundSpeed(
const Real prim[NHYDRO]) {
228 Real fsig = 1., feps = 1.;
229 for (
int n = 1; n <= NVAPOR; ++n) {
230 fsig += prim[n] * (pthermo->GetCvRatioMass(n) - 1.);
231 feps += prim[n] * (pthermo->GetInvMuRatio(n) - 1.);
234 return std::sqrt((1. + (gamma_ - 1) * feps / fsig) * prim[IPR] / prim[IDN]);
245 Real& w_d = prim(IDN, i);
246 Real& w_p = prim(IPR, i);
249 w_d = (w_d > density_floor_) ? w_d : density_floor_;
251 w_p = (w_p > pressure_floor_) ? w_p : pressure_floor_;
265 int k,
int j,
int i) {
266 Real gm1 = GetGamma() - 1.0;
267 Real& w_d = prim(IDN, k,
j, i);
268 Real& w_p = prim(IPR, k,
j, i);
270 Real& u_d = cons(IDN, k,
j, i);
271 Real& u_e = cons(IEN, k,
j, i);
273 w_d = (w_d > density_floor_) ? w_d : density_floor_;
277 Real e_k = 0.5 * w_d *
278 (SQR(prim(IVX, k,
j, i)) + SQR(prim(IVY, k,
j, i)) +
279 SQR(prim(IVZ, k,
j, i)));
281 u_e = (w_p > pressure_floor_) ? u_e : ((pressure_floor_ / gm1) + e_k);
282 w_p = (w_p > pressure_floor_) ? w_p : pressure_floor_;
void apply_vapor_limiter(AthenaArray< Real > *pu, MeshBlock *pmb)
static Thermodynamics const * GetInstance()
Return a pointer to the one and only instance of Thermodynamics.
double min(double x1, double x2, double x3)
double max(double x1, double x2, double x3)
std::string str_grid_ij(AthenaArray< Real > const &var, int n, int k, int j, int i, int il, int iu, int jl, int ju)