Rebalance density and potential temperature columns to satisfy hydrostatic equilibrium.
31 #ifdef AMREX_USE_FLOAT
39 int k_dom_lo = geom.Domain().smallEnd(2);
41 const BoxArray& ba =
rho.boxArray();
63 const bool multi_band = (band_klo.size() > 1);
65 enum { P_below = 0, Th_below, qv_below, qt_below, z_below, done_below, n_below };
68 below.define(ba,
rho.DistributionMap(), n_below, IntVect(0,0,1));
72 for (
const int klo_band : band_klo) {
74 if (klo_band != band_klo[0]) { below.FillBoundary(); }
76 for (MFIter mfi(
rho,
TileNoZ()); mfi.isValid(); ++mfi) {
77 Box bx = mfi.tilebox();
78 int klo = bx.smallEnd(2);
79 int khi = bx.bigEnd(2);
83 if (
klo != klo_band) {
continue; }
90 if (use_sfc &&
klo > k_dom_lo) {
91 Box slab_below = mfi.validbox();
92 slab_below.setRange(2,
klo-1);
94 "rebalance_columns with use_sfc requires every column "
95 "to reach the bottom of the domain: the integration is "
96 "seeded from p_0 at the surface.");
100 const Array4< Real>&
rho_arr =
rho.array(mfi);
101 const Array4< Real>& th_arr =
theta.array(mfi);
102 const Array4<const Real>&
qv_arr =
qv.const_array(mfi);
103 const Array4<const Real>& qt_arr =
qt.const_array(mfi);
105 const Array4<const Real>& z_arr = z_phys->const_array(mfi);
107 const Array4<Real> below_arr = (multi_band) ? below.array(mfi) : Array4<Real>{};
108 const bool can_continue = multi_band && (
klo > k_dom_lo);
110 ParallelFor(bx, [=,RdoCp_d=
RdoCp] AMREX_GPU_DEVICE (
int i,
int j,
int ) noexcept
114 Real rho_tot_hi, rho_tot_lo;
125 if (can_continue && below_arr(i,j,
klo-1,done_below) >
zero) {
126 P_lo = below_arr(i,j,
klo-1,P_below);
127 Th_lo = below_arr(i,j,
klo-1,Th_below);
128 qv_lo = below_arr(i,j,
klo-1,qv_below);
129 qt_lo = below_arr(i,j,
klo-1,qt_below);
130 z_lo = below_arr(i,j,
klo-1,z_below);
138 z_hi =
Real(0.125) * (z_arr(i,j,
klo ) + z_arr(i+1,j,
klo ) + z_arr(i,j+1,
klo ) + z_arr(i+1,j+1,
klo )
139 +z_arr(i,j,
klo+1) + z_arr(i+1,j,
klo+1) + z_arr(i,j+1,
klo+1) + z_arr(i+1,j+1,
klo+1));
143 qt_lo = qt_arr(i,j,
klo);
145 Th_lo = th_arr(i,j,
klo);
148 rho_tot_lo = R_lo * (
one + qt_lo);
149 C = -P_lo +
myhalf*rho_tot_lo*grav*
dz;
152 qt_hi = qt_arr(i,j,
klo);
154 Th_hi = th_arr(i,j,
klo);
158 rho_tot_hi = R_hi * (
one + qt_hi);
159 F = P_hi +
myhalf*rho_tot_hi*grav*
dz + C;
163 grav, C, Th_hi, T_hi,
165 P_hi, R_hi, F, maintain_Th);
175 z_lo =
Real(0.125) * (z_arr(i,j,
klo ) + z_arr(i+1,j,
klo ) + z_arr(i,j+1,
klo ) + z_arr(i+1,j+1,
klo )
176 +z_arr(i,j,
klo+1) + z_arr(i+1,j,
klo+1) + z_arr(i,j+1,
klo+1) + z_arr(i+1,j+1,
klo+1));
181 Th_lo = th_arr(i,j,
klo);
183 qt_lo = qt_arr(i,j,
klo);
187 for (
int k(
klo); k<=
khi; ++k)
191 z_hi =
Real(0.125) * (z_arr(i,j,k ) + z_arr(i+1,j,k ) + z_arr(i,j+1,k ) + z_arr(i+1,j+1,k )
192 +z_arr(i,j,k+1) + z_arr(i+1,j,k+1) + z_arr(i,j+1,k+1) + z_arr(i+1,j+1,k+1));
197 rho_tot_lo = R_lo * (
one + qt_lo);
198 C = -P_lo +
myhalf*rho_tot_lo*grav*
dz;
201 qt_hi = qt_arr(i,j,k);
203 Th_hi = th_arr(i,j,k);
206 rho_tot_hi = R_hi * (
one + qt_hi);
207 F = P_hi +
myhalf*rho_tot_hi*grav*
dz + C;
211 grav, C, Th_hi, T_hi,
213 P_hi, R_hi, F, maintain_Th);
217 if (!maintain_Th) { th_arr(i,j,k) =
getThgivenTandP(T_hi, P_hi, RdoCp_d); }
220 Th_lo = th_arr(i,j,k);
227 below_arr(i,j,k,P_below) = P_lo;
228 below_arr(i,j,k,Th_below) = Th_lo;
229 below_arr(i,j,k,qv_below) = qv_lo;
230 below_arr(i,j,k,qt_below) = qt_lo;
231 below_arr(i,j,k,z_below) = z_lo;
232 below_arr(i,j,k,done_below) =
one;
Vector< int > column_bands(const BoxArray &ba)
Definition: ERF_ColumnBands.cpp:13
constexpr amrex::Real p_0
Definition: ERF_Constants.H:53
constexpr amrex::Real CONST_GRAV
Definition: ERF_Constants.H:56
constexpr amrex::Real RdoCp
Definition: ERF_Constants.H:41
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real getRhogivenThetaPress(const amrex::Real th, const amrex::Real p, const amrex::Real rdOcp, const amrex::Real qv=amrex::Real(0))
Definition: ERF_EOS.H:96
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real getThgivenTandP(const amrex::Real T, const amrex::Real P, const amrex::Real rdOcp)
Definition: ERF_EOS.H:18
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
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real getTgivenPandTh(const amrex::Real P, const amrex::Real th, const amrex::Real rdOcp)
Definition: ERF_EOS.H:32
const int klo
Definition: ERF_InitCustomPert_ABL.H:75
const int khi
Definition: ERF_InitCustomPert_Bubble.H:21
AMREX_ALWAYS_ASSERT_WITH_MESSAGE(m_cloud_chamber_config.active, "Cloud Chamber: initializer reached without a parsed configuration")
auto qv_arr
Definition: ERF_InitCustomPert_MultiSpeciesBubble.H:210
ParallelFor(fab_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);})
constexpr amrex::Real one
Definition: ERF_NumericalConstants.H:30
constexpr amrex::Real zero
Definition: ERF_NumericalConstants.H:29
constexpr amrex::Real myhalf
Definition: ERF_NumericalConstants.H:34
amrex::Real Real
Definition: ERF_ShocInterface.H:19
AMREX_FORCE_INLINE amrex::IntVect TileNoZ()
Definition: ERF_TileNoZ.H:11
auto rho_arr
Definition: ERF_UpdateWSubsidence_SineMassFlux.H:3
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void Newton_Raphson_hse(const Real &m_tol, const Real &RdoCp, const Real &dz, const Real &g, const Real &C, const Real &Th, const Real &T, const Real &qt, const Real &qv, Real &P, Real &rd, Real &F, const bool &maintain_Th)
Definition: ERF_HSEUtils.H:46
@ theta
Definition: ERF_SLM.H:19
@ rho
Definition: ERF_Kessler.H:25
@ qt
Definition: ERF_Kessler.H:30
@ qv
Definition: ERF_Kessler.H:31
@ dz
Definition: ERF_AdvanceWDM6.cpp:272