ERF
Energy Research and Forecasting: An Atmospheric Modeling Code
ShocPreprocess Class Reference

#include <ERF_ShocPreprocess.H>

Static Public Member Functions

static void fill_columns (ShocColumnData &col, const amrex::MFIter &mfi, const amrex::MultiFab &cons, const amrex::MultiFab &xvel, const amrex::MultiFab &yvel, const amrex::MultiFab &zvel, const amrex::MultiFab *hfx3, const amrex::MultiFab *qfx3, const amrex::MultiFab *tau13, const amrex::MultiFab *tau23, const amrex::MultiFab &z_phys_nd, const amrex::Geometry &geom, const MoistureComponentIndices &moisture_indices)
 

Member Function Documentation

◆ fill_columns()

void ShocPreprocess::fill_columns ( ShocColumnData col,
const amrex::MFIter &  mfi,
const amrex::MultiFab &  cons,
const amrex::MultiFab &  xvel,
const amrex::MultiFab &  yvel,
const amrex::MultiFab &  zvel,
const amrex::MultiFab *  hfx3,
const amrex::MultiFab *  qfx3,
const amrex::MultiFab *  tau13,
const amrex::MultiFab *  tau23,
const amrex::MultiFab &  z_phys_nd,
const amrex::Geometry &  geom,
const MoistureComponentIndices moisture_indices 
)
static
44 {
45  const auto& cons_arr = cons.const_array(mfi);
46  const auto& u_arr = xvel.const_array(mfi);
47  const auto& v_arr = yvel.const_array(mfi);
48  const auto& w_arr = zvel.const_array(mfi);
49  const auto& z_arr = z_phys_nd.const_array(mfi);
50 
51  const Array4<const Real> hfx_arr = hfx3 ? hfx3->const_array(mfi) : Array4<const Real>{};
52  const Array4<const Real> qfx_arr = qfx3 ? qfx3->const_array(mfi) : Array4<const Real>{};
53  const Array4<const Real> t13_arr = tau13 ? tau13->const_array(mfi) : Array4<const Real>{};
54  const Array4<const Real> t23_arr = tau23 ? tau23->const_array(mfi) : Array4<const Real>{};
55 
56  auto zt_arr = col.zt.array();
57  auto zi_arr = col.zi.array();
58  auto dz_arr = col.dz.array();
59  auto p_mid_arr = col.p_mid.array();
60  auto p_int_arr = col.p_int.array();
61  auto rho_arr = col.rho.array();
62  auto theta_arr = col.theta.array();
63  auto exner_arr = col.exner.array();
64  auto theta_v_arr = col.theta_v.array();
65  auto thetal_arr = col.thetal.array();
66  auto qv_arr = col.qv.array();
67  auto qc_arr = col.qc.array();
68  auto qi_arr = col.qi.array();
69  auto qw_arr = col.qw.array();
70  auto shoc_ql_arr = col.shoc_ql.array();
71  auto tabs_arr = col.tabs.array();
72  auto tke_arr = col.tke.array();
73  auto ucol_arr = col.u.array();
74  auto vcol_arr = col.v.array();
75  auto wcol_arr = col.w.array();
76  auto dse_arr = col.host_dse.array();
77  auto sflux_arr = col.surf_sens_flux.array();
78  auto lflux_arr = col.surf_lat_flux.array();
79  auto tauu_arr = col.surf_tau_u.array();
80  auto tauv_arr = col.surf_tau_v.array();
81 
82  const auto problo = geom.ProbLoArray();
83  const auto dx = geom.CellSizeArray();
84  const int klo = col.layout.kmin;
85  const int khi = col.layout.kmax;
86  const int ncomp = cons.nComp();
87  const auto layout = col.layout;
88  amrex::ignore_unused(problo, dx);
89  const Box xy_box = amrex::makeSlab(mfi.validbox(), 2, klo);
90 
91  ParallelFor(xy_box, [=] AMREX_GPU_DEVICE (int i, int j, int) noexcept
92  {
93  const int ic = shoc_column_index(layout, i, j);
94  const Real rho_sfc = amrex::max(cons_arr(i,j,klo,Rho_comp), 1.0e-12_rt);
95 
96  // ERF host fluxes/stresses are stored as density-weighted lower
97  // boundary fluxes. SHOC consumes kinematic surface fluxes.
98  if (hfx3) sflux_arr(ic,0,0) = hfx_arr(i,j,klo) / rho_sfc;
99  if (qfx3) lflux_arr(ic,0,0) = qfx_arr(i,j,klo) / rho_sfc;
100  if (tau13) {
101  tauu_arr(ic,0,0) = 0.5_rt * (t13_arr(i,j,klo) + t13_arr(i+1,j,klo)) / rho_sfc;
102  }
103  if (tau23) {
104  tauv_arr(ic,0,0) = 0.5_rt * (t23_arr(i,j,klo) + t23_arr(i,j+1,klo)) / rho_sfc;
105  }
106 
107  for (int k = klo; k <= khi; ++k) {
108  const int kk = k - klo;
109  // z_phys_nd is nodal in x, y, and z. Pack SHOC column interface
110  // heights as the four-node horizontal average over the ERF cell
111  // footprint, matching the EAMxx SHOC coupling.
112  const Real zlo = four_node_z_avg(z_arr, i, j, k);
113  const Real zhi = four_node_z_avg(z_arr, i, j, k+1);
114  const Real zc = 0.5_rt * (zlo + zhi);
115  const Real dz = zhi - zlo;
116  const Real rho = cons_arr(i,j,k,Rho_comp);
117  const Real theta = cons_arr(i,j,k,RhoTheta_comp) / rho;
118  const Real qv = load_q(cons_arr, i, j, k, moisture_indices.qv, rho, ncomp);
119  const Real qc = load_q(cons_arr, i, j, k, moisture_indices.qc, rho, ncomp);
120  const Real qi = load_q(cons_arr, i, j, k, moisture_indices.qi, rho, ncomp);
121  const Real p = getPgivenRTh(cons_arr(i,j,k,RhoTheta_comp), qv);
122  const Real tabs = getTgivenRandRTh(rho, cons_arr(i,j,k,RhoTheta_comp), qv);
123  const Real ql_np = qc + qi;
124  const Real exner = tabs / amrex::max(theta, 1.0e-12_rt);
125  // SHOC carries a liquid-water potential temperature-like variable.
126  // For native SHOC coupling, include phase-aware condensate
127  // heating so theta = theta_l + (Lv*qc + Ls*qi)/(Cp*exner).
128  const Real thetal = shoc::thetal_from_theta(theta, qc, qi, exner);
129  const Real theta_v = theta * (1.0_rt + 0.61_rt * qv - ql_np);
130  const Real qke = cons_arr(i,j,k,RhoKE_comp) / rho;
131 
132  zt_arr(ic,kk,0) = zc;
133  zi_arr(ic,kk,0) = zlo;
134  zi_arr(ic,kk+1,0) = zhi;
135  dz_arr(ic,kk,0) = dz;
136  p_mid_arr(ic,kk,0) = p;
137  rho_arr(ic,kk,0) = rho;
138  theta_arr(ic,kk,0) = theta;
139  exner_arr(ic,kk,0) = exner;
140  theta_v_arr(ic,kk,0) = theta_v;
141  thetal_arr(ic,kk,0) = thetal;
142  qv_arr(ic,kk,0) = qv;
143  qc_arr(ic,kk,0) = qc;
144  qi_arr(ic,kk,0) = qi;
145  qw_arr(ic,kk,0) = qv + qc + qi;
146  shoc_ql_arr(ic,kk,0) = ql_np;
147  tabs_arr(ic,kk,0) = tabs;
148  tke_arr(ic,kk,0) = qke;
149  dse_arr(ic,kk,0) = Cp_d * tabs + CONST_GRAV * zc;
150 
151  ucol_arr(ic,kk,0) = 0.5_rt * (u_arr(i,j,k) + u_arr(i+1,j,k));
152  vcol_arr(ic,kk,0) = 0.5_rt * (v_arr(i,j,k) + v_arr(i,j+1,k));
153  wcol_arr(ic,kk,0) = 0.5_rt * (w_arr(i,j,k) + w_arr(i,j,k+1));
154  }
155 
156  p_int_arr(ic,0,0) = p_mid_arr(ic,0,0);
157  for (int k = klo+1; k <= khi; ++k) {
158  const int kk = k - klo;
159  p_int_arr(ic,kk,0) = 0.5_rt * (p_mid_arr(ic,kk-1,0) + p_mid_arr(ic,kk,0));
160  }
161  p_int_arr(ic,layout.nlev,0) = p_mid_arr(ic,layout.nlev-1,0);
162  });
163 }
constexpr amrex::Real Cp_d
Definition: ERF_Constants.H:44
constexpr amrex::Real CONST_GRAV
Definition: ERF_Constants.H:53
@ tau23
Definition: ERF_DataStruct.H:32
@ tau13
Definition: ERF_DataStruct.H:32
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real getTgivenRandRTh(const amrex::Real rho, const amrex::Real rhotheta, const amrex::Real qv=amrex::Real(0))
Definition: ERF_EOS.H:46
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real getPgivenRTh(const amrex::Real rhotheta, const amrex::Real qv=amrex::Real(0))
Definition: ERF_EOS.H:81
#define Rho_comp
Definition: ERF_IndexDefines.H:36
#define RhoTheta_comp
Definition: ERF_IndexDefines.H:37
#define RhoKE_comp
Definition: ERF_IndexDefines.H:38
auto problo
Definition: ERF_InitCustomPertVels_ABL.H:20
const Real zc
Definition: ERF_InitCustomPert_ABL.H:35
const Real dx
Definition: ERF_InitCustomPert_ABL.H:23
const int khi
Definition: ERF_InitCustomPert_Bubble.H:21
rho
Definition: ERF_InitCustomPert_Bubble.H:106
auto qv_arr
Definition: ERF_InitCustomPert_MultiSpeciesBubble.H:210
ParallelFor(grown_box, [=] AMREX_GPU_DEVICE(int i, int j, int k) { qrcuten_arr(i, j, k)=Real(0);qscuten_arr(i, j, k)=Real(0);qicuten_arr(i, j, k)=Real(0);})
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE int shoc_column_index(const ShocColumnLayout &layout, int i, int j)
Definition: ERF_ShocColumnData.H:130
amrex::Real Real
Definition: ERF_ShocInterface.H:19
auto rho_arr
Definition: ERF_UpdateWSubsidence_SineMassFlux.H:3
@ theta
Definition: ERF_MM5.H:20
@ tabs
Definition: ERF_Kessler.H:25
@ qv
Definition: ERF_Kessler.H:29
@ qc
Definition: ERF_SatAdj.H:40
@ qi
Definition: ERF_WSM6.H:26
@ xvel
Definition: ERF_IndexDefines.H:175
@ cons
Definition: ERF_IndexDefines.H:174
@ zvel
Definition: ERF_IndexDefines.H:177
@ yvel
Definition: ERF_IndexDefines.H:176
@ p
Definition: ERF_WSM6.H:176
@ dz
Definition: ERF_AdvanceWSM6.cpp:104
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real thetal_from_theta(amrex::Real theta, amrex::Real qc, amrex::Real qi, amrex::Real exner) noexcept
Definition: ERF_ShocThermoUtils.H:52
int qi
Definition: ERF_DataStruct.H:109
int qv
Definition: ERF_DataStruct.H:107
int qc
Definition: ERF_DataStruct.H:108
amrex::FArrayBox theta_v
Definition: ERF_ShocTypes.H:216
amrex::FArrayBox theta
Definition: ERF_ShocTypes.H:214
amrex::FArrayBox qi
Definition: ERF_ShocTypes.H:220
amrex::FArrayBox dz
Definition: ERF_ShocTypes.H:210
amrex::FArrayBox surf_lat_flux
Definition: ERF_ShocTypes.H:277
amrex::FArrayBox rho
Definition: ERF_ShocTypes.H:213
amrex::FArrayBox shoc_ql
Definition: ERF_ShocTypes.H:243
amrex::FArrayBox w
Definition: ERF_ShocTypes.H:226
amrex::FArrayBox host_dse
Definition: ERF_ShocTypes.H:227
amrex::FArrayBox qc
Definition: ERF_ShocTypes.H:219
amrex::FArrayBox surf_tau_v
Definition: ERF_ShocTypes.H:279
amrex::FArrayBox tke
Definition: ERF_ShocTypes.H:223
amrex::FArrayBox p_int
Definition: ERF_ShocTypes.H:212
amrex::FArrayBox exner
Definition: ERF_ShocTypes.H:215
ShocColumnLayout layout
Definition: ERF_ShocTypes.H:205
amrex::FArrayBox zi
Definition: ERF_ShocTypes.H:209
amrex::FArrayBox tabs
Definition: ERF_ShocTypes.H:222
amrex::FArrayBox surf_sens_flux
Definition: ERF_ShocTypes.H:276
amrex::FArrayBox qw
Definition: ERF_ShocTypes.H:221
amrex::FArrayBox v
Definition: ERF_ShocTypes.H:225
amrex::FArrayBox zt
Definition: ERF_ShocTypes.H:208
amrex::FArrayBox qv
Definition: ERF_ShocTypes.H:218
amrex::FArrayBox p_mid
Definition: ERF_ShocTypes.H:211
amrex::FArrayBox u
Definition: ERF_ShocTypes.H:224
amrex::FArrayBox surf_tau_u
Definition: ERF_ShocTypes.H:278
amrex::FArrayBox thetal
Definition: ERF_ShocTypes.H:217
int kmax
Definition: ERF_ShocTypes.H:200
int kmin
Definition: ERF_ShocTypes.H:199

Referenced by ShocDriver::advance().

Here is the call graph for this function:
Here is the caller graph for this function:

The documentation for this class was generated from the following files: