54 #ifndef ERF_RICHARDSON_NUMBER_H_
55 #define ERF_RICHARDSON_NUMBER_H_
57 #include <AMReX_GpuQualifiers.H>
58 #include <AMReX_REAL.H>
83 const amrex::Array4<const amrex::Real>& cell_data,
133 const amrex::Array4<const amrex::Real>& cell_data,
138 const int qv_index = moisture_indices.
qv;
139 const int qc_index = moisture_indices.
qc;
143 bool saturated =
IsSaturated(i, j, k, cell_data, qc_index);
148 if (saturated && qc_index >= 0) {
153 inv_theta =
one / theta_l;
154 dtheta_dz =
myhalf * (theta_l_kp1 - theta_l_km1) * dzInv;
156 }
else if (qv_index >= 0) {
161 inv_theta =
one / theta_v;
162 dtheta_dz =
myhalf * (theta_v_kp1 - theta_v_km1) * dzInv;
166 amrex::Real theta_kp1 = cell_data(i, j, k+1, rhoTheta_comp) / cell_data(i, j, k+1, rho_comp);
167 amrex::Real theta_km1 = cell_data(i, j, k-1, rhoTheta_comp) / cell_data(i, j, k-1, rho_comp);
170 dtheta_dz =
myhalf * (theta_kp1 - theta_km1) * dzInv;
173 return const_grav * inv_theta * dtheta_dz;
193 const amrex::Array4<const amrex::EBCellFlag>& c_cflag,
196 const amrex::Array4<const amrex::Real>& cell_data,
201 const int qv_index = moisture_indices.
qv;
202 const int qc_index = moisture_indices.
qc;
206 bool saturated =
IsSaturated(i, j, k, cell_data, qc_index);
211 const bool is_covered_kp1 = c_cflag(i,j,k+1).isCovered();
212 const bool is_covered_km1 = c_cflag(i,j,k-1).isCovered();
214 if (saturated && qc_index >= 0) {
218 inv_theta =
one / theta_l;
220 if (is_covered_kp1) {
222 if (is_covered_km1) {
228 if (c_cflag(i,j,k-2).isCovered()) {
229 dtheta_dz = (theta_l - theta_l_km1) * dzInv;
232 dtheta_dz = (
three*theta_l -
four*theta_l_km1 + theta_l_km2) *
myhalf * dzInv;
235 }
else if (is_covered_km1) {
239 if (c_cflag(i,j,k+2).isCovered()) {
240 dtheta_dz = (theta_l_kp1 - theta_l) * dzInv;
243 dtheta_dz = (-theta_l_kp2 +
four*theta_l_kp1 -
three*theta_l) *
myhalf * dzInv;
250 dtheta_dz = (theta_l_kp1 - theta_l_km1) *
myhalf * dzInv;
253 }
else if (qv_index >= 0) {
257 inv_theta =
one / theta_v;
259 if (is_covered_kp1) {
261 if (is_covered_km1) {
267 if (c_cflag(i,j,k-2).isCovered()) {
268 dtheta_dz = (theta_v - theta_v_km1) * dzInv;
271 dtheta_dz = (
three*theta_v -
four*theta_v_km1 + theta_v_km2) *
myhalf * dzInv;
274 }
else if (is_covered_km1) {
278 if (c_cflag(i,j,k+2).isCovered()) {
279 dtheta_dz = (theta_v_kp1 - theta_v) * dzInv;
282 dtheta_dz = (-theta_v_kp2 +
four*theta_v_kp1 -
three*theta_v) *
myhalf * dzInv;
289 dtheta_dz = (theta_v_kp1 - theta_v_km1) *
myhalf * dzInv;
298 if (is_covered_kp1) {
300 if (is_covered_km1) {
304 const amrex::Real theta_km1 = cell_data(i, j, k-1, rhoTheta_comp) / cell_data(i, j, k-1, rho_comp);
306 if (c_cflag(i,j,k-2).isCovered()) {
307 dtheta_dz = (
theta - theta_km1) * dzInv;
309 const amrex::Real theta_km2 = cell_data(i, j, k-2, rhoTheta_comp) / cell_data(i, j, k-2, rho_comp);
313 }
else if (is_covered_km1) {
315 const amrex::Real theta_kp1 = cell_data(i, j, k+1, rhoTheta_comp) / cell_data(i, j, k+1, rho_comp);
317 if (c_cflag(i,j,k+2).isCovered()) {
318 dtheta_dz = (theta_kp1 -
theta) * dzInv;
320 const amrex::Real theta_kp2 = cell_data(i, j, k+2, rhoTheta_comp) / cell_data(i, j, k+2, rho_comp);
326 const amrex::Real theta_kp1 = cell_data(i, j, k+1, rhoTheta_comp) / cell_data(i, j, k+1, rho_comp);
327 const amrex::Real theta_km1 = cell_data(i, j, k-1, rhoTheta_comp) / cell_data(i, j, k-1, rho_comp);
328 dtheta_dz = (theta_kp1 - theta_km1) *
myhalf * dzInv;
332 return const_grav * inv_theta * dtheta_dz;
368 const amrex::Array4<const amrex::Real>& u,
369 const amrex::Array4<const amrex::Real>& v)
380 amrex::Real S2_vert = du_dz * du_dz + dv_dz * dv_dz;
404 const amrex::Array4<const amrex::EBCellFlag>& c_cflag,
405 const amrex::Array4<const amrex::Real>& u_vfrac,
406 const amrex::Array4<const amrex::Real>& v_vfrac,
408 const amrex::Array4<const amrex::Real>& u,
409 const amrex::Array4<const amrex::Real>& v,
410 bool& shear_is_valid)
416 auto cell_avg = [=] (
const amrex::Array4<const amrex::Real>& vfrac,
417 const amrex::Array4<const amrex::Real>& vel,
418 int ii,
int jj,
int kk,
int di,
int dj,
424 if (fsum <=
zero) {
return false; }
425 q = ((f0 >
zero ? f0 * vel(ii, jj, kk) :
zero) +
426 (f1 >
zero ? f1 * vel(ii+
di, jj+dj, kk) :
zero)) / fsum;
436 auto vert_deriv = [=] (
const amrex::Array4<const amrex::Real>& vfrac,
437 const amrex::Array4<const amrex::Real>& vel,
441 const bool have_km1 = !c_cflag(i,j,k-1).isCovered() &&
442 cell_avg(vfrac, vel, i, j, k-1,
di, dj, c_km1);
443 const bool have_kp1 = !c_cflag(i,j,k+1).isCovered() &&
444 cell_avg(vfrac, vel, i, j, k+1,
di, dj, c_kp1);
448 if (have_km1 && have_kp1) {
449 dq_dz =
myhalf * (c_kp1 - c_km1) * dzInv;
455 if (!cell_avg(vfrac, vel, i, j, k,
di, dj, c_c)) {
return false; }
459 if (!c_cflag(i,j,k-2).isCovered() &&
460 cell_avg(vfrac, vel, i, j, k-2,
di, dj, c_km2)) {
463 dq_dz = (c_c - c_km1) * dzInv;
470 if (!c_cflag(i,j,k+2).isCovered() &&
471 cell_avg(vfrac, vel, i, j, k+2,
di, dj, c_kp2)) {
474 dq_dz = (c_kp1 - c_c) * dzInv;
484 if (!vert_deriv(u_vfrac, u, 1, 0, du_dz) ||
485 !vert_deriv(v_vfrac, v, 0, 1, dv_dz)) {
486 shear_is_valid =
false;
489 shear_is_valid =
true;
491 amrex::Real S2_vert = du_dz * du_dz + dv_dz * dv_dz;
509 return N2_moist / S2_safe;
532 return stability_factor;
#define Rho_comp
Definition: ERF_IndexDefines.H:42
#define RhoTheta_comp
Definition: ERF_IndexDefines.H:43
AMREX_GPU_DEVICE AMREX_FORCE_INLINE amrex::Real GetThetav(const int &i, const int &j, const int &k, const amrex::Array4< amrex::Real const > &cell_data, const MoistureComponentIndices &moisture_indices)
Definition: ERF_MoistUtils.H:74
AMREX_GPU_DEVICE AMREX_FORCE_INLINE amrex::Real GetThetal(const int &i, const int &j, const int &k, const amrex::Array4< amrex::Real const > &cell_data, const MoistureComponentIndices &moisture_indices)
Definition: ERF_MoistUtils.H:130
constexpr amrex::Real three
Definition: ERF_NumericalConstants.H:39
constexpr amrex::Real four
Definition: ERF_NumericalConstants.H:40
constexpr amrex::Real one
Definition: ERF_NumericalConstants.H:37
constexpr amrex::Real zero
Definition: ERF_NumericalConstants.H:36
constexpr amrex::Real myhalf
Definition: ERF_NumericalConstants.H:41
AMREX_GPU_DEVICE AMREX_FORCE_INLINE bool IsSaturated(int i, int j, int k, const amrex::Array4< const amrex::Real > &cell_data, int qc_index)
Definition: ERF_RichardsonNumber.H:82
AMREX_GPU_DEVICE AMREX_FORCE_INLINE amrex::Real StabilityFunction(amrex::Real Ri, amrex::Real Ri_crit)
Definition: ERF_RichardsonNumber.H:522
AMREX_GPU_DEVICE AMREX_FORCE_INLINE amrex::Real ComputeVerticalShear2(int i, int j, int k, amrex::Real dzInv, const amrex::Array4< const amrex::Real > &u, const amrex::Array4< const amrex::Real > &v)
Definition: ERF_RichardsonNumber.H:366
AMREX_GPU_DEVICE AMREX_FORCE_INLINE amrex::Real ComputeRichardson(amrex::Real N2_moist, amrex::Real S2_vert)
Definition: ERF_RichardsonNumber.H:506
AMREX_GPU_DEVICE AMREX_FORCE_INLINE amrex::Real ComputeN2(int i, int j, int k, amrex::Real dzInv, amrex::Real const_grav, const amrex::Array4< const amrex::Real > &cell_data, const MoistureComponentIndices &moisture_indices)
Definition: ERF_RichardsonNumber.H:130
AMREX_GPU_DEVICE AMREX_FORCE_INLINE amrex::Real ComputeN2_EB(int i, int j, int k, const amrex::Array4< const amrex::EBCellFlag > &c_cflag, amrex::Real dzInv, amrex::Real const_grav, const amrex::Array4< const amrex::Real > &cell_data, const MoistureComponentIndices &moisture_indices)
Definition: ERF_RichardsonNumber.H:192
AMREX_GPU_DEVICE AMREX_FORCE_INLINE amrex::Real ComputeVerticalShear2_EB(int i, int j, int k, const amrex::Array4< const amrex::EBCellFlag > &c_cflag, const amrex::Array4< const amrex::Real > &u_vfrac, const amrex::Array4< const amrex::Real > &v_vfrac, amrex::Real dzInv, const amrex::Array4< const amrex::Real > &u, const amrex::Array4< const amrex::Real > &v, bool &shear_is_valid)
Definition: ERF_RichardsonNumber.H:403
amrex::Real Real
Definition: ERF_ShocInterface.H:19
@ rho
Definition: ERF_Kessler.H:25
@ theta
Definition: ERF_Kessler.H:26
@ qc
Definition: ERF_SatAdj.H:42
@ q
Definition: ERF_WSM6.H:273
real(c_double), private di
Definition: ERF_module_mp_morr_two_moment.F90:203
The moisture data carried by the active microphysics scheme.
Definition: ERF_DataStruct.H:238
int qv
water vapor
Definition: ERF_DataStruct.H:249
int qc
cloud liquid water
Definition: ERF_DataStruct.H:250