1 #ifndef ERF_PBLMODELS_H_
2 #define ERF_PBLMODELS_H_
8 #include <AMReX_MultiFab.H>
9 #include <AMReX_Periodicity.H>
38 const amrex::MultiFab&
xvel,
39 const amrex::MultiFab&
yvel,
40 amrex::MultiFab& cons_in,
41 amrex::MultiFab& eddyViscosity,
42 const amrex::Geometry& geom,
44 std::unique_ptr<SurfaceLayer>& SurfLayer,
45 bool use_terrain_fitted_coords,
48 const amrex::BCRec* bc_ptr,
50 const std::unique_ptr<amrex::MultiFab>& z_phys_nd,
51 const std::unique_ptr<amrex::MultiFab>& z_phys_cc,
74 const amrex::MultiFab&
yvel,
75 const amrex::MultiFab& cons_in,
76 amrex::MultiFab& eddyViscosity,
77 const amrex::Geometry& geom,
79 std::unique_ptr<SurfaceLayer>& SurfLayer,
80 bool use_terrain_fitted_coords,
83 const amrex::BCRec* bc_ptr,
85 const std::unique_ptr<amrex::MultiFab>& z_phys_nd,
86 const std::unique_ptr<amrex::MultiFab>& z_phys_cc,
109 const amrex::MultiFab&
yvel,
110 const amrex::MultiFab& cons_in,
111 amrex::MultiFab& eddyViscosity,
112 const amrex::Geometry& geom,
114 std::unique_ptr<SurfaceLayer>& SurfLayer,
115 bool use_terrain_fitted_coords,
118 const amrex::BCRec* bc_ptr,
120 const std::unique_ptr<amrex::MultiFab>& z_phys_nd,
121 const std::unique_ptr<amrex::MultiFab>& z_phys_cc,
144 const amrex::MultiFab&
yvel,
145 const amrex::MultiFab& cons_in,
146 amrex::MultiFab& eddyViscosity,
147 const amrex::Geometry& geom,
149 std::unique_ptr<SurfaceLayer>& SurfLayer,
150 bool use_terrain_fitted_coords,
153 const amrex::BCRec* bc_ptr,
155 const std::unique_ptr<amrex::MultiFab>& z_phys_nd,
156 const std::unique_ptr<amrex::MultiFab>& z_phys_cc,
181 const amrex::MultiFab&
yvel,
182 const amrex::MultiFab& cons_in,
183 amrex::MultiFab& eddyViscosity,
184 const amrex::Geometry& geom,
186 std::unique_ptr<SurfaceLayer>& SurfLayer,
187 bool use_terrain_fitted_coords,
190 const amrex::BCRec* bc_ptr,
192 const std::unique_ptr<amrex::MultiFab>& z_phys_nd,
193 const std::unique_ptr<amrex::MultiFab>& z_phys_cc,
195 const amrex::MultiFab* terrain_blank =
nullptr);
228 const amrex::MultiFab&
yvel,
229 const amrex::MultiFab& cons_in,
230 amrex::MultiFab& eddyViscosity,
231 const amrex::Geometry& geom,
233 std::unique_ptr<SurfaceLayer>& SurfLayer,
234 bool use_terrain_fitted_coords,
237 const amrex::BCRec* bc_ptr,
239 const std::unique_ptr<amrex::MultiFab>& z_phys_nd,
240 const std::unique_ptr<amrex::MultiFab>& z_phys_cc,
242 const amrex::MultiFab* qheating_rates =
nullptr,
243 const amrex::MultiFab* terrain_blank =
nullptr);
294 const StratType strat,
295 const amrex::Array4<const amrex::Real>& cell_data,
300 }
else if (strat == StratType::thetal) {
301 return GetThetal(i,j,k,cell_data,moisture_indices);
303 return GetThetav(i,j,k,cell_data,moisture_indices);
310 const amrex::Array4<const amrex::Real>& uvel,
311 const amrex::Array4<const amrex::Real>& vvel,
312 const amrex::Array4<const amrex::Real>& cell_data,
316 const bool c_ext_dir_on_zlo,
317 const bool c_ext_dir_on_zhi,
318 const bool u_ext_dir_on_zlo,
319 const bool u_ext_dir_on_zhi,
320 const bool v_ext_dir_on_zlo,
321 const bool v_ext_dir_on_zhi,
326 const StratType strat = StratType::thetav)
332 if ( k==izmax && c_ext_dir_on_zhi ) {
333 dthetadz = (
GetPBLStratVar(i,j,k+1,strat,cell_data,moisture_indices)
335 }
else if ( k==izmin && c_ext_dir_on_zlo ) {
336 dthetadz = (
GetPBLStratVar(i,j,k ,strat,cell_data,moisture_indices)
339 dthetadz = (
GetPBLStratVar(i,j,k+1,strat,cell_data,moisture_indices)
343 if ( k==izmax && u_ext_dir_on_zhi ) {
344 dudz =
myhalf*( uvel(i ,j,k+1) - uvel(i ,j,k)
346 }
else if ( k==izmin && u_ext_dir_on_zlo ) {
347 dudz =
myhalf*( uvel(i ,j,k) - uvel(i ,j,k-1)
350 dudz =
myhalf*( uvel(i ,j,k+1) - uvel(i ,j,k-1)
351 +uvel(i+1,j,k+1) - uvel(i+1,j,k-1) )*dz_inv.
interior;
354 if ( k==izmax && v_ext_dir_on_zhi ) {
355 dvdz =
myhalf*( vvel(i,j ,k+1) - vvel(i,j ,k)
357 }
else if ( k==izmin && v_ext_dir_on_zlo ) {
358 dvdz =
myhalf*( vvel(i,j ,k) - vvel(i,j ,k-1)
361 dvdz =
myhalf*( vvel(i,j ,k+1) - vvel(i,j ,k-1)
362 +vvel(i,j+1,k+1) - vvel(i,j+1,k-1) )*dz_inv.
interior;
435 dudz = sl.
u_star * sfuns.calc_phi_m(sl.
zeta) * inv_kappa_z;
437 dthetadz = sl.
tstar_v * sfuns.calc_phi_h(sl.
zeta) * inv_kappa_z;
463 const amrex::Array4<const amrex::Real>& uvel,
464 const amrex::Array4<const amrex::Real>& vvel,
465 const amrex::Array4<const amrex::Real>& cell_data,
466 const amrex::Array4<const amrex::Real>& cell_prim,
467 const amrex::Array4<const amrex::Real>& K_turb,
468 const amrex::Box& domain,
473 bool c_ext_dir_on_zlo,
474 bool c_ext_dir_on_zhi,
475 bool u_ext_dir_on_zlo,
476 bool u_ext_dir_on_zhi,
477 bool v_ext_dir_on_zlo,
478 bool v_ext_dir_on_zhi,
479 const amrex::Array4<const amrex::Real>&
tau13,
480 const amrex::Array4<const amrex::Real>&
tau23,
481 const amrex::Array4<const amrex::Real>& hfx_z,
482 const amrex::Array4<const amrex::Real>& qfx1_z,
483 bool surface_layer_on_zlo)
487 int izmin = domain.smallEnd(2);
488 int izmax = domain.bigEnd(2);
499 const bool use_surface_fluxes = ( surface_layer_on_zlo && (k == izmin) &&
502 if (use_surface_fluxes)
523 cell_data(i,j,k,moisture_indices.
qv) /
rho :
zero;
530 const amrex::Real tau_s = std::sqrt(t13_s*t13_s + t23_s*t23_s);
536 if (qfx1_z) { hfxv_s +=
epsv *
theta * qfx1_z(i,j,k); }
549 if (std::abs(hfxv_s) > eps &&
ustar > eps) {
552 zeta = z1 / l_obukhov;
580 const amrex::Real tau_proj = (t13_c*t13_s + t23_c*t23_s) / tau_s;
585 source_term += (
CONST_GRAV/theta_mean) * hfxv_c;
592 uvel, vvel, cell_data, izmin, izmax, dz_inv,
593 c_ext_dir_on_zlo, c_ext_dir_on_zhi,
594 u_ext_dir_on_zlo, u_ext_dir_on_zhi,
595 v_ext_dir_on_zlo, v_ext_dir_on_zhi,
596 dthetadz, dudz, dvdz,
604 source_term += K_turb(i,j,k,
EddyDiff::Mom_v) * (dudz*dudz + dvdz*dvdz);
612 if (std::abs(qke) >
zero) {
631 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
652 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
658 return {
two / (dz_lo +
two*
dz[k] + dz_hi),
669 amrex::Array4<const amrex::Real>
z_cc;
678 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
723 const amrex::Box& xybx_valid,
726 const amrex::Box& domain,
727 const amrex::Periodicity& periodicity)
729 if (passes <= 0) {
return; }
733 pblh_fab.box().contains(amrex::grow(xybx_valid, amrex::IntVect(passes,passes,0))),
734 "ApplyPBLHSmoothing: the PBLH work array needs `passes` columns of halo "
735 "around the region being smoothed");
738 amrex::FArrayBox pblh_temp(pblh_fab.box(), 1, amrex::The_Async_Arena());
739 auto pblh = pblh_fab.array();
740 auto pblh_tmp = pblh_temp.array();
742 const auto& dom_lo = amrex::lbound(domain);
743 const auto& dom_hi = amrex::ubound(domain);
745 const bool per_x = periodicity.isPeriodic(0);
746 const bool per_y = periodicity.isPeriodic(1);
751 for (
int pass = 0; pass < passes; ++pass) {
752 const int halo = passes - 1 - pass;
753 const amrex::Box bx = amrex::grow(xybx_valid, amrex::IntVect(halo,halo,0));
760 const int i_xlo = (per_x || i > dom_lo.x) ? (i - 1) : i;
761 const int i_xhi = (per_x || i < dom_hi.x) ? (i + 1) : i;
762 const int j_ylo = (per_y || j > dom_lo.y) ? (j - 1) : j;
763 const int j_yhi = (per_y || j < dom_hi.y) ? (j + 1) : j;
766 pblh_tmp(i, j, 0) = weight * pblh(i, j, 0)
767 + wt_side * (pblh(i_xlo, j, 0) + pblh(i_xhi, j, 0) +
768 pblh(i, j_ylo, 0) + pblh(i, j_yhi, 0));
773 pblh_fab.copy<amrex::RunOn::Device>(pblh_temp, bx, 0, bx, 0, 1);
804 inline std::unique_ptr<amrex::MultiFab>
806 const std::function<
void(amrex::MultiFab&)>&
fill)
808 const amrex::IntVect ng_src = src.nGrowVect();
809 const amrex::IntVect ng_dst(
ng,
ng, ng_src[2]);
810 const int ncomp = src.nComp();
813 constexpr
amrex::Real unset = std::numeric_limits<amrex::Real>::max();
815 auto dst = std::make_unique<amrex::MultiFab>(src.boxArray(), src.DistributionMap(),
818 amrex::MultiFab::Copy(*dst, src, 0, 0, ncomp, ng_src);
821 for (amrex::MFIter mfi(*dst); mfi.isValid(); ++mfi) {
823 const amrex::Box have = amrex::grow(mfi.validbox(), ng_src);
824 const auto lo = amrex::lbound(have);
825 const auto hi = amrex::ubound(have);
826 auto a = dst->array(mfi);
829 if (have.contains(i, j, k)) { return; }
830 const int ic = amrex::min(amrex::max(i,
lo.x),
hi.x);
831 const int jc = amrex::min(amrex::max(j,
lo.y),
hi.y);
832 for (
int n = 0; n < ncomp; ++n) {
833 if (a(i, j, k, n) == unset) { a(i, j, k, n) = a(ic, jc, k, n); }
constexpr amrex::Real epsv
Definition: ERF_Constants.H:56
constexpr amrex::Real KAPPA
Definition: ERF_Constants.H:71
constexpr amrex::Real CONST_GRAV
Definition: ERF_Constants.H:72
@ tau23
Definition: ERF_DataStruct.H:49
@ tau13
Definition: ERF_DataStruct.H:49
#define Rho_comp
Definition: ERF_IndexDefines.H:53
#define RhoTheta_comp
Definition: ERF_IndexDefines.H:54
#define PrimKE_comp
Definition: ERF_IndexDefines.H:80
const bool use_moisture
Definition: ERF_InitCustomPert_ABL.H:71
AMREX_ALWAYS_ASSERT_WITH_MESSAGE(axis >=0 &&axis< AMREX_SPACEDIM, "prob.axis must be 0, 1 or 2")
for(int i=0;i< m_num_species;i++)
Definition: ERF_InitCustomPert_MultiSpeciesBubble.H:52
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:93
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:127
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 four
Definition: ERF_NumericalConstants.H:40
constexpr amrex::Real two
Definition: ERF_NumericalConstants.H:38
constexpr amrex::Real one
Definition: ERF_NumericalConstants.H:37
constexpr amrex::Real fourth
Definition: ERF_NumericalConstants.H:42
constexpr amrex::Real zero
Definition: ERF_NumericalConstants.H:36
constexpr amrex::Real myhalf
Definition: ERF_NumericalConstants.H:41
std::unique_ptr< amrex::MultiFab > WidenForPBLH(const amrex::MultiFab &src, const int ng, const std::function< void(amrex::MultiFab &)> &fill)
Definition: ERF_PBLModels.H:805
AMREX_GPU_DEVICE AMREX_FORCE_INLINE amrex::Real GetPBLStratVar(int i, int j, int k, const StratType strat, const amrex::Array4< const amrex::Real > &cell_data, const MoistureComponentIndices &moisture_indices)
Definition: ERF_PBLModels.H:293
void ComputeDiffusivityYSU(const amrex::MultiFab &xvel, const amrex::MultiFab &yvel, const amrex::MultiFab &cons_in, amrex::MultiFab &eddyViscosity, const amrex::Geometry &geom, const TurbChoice &turbChoice, std::unique_ptr< SurfaceLayer > &SurfLayer, bool use_terrain_fitted_coords, bool use_moisture, int level, const amrex::BCRec *bc_ptr, bool, const std::unique_ptr< amrex::MultiFab > &z_phys_nd, const std::unique_ptr< amrex::MultiFab > &z_phys_cc, const MoistureComponentIndices &moisture_indices)
void ComputeDiffusivityMYNNEDMF(const amrex::MultiFab &xvel, const amrex::MultiFab &yvel, const amrex::MultiFab &cons_in, amrex::MultiFab &eddyViscosity, const amrex::Geometry &geom, const TurbChoice &turbChoice, std::unique_ptr< SurfaceLayer > &SurfLayer, bool use_terrain_fitted_coords, bool use_moisture, int level, const amrex::BCRec *bc_ptr, bool, const std::unique_ptr< amrex::MultiFab > &z_phys_nd, const std::unique_ptr< amrex::MultiFab > &z_phys_cc, const MoistureComponentIndices &moisture_indices)
AMREX_GPU_DEVICE AMREX_FORCE_INLINE void ComputeVerticalDerivativesPBL(int i, int j, int k, const amrex::Array4< const amrex::Real > &uvel, const amrex::Array4< const amrex::Real > &vvel, const amrex::Array4< const amrex::Real > &cell_data, const int izmin, const int izmax, const PBLDerivativeDzInv &dz_inv, const bool c_ext_dir_on_zlo, const bool c_ext_dir_on_zhi, const bool u_ext_dir_on_zlo, const bool u_ext_dir_on_zhi, const bool v_ext_dir_on_zlo, const bool v_ext_dir_on_zhi, amrex::Real &dthetadz, amrex::Real &dudz, amrex::Real &dvdz, const MoistureComponentIndices &moisture_indices, const StratType strat=StratType::thetav)
Definition: ERF_PBLModels.H:309
AMREX_GPU_DEVICE AMREX_FORCE_INLINE amrex::Real ComputeQKESourceTerms(int i, int j, int k, const amrex::Array4< const amrex::Real > &uvel, const amrex::Array4< const amrex::Real > &vvel, const amrex::Array4< const amrex::Real > &cell_data, const amrex::Array4< const amrex::Real > &cell_prim, const amrex::Array4< const amrex::Real > &K_turb, const amrex::Box &domain, const PBLDerivativeDzInv dz_inv, amrex::Real pbl_mynn_B1_l, const amrex::Real theta_mean, const MoistureComponentIndices &moisture_indices, bool c_ext_dir_on_zlo, bool c_ext_dir_on_zhi, bool u_ext_dir_on_zlo, bool u_ext_dir_on_zhi, bool v_ext_dir_on_zlo, bool v_ext_dir_on_zhi, const amrex::Array4< const amrex::Real > &tau13, const amrex::Array4< const amrex::Real > &tau23, const amrex::Array4< const amrex::Real > &hfx_z, const amrex::Array4< const amrex::Real > &qfx1_z, bool surface_layer_on_zlo)
Definition: ERF_PBLModels.H:462
void ComputeDiffusivityMRF(const amrex::MultiFab &xvel, const amrex::MultiFab &yvel, const amrex::MultiFab &cons_in, amrex::MultiFab &eddyViscosity, const amrex::Geometry &geom, const TurbChoice &turbChoice, std::unique_ptr< SurfaceLayer > &SurfLayer, bool use_terrain_fitted_coords, bool use_moisture, int level, const amrex::BCRec *bc_ptr, bool, const std::unique_ptr< amrex::MultiFab > &z_phys_nd, const std::unique_ptr< amrex::MultiFab > &z_phys_cc, const MoistureComponentIndices &moisture_indices, const amrex::MultiFab *terrain_blank=nullptr)
void ComputeDiffusivityMYNN25(const amrex::MultiFab &xvel, const amrex::MultiFab &yvel, const amrex::MultiFab &cons_in, amrex::MultiFab &eddyViscosity, const amrex::Geometry &geom, const TurbChoice &turbChoice, std::unique_ptr< SurfaceLayer > &SurfLayer, bool use_terrain_fitted_coords, bool use_moisture, int level, const amrex::BCRec *bc_ptr, bool, const std::unique_ptr< amrex::MultiFab > &z_phys_nd, const std::unique_ptr< amrex::MultiFab > &z_phys_cc, const MoistureComponentIndices &moisture_indices)
void ApplyPBLHSmoothing(amrex::FArrayBox &pblh_fab, const amrex::Box &xybx_valid, const amrex::Real weight, const int passes, const amrex::Box &domain, const amrex::Periodicity &periodicity)
Apply spatial smoothing to PBLH field using 5-point stencil.
Definition: ERF_PBLModels.H:722
void ComputeDiffusivityYSUNew(const amrex::MultiFab &xvel, const amrex::MultiFab &yvel, const amrex::MultiFab &cons_in, amrex::MultiFab &eddyViscosity, const amrex::Geometry &geom, const TurbChoice &turbChoice, std::unique_ptr< SurfaceLayer > &SurfLayer, bool use_terrain_fitted_coords, bool use_moisture, int level, const amrex::BCRec *bc_ptr, bool, const std::unique_ptr< amrex::MultiFab > &z_phys_nd, const std::unique_ptr< amrex::MultiFab > &z_phys_cc, const MoistureComponentIndices &moisture_indices, const amrex::MultiFab *qheating_rates=nullptr, const amrex::MultiFab *terrain_blank=nullptr)
AMREX_GPU_DEVICE AMREX_FORCE_INLINE void ApplySurfaceLayerGradientsPBL(const PBLSurfaceLayerGradient &sl, amrex::Real &dthetadz, amrex::Real &dudz, amrex::Real &dvdz)
Definition: ERF_PBLModels.H:428
void ComputeDiffusivityMYJ(double dt, const amrex::MultiFab &xvel, const amrex::MultiFab &yvel, amrex::MultiFab &cons_in, amrex::MultiFab &eddyViscosity, const amrex::Geometry &geom, const TurbChoice &turbChoice, std::unique_ptr< SurfaceLayer > &SurfLayer, bool use_terrain_fitted_coords, bool use_moisture, int level, const amrex::BCRec *bc_ptr, bool, const std::unique_ptr< amrex::MultiFab > &z_phys_nd, const std::unique_ptr< amrex::MultiFab > &z_phys_cc, const MoistureComponentIndices &moisture_indices)
AMREX_GPU_DEVICE AMREX_FORCE_INLINE amrex::Real ComputeVirtualTStarPBL(amrex::Real t_star, amrex::Real q_star, amrex::Real theta, amrex::Real qv, bool use_moisture)
Definition: ERF_PBLModels.H:391
amrex::Real Real
Definition: ERF_ShocInterface.H:19
@ Theta_v
Definition: ERF_IndexDefines.H:290
@ Turb_lengthscale
Definition: ERF_IndexDefines.H:294
@ Mom_v
Definition: ERF_IndexDefines.H:289
@ ustar
Definition: ERF_SLM.H:28
@ rho
Definition: ERF_Kessler.H:25
@ theta
Definition: ERF_Kessler.H:26
@ qv
Definition: ERF_Kessler.H:31
@ ng
Definition: ERF_Morrison.H:51
@ xvel
Definition: ERF_IndexDefines.H:255
@ yvel
Definition: ERF_IndexDefines.H:256
real(c_double), parameter epsilon
Definition: ERF_module_model_constants.F90:12
void fill(MultiFab &dst, int temperature_comp, int mixing_ratio_comp, int source_comp, const Sources &sources, Real missing_value)
Definition: ERF_NearSurfaceDiagnostics.cpp:42
The moisture data carried by the active microphysics scheme.
Definition: ERF_DataStruct.H:251
int qv
water vapor
Definition: ERF_DataStruct.H:262
Functor for inverse vertical spacings with constant grid spacing.
Definition: ERF_PBLModels.H:624
amrex::Real value
Definition: ERF_PBLModels.H:625
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE PBLDerivativeDzInv operator()(int, int, int) const noexcept
Definition: ERF_PBLModels.H:632
Functor for inverse vertical spacings for stretched grids using a spacing array.
Definition: ERF_PBLModels.H:642
const amrex::Real * dz
Definition: ERF_PBLModels.H:643
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE PBLDerivativeDzInv operator()(int, int, int k) const noexcept
Definition: ERF_PBLModels.H:653
int klo
Definition: ERF_PBLModels.H:644
int khi
Definition: ERF_PBLModels.H:645
Functor for inverse vertical spacings for terrain-following grids using cell-center heights.
Definition: ERF_PBLModels.H:668
amrex::Array4< const amrex::Real > z_cc
Definition: ERF_PBLModels.H:669
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE PBLDerivativeDzInv operator()(int i, int j, int k) const noexcept
Definition: ERF_PBLModels.H:679
Definition: ERF_PBLModels.H:253
amrex::Real dirichlet_hi
Definition: ERF_PBLModels.H:258
amrex::Real interior
Definition: ERF_PBLModels.H:256
amrex::Real dirichlet_lo
Definition: ERF_PBLModels.H:257
Definition: ERF_PBLModels.H:371
amrex::Real tstar_v
virtual temperature scale
Definition: ERF_PBLModels.H:373
amrex::Real zeta
stability coordinate z/L
Definition: ERF_PBLModels.H:375
amrex::Real u_star
friction velocity
Definition: ERF_PBLModels.H:372
amrex::Real zval
height of the cell center above the surface
Definition: ERF_PBLModels.H:374
Definition: ERF_TurbStruct.H:119
Definition: ERF_MOSTUtils.H:67