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

#include <ERF_ShocInterface.H>

Collaboration diagram for SHOCInterface:

Classes

struct  Buffer
 
struct  SHOCPostprocess
 
struct  SHOCPreprocess
 

Public Member Functions

 SHOCInterface (const int &lev, SolverChoice &sc)
 
void set_grids (int &level, const amrex::BoxArray &ba, amrex::Geometry &geom, amrex::MultiFab *cons, amrex::MultiFab *xvel, amrex::MultiFab *yvel, amrex::MultiFab *zvel, amrex::Real *w_subsid, amrex::MultiFab *tau13, amrex::MultiFab *tau23, amrex::MultiFab *hfx3, amrex::MultiFab *qfx3, amrex::MultiFab *eddyDiffs, amrex::MultiFab *z_phys)
 
void initialize_impl ()
 
void run_impl (const double dt)
 
void finalize_impl (const double dt)
 
void alloc_buffers ()
 
void dealloc_buffers ()
 
void mf_to_kokkos_buffers ()
 
void kokkos_buffers_to_mf (const double dt)
 
std::string name () const
 
void set_eddy_diffs ()
 
void set_diff_stresses ()
 
void add_fast_tend (amrex::Vector< amrex::MultiFab > &S_rhs)
 
void add_slow_tend (const amrex::MFIter &mfi, const amrex::Box &tbx, const amrex::Array4< amrex::Real > &cc_rhs_arr)
 

Protected Member Functions

void check_flux_state_consistency (const double dt)
 
void apply_turbulent_mountain_stress ()
 
void set_computed_group_impl ()
 
size_t requested_buffer_size_in_bytes () const
 
void init_buffers ()
 
Int wsm_num_slots () const
 

Protected Attributes

amrex::Vector< int > m_col_offsets
 
Int m_num_cols = 0
 
Int m_num_layers = 0
 
Int m_npbl
 
Int m_nadv
 
Int m_num_tracers = 3
 
Int m_num_vel_comp = 2
 
Int hdtime
 
int m_lev
 
int m_step
 
amrex::Geometry m_geom
 
amrex::BoxArray m_ba
 
amrex::MultiFab * m_cons = nullptr
 
amrex::MultiFab * m_xvel = nullptr
 
amrex::MultiFab * m_yvel = nullptr
 
amrex::MultiFab * m_zvel = nullptr
 
amrex::Realm_w_subsid = nullptr
 
amrex::MultiFab * m_tau13 = nullptr
 
amrex::MultiFab * m_tau23 = nullptr
 
amrex::MultiFab * m_hfx3 = nullptr
 
amrex::MultiFab * m_qfx3 = nullptr
 
amrex::MultiFab * m_mu = nullptr
 
amrex::MultiFab * m_z_phys = nullptr
 
amrex::MultiFab c_tend
 
amrex::MultiFab u_tend
 
amrex::MultiFab v_tend
 
bool m_first_step = true
 
Buffer m_buffer
 
SHF::SHOCInput input
 
SHF::SHOCInputOutput input_output
 
SHF::SHOCOutput output
 
SHF::SHOCHistoryOutput history_output
 
SHF::SHOCRuntime runtime_options
 
SHOCPreprocess shoc_preprocess
 
SHOCPostprocess shoc_postprocess
 
ekat::WorkspaceManager< Spack, KT::Device > workspace_mgr
 
view_1d tot_buff_view
 
bool apply_tms = false
 
bool check_flux_state = false
 
bool extra_shoc_diags = false
 
bool column_conservation_check = false
 
view_2d omega
 
view_1d surf_sens_flux
 
sview_2d surf_mom_flux
 
view_1d surf_evap
 
view_2d T_mid
 
view_2d qv
 
view_1d surf_drag_coeff_tms
 
view_2d p_mid
 
view_2d p_int
 
view_2d pseudo_dens
 
view_1d phis
 
view_3d horiz_wind
 
view_2d sgs_buoy_flux
 
view_2d tk
 
view_2d cldfrac_liq
 
view_2d tke
 
view_2d qc
 
view_1d pblh
 
view_2d inv_qc_relvar
 
view_2d tkh
 
view_2d w_sec
 
view_2d cldfrac_liq_prev
 
view_1d ustar
 
view_1d obklen
 
view_2d brunt
 
view_2d shoc_mix
 
view_2d isotropy
 
view_2d shoc_cond
 
view_2d shoc_evap
 
view_2d wthl_sec
 
view_2d thl_sec
 
view_2d wqw_sec
 
view_2d qw_sec
 
view_2d uw_sec
 
view_2d vw_sec
 
view_2d w3
 
view_3d_strided qtracers
 
view_1d vapor_flux
 
view_1d water_flux
 
view_1d ice_flux
 
view_1d heat_flux
 

Static Protected Attributes

static constexpr Int shoc_extra_trac_slots = 3
 

Private Types

using SHF = scream::shoc::Functions< Real, KokkosDefaultDevice >
 
using PF = scream::PhysicsFunctions< KokkosDefaultDevice >
 
using C = scream::physics::Constants< Real >
 
using KT = ekat::KokkosTypes< KokkosDefaultDevice >
 
using SC = scream::shoc::Constants< Real >
 
using Spack = typename SHF::Spack
 
using IntSmallPack = typename SHF::IntSmallPack
 
using Smask = typename SHF::Smask
 
using view_1d_int = typename KT::template view_1d< Int >
 
using view_1d = typename SHF::view_1d< Real >
 
using view_1d_const = typename SHF::view_1d< const Real >
 
using view_2d = typename SHF::view_2d< SHF::Spack >
 
using view_2d_const = typename SHF::view_2d< const Spack >
 
using sview_2d = typename KT::template view_2d< Real >
 
using sview_2d_const = typename KT::template view_2d< const Real >
 
using view_3d = typename SHF::view_3d< Spack >
 
using view_3d_const = typename SHF::view_3d< const Spack >
 
using view_3d_strided = typename SHF::view_3d_strided< Spack >
 
using WSM = ekat::WorkspaceManager< Spack, KT::Device >
 
template<typename ScalarT >
using uview_1d = ekat::Unmanaged< typename KT::template view_1d< ScalarT > >
 
template<typename ScalarT >
using uview_2d = ekat::Unmanaged< typename KT::template view_2d< ScalarT > >
 

Member Typedef Documentation

◆ C

using SHOCInterface::C = scream::physics::Constants<Real>
private

◆ IntSmallPack

using SHOCInterface::IntSmallPack = typename SHF::IntSmallPack
private

◆ KT

using SHOCInterface::KT = ekat::KokkosTypes<KokkosDefaultDevice>
private

◆ PF

using SHOCInterface::PF = scream::PhysicsFunctions<KokkosDefaultDevice>
private

◆ SC

using SHOCInterface::SC = scream::shoc::Constants<Real>
private

◆ SHF

using SHOCInterface::SHF = scream::shoc::Functions<Real, KokkosDefaultDevice>
private

◆ Smask

using SHOCInterface::Smask = typename SHF::Smask
private

◆ Spack

using SHOCInterface::Spack = typename SHF::Spack
private

◆ sview_2d

using SHOCInterface::sview_2d = typename KT::template view_2d<Real>
private

◆ sview_2d_const

using SHOCInterface::sview_2d_const = typename KT::template view_2d<const Real>
private

◆ uview_1d

template<typename ScalarT >
using SHOCInterface::uview_1d = ekat::Unmanaged<typename KT::template view_1d<ScalarT> >
private

◆ uview_2d

template<typename ScalarT >
using SHOCInterface::uview_2d = ekat::Unmanaged<typename KT::template view_2d<ScalarT> >
private

◆ view_1d

using SHOCInterface::view_1d = typename SHF::view_1d<Real>
private

◆ view_1d_const

using SHOCInterface::view_1d_const = typename SHF::view_1d<const Real>
private

◆ view_1d_int

using SHOCInterface::view_1d_int = typename KT::template view_1d<Int>
private

◆ view_2d

using SHOCInterface::view_2d = typename SHF::view_2d<SHF::Spack>
private

◆ view_2d_const

using SHOCInterface::view_2d_const = typename SHF::view_2d<const Spack>
private

◆ view_3d

using SHOCInterface::view_3d = typename SHF::view_3d<Spack>
private

◆ view_3d_const

using SHOCInterface::view_3d_const = typename SHF::view_3d<const Spack>
private

◆ view_3d_strided

using SHOCInterface::view_3d_strided = typename SHF::view_3d_strided<Spack>
private

◆ WSM

using SHOCInterface::WSM = ekat::WorkspaceManager<Spack, KT::Device>
private

Constructor & Destructor Documentation

◆ SHOCInterface()

SHOCInterface::SHOCInterface ( const int &  lev,
SolverChoice sc 
)
9 {
10  //
11  // Defaults set from E3SM/components/eamxx/cime_config/namelist_defaults_eamxx.xml
12  //
13  // Turn off SGS variability in SHOC, effectively reducing it to a Real(1.5) TKE closure?
14  bool def_shoc_1p5tke = false;
15  // Minimum value of stability correction
16  Real def_lambda_low = Real(0.001);
17  // Maximum value of stability correction
18  Real def_lambda_high = Real(0.04);
19  // Slope of change from lambda_low to lambda_high
20  Real def_lambda_slope = Real(2.65);
21  // stability threshold for which to apply more stability correction
22  Real def_lambda_thresh = Real(0.02);
23  // Temperature variance tuning factor
24  Real def_thl2tune = one;
25  // Moisture variance tuning factor
26  Real def_qw2tune = one;
27  // Temperature moisture covariance
28  Real def_qwthl2tune = one;
29  // Vertical velocity variance
30  Real def_w2tune = one;
31  // Length scale factor
32  Real def_length_fac = Real(0.5);
33  // Third moment vertical velocity damping factor
34  Real def_c_diag_3rd_mom = Real(7.0);
35  // Eddy diffusivity coefficient for heat
36  Real def_coeff_kh = Real(0.1);
37  // Eddy diffusivity coefficient for momentum
38  Real def_coeff_km = Real(0.1);
39 
40  runtime_options.lambda_low = def_lambda_low;
41  runtime_options.lambda_high = def_lambda_high;
42  runtime_options.lambda_slope = def_lambda_slope;
43  runtime_options.lambda_thresh = def_lambda_thresh;
44 
45  runtime_options.thl2tune = def_thl2tune;
46  runtime_options.qwthl2tune = def_qwthl2tune;
47  runtime_options.qw2tune = def_qw2tune;
48  runtime_options.w2tune = def_w2tune;
49 
50  runtime_options.length_fac = def_length_fac;
51  runtime_options.c_diag_3rd_mom = def_c_diag_3rd_mom;
52  runtime_options.Ckh = def_coeff_kh;
53  runtime_options.Ckm = def_coeff_km;
54  runtime_options.shoc_1p5tke = def_shoc_1p5tke;
55  runtime_options.extra_diags = extra_shoc_diags;
56 
57  // Construct parser object for following reads
58  ParmParse pp("erf.shoc");
59 
60  // Parse runtime inputs at start up
61  pp.queryAdd("lambda_low" , runtime_options.lambda_low );
62  pp.queryAdd("lambda_high" , runtime_options.lambda_high );
63  pp.queryAdd("lambda_slope" , runtime_options.lambda_slope );
64  pp.queryAdd("lambda_thresh" , runtime_options.lambda_thresh );
65  pp.queryAdd("thl2tune" , runtime_options.thl2tune );
66  pp.queryAdd("qw2tune" , runtime_options.qw2tune );
67  pp.queryAdd("qwthl2tune" , runtime_options.qwthl2tune );
68  pp.queryAdd("w2tune" , runtime_options.w2tune );
69  pp.queryAdd("length_fac" , runtime_options.length_fac );
70  pp.queryAdd("c_diag_3rd_mom" , runtime_options.c_diag_3rd_mom);
71  pp.queryAdd("coeff_kh" , runtime_options.Ckh );
72  pp.queryAdd("coeff_km" , runtime_options.Ckm );
73  pp.queryAdd("shoc_1p5tke" , runtime_options.shoc_1p5tke );
74  pp.queryAdd("extra_shoc_diags", runtime_options.extra_diags );
75 
76  // Set to default but allow us to change it through the inputs file
77  pp.queryAdd("apply_tms", apply_tms);
78  pp.queryAdd("check_flux_state", check_flux_state);
79  pp.queryAdd("extra_shoc_diags", extra_shoc_diags);
80  pp.queryAdd("column_conservation_check", column_conservation_check);
81 }
ParmParse pp("prob")
constexpr amrex::Real one
Definition: ERF_NumericalConstants.H:30
amrex::Real Real
Definition: ERF_ShocInterface.H:19
bool check_flux_state
Definition: ERF_ShocInterface.H:682
bool extra_shoc_diags
Definition: ERF_ShocInterface.H:683
bool apply_tms
Definition: ERF_ShocInterface.H:681
SHF::SHOCRuntime runtime_options
Definition: ERF_ShocInterface.H:663
bool column_conservation_check
Definition: ERF_ShocInterface.H:684
Here is the call graph for this function:

Member Function Documentation

◆ add_fast_tend()

void SHOCInterface::add_fast_tend ( amrex::Vector< amrex::MultiFab > &  S_rhs)
718 {
719  for (MFIter mfi(*m_cons); mfi.isValid(); ++mfi) {
720  const auto& vbx_cc = mfi.validbox();
721  const auto& vbx_x = convert(vbx_cc,IntVect(1,0,0));
722  const auto& vbx_y = convert(vbx_cc,IntVect(0,1,0));
723 
724  const Array4<const Real>& c_arr = m_cons->const_array(mfi);
725 
726  const Array4<Real>& cc_rhs_arr = S_rhs[IntVars::cons].array(mfi);
727  const Array4<Real>& ru_rhs_arr = S_rhs[IntVars::xmom].array(mfi);
728  const Array4<Real>& rv_rhs_arr = S_rhs[IntVars::ymom].array(mfi);
729 
730  const Array4<const Real>& c_tend_arr = c_tend.const_array(mfi);
731  const Array4<const Real>& u_tend_arr = u_tend.const_array(mfi);
732  const Array4<const Real>& v_tend_arr = v_tend.const_array(mfi);
733 
734  ParallelFor(vbx_cc, vbx_x, vbx_y,
735  [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept
736  {
737  cc_rhs_arr(i,j,k,RhoTheta_comp) += c_arr(i,j,k,Rho_comp) * c_tend_arr(i,j,k,RhoTheta_comp);
738  },
739  [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept
740  {
741  Real rho_on_u_face = Real(0.5) * (c_arr(i-1,j,k,Rho_comp)
742  + c_arr(i,j,k,Rho_comp));
743  ru_rhs_arr(i,j,k) += rho_on_u_face * u_tend_arr(i,j,k);
744  },
745  [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept
746  {
747  Real rho_on_v_face = Real(0.5) * (c_arr(i,j-1,k,Rho_comp)
748  + c_arr(i,j,k,Rho_comp));
749  rv_rhs_arr(i,j,k) += rho_on_v_face * v_tend_arr(i,j,k);
750  });
751  }
752 }
#define Rho_comp
Definition: ERF_IndexDefines.H:39
#define RhoTheta_comp
Definition: ERF_IndexDefines.H:40
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);})
amrex::MultiFab c_tend
Definition: ERF_ShocInterface.H:648
amrex::MultiFab * m_cons
Definition: ERF_ShocInterface.H:625
amrex::MultiFab u_tend
Definition: ERF_ShocInterface.H:649
amrex::MultiFab v_tend
Definition: ERF_ShocInterface.H:650
@ ymom
Definition: ERF_IndexDefines.H:234
@ cons
Definition: ERF_IndexDefines.H:232
@ xmom
Definition: ERF_IndexDefines.H:233
Here is the call graph for this function:

◆ add_slow_tend()

void SHOCInterface::add_slow_tend ( const amrex::MFIter &  mfi,
const amrex::Box &  tbx,
const amrex::Array4< amrex::Real > &  cc_rhs_arr 
)
759 {
760  bool moist = (m_cons->nComp() > RhoQ1_comp);
761 
762  const Array4<const Real>& c_arr = m_cons->const_array(mfi);
763 
764  const Array4<const Real>& c_tend_arr = c_tend.const_array(mfi);
765 
766  ParallelFor(tbx, [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept
767  {
768  cc_rhs_arr(i,j,k,RhoKE_comp) += c_arr(i,j,k,Rho_comp) * c_tend_arr(i,j,k,RhoKE_comp);
769  if (moist) {
770  cc_rhs_arr(i,j,k,RhoQ1_comp) += c_arr(i,j,k,Rho_comp) * c_tend_arr(i,j,k,RhoQ1_comp);
771  cc_rhs_arr(i,j,k,RhoQ2_comp) += c_arr(i,j,k,Rho_comp) * c_tend_arr(i,j,k,RhoQ2_comp);
772  }
773  });
774 }
#define RhoQ2_comp
Definition: ERF_IndexDefines.H:46
#define RhoQ1_comp
Definition: ERF_IndexDefines.H:45
#define RhoKE_comp
Definition: ERF_IndexDefines.H:41
Here is the call graph for this function:

◆ alloc_buffers()

void SHOCInterface::alloc_buffers ( )
201 {
202  // Interface data structures
203  //=======================================================
204  omega = view_2d("Omega" , m_num_cols, m_num_layers );
205  surf_sens_flux = view_1d("Sfc sens flux" , m_num_cols);
206  surf_mom_flux = sview_2d("Sfc mom flux" , m_num_cols, m_num_vel_comp);
207  surf_evap = view_1d("Sfc evap" , m_num_cols);
208  T_mid = view_2d("T_mid" , m_num_cols, m_num_layers );
209  qv = view_2d("Qv" , m_num_cols, m_num_layers );
210  surf_drag_coeff_tms = view_1d("surf_drag_coeff", m_num_cols);
211 
212  // Input data structures
213  //=======================================================
214  p_mid = view_2d("P_mid" , m_num_cols, m_num_layers );
215  p_int = view_2d("P_int" , m_num_cols, m_num_layers+1);
216  pseudo_dens = view_2d("Pseudo density" , m_num_cols, m_num_layers );
217  phis = view_1d("Phis" , m_num_cols);
218 
219  // Input/Output data structures
220  //=======================================================
222  cldfrac_liq = view_2d("Cld_frac_liq" , m_num_cols, m_num_layers );
223  tke = view_2d("Tke" , m_num_cols, m_num_layers );
224  qc = view_2d("Qc" , m_num_cols, m_num_layers );
225 
226  // Output data structures
227  //=======================================================
228  pblh = view_1d("pbl_height" , m_num_cols);
229  inv_qc_relvar = view_2d("inv_qc_relvar" , m_num_cols, m_num_layers);
230  tkh = view_2d("eddy_diff_heat" , m_num_cols, m_num_layers);
231  w_sec = view_2d("w_sec" , m_num_cols, m_num_layers);
232  cldfrac_liq_prev = view_2d("cld_frac_liq_prev" , m_num_cols, m_num_layers );
233  ustar = view_1d("ustar" , m_num_cols);
234  obklen = view_1d("obklen" , m_num_cols);
235 
236  // Extra diagnostic data structures
237  //=======================================================
238  if (extra_shoc_diags) {
239  brunt = view_2d("brunt" , m_num_cols, m_num_layers);
240  shoc_mix = view_2d("shoc_mix" , m_num_cols, m_num_layers);
241  isotropy = view_2d("isotropy" , m_num_cols, m_num_layers);
242  shoc_cond = view_2d("shoc_cond", m_num_cols, m_num_layers);
243  shoc_evap = view_2d("shoc_evap", m_num_cols, m_num_layers);
244 
245  wthl_sec = view_2d("wthl_sec" , m_num_cols, m_num_layers+1);
246  thl_sec = view_2d("thl_sec" , m_num_cols, m_num_layers+1);
247  wqw_sec = view_2d("wqw_sec" , m_num_cols, m_num_layers+1);
248  qw_sec = view_2d("qw_sec" , m_num_cols, m_num_layers+1);
249  uw_sec = view_2d("uw_sec" , m_num_cols, m_num_layers+1);
250  vw_sec = view_2d("vw_sec" , m_num_cols, m_num_layers+1);
251  w3 = view_2d("w3" , m_num_cols, m_num_layers+1);
252  }
253 
254  // Tracer data structures
255  //=======================================================
256  // NOTE: Use layoutright format
257  Kokkos::LayoutStride layout(m_num_cols , m_num_tracers*m_num_layers, // stride for dim0
258  m_num_tracers, m_num_layers, // stride for dim1
259  m_num_layers , 1 // stride for dim2
260  );
261  qtracers = view_3d_strided("Qtracers" , layout);
262 
263  // Boundary flux data structures
264  //=======================================================
266  vapor_flux = view_1d("vapor_flux", m_num_cols);
267  water_flux = view_1d("water_flux", m_num_cols);
268  ice_flux = view_1d("ice_flux" , m_num_cols);
269  heat_flux = view_1d("heat_flux" , m_num_cols);
270  }
271 }
view_2d p_int
Definition: ERF_ShocInterface.H:699
view_2d wqw_sec
Definition: ERF_ShocInterface.H:732
view_1d surf_drag_coeff_tms
Definition: ERF_ShocInterface.H:694
view_2d thl_sec
Definition: ERF_ShocInterface.H:731
view_2d tkh
Definition: ERF_ShocInterface.H:716
view_2d cldfrac_liq
Definition: ERF_ShocInterface.H:708
typename KT::template view_2d< Real > sview_2d
Definition: ERF_ShocInterface.H:65
Int m_num_layers
Definition: ERF_ShocInterface.H:605
view_2d vw_sec
Definition: ERF_ShocInterface.H:735
view_1d ice_flux
Definition: ERF_ShocInterface.H:746
view_2d shoc_cond
Definition: ERF_ShocInterface.H:727
view_2d brunt
Definition: ERF_ShocInterface.H:724
view_1d heat_flux
Definition: ERF_ShocInterface.H:747
Int m_num_vel_comp
Definition: ERF_ShocInterface.H:609
view_1d surf_sens_flux
Definition: ERF_ShocInterface.H:689
view_1d pblh
Definition: ERF_ShocInterface.H:714
Int m_num_cols
Definition: ERF_ShocInterface.H:604
view_2d p_mid
Definition: ERF_ShocInterface.H:698
view_2d uw_sec
Definition: ERF_ShocInterface.H:734
view_2d qc
Definition: ERF_ShocInterface.H:710
view_2d shoc_mix
Definition: ERF_ShocInterface.H:725
view_2d qw_sec
Definition: ERF_ShocInterface.H:733
view_2d cldfrac_liq_prev
Definition: ERF_ShocInterface.H:718
view_2d omega
Definition: ERF_ShocInterface.H:688
typename SHF::view_3d_strided< Spack > view_3d_strided
Definition: ERF_ShocInterface.H:69
view_1d vapor_flux
Definition: ERF_ShocInterface.H:744
view_1d obklen
Definition: ERF_ShocInterface.H:720
view_2d pseudo_dens
Definition: ERF_ShocInterface.H:700
view_2d inv_qc_relvar
Definition: ERF_ShocInterface.H:715
view_1d surf_evap
Definition: ERF_ShocInterface.H:691
view_2d w_sec
Definition: ERF_ShocInterface.H:717
view_1d phis
Definition: ERF_ShocInterface.H:701
view_2d shoc_evap
Definition: ERF_ShocInterface.H:728
view_3d horiz_wind
Definition: ERF_ShocInterface.H:705
typename SHF::view_1d< Real > view_1d
Definition: ERF_ShocInterface.H:61
view_3d_strided qtracers
Definition: ERF_ShocInterface.H:740
view_1d ustar
Definition: ERF_ShocInterface.H:719
view_2d w3
Definition: ERF_ShocInterface.H:736
Int m_num_tracers
Definition: ERF_ShocInterface.H:608
sview_2d surf_mom_flux
Definition: ERF_ShocInterface.H:690
typename SHF::view_2d< SHF::Spack > view_2d
Definition: ERF_ShocInterface.H:63
view_2d qv
Definition: ERF_ShocInterface.H:693
view_2d wthl_sec
Definition: ERF_ShocInterface.H:730
view_2d tke
Definition: ERF_ShocInterface.H:709
view_1d water_flux
Definition: ERF_ShocInterface.H:745
view_2d T_mid
Definition: ERF_ShocInterface.H:692
typename SHF::view_3d< Spack > view_3d
Definition: ERF_ShocInterface.H:67
view_2d isotropy
Definition: ERF_ShocInterface.H:726

◆ apply_turbulent_mountain_stress()

void SHOCInterface::apply_turbulent_mountain_stress ( )
protected
1131 {
1132  auto rrho_i = m_buffer.rrho_i;
1133  auto upwp_sfc = m_buffer.upwp_sfc;
1134  auto vpwp_sfc = m_buffer.vpwp_sfc;
1135  auto surf_drag_coeff_tms_d = surf_drag_coeff_tms;
1136  auto horiz_wind_d = horiz_wind;
1137 
1138  const int nlev_v = (m_num_layers-1)/Spack::n;
1139  const int nlev_p = (m_num_layers-1)%Spack::n;
1140  const int nlevi_v = m_num_layers/Spack::n;
1141  const int nlevi_p = m_num_layers%Spack::n;
1142 
1143  Kokkos::parallel_for("apply_tms", KT::RangePolicy(0, m_num_cols), KOKKOS_LAMBDA (const int i)
1144  {
1145  upwp_sfc(i) -= surf_drag_coeff_tms_d(i)*horiz_wind_d(i,0,nlev_v)[nlev_p]/rrho_i(i,nlevi_v)[nlevi_p];
1146  vpwp_sfc(i) -= surf_drag_coeff_tms_d(i)*horiz_wind_d(i,1,nlev_v)[nlev_p]/rrho_i(i,nlevi_v)[nlevi_p];
1147  });
1148 }
Buffer m_buffer
Definition: ERF_ShocInterface.H:656
uview_1d< Real > upwp_sfc
Definition: ERF_ShocInterface.H:490
uview_1d< Real > vpwp_sfc
Definition: ERF_ShocInterface.H:491
uview_2d< Spack > rrho_i
Definition: ERF_ShocInterface.H:511

◆ check_flux_state_consistency()

void SHOCInterface::check_flux_state_consistency ( const double  dt)
protected
1153 {
1154  using PC = scream::physics::Constants<Real>;
1155  using RU = ekat::ReductionUtils<KT::ExeSpace>;
1156  using TPF = ekat::TeamPolicyFactory<KT::ExeSpace>;
1157 
1158  const Real gravit = PC::gravit;
1159  const Real qmin = 1e-12; // minimum permitted constituent concentration (kg/kg)
1160 
1161  const auto& pseudo_density = pseudo_dens;
1162  auto qv_d = qv;
1163  auto surf_evap_d = surf_evap;
1164 
1165  const auto nlevs = m_num_layers;
1166  const auto nlev_packs = ekat::npack<Spack>(nlevs);
1167  const auto last_pack_idx = (nlevs-1)/Spack::n;
1168  const auto last_pack_entry = (nlevs-1)%Spack::n;
1169  const auto policy = TPF::get_default_team_policy(m_num_cols, nlev_packs);
1170  Kokkos::parallel_for("check_flux_state_consistency",
1171  policy,
1172  KOKKOS_LAMBDA (const KT::MemberType& team)
1173  {
1174  const auto i = team.league_rank();
1175 
1176  const auto& pseudo_density_i = ekat::subview(pseudo_density, i);
1177  const auto& qv_i = ekat::subview(qv_d, i);
1178 
1179  // reciprocal of pseudo_density at the bottom layer
1180  const auto rpdel = one/pseudo_density_i(last_pack_idx)[last_pack_entry];
1181 
1182  // Check if the negative surface latent heat flux can exhaust
1183  // the moisture in the lowest model level. If so, apply fixer.
1184  const auto condition = surf_evap_d(i) - (qmin - qv_i(last_pack_idx)[last_pack_entry])/(dt*gravit*rpdel);
1185  if (condition < 0) {
1186  const auto cc = std::fabs(surf_evap_d(i)*dt*gravit);
1187 
1188  auto tracer_mass = [&](const int k)
1189  {
1190  return qv_i(k)*pseudo_density_i(k);
1191  };
1192  Real mm = RU::view_reduction(team, 0, nlevs, tracer_mass);
1193 
1194  EKAT_KERNEL_ASSERT_MSG(mm >= cc, "Error! Total mass of column vapor should be greater than mass of surf_evap.\n");
1195 
1196  Kokkos::parallel_for(Kokkos::TeamVectorRange(team, nlev_packs), [&](const int& k)
1197  {
1198  const auto adjust = cc*qv_i(k)*pseudo_density_i(k)/mm;
1199  qv_i(k) = (qv_i(k)*pseudo_density_i(k) - adjust)/pseudo_density_i(k);
1200  });
1201 
1202  surf_evap_d(i) = 0;
1203  }
1204  });
1205 }
@ PC
Definition: ERF_IndexDefines.H:158

◆ dealloc_buffers()

void SHOCInterface::dealloc_buffers ( )
276 {
277  // Contiguous memory buffer view
278  //=======================================================
280 
281  // Interface data structures
282  //=======================================================
283  omega = view_2d();
286  surf_evap = view_1d();
287  T_mid = view_2d();
288  qv = view_2d();
290 
291  // Input data structures
292  //=======================================================
293  p_mid = view_2d();
294  p_int = view_2d();
295  pseudo_dens = view_2d();
296  phis = view_1d();
297 
298  // Input/Output data structures
299  //=======================================================
300  horiz_wind = view_3d();
301  cldfrac_liq = view_2d();
302  tke = view_2d();
303  qc = view_2d();
304 
305  // Output data structures
306  //=======================================================
307  pblh = view_1d();
309  tkh = view_2d();
310  w_sec = view_2d();
312  ustar = view_1d();
313  obklen = view_1d();
314 
315  // Extra diagnostic data structures
316  //=======================================================
317  if (extra_shoc_diags) {
318  brunt = view_2d();
319  shoc_mix = view_2d();
320  isotropy = view_2d();
321  shoc_cond = view_2d();
322  shoc_evap = view_2d();
323 
324  wthl_sec = view_2d();
325  thl_sec = view_2d();
326  wqw_sec = view_2d();
327  qw_sec = view_2d();
328  uw_sec = view_2d();
329  vw_sec = view_2d();
330  w3 = view_2d();
331  }
332 
333  // Tracer data structures
334  //=======================================================
336 
337  // Boundary flux data structures
338  //=======================================================
340  vapor_flux = view_1d();
341  water_flux = view_1d();
342  ice_flux = view_1d();
343  heat_flux = view_1d();
344  }
345 }
view_1d tot_buff_view
Definition: ERF_ShocInterface.H:677

◆ finalize_impl()

void SHOCInterface::finalize_impl ( const double  dt)
1118 {
1119  // Do nothing (per SHOCMacrophysics::finalize_impl())
1120 
1121  // Fill the AMReX MFs from Kokkos Views
1123 
1124  // Deallocate the buffer arrays
1125  dealloc_buffers();
1126 }
void kokkos_buffers_to_mf(const double dt)
Definition: ERF_ShocInterface.cpp:520
void dealloc_buffers()
Definition: ERF_ShocInterface.cpp:275

◆ init_buffers()

void SHOCInterface::init_buffers ( )
protected
803 {
804 
805  // Buffer of contiguous memory
806  auto buffer_size = requested_buffer_size_in_bytes();
807  tot_buff_view = view_1d("contiguous shoc_buffer",buffer_size);
808  Real* mem = reinterpret_cast<Real*>(tot_buff_view.data());
809 
810  // 1d scalar views
811  using scalar_view_t = decltype(m_buffer.wpthlp_sfc);
812  scalar_view_t* _1d_scalar_view_ptrs[Buffer::num_1d_scalar_ncol] =
814 #ifdef SCREAM_SHOC_SMALL_KERNELS
815  , &m_buffer.se_b, &m_buffer.ke_b, &m_buffer.wv_b, &m_buffer.wl_b
816  , &m_buffer.se_a, &m_buffer.ke_a, &m_buffer.wv_a, &m_buffer.wl_a
817  , &m_buffer.kbfs, &m_buffer.ustar2, &m_buffer.wstar
818 #endif
819  };
820  for (int i = 0; i < Buffer::num_1d_scalar_ncol; ++i) {
821  *_1d_scalar_view_ptrs[i] = scalar_view_t(mem, m_num_cols);
822  mem += _1d_scalar_view_ptrs[i]->size();
823  }
824 
825  Spack* s_mem = reinterpret_cast<Spack*>(mem);
826 
827  // 2d packed views
828  const int nlev_packs = ekat::npack<Spack>(m_num_layers);
829  const int nlevi_packs = ekat::npack<Spack>(m_num_layers+1);
830  const int num_tracer_packs = ekat::npack<Spack>(m_num_tracers);
831 
832  m_buffer.pref_mid = decltype(m_buffer.pref_mid)(s_mem, nlev_packs);
833  s_mem += m_buffer.pref_mid.size();
834 
835  using spack_2d_view_t = decltype(m_buffer.z_mid);
836  spack_2d_view_t* _2d_spack_mid_view_ptrs[Buffer::num_2d_vector_mid] =
840 #ifdef SCREAM_SHOC_SMALL_KERNELS
841  , &m_buffer.rho_zt, &m_buffer.shoc_qv, &m_buffer.tabs, &m_buffer.dz_zt
842 #endif
843  };
844 
845  spack_2d_view_t* _2d_spack_int_view_ptrs[Buffer::num_2d_vector_int] =
849 #ifdef SCREAM_SHOC_SMALL_KERNELS
850  , &m_buffer.dz_zi
851 #endif
852  };
853 
854  for (int i = 0; i < Buffer::num_2d_vector_mid; ++i) {
855  *_2d_spack_mid_view_ptrs[i] = spack_2d_view_t(s_mem, m_num_cols, nlev_packs);
856  s_mem += _2d_spack_mid_view_ptrs[i]->size();
857  }
858 
859  for (int i = 0; i < Buffer::num_2d_vector_int; ++i) {
860  *_2d_spack_int_view_ptrs[i] = spack_2d_view_t(s_mem, m_num_cols, nlevi_packs);
861  s_mem += _2d_spack_int_view_ptrs[i]->size();
862  }
863  m_buffer.wtracer_sfc = decltype(m_buffer.wtracer_sfc)(s_mem, m_num_cols, num_tracer_packs);
864  s_mem += m_buffer.wtracer_sfc.size();
865 
866  // WSM data
867  m_buffer.wsm_data = s_mem;
868 }
size_t requested_buffer_size_in_bytes() const
Definition: ERF_ShocInterface.cpp:778
typename SHF::Spack Spack
Definition: ERF_ShocInterface.H:57
uview_2d< Spack > w3
Definition: ERF_ShocInterface.H:536
uview_2d< Spack > qc_copy
Definition: ERF_ShocInterface.H:523
uview_2d< Spack > dse
Definition: ERF_ShocInterface.H:521
uview_2d< Spack > vw_sec
Definition: ERF_ShocInterface.H:535
uview_1d< Real > wpthlp_sfc
Definition: ERF_ShocInterface.H:488
uview_2d< Spack > thv
Definition: ERF_ShocInterface.H:512
uview_2d< Spack > wqls_sec
Definition: ERF_ShocInterface.H:537
uview_2d< Spack > wthl_sec
Definition: ERF_ShocInterface.H:531
uview_2d< Spack > thlm
Definition: ERF_ShocInterface.H:519
uview_2d< Spack > uw_sec
Definition: ERF_ShocInterface.H:534
uview_2d< Spack > z_mid
Definition: ERF_ShocInterface.H:508
uview_2d< Spack > rrho
Definition: ERF_ShocInterface.H:510
uview_2d< Spack > wtke_sec
Definition: ERF_ShocInterface.H:533
uview_2d< Spack > unused
Definition: ERF_ShocInterface.H:507
Spack * wsm_data
Definition: ERF_ShocInterface.H:548
static constexpr int num_2d_vector_int
Definition: ERF_ShocInterface.H:481
uview_2d< Spack > wtracer_sfc
Definition: ERF_ShocInterface.H:516
uview_2d< Spack > inv_exner
Definition: ERF_ShocInterface.H:518
uview_2d< Spack > qwthl_sec
Definition: ERF_ShocInterface.H:530
uview_2d< Spack > qw
Definition: ERF_ShocInterface.H:520
uview_2d< Spack > brunt
Definition: ERF_ShocInterface.H:538
uview_2d< Spack > shoc_mix
Definition: ERF_ShocInterface.H:525
uview_2d< Spack > tke_copy
Definition: ERF_ShocInterface.H:522
static constexpr int num_1d_scalar_ncol
Definition: ERF_ShocInterface.H:474
uview_2d< Spack > isotropy
Definition: ERF_ShocInterface.H:526
uview_2d< Spack > zt_grid
Definition: ERF_ShocInterface.H:514
uview_2d< Spack > w_sec
Definition: ERF_ShocInterface.H:527
uview_2d< Spack > thl_sec
Definition: ERF_ShocInterface.H:528
uview_2d< Spack > wm_zt
Definition: ERF_ShocInterface.H:517
uview_2d< Spack > qw_sec
Definition: ERF_ShocInterface.H:529
uview_2d< Spack > wqw_sec
Definition: ERF_ShocInterface.H:532
uview_2d< Spack > z_int
Definition: ERF_ShocInterface.H:509
uview_2d< Spack > shoc_ql2
Definition: ERF_ShocInterface.H:524
uview_1d< Real > wprtp_sfc
Definition: ERF_ShocInterface.H:489
uview_2d< Spack > zi_grid
Definition: ERF_ShocInterface.H:515
static constexpr int num_2d_vector_mid
Definition: ERF_ShocInterface.H:480
uview_1d< Spack > pref_mid
Definition: ERF_ShocInterface.H:505
uview_2d< Spack > dz
Definition: ERF_ShocInterface.H:513

◆ initialize_impl()

void SHOCInterface::initialize_impl ( )
873 {
874  // Alias local variables from temporary buffer
875  auto z_mid = m_buffer.z_mid;
876  auto z_int = m_buffer.z_int;
877  auto wpthlp_sfc = m_buffer.wpthlp_sfc;
878  auto wprtp_sfc = m_buffer.wprtp_sfc;
879  auto upwp_sfc = m_buffer.upwp_sfc;
880  auto vpwp_sfc = m_buffer.vpwp_sfc;
881  auto rrho = m_buffer.rrho;
882  auto rrho_i = m_buffer.rrho_i;
883  auto thv = m_buffer.thv;
884  auto dz = m_buffer.dz;
885  auto zt_grid = m_buffer.zt_grid;
886  auto zi_grid = m_buffer.zi_grid;
887  auto wtracer_sfc = m_buffer.wtracer_sfc;
888  auto wm_zt = m_buffer.wm_zt;
889  auto inv_exner = m_buffer.inv_exner;
890  auto thlm = m_buffer.thlm;
891  auto qw = m_buffer.qw;
892  auto dse = m_buffer.dse;
893  auto tke_copy = m_buffer.tke_copy;
894  auto qc_copy = m_buffer.qc_copy;
895  auto shoc_ql2 = m_buffer.shoc_ql2;
896 
897  // For now, set z_int(i,nlevs) = z_surf = 0
898  const Real z_surf = Real(0.);
899 
900  // Set preprocess variables
903  surf_mom_flux, qtracers, qv, qc, qc_copy, tke, tke_copy, z_mid, z_int,
904  dse, rrho, rrho_i, thv, dz, zt_grid, zi_grid, wpthlp_sfc, wprtp_sfc, upwp_sfc,
905  vpwp_sfc, wtracer_sfc, wm_zt, inv_exner, thlm, qw, cldfrac_liq, cldfrac_liq_prev);
906 
907  // Input Variables:
908  input.zt_grid = shoc_preprocess.zt_grid;
909  input.zi_grid = shoc_preprocess.zi_grid;
910  input.pres = p_mid;
911  input.presi = p_int;
912  input.pdel = pseudo_dens;
913  input.thv = shoc_preprocess.thv;
914  input.w_field = shoc_preprocess.wm_zt;
915  input.wthl_sfc = shoc_preprocess.wpthlp_sfc;
916  input.wqw_sfc = shoc_preprocess.wprtp_sfc;
917  input.uw_sfc = shoc_preprocess.upwp_sfc;
918  input.vw_sfc = shoc_preprocess.vpwp_sfc;
919  input.wtracer_sfc = shoc_preprocess.wtracer_sfc;
920  input.inv_exner = shoc_preprocess.inv_exner;
921  input.phis = phis;
922 
923  // Input/Output Variables
928  input_output.horiz_wind = horiz_wind;
929  input_output.wthv_sec = sgs_buoy_flux;
931  input_output.tk = tk;
932  input_output.shoc_cldfrac = cldfrac_liq;
933  input_output.shoc_ql = qc_copy;
934 
935  // Output Variables
936  output.pblh = pblh;
937  output.shoc_ql2 = shoc_ql2;
938  output.tkh = tkh;
939  output.ustar = ustar;
940  output.obklen = obklen;
941 
942  // Output (diagnostic)
943  history_output.shoc_mix = m_buffer.shoc_mix;
944  history_output.isotropy = m_buffer.isotropy;
945  if (extra_shoc_diags) {
946  history_output.shoc_cond = shoc_cond;
947  history_output.shoc_evap = shoc_evap;
948  } else {
949  history_output.shoc_cond = m_buffer.unused;
950  history_output.shoc_evap = m_buffer.unused;
951  }
952  history_output.w_sec = w_sec;
953  history_output.thl_sec = m_buffer.thl_sec;
954  history_output.qw_sec = m_buffer.qw_sec;
955  history_output.qwthl_sec = m_buffer.qwthl_sec;
956  history_output.wthl_sec = m_buffer.wthl_sec;
957  history_output.wqw_sec = m_buffer.wqw_sec;
958  history_output.wtke_sec = m_buffer.wtke_sec;
959  history_output.uw_sec = m_buffer.uw_sec;
960  history_output.vw_sec = m_buffer.vw_sec;
962  history_output.wqls_sec = m_buffer.wqls_sec;
963  history_output.brunt = m_buffer.brunt;
964 
965 #ifdef SCREAM_SHOC_SMALL_KERNELS
966  temporaries.se_b = m_buffer.se_b;
967  temporaries.ke_b = m_buffer.ke_b;
968  temporaries.wv_b = m_buffer.wv_b;
969  temporaries.wl_b = m_buffer.wl_b;
970  temporaries.se_a = m_buffer.se_a;
971  temporaries.ke_a = m_buffer.ke_a;
972  temporaries.wv_a = m_buffer.wv_a;
973  temporaries.wl_a = m_buffer.wl_a;
974  temporaries.kbfs = m_buffer.kbfs;
975  temporaries.ustar2 = m_buffer.ustar2;
976  temporaries.wstar = m_buffer.wstar;
977 
978  temporaries.rho_zt = m_buffer.rho_zt;
979  temporaries.shoc_qv = m_buffer.shoc_qv;
980  temporaries.tabs = m_buffer.tabs;
981  temporaries.dz_zt = m_buffer.dz_zt;
982  temporaries.dz_zi = m_buffer.dz_zi;
983 #endif
984 
985  // Set postprocess variables
987  rrho, qv, qw, qc, qc_copy, tke,
988  tke_copy, qtracers, shoc_ql2,
990  T_mid, dse, z_mid, phis);
991 
992  // Setup WSM for internal local variables
993  using TPF = ekat::TeamPolicyFactory<KT::ExeSpace>;
994  const auto nlev_packs = ekat::npack<Spack>(m_num_layers);
995  const auto nlevi_packs = ekat::npack<Spack>(m_num_layers+1);
996  const auto default_policy = TPF::get_default_team_policy(m_num_cols, nlev_packs);
997  const Int num_slots = wsm_num_slots();
998 
999  // The WSM data sits at the tail of the contiguous buffer, so the slots we
1000  // hand it here must not exceed what requested_buffer_size_in_bytes() set aside.
1001  const size_t wsm_offset = static_cast<size_t>(reinterpret_cast<Real*>(m_buffer.wsm_data)
1002  - tot_buff_view.data());
1003  const size_t wsm_reals = WSM::get_total_bytes_needed(nlevi_packs, num_slots,
1004  default_policy)/sizeof(Real);
1005  AMREX_ALWAYS_ASSERT_WITH_MESSAGE(wsm_offset + wsm_reals <= tot_buff_view.size(),
1006  "SHOC WSM slots exceed the reserved buffer; "
1007  "wsm_num_slots() and requested_buffer_size_in_bytes() disagree");
1008 
1009  workspace_mgr.setup(m_buffer.wsm_data, nlevi_packs, num_slots, default_policy);
1010 
1011  // NOTE: Vertical indices were permuted, so top and bottom are correct
1012  // Maximum number of levels in pbl from surface
1013  const int ntop_shoc = 0;
1014  const int nbot_shoc = m_num_layers;
1015  auto p_mid_d = p_mid;
1016  view_1d pref_mid("pref_mid", m_num_layers);
1017  Spack* s_mem = reinterpret_cast<Spack*>(pref_mid.data());
1018  SHF::view_1d<Spack> pref_mid_um(s_mem, m_num_layers);
1019  const auto policy = TPF::get_default_team_policy(m_num_cols, nlev_packs);
1020  Kokkos::parallel_for("pref_mid",
1021  policy,
1022  KOKKOS_LAMBDA (const KT::MemberType& team)
1023  {
1024  const auto i = team.league_rank();
1025  if (i==0) {
1026  const auto& pmid_i = ekat::subview(p_mid_d, i);
1027  Kokkos::parallel_for(Kokkos::TeamVectorRange(team, nlev_packs), [&](const int& k)
1028  {
1029  pref_mid_um(k) = pmid_i(k);
1030  });
1031  }
1032  });
1033  Kokkos::fence();
1034  m_npbl = SHF::shoc_init(nbot_shoc,ntop_shoc,pref_mid_um);
1035 
1036  // Cell length for input dx and dy
1037  view_1d cell_length_x("cell_length_x", m_num_cols);
1038  view_1d cell_length_y("cell_length_y", m_num_cols);
1039  Kokkos::deep_copy(cell_length_x, m_geom.CellSize(0));
1040  Kokkos::deep_copy(cell_length_y, m_geom.CellSize(1));
1041  input.dx = cell_length_x;
1042  input.dy = cell_length_y;
1043 }
AMREX_ALWAYS_ASSERT_WITH_MESSAGE(m_cloud_chamber_config.active, "Cloud Chamber: initializer reached without a parsed configuration")
int Int
Definition: ERF_ShocInterface.H:20
SHOCPreprocess shoc_preprocess
Definition: ERF_ShocInterface.H:669
amrex::Geometry m_geom
Definition: ERF_ShocInterface.H:619
view_2d sgs_buoy_flux
Definition: ERF_ShocInterface.H:706
SHF::SHOCOutput output
Definition: ERF_ShocInterface.H:661
ekat::WorkspaceManager< Spack, KT::Device > workspace_mgr
Definition: ERF_ShocInterface.H:673
Int m_npbl
Definition: ERF_ShocInterface.H:606
SHF::SHOCInput input
Definition: ERF_ShocInterface.H:659
SHOCPostprocess shoc_postprocess
Definition: ERF_ShocInterface.H:670
SHF::SHOCInputOutput input_output
Definition: ERF_ShocInterface.H:660
view_2d tk
Definition: ERF_ShocInterface.H:707
SHF::SHOCHistoryOutput history_output
Definition: ERF_ShocInterface.H:662
Int wsm_num_slots() const
Definition: ERF_ShocInterface.H:591
@ dz
Definition: ERF_AdvanceWDM6.cpp:272
void set_variables(const int ncol_, const int nlev_, const view_2d_const &rrho_, const view_2d &qv_, const view_2d_const &qw_, const view_2d &qc_, const view_2d_const &qc_copy_, const view_2d &tke_, const view_2d_const &tke_copy_, const view_3d_strided &qtracers_, const view_2d_const &qc2_, const view_2d &cldfrac_liq_, const view_2d &inv_qc_relvar_, const view_2d &T_mid_, const view_2d_const &dse_, const view_2d_const &z_mid_, const view_1d_const phis_)
Definition: ERF_ShocInterface.H:430
view_3d_strided qtracers
Definition: ERF_ShocInterface.H:266
view_2d thlm
Definition: ERF_ShocInterface.H:288
view_2d zt_grid
Definition: ERF_ShocInterface.H:279
view_2d inv_exner
Definition: ERF_ShocInterface.H:287
view_2d wm_zt
Definition: ERF_ShocInterface.H:286
view_2d wtracer_sfc
Definition: ERF_ShocInterface.H:285
view_1d wprtp_sfc
Definition: ERF_ShocInterface.H:282
view_2d qw
Definition: ERF_ShocInterface.H:289
view_1d upwp_sfc
Definition: ERF_ShocInterface.H:283
view_1d wpthlp_sfc
Definition: ERF_ShocInterface.H:281
view_1d vpwp_sfc
Definition: ERF_ShocInterface.H:284
view_2d shoc_s
Definition: ERF_ShocInterface.H:272
view_2d tke_copy
Definition: ERF_ShocInterface.H:274
view_2d zi_grid
Definition: ERF_ShocInterface.H:280
view_2d thv
Definition: ERF_ShocInterface.H:277
void set_variables(const int ncol_, const int nlev_, const Real z_surf_, const view_2d_const &T_mid_, const view_2d_const &p_mid_, const view_2d_const &p_int_, const view_2d_const &pseudo_density_, const view_2d_const &omega_, const view_1d_const &phis_, const view_1d_const &surf_sens_flux_, const view_1d_const &surf_evap_, const sview_2d_const &surf_mom_flux_, const view_3d_strided &qtracers_, const view_2d &qv_, const view_2d_const &qc_, const view_2d &qc_copy_, const view_2d &tke_, const view_2d &tke_copy_, const view_2d &z_mid_, const view_2d &z_int_, const view_2d &dse_, const view_2d &rrho_, const view_2d &rrho_i_, const view_2d &thv_, const view_2d &dz_, const view_2d &zt_grid_, const view_2d &zi_grid_, const view_1d &wpthlp_sfc_, const view_1d &wprtp_sfc_, const view_1d &upwp_sfc_, const view_1d &vpwp_sfc_, const view_2d &wtracer_sfc_, const view_2d &wm_zt_, const view_2d &inv_exner_, const view_2d &thlm_, const view_2d &qw_, const view_2d &cldfrac_liq_, const view_2d &cldfrac_liq_prev_)
Definition: ERF_ShocInterface.H:295
Here is the call graph for this function:

◆ kokkos_buffers_to_mf()

void SHOCInterface::kokkos_buffers_to_mf ( const double  dt)
521 {
522  //
523  // Expose for device capture
524  //
525 
526  // Buffer data structures
527  //=======================================================
528  auto thlm_d = m_buffer.thlm;
529 
530  // Interface data structures
531  //=======================================================
532  auto T_mid_d = T_mid;
533  auto qv_d = qv;
534 
535  // Input/Output data structures
536  //=======================================================
537  auto horiz_wind_d = horiz_wind;
538  auto tke_d = tke;
539  auto qc_d = qc;
540 
541  bool moist = (m_cons->nComp() > RhoQ1_comp);
542  for (MFIter mfi(*m_cons); mfi.isValid(); ++mfi) {
543  // NOTE: No ghost cells when going back to MFs
544  const auto& vbx_cc = mfi.validbox();
545  const auto& vbx_x = convert(vbx_cc,IntVect(1,0,0));
546  const auto& vbx_y = convert(vbx_cc,IntVect(0,1,0));
547 
548  // NOTE: Grown box only for mapping
549  const auto& gbx = mfi.tilebox(IntVect(0,0,0),IntVect(1,1,0));
550  const int nx = gbx.length(0);
551  const int imin = gbx.smallEnd(0);
552  const int jmin = gbx.smallEnd(1);
553  const int kmax = gbx.bigEnd(2);
554  const int offset = m_col_offsets[mfi.index()];
555 
556  const Array4<const Real>& cons_arr = m_cons->const_array(mfi);
557  const Array4<const Real>& u_arr = m_xvel->const_array(mfi);
558  const Array4<const Real>& v_arr = m_yvel->const_array(mfi);
559 
560  const Array4<Real>& c_tend_arr = c_tend.array(mfi);
561  const Array4<Real>& u_tend_arr = u_tend.array(mfi);
562  const Array4<Real>& v_tend_arr = v_tend.array(mfi);
563 
564  // Interpolate SHOC cell-centered wind increments to faces. Reconstructing the
565  // face winds first would apply a horizontal filter even for a zero increment.
566  ParallelFor(vbx_cc, vbx_x, vbx_y,
567  [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept
568  {
569  // NOTE: k gets permuted with ilay
570  // map [i,j,k] 0-based to [icol, ilay] 0-based
571  const int icol = (j-jmin)*nx + (i-imin) + offset;
572  const int ilay = kmax - k;
573 
574  // Density at CC
575  Real r = cons_arr(i,j,k,Rho_comp);
576 
577  // Theta at CC (eamxx_common_physics_functions_impl.hpp L123)
578  Real Th = thlm_d(icol,ilay)[0] / ( one - (one / T_mid_d(icol,ilay)[0])
579  * (C::LatVap/C::Cpair) * qc_d(icol,ilay)[0] );
580 
581  // Populate the tendencies
582  c_tend_arr(i,j,k,RhoTheta_comp) = ( Th - cons_arr(i,j,k,RhoTheta_comp)/r ) / dt;
583  c_tend_arr(i,j,k,RhoKE_comp) = ( tke_d(icol,ilay)[0] - cons_arr(i,j,k,RhoKE_comp )/r ) / dt;
584  if (moist) {
585  c_tend_arr(i,j,k,RhoQ1_comp) = ( qv_d(icol,ilay)[0] - cons_arr(i,j,k,RhoQ1_comp)/r ) / dt;
586  c_tend_arr(i,j,k,RhoQ2_comp) = ( qc_d(icol,ilay)[0] - cons_arr(i,j,k,RhoQ2_comp)/r ) / dt;
587  }
588  },
589  [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept
590  {
591  // NOTE: k gets permuted with ilay
592  // map [i,j,k] 0-based to [icol, ilay] 0-based
593  const int icol = (j-jmin)*nx + (i-imin) + offset;
594  const int ilay = kmax - k;
595 
596  int icolim = (j-jmin)*nx + (i-1-imin) + offset;
597  Real du_cc = horiz_wind_d(icol,0,ilay)[0]
598  - Real(0.5) * (u_arr(i,j,k) + u_arr(i+1,j,k));
599  Real du_cc_im = horiz_wind_d(icolim,0,ilay)[0]
600  - Real(0.5) * (u_arr(i-1,j,k) + u_arr(i,j,k));
601  u_tend_arr(i,j,k) = Real(0.5) * (du_cc_im + du_cc) / dt;
602  },
603  [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept
604  {
605  // NOTE: k gets permuted with ilay
606  // map [i,j,k] 0-based to [icol, ilay] 0-based
607  const int icol = (j-jmin)*nx + (i-imin) + offset;
608  const int ilay = kmax - k;
609 
610  int icoljm = (j-1-jmin)*nx + (i-imin) + offset;
611  Real dv_cc = horiz_wind_d(icol,1,ilay)[0]
612  - Real(0.5) * (v_arr(i,j,k) + v_arr(i,j+1,k));
613  Real dv_cc_jm = horiz_wind_d(icoljm,1,ilay)[0]
614  - Real(0.5) * (v_arr(i,j-1,k) + v_arr(i,j,k));
615  v_tend_arr(i,j,k) = Real(0.5) * (dv_cc_jm + dv_cc) / dt;
616  });
617  }
618 }
const int nx
Definition: ERF_InitCustomPertVels_CloudChamber.H:14
AMREX_FORCE_INLINE IntVect offset(const int face_dir, const int normal)
Definition: ERF_ReadBndryPlanes.cpp:32
amrex::MultiFab * m_yvel
Definition: ERF_ShocInterface.H:629
amrex::MultiFab * m_xvel
Definition: ERF_ShocInterface.H:628
amrex::Vector< int > m_col_offsets
Definition: ERF_ShocInterface.H:600
Here is the call graph for this function:

◆ mf_to_kokkos_buffers()

void SHOCInterface::mf_to_kokkos_buffers ( )
350 {
351  // FillBoundary for internal ghost cells for u/v averaging
352  m_tau13->FillBoundary(m_geom.periodicity());
353  m_tau23->FillBoundary(m_geom.periodicity());
354  m_hfx3->FillBoundary(m_geom.periodicity());
355  m_qfx3->FillBoundary(m_geom.periodicity());
356 
357  //
358  // Expose for device capture
359  //
360 
361  // Interface data structures
362  //=======================================================
363  auto omega_d = omega;
364  auto surf_sens_flux_d = surf_sens_flux;
365  auto surf_mom_flux_d = surf_mom_flux;
366  auto surf_evap_d = surf_evap;
367  auto T_mid_d = T_mid;
368  auto qv_d = qv;
369  auto surf_drag_coeff_tms_d = surf_drag_coeff_tms;
370 
371  // Input data structures
372  //=======================================================
373  auto p_mid_d = p_mid;
374  auto p_int_d = p_int;
375  auto pseudo_dens_d = pseudo_dens;
376  auto phis_d = phis;
377 
378  // Input/Output data structures
379  //=======================================================
380  auto horiz_wind_d = horiz_wind;
381  auto cldfrac_liq_d = cldfrac_liq;
382  auto tke_d = tke;
383  auto qc_d = qc;
384 
385  // Enforce the correct grid heights and density
386  //=======================================================
387  auto dz_d = m_buffer.dz;
388 
389  // Subsidence pointer to device vector data
390  Real* w_sub = m_w_subsid;
391 
392  int nlay = m_num_layers;
393  Real dz = m_geom.CellSize(2);
394  bool moist = (m_cons->nComp() > RhoQ1_comp);
395  auto ProbLoArr = m_geom.ProbLoArray();
396 
397  auto domain = m_geom.Domain();
398  int ilo = domain.smallEnd(0);
399  int ihi = domain.bigEnd(0);
400  int jlo = domain.smallEnd(1);
401  int jhi = domain.bigEnd(1);
402 
403  for (MFIter mfi(*m_cons); mfi.isValid(); ++mfi) {
404  // NOTE: Grown box to get ghost cells in views
405  const auto& gbx = mfi.tilebox(IntVect(0,0,0),IntVect(1,1,0));
406  const int nx = gbx.length(0);
407  const int imin = gbx.smallEnd(0);
408  const int jmin = gbx.smallEnd(1);
409  const int kmax = gbx.bigEnd(2);
410  const int offset = m_col_offsets[mfi.index()];
411 
412  const Array4<const Real>& cons_arr = m_cons->const_array(mfi);
413 
414  const Array4<const Real>& u_arr = m_xvel->const_array(mfi);
415  const Array4<const Real>& v_arr = m_yvel->const_array(mfi);
416  const Array4<const Real>& w_arr = m_zvel->const_array(mfi);
417 
418  const Array4<const Real>& t13_arr = m_tau13->const_array(mfi);
419  const Array4<const Real>& t23_arr = m_tau23->const_array(mfi);
420  const Array4<const Real>& hfx3_arr = m_hfx3->const_array(mfi);
421  const Array4<const Real>& qfx3_arr = m_qfx3->const_array(mfi);
422 
423  const Array4<const Real>& z_arr = (m_z_phys) ? m_z_phys->const_array(mfi) :
424  Array4<const Real>{};
425  ParallelFor(gbx, [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept
426  {
427  // NOTE: k gets permuted with ilay
428  // map [i,j,k] 0-based to [icol, ilay] 0-based
429  const int icol = (j-jmin)*nx + (i-imin) + offset;
430  const int ilay = kmax - k;
431  const int ilayi = kmax + 1 - k;
432 
433  // EOS input (at CC)
434  Real r = cons_arr(i,j,k,Rho_comp);
435  Real rt = cons_arr(i,j,k,RhoTheta_comp);
436  Real qv = (moist) ? cons_arr(i,j,k,RhoQ1_comp)/r : Real(0.);
437  Real qc = (moist) ? cons_arr(i,j,k,RhoQ2_comp)/r : Real(0.);
438 
439  // EOS avg to z-face
440  Real r_lo = cons_arr(i,j,k-1,Rho_comp);
441  Real rt_lo = cons_arr(i,j,k-1,RhoTheta_comp);
442  Real qv_lo = (moist) ? cons_arr(i,j,k-1,RhoQ1_comp)/r_lo : Real(0.);
443  Real rt_avg = Real(0.5) * (rt + rt_lo);
444  Real qv_avg = Real(0.5) * (qv + qv_lo);
445 
446  // Delta z
447  Real delz = (z_arr) ? Real(0.25) * ( (z_arr(i ,j ,k+1) - z_arr(i ,j ,k))
448  + (z_arr(i+1,j ,k+1) - z_arr(i+1,j ,k))
449  + (z_arr(i ,j+1,k+1) - z_arr(i ,j+1,k))
450  + (z_arr(i+1,j+1,k+1) - z_arr(i+1,j+1,k)) ) : dz;
451 
452  // W at cc (cannot be 0?; inspection of shoc code...)
453  Real w_cc = Real(0.5) * (w_arr(i,j,k) + w_arr(i,j,k+1));
454  w_cc += (w_sub) ? Real(0.5) * (w_sub[k] + w_sub[k+1]) : Real(0.);
455  Real w_limited = std::copysign(std::max(std::fabs(w_cc),Real(1.0e-6)),w_cc);
456 
457  // Input/Output data structures
458  //=======================================================
459  horiz_wind_d(icol,0,ilay) = Real(0.5) * (u_arr(i,j,k) + u_arr(i+1,j ,k));
460  horiz_wind_d(icol,1,ilay) = Real(0.5) * (v_arr(i,j,k) + v_arr(i ,j+1,k));
461  cldfrac_liq_d(icol,ilay) = (qc>Real(0.)) ? Real(1.) : Real(0.);
462  tke_d(icol,ilay) = std::max(cons_arr(i,j,k,RhoKE_comp)/r, Real(0.));
463  qc_d(icol,ilay) = qc;
464 
465  // Interface data structures
466  //=======================================================
467  // eamxx_common_physics_functions_impl.hpp: calculate_vertical_velocity
468  omega_d(icol,ilay) = -w_limited * r * CONST_GRAV;
469  if (k==0) {
470  int ii = std::min(std::max(i,ilo),ihi);
471  int jj = std::min(std::max(j,jlo),jhi);
472 
473  surf_mom_flux_d(icol,0) = Real(0.5) * (t13_arr(ii,jj,k) + t13_arr(ii+1,jj ,k));
474  surf_mom_flux_d(icol,1) = Real(0.5) * (t23_arr(ii,jj,k) + t23_arr(ii ,jj+1,k));
475  // No unit conversion to W/m^2 (ERF_ShocInterface.H L224)
476  surf_sens_flux_d(icol) = hfx3_arr(ii,jj,k);
477  surf_evap_d(icol) = (moist) ? qfx3_arr(ii,jj,k) : Real(0.);
478  // EAMxx TMS expects rho * Cd * |U| [kg/(m^2 s)]. Back it out
479  // from the conservative surface-stress and wind magnitudes.
480  Real wsp = std::sqrt( horiz_wind_d(icol,0,ilay)[0]*horiz_wind_d(icol,0,ilay)[0]
481  + horiz_wind_d(icol,1,ilay)[0]*horiz_wind_d(icol,1,ilay)[0] );
482  Real stress_mag = std::sqrt( surf_mom_flux_d(icol,0)*surf_mom_flux_d(icol,0)
483  + surf_mom_flux_d(icol,1)*surf_mom_flux_d(icol,1) );
484  surf_drag_coeff_tms_d(icol) = (wsp > Real(1.0e-8)) ? stress_mag / wsp : Real(0.);
485  }
486  T_mid_d(icol,ilay) = getTgivenRandRTh(r, rt, qv);
487  qv_d(icol,ilay) = qv;
488 
489  // Input data structures
490  //=======================================================
491  p_mid_d(icol,ilay) = getPgivenRTh(rt, qv);
492  p_int_d(icol,ilayi) = getPgivenRTh(rt_avg, qv_avg);
493  // eamxx_common_physics_functions_impl.hpp: calculate_density
494  pseudo_dens_d(icol,ilay) = r * CONST_GRAV * delz;
495  // Enforce the grid spacing
496  dz_d(icol,ilay) = delz;
497  // Surface geopotential
498  if (k==0) {
499  Real z = (z_arr) ? Real(0.125) * ( (z_arr(i ,j ,k+1) + z_arr(i ,j ,k))
500  + (z_arr(i+1,j ,k+1) + z_arr(i+1,j ,k))
501  + (z_arr(i ,j+1,k+1) + z_arr(i ,j+1,k))
502  + (z_arr(i+1,j+1,k+1) + z_arr(i+1,j+1,k)) ) : ProbLoArr[2];
503  phis_d(icol) = CONST_GRAV * z;
504  }
505 
506  if (ilay==0) {
507  Real r_hi = cons_arr(i,j,k+1,Rho_comp);
508  Real rt_hi = cons_arr(i,j,k+1,RhoTheta_comp);
509  Real qv_hi = (moist) ? std::max(cons_arr(i,j,k+1,RhoQ1_comp)/r_hi,Real(0.)) : Real(0.);
510  rt_avg = Real(0.5) * (rt + rt_hi);
511  qv_avg = Real(0.5) * (qv + qv_hi);
512  p_int_d(icol,0) = getPgivenRTh(rt_avg, qv_avg);
513  }
514  });
515  }
516 }
constexpr amrex::Real CONST_GRAV
Definition: ERF_Constants.H:56
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
amrex::MultiFab * m_z_phys
Definition: ERF_ShocInterface.H:645
amrex::MultiFab * m_qfx3
Definition: ERF_ShocInterface.H:639
amrex::MultiFab * m_zvel
Definition: ERF_ShocInterface.H:630
amrex::MultiFab * m_tau23
Definition: ERF_ShocInterface.H:637
amrex::MultiFab * m_tau13
Definition: ERF_ShocInterface.H:636
amrex::MultiFab * m_hfx3
Definition: ERF_ShocInterface.H:638
amrex::Real * m_w_subsid
Definition: ERF_ShocInterface.H:633
@ delz
Definition: ERF_WSM6.H:281
Here is the call graph for this function:

◆ name()

std::string SHOCInterface::name ( ) const
inline
131 { return "shoc"; }

◆ requested_buffer_size_in_bytes()

size_t SHOCInterface::requested_buffer_size_in_bytes ( ) const
protected
779 {
780  using TPF = ekat::TeamPolicyFactory<KT::ExeSpace>;
781 
782  const int nlev_packs = ekat::npack<Spack>(m_num_layers);
783  const int nlevi_packs = ekat::npack<Spack>(m_num_layers+1);
784  const int num_tracer_packs = ekat::npack<Spack>(m_num_tracers);
785 
786  // Number of Reals needed by local views in the interface
787  const size_t interface_request = Buffer::num_1d_scalar_ncol*m_num_cols*sizeof(Real) +
788  Buffer::num_1d_scalar_nlev*nlev_packs*sizeof(Spack) +
789  Buffer::num_2d_vector_mid*m_num_cols*nlev_packs*sizeof(Spack) +
790  Buffer::num_2d_vector_int*m_num_cols*nlevi_packs*sizeof(Spack) +
791  Buffer::num_2d_vector_tr*m_num_cols*num_tracer_packs*sizeof(Spack);
792 
793  // Number of Reals needed by the WorkspaceManager passed to shoc_main
794  const auto policy = TPF::get_default_team_policy(m_num_cols, nlev_packs);
795  const size_t wsm_request = WSM::get_total_bytes_needed(nlevi_packs, wsm_num_slots(), policy);
796 
797  return ( (interface_request + wsm_request)/sizeof(Real) );
798 }
static constexpr int num_2d_vector_tr
Definition: ERF_ShocInterface.H:486
static constexpr int num_1d_scalar_nlev
Definition: ERF_ShocInterface.H:478

◆ run_impl()

void SHOCInterface::run_impl ( const double  dt)
1048 {
1049  using TPF = ekat::TeamPolicyFactory<KT::ExeSpace>;
1050 
1051  EKAT_REQUIRE_MSG (dt<=300,
1052  "Error! SHOC is intended to run with a timestep no longer than 5 minutes.\n"
1053  " Please, reduce timestep (perhaps increasing subcycling iterations).\n");
1054 
1055  const auto nlev_packs = ekat::npack<Spack>(m_num_layers);
1056  const auto scan_policy = TPF::get_thread_range_parallel_scan_team_policy(m_num_cols, nlev_packs);
1057  const auto default_policy = TPF::get_default_team_policy(m_num_cols, nlev_packs);
1058 
1059  // Preprocessing of SHOC inputs. Kernel contains a parallel_scan,
1060  // so a special TeamPolicy is required.
1061  Kokkos::parallel_for("shoc_preprocess",
1062  scan_policy,
1063  shoc_preprocess);
1064  Kokkos::fence();
1065 
1066  auto wtracer_sfc = shoc_preprocess.wtracer_sfc;
1067  Kokkos::deep_copy(wtracer_sfc, 0);
1068 
1069  if (apply_tms) {
1071  }
1072 
1073  if (check_flux_state) {
1075  }
1076 
1077  // For now set the host timestep to the shoc timestep. This forces
1078  // number of SHOC timesteps (nadv) to be one
1079  // TODO: input parameter?
1080  hdtime = dt;
1081  m_nadv = std::max(static_cast<int>(round(hdtime/dt)),1);
1082 
1083  // Reset internal WSM variables.
1084  workspace_mgr.reset_internals();
1085 
1086  // Run shoc main
1087  SHF::shoc_main(m_num_cols, m_num_layers, m_num_layers+1, m_npbl, m_nadv, m_num_tracers, dt,
1089 #ifdef SCREAM_SHOC_SMALL_KERNELS
1090  , temporaries
1091 #endif
1092  );
1093 
1094  // Postprocessing of SHOC outputs
1095  Kokkos::parallel_for("shoc_postprocess",
1096  default_policy,
1098  Kokkos::fence();
1099 
1100  // Extra SHOC output diagnostics
1101  if (runtime_options.extra_diags) {
1102  Kokkos::deep_copy(shoc_mix,history_output.shoc_mix);
1103  Kokkos::deep_copy(brunt,history_output.brunt);
1104  Kokkos::deep_copy(w3,history_output.w3);
1105  Kokkos::deep_copy(isotropy,history_output.isotropy);
1106  Kokkos::deep_copy(wthl_sec,history_output.wthl_sec);
1107  Kokkos::deep_copy(wqw_sec,history_output.wqw_sec);
1108  Kokkos::deep_copy(uw_sec,history_output.uw_sec);
1109  Kokkos::deep_copy(vw_sec,history_output.vw_sec);
1110  Kokkos::deep_copy(qw_sec,history_output.qw_sec);
1111  Kokkos::deep_copy(thl_sec,history_output.thl_sec);
1112  }
1113 }
Int m_nadv
Definition: ERF_ShocInterface.H:607
void check_flux_state_consistency(const double dt)
Definition: ERF_ShocInterface.cpp:1152
Int hdtime
Definition: ERF_ShocInterface.H:610
void apply_turbulent_mountain_stress()
Definition: ERF_ShocInterface.cpp:1130

◆ set_computed_group_impl()

void SHOCInterface::set_computed_group_impl ( )
protected

◆ set_diff_stresses()

void SHOCInterface::set_diff_stresses ( )
686 {
687  for (MFIter mfi(*m_hfx3); mfi.isValid(); ++mfi) {
688  const auto& vbx_cc = mfi.validbox();
689  const auto& vbx_xz = convert(vbx_cc,IntVect(1,0,1));
690  const auto& vbx_yz = convert(vbx_cc,IntVect(0,1,1));
691 
692  const Array4<Real>& hfx_arr = m_hfx3->array(mfi);
693  const Array4<Real>& qfx_arr = m_qfx3->array(mfi);
694 
695  const Array4<Real>& t13_arr = m_tau13->array(mfi);
696  const Array4<Real>& t23_arr = m_tau23->array(mfi);
697 
698  ParallelFor(vbx_cc, vbx_xz, vbx_yz,
699  [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept
700  {
701  hfx_arr(i,j,k) = Real(0.);
702  qfx_arr(i,j,k) = Real(0.);
703  },
704  [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept
705  {
706  t13_arr(i,j,k) = Real(0.);
707  },
708  [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept
709  {
710  t23_arr(i,j,k) = Real(0.);
711  });
712  }
713 }
Here is the call graph for this function:

◆ set_eddy_diffs()

void SHOCInterface::set_eddy_diffs ( )
623 {
624  //
625  // Expose for device capture
626  //
627 
628  // Input/Output data structures
629  //=======================================================
630  auto tk_d = tk;
631 
632  // NOTE: Loop on grown box to fill ghost cells but limit
633  // to valid box where views are defined.
634  for (MFIter mfi(*m_mu); mfi.isValid(); ++mfi) {
635  const auto& gbx_cc = mfi.growntilebox();
636  const auto& vbx_cc = mfi.validbox();
637 
638  // NOTE: Grown box only for mapping
639  const auto& gbx = mfi.tilebox(IntVect(0,0,0),IntVect(1,1,0));
640  const int nx = gbx.length(0);
641  const int imin = gbx.smallEnd(0);
642  const int jmin = gbx.smallEnd(1);
643  const int kmax = gbx.bigEnd(2);
644  const int offset = m_col_offsets[mfi.index()];
645 
646  // Limiting to validbox
647  const int iminv = vbx_cc.smallEnd(0);
648  const int imaxv = vbx_cc.bigEnd(0);
649  const int jminv = vbx_cc.smallEnd(1);
650  const int jmaxv = vbx_cc.bigEnd(1);
651  const int kminv = vbx_cc.smallEnd(2);
652  const int kmaxv = vbx_cc.bigEnd(2);
653 
654  const Array4<Real>& mu_arr = m_mu->array(mfi);
655  const Array4<const Real>& cons_arr = m_cons->const_array(mfi);
656 
657  ParallelFor(gbx_cc, [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept
658  {
659  // Limiting
660  int ii = std::min(std::max(i,iminv),imaxv);
661  int jj = std::min(std::max(j,jminv),jmaxv);
662  int kk = std::min(std::max(k,kminv),kmaxv);
663 
664  // NOTE: k gets permuted with ilay
665  // map [i,j,k] 0-based to [icol, ilay] 0-based
666  const int icol = (jj-jmin)*nx + (ii-imin) + offset;
667  const int ilay = kmax - kk;
668 
669  // NOTE: SHOC provides kinematic diffusivity, while eddyDiffs stores
670  // density-weighted diffusivity. Set mom_v for tau_33; all
671  // other vertical components are 0.
672  mu_arr(i,j,k,EddyDiff::Mom_v) = cons_arr(ii,jj,kk,Rho_comp) * tk_d(icol,ilay)[0];
673  mu_arr(i,j,k,EddyDiff::Theta_v) = Real(0.);
674  mu_arr(i,j,k,EddyDiff::KE_v) = Real(0.);
675  mu_arr(i,j,k,EddyDiff::Q_v) = Real(0.);
676  });
677  }
678 
679  // Correct the internal ghost cells that have foextrap
680  m_mu->FillBoundary(m_geom.periodicity());
681 }
amrex::MultiFab * m_mu
Definition: ERF_ShocInterface.H:642
@ Theta_v
Definition: ERF_IndexDefines.H:250
@ Q_v
Definition: ERF_IndexDefines.H:253
@ Mom_v
Definition: ERF_IndexDefines.H:249
@ KE_v
Definition: ERF_IndexDefines.H:251
Here is the call graph for this function:

◆ set_grids()

void SHOCInterface::set_grids ( int &  level,
const amrex::BoxArray &  ba,
amrex::Geometry &  geom,
amrex::MultiFab *  cons,
amrex::MultiFab *  xvel,
amrex::MultiFab *  yvel,
amrex::MultiFab *  zvel,
amrex::Real w_subsid,
amrex::MultiFab *  tau13,
amrex::MultiFab *  tau23,
amrex::MultiFab *  hfx3,
amrex::MultiFab *  qfx3,
amrex::MultiFab *  eddyDiffs,
amrex::MultiFab *  z_phys 
)
136 {
137  // Set data members that may change
138  m_lev = level;
139  m_geom = geom;
140  m_cons = cons;
141  m_xvel = xvel;
142  m_yvel = yvel;
143  m_zvel = zvel;
144  m_w_subsid = w_subsid;
145  m_tau13 = tau13;
146  m_tau23 = tau23;
147  m_hfx3 = hfx3;
148  m_qfx3 = qfx3;
149  m_mu = eddyDiffs;
150  m_z_phys = z_phys;
151 
152  // Ensure the boxes span klo -> khi
153  int klo = geom.Domain().smallEnd(2);
154  int khi = geom.Domain().bigEnd(2);
155 
156  // Reset vector of offsets for columnar data
157  m_num_layers = geom.Domain().length(2);
158 
159  int num_cols = 0;
160  m_col_offsets.clear();
161  m_col_offsets.resize(int(ba.size()));
162  for (MFIter mfi(*m_cons); mfi.isValid(); ++mfi) {
163  // NOTE: Get lateral ghost cells for CC <--> FC
164  const auto& gbx = mfi.tilebox(IntVect(0,0,0),IntVect(1,1,0));
165  AMREX_ALWAYS_ASSERT_WITH_MESSAGE((klo == gbx.smallEnd(2)) &&
166  (khi == gbx.bigEnd(2)),
167  "Vertical decomposition with shoc is not allowed.");
168  int nx = gbx.length(0);
169  int ny = gbx.length(1);
170  m_col_offsets[mfi.index()] = num_cols;
171  num_cols += nx * ny;
172  }
173 
174  // Resize the Kokkos variables that persist in memory
175  if (num_cols != m_num_cols) {
177  tk = view_2d();
178  sgs_buoy_flux = view_2d("sgs_buoy_flux", num_cols, m_num_layers);
179  tk = view_2d("eddy_diff_mom", num_cols, m_num_layers);
180  }
181  m_num_cols = num_cols;
182 
183  // Allocate the tendency MultiFabs
184  c_tend.define(m_cons->boxArray(), m_cons->DistributionMap(), m_cons->nComp(), 0);
185  u_tend.define(m_xvel->boxArray(), m_xvel->DistributionMap(), m_xvel->nComp(), 0);
186  v_tend.define(m_yvel->boxArray(), m_yvel->DistributionMap(), m_yvel->nComp(), 0);
187 
188  // Allocate the buffer arrays in ERF
189  alloc_buffers();
190 
191  // Allocate the m_buffer struct
192  init_buffers();
193 
194  // Fill the KOKKOS Views from AMReX MFs
196 }
@ tau23
Definition: ERF_DataStruct.H:40
@ tau13
Definition: ERF_DataStruct.H:40
const int ny
Definition: ERF_InitCustomPertVels_CloudChamber.H:15
const int klo
Definition: ERF_InitCustomPert_ABL.H:75
const int khi
Definition: ERF_InitCustomPert_Bubble.H:21
void alloc_buffers()
Definition: ERF_ShocInterface.cpp:200
void init_buffers()
Definition: ERF_ShocInterface.cpp:802
int m_lev
Definition: ERF_ShocInterface.H:613
void mf_to_kokkos_buffers()
Definition: ERF_ShocInterface.cpp:349
@ xvel
Definition: ERF_IndexDefines.H:215
@ cons
Definition: ERF_IndexDefines.H:214
@ zvel
Definition: ERF_IndexDefines.H:217
@ yvel
Definition: ERF_IndexDefines.H:216
Here is the call graph for this function:

◆ wsm_num_slots()

Int SHOCInterface::wsm_num_slots ( ) const
inlineprotected
592  {
593  const Int n_wind_slots = ekat::npack<Spack>(m_num_vel_comp)*Spack::n;
594  const Int n_trac_slots = ekat::npack<Spack>(m_num_tracers +
595  shoc_extra_trac_slots)*Spack::n;
596  return ( 14 + (n_wind_slots + n_trac_slots) );
597  }
static constexpr Int shoc_extra_trac_slots
Definition: ERF_ShocInterface.H:585

Member Data Documentation

◆ apply_tms

bool SHOCInterface::apply_tms = false
protected

◆ brunt

view_2d SHOCInterface::brunt
protected

◆ c_tend

amrex::MultiFab SHOCInterface::c_tend
protected

◆ check_flux_state

bool SHOCInterface::check_flux_state = false
protected

◆ cldfrac_liq

view_2d SHOCInterface::cldfrac_liq
protected

◆ cldfrac_liq_prev

view_2d SHOCInterface::cldfrac_liq_prev
protected

◆ column_conservation_check

bool SHOCInterface::column_conservation_check = false
protected

◆ extra_shoc_diags

bool SHOCInterface::extra_shoc_diags = false
protected

◆ hdtime

Int SHOCInterface::hdtime
protected

◆ heat_flux

view_1d SHOCInterface::heat_flux
protected

◆ history_output

SHF::SHOCHistoryOutput SHOCInterface::history_output
protected

◆ horiz_wind

view_3d SHOCInterface::horiz_wind
protected

◆ ice_flux

view_1d SHOCInterface::ice_flux
protected

◆ input

SHF::SHOCInput SHOCInterface::input
protected

◆ input_output

SHF::SHOCInputOutput SHOCInterface::input_output
protected

◆ inv_qc_relvar

view_2d SHOCInterface::inv_qc_relvar
protected

◆ isotropy

view_2d SHOCInterface::isotropy
protected

◆ m_ba

amrex::BoxArray SHOCInterface::m_ba
protected

◆ m_buffer

Buffer SHOCInterface::m_buffer
protected

◆ m_col_offsets

amrex::Vector<int> SHOCInterface::m_col_offsets
protected

◆ m_cons

amrex::MultiFab* SHOCInterface::m_cons = nullptr
protected

◆ m_first_step

bool SHOCInterface::m_first_step = true
protected

◆ m_geom

amrex::Geometry SHOCInterface::m_geom
protected

◆ m_hfx3

amrex::MultiFab* SHOCInterface::m_hfx3 = nullptr
protected

◆ m_lev

int SHOCInterface::m_lev
protected

◆ m_mu

amrex::MultiFab* SHOCInterface::m_mu = nullptr
protected

◆ m_nadv

Int SHOCInterface::m_nadv
protected

◆ m_npbl

Int SHOCInterface::m_npbl
protected

◆ m_num_cols

Int SHOCInterface::m_num_cols = 0
protected

◆ m_num_layers

Int SHOCInterface::m_num_layers = 0
protected

◆ m_num_tracers

Int SHOCInterface::m_num_tracers = 3
protected

Referenced by wsm_num_slots().

◆ m_num_vel_comp

Int SHOCInterface::m_num_vel_comp = 2
protected

Referenced by wsm_num_slots().

◆ m_qfx3

amrex::MultiFab* SHOCInterface::m_qfx3 = nullptr
protected

◆ m_step

int SHOCInterface::m_step
protected

◆ m_tau13

amrex::MultiFab* SHOCInterface::m_tau13 = nullptr
protected

◆ m_tau23

amrex::MultiFab* SHOCInterface::m_tau23 = nullptr
protected

◆ m_w_subsid

amrex::Real* SHOCInterface::m_w_subsid = nullptr
protected

◆ m_xvel

amrex::MultiFab* SHOCInterface::m_xvel = nullptr
protected

◆ m_yvel

amrex::MultiFab* SHOCInterface::m_yvel = nullptr
protected

◆ m_z_phys

amrex::MultiFab* SHOCInterface::m_z_phys = nullptr
protected

◆ m_zvel

amrex::MultiFab* SHOCInterface::m_zvel = nullptr
protected

◆ obklen

view_1d SHOCInterface::obklen
protected

◆ omega

view_2d SHOCInterface::omega
protected

◆ output

SHF::SHOCOutput SHOCInterface::output
protected

◆ p_int

view_2d SHOCInterface::p_int
protected

◆ p_mid

view_2d SHOCInterface::p_mid
protected

◆ pblh

view_1d SHOCInterface::pblh
protected

◆ phis

view_1d SHOCInterface::phis
protected

◆ pseudo_dens

view_2d SHOCInterface::pseudo_dens
protected

◆ qc

view_2d SHOCInterface::qc
protected

◆ qtracers

view_3d_strided SHOCInterface::qtracers
protected

◆ qv

view_2d SHOCInterface::qv
protected

◆ qw_sec

view_2d SHOCInterface::qw_sec
protected

◆ runtime_options

SHF::SHOCRuntime SHOCInterface::runtime_options
protected

◆ sgs_buoy_flux

view_2d SHOCInterface::sgs_buoy_flux
protected

◆ shoc_cond

view_2d SHOCInterface::shoc_cond
protected

◆ shoc_evap

view_2d SHOCInterface::shoc_evap
protected

◆ shoc_extra_trac_slots

constexpr Int SHOCInterface::shoc_extra_trac_slots = 3
staticconstexprprotected

Referenced by wsm_num_slots().

◆ shoc_mix

view_2d SHOCInterface::shoc_mix
protected

◆ shoc_postprocess

SHOCPostprocess SHOCInterface::shoc_postprocess
protected

◆ shoc_preprocess

SHOCPreprocess SHOCInterface::shoc_preprocess
protected

◆ surf_drag_coeff_tms

view_1d SHOCInterface::surf_drag_coeff_tms
protected

◆ surf_evap

view_1d SHOCInterface::surf_evap
protected

◆ surf_mom_flux

sview_2d SHOCInterface::surf_mom_flux
protected

◆ surf_sens_flux

view_1d SHOCInterface::surf_sens_flux
protected

◆ T_mid

view_2d SHOCInterface::T_mid
protected

◆ thl_sec

view_2d SHOCInterface::thl_sec
protected

◆ tk

view_2d SHOCInterface::tk
protected

◆ tke

view_2d SHOCInterface::tke
protected

◆ tkh

view_2d SHOCInterface::tkh
protected

◆ tot_buff_view

view_1d SHOCInterface::tot_buff_view
protected

◆ u_tend

amrex::MultiFab SHOCInterface::u_tend
protected

◆ ustar

view_1d SHOCInterface::ustar
protected

◆ uw_sec

view_2d SHOCInterface::uw_sec
protected

◆ v_tend

amrex::MultiFab SHOCInterface::v_tend
protected

◆ vapor_flux

view_1d SHOCInterface::vapor_flux
protected

◆ vw_sec

view_2d SHOCInterface::vw_sec
protected

◆ w3

view_2d SHOCInterface::w3
protected

◆ w_sec

view_2d SHOCInterface::w_sec
protected

◆ water_flux

view_1d SHOCInterface::water_flux
protected

◆ workspace_mgr

ekat::WorkspaceManager<Spack, KT::Device> SHOCInterface::workspace_mgr
protected

◆ wqw_sec

view_2d SHOCInterface::wqw_sec
protected

◆ wthl_sec

view_2d SHOCInterface::wthl_sec
protected

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