ERF
Energy Research and Forecasting: An Atmospheric Modeling Code
ERF_PBLModels.H File Reference
#include <AMReX_Periodicity.H>
#include "ERF_Constants.H"
#include "ERF_DataStruct.H"
Include dependency graph for ERF_PBLModels.H:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  PBLDerivativeDzInv
 
struct  PBLDerivativeDzInv_N
 Functor for inverse vertical spacings with constant grid spacing. More...
 
struct  PBLDerivativeDzInv_S
 Functor for inverse vertical spacings for stretched grids using a spacing array. More...
 
struct  PBLDerivativeDzInv_T
 Functor for inverse vertical spacings for terrain-following grids using cell-center heights. More...
 

Functions

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)
 
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 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)
 
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 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 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 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)
 
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)
 
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. More...
 

Function Documentation

◆ ApplyPBLHSmoothing()

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 
)
inline

Apply spatial smoothing to PBLH field using 5-point stencil.

Applies a simple 5-point spatial averaging to reduce grid-to-grid noise in the diagnosed PBLH field. This is standard post-processing practice for discrete Rib-crossing detection as described in Seibert et al. (2000): "Review and intercomparison of operational methods for the determination of the mixing height", Atmospheric Environment, 34, 1001-1027.

Stencil: PBLH_smooth(i,j) = w * PBLH(i,j) + (1-w)/4 * [PBLH(i+-1,j) + PBLH(i,j+-1)]

The stencil reads one column outside the region it writes, so the result on a cell depends on columns that a single tile – or a single box – does not own. The caller therefore names the region it wants smoothed (xybx_valid, normally the planar tile box) inside a work array carrying passes columns of halo around it, filled from the same inputs. Pass p writes the region grown by passes-1-p and reads the one grown by passes-p, so each pass consumes one column of halo and the last lands exactly on xybx_valid. Every read stays inside the array, and the result does not depend on how the domain is divided into boxes or tiles.

At a non-periodic domain edge there is no column to read, so the stencil reuses the cell's own value (reflective/Neumann). Across a periodic edge the halo holds the wrapped columns and is read directly, which is why the periodicity has to be passed in: clamping there would fold an edge into a domain that has none.

Parameters
[in,out]pblh_fabFArrayBox holding the 2D PBLH field (component 0), sized to contain xybx_valid grown by passes in x and y
[in]xybx_validRegion to smooth (x,y indices only)
[in]weightCenter cell weight in stencil (must be in [0,1])
[in]passesNumber of smoothing iterations
[in]domainDomain box, for the reflective edge condition
[in]periodicityDomain periodicity, so periodic edges read the halo
521 {
522  if (passes <= 0) { return; }
523 
524  // The caller must supply the halo the passes will consume; see the note above.
526  pblh_fab.box().contains(amrex::grow(xybx_valid, amrex::IntVect(passes,passes,0))),
527  "ApplyPBLHSmoothing: the PBLH work array needs `passes` columns of halo "
528  "around the region being smoothed");
529 
530  // Use a temporary to hold intermediate results
531  amrex::FArrayBox pblh_temp(pblh_fab.box(), 1, amrex::The_Async_Arena());
532  auto pblh = pblh_fab.array();
533  auto pblh_tmp = pblh_temp.array();
534 
535  const auto& dom_lo = amrex::lbound(domain);
536  const auto& dom_hi = amrex::ubound(domain);
537 
538  const bool per_x = periodicity.isPeriodic(0);
539  const bool per_y = periodicity.isPeriodic(1);
540 
541  const amrex::Real wt_side = (one - weight) / four; // Weight for each of 4 neighbors
542 
543  // Apply smoothing passes
544  for (int pass = 0; pass < passes; ++pass) {
545  const int halo = passes - 1 - pass;
546  const amrex::Box bx = amrex::grow(xybx_valid, amrex::IntVect(halo,halo,0));
547 
548  amrex::ParallelFor(bx, [=] AMREX_GPU_DEVICE(int i, int j, int) noexcept
549  {
550  // Reflective (Neumann) at a non-periodic domain edge: reuse the cell's
551  // own value. Everywhere else -- including across a periodic edge, where
552  // the halo holds the wrapped column -- read the neighbour.
553  const int i_xlo = (per_x || i > dom_lo.x) ? (i - 1) : i;
554  const int i_xhi = (per_x || i < dom_hi.x) ? (i + 1) : i;
555  const int j_ylo = (per_y || j > dom_lo.y) ? (j - 1) : j;
556  const int j_yhi = (per_y || j < dom_hi.y) ? (j + 1) : j;
557 
558  // 5-point stencil
559  pblh_tmp(i, j, 0) = weight * pblh(i, j, 0)
560  + wt_side * (pblh(i_xlo, j, 0) + pblh(i_xhi, j, 0) +
561  pblh(i, j_ylo, 0) + pblh(i, j_yhi, 0));
562  });
563 
564  // Copy back only what this pass computed: outside bx the array still holds
565  // the previous pass, which no later pass reads.
566  pblh_fab.copy<amrex::RunOn::Device>(pblh_temp, bx, 0, bx, 0, 1);
567  }
568 }
AMREX_ALWAYS_ASSERT_WITH_MESSAGE(m_cloud_chamber_config.active, "Cloud Chamber: initializer reached without a parsed configuration")
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:33
constexpr amrex::Real one
Definition: ERF_NumericalConstants.H:30
amrex::Real Real
Definition: ERF_ShocInterface.H:19

Referenced by ComputeDiffusivityMRF(), and ComputeDiffusivityYSUNew().

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

◆ ComputeDiffusivityMRF()

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 
)

Compute eddy diffusivities of momentum (eddy viscosity) and heat using the Medium Range Forecast (MRF) boundary layer scheme based on Hong and Pan (1996). Reference: Hong, S. Y., and H.-L. Pan, 1996: Nonlocal Boundary Layer Vertical Diffusion in a Medium-Range Forecast Model. Monthly Weather Review, 124, 2322-2339. https://doi.org/10.1175/1520-0493(1996)124<2322:NBLVDI>2.0.CO;2

Parameters
[in]xvelVelocity in x-dir
[in]yvelVelocity in y-dir
[in]cons_inCell center conserved quantities
[out]eddyViscosityHolds turbulent viscosity
[in]geomProblem geometry
[in]turbChoiceContainer with turbulence parameters
[in]SurfLayerPointer to Monin-Obukhov class if instantiated
[in]use_moistureIf we have microphysics enabled
[in]levelCurrent level
[in]bc_ptrPointer to array with boundary condition info
[in]vert_onlyOnly compute vertical eddy diffusivities
[in]z_phys_ndPhysical location of grid nodes, if terrain (or grid stretching) is enabled
[in]z_phys_ccPhysical location of cell centers

◆ ComputeDiffusivityMYJ()

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 
)

Compute eddy diffusivities of momentum (eddy viscosity) and heat using the Mellor-Yamada-Janjić (MYJ) boundary layer scheme. Reference: Janjić, Z. I., 1994: The Step-Mountain Eta Coordinate Model: Further Developments of the Convection, Viscous Sublayer, and Turbulence Closure Schemes. Monthly Weather Review, 122, 927–945. https://doi.org/10.1175/1520-0493(1994)122<0927:TSMECM>2.0.CO;2

Parameters
[in]xvelVelocity in x-dir
[in]yvelVelocity in y-dir
[in]cons_inCell center conserved quantities
[out]eddyViscosityHolds turbulent viscosity
[in]geomProblem geometry
[in]turbChoiceContainer with turbulence parameters
[in]SurfLayerPointer to Monin-Obukhov class if instantiated
[in]use_moistureIf we have microphysics enabled
[in]levelCurrent level
[in]bc_ptrPointer to array with boundary condition info
[in]vert_onlyOnly compute vertical eddy diffusivities
[in]z_phys_ndPhysical location of grid nodes, if terrain (or grid stretching) is enabled
[in]z_phys_ccPhysical location of cell centers

◆ ComputeDiffusivityMYNN25()

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 
)

Compute eddy diffusivities of momentum (eddy viscosity) and heat using the Mellor-Yamada-Nakanishi-Niino Level amrex::Real(2.5) PBL scheme

Parameters
[in]xvelVelocity in x-dir
[in]yvelVelocity in y-dir
[in]cons_inCell center conserved quantities
[out]eddyViscosityHolds turbulent viscosity
[in]geomProblem geometry
[in]turbChoiceContainer with turbulence parameters
[in]SurfLayerPointer to Monin-Obukhov class if instantiated
[in]use_moistureIf we have microphysics enabled
[in]levelCurrent level
[in]bc_ptrPointer to array with boundary condition info
[in]vert_onlyOnly compute vertical eddy diffusivities
[in]z_phys_ndPhysical location of grid nodes, if terrain (or grid stretching) is enabled
[in]z_phys_ccPhysical location of cell centers

◆ ComputeDiffusivityMYNNEDMF()

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 
)

Compute eddy diffusivities of momentum (eddy viscosity) and heat using the Mellor-Yamada-Nakanishi-Niino Level amrex::Real(2.5) PBL scheme

Parameters
[in]xvelVelocity in x-dir
[in]yvelVelocity in y-dir
[in]cons_inCell center conserved quantities
[out]eddyViscosityHolds turbulent viscosity
[in]geomProblem geometry
[in]turbChoiceContainer with turbulence parameters
[in]SurfLayerPointer to Monin-Obukhov class if instantiated
[in]use_moistureIf we have microphysics enabled
[in]levelCurrent level
[in]bc_ptrPointer to array with boundary condition info
[in]vert_onlyOnly compute vertical eddy diffusivities
[in]z_phys_ndPhysical location of grid nodes, if terrain (or grid stretching) is enabled
[in]z_phys_ccPhysical location of cell centers

◆ ComputeDiffusivityYSU()

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 
)

Compute eddy diffusivities of momentum (eddy viscosity) and heat using the Yonsei University PBL scheme

Parameters
[in]xvelVelocity in x-dir
[in]yvelVelocity in y-dir
[in]cons_inCell center conserved quantities
[out]eddyViscosityHolds turbulent viscosity
[in]geomProblem geometry
[in]turbChoiceContainer with turbulence parameters
[in]SurfLayerPointer to Monin-Obukhov class if instantiated
[in]use_moistureIf we have microphysics enabled
[in]levelCurrent level
[in]bc_ptrPointer to array with boundary condition info
[in]vert_onlyOnly compute vertical eddy diffusivities
[in]z_phys_ndPhysical location of grid nodes, if terrain (or grid stretching) is enabled
[in]z_phys_ccPhysical location of cell centers

◆ ComputeDiffusivityYSUNew()

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 
)

Compute eddy diffusivities of momentum (eddy viscosity) and heat using the WRF Yonsei University (YSU) PBL scheme.

Based on: Hong, Noh & Dudhia (2006), MWR, https://doi.org/10.1175/MWR3250.1 Hong (2010), QJRMS, https://doi.org/10.1002/qj.665

Features: three-pass bulk-Richardson PBLH diagnosis, nonlocal countergradient fluxes, explicit entrainment at PBL top, and grid-adaptive Richardson-number mixing in free atmosphere.

Parameters
[in]xvelx-direction velocity
[in]yvely-direction velocity
[in]cons_incell-center conserved quantities
[out]eddyViscosityturbulent eddy viscosity
[in]geomproblem geometry
[in]turbChoiceturbulence parameter container
[in]SurfLayerMonin-Obukhov surface layer object
[in]use_terrain_fitted_coordsflag for terrain coordinates
[in]use_moistureflag for moisture active
[in]levelAMR level
[in]bc_ptrboundary condition array
[in]vert_onlycompute vertical diffusivity only
[in]z_phys_ndphysical node heights (terrain)
[in]z_phys_ccphysical cell-center heights
[in]moisture_indicescomponent index mapping for moisture variables
[in]qheating_ratesradiation heating rates (SW, LW components); optional

◆ ComputeQKESourceTerms()

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 
)

Function for computing the QKE source terms (NN09, Eqn. 5).

Parameters
[in]uvelocity in x-dir
[in]vvelocity in y-dir
[in]cell_dataconserved cell center vars
[in]cell_primprimitive cell center vars
[in]K_turbturbulent viscosity
[in]domainbox of the whole domain
[in]dz_invinverse spacings for interior and Dirichlet-boundary differences
[in]pbl_mynn_B1_la parameter
[in]theta_meanaverage theta
370 {
371  // Compute some relevant derivatives
372  amrex::Real dthetadz, dudz, dvdz;
373  amrex::Real source_term = zero;
374 
375  int izmin = domain.smallEnd(2);
376  int izmax = domain.bigEnd(2);
377 
379  uvel, vvel, cell_data, izmin, izmax, dz_inv,
380  c_ext_dir_on_zlo, c_ext_dir_on_zhi,
381  u_ext_dir_on_zlo, u_ext_dir_on_zhi,
382  v_ext_dir_on_zlo, v_ext_dir_on_zhi,
383  dthetadz, dudz, dvdz,
384  moisture_indices);
385 
386  // Notes:
387  // - We transport TKE = myhalf*QKE rather than QKE, so the RHS terms do not
388  // have a factor of two.
389  // - Transport terms due to turbulence and pressure are included when
390  // DiffusionSrcForState_* is called from ERF_slow_rhs_post.
391  // - Eddy diffusivities are updated at the beginning of each time step only.
392 
393  // Second-order turbulent fluxes, e.g.:
394  // -<uw> = L q SM dU/dz (NN09, Eqn. 18)
395  // = Kmv/rho dU/dz
396 
397  // Shear Production
398  source_term += K_turb(i,j,k,EddyDiff::Mom_v) * (dudz*dudz + dvdz*dvdz);
399 
400  // Buoyancy Production
401  source_term -= (CONST_GRAV/theta_mean)*K_turb(i,j,k,EddyDiff::Theta_v)*dthetadz;
402 
403  // Dissipation (NN09, Eqn. 12)
404  amrex::Real qke = two * cell_prim(i,j,k,PrimKE_comp);
405  if (std::abs(qke) > zero) {
406  source_term -= cell_data(i,j,k,Rho_comp) * std::pow(qke,amrex::Real(1.5)) /
407  (pbl_mynn_B1_l * K_turb(i,j,k,EddyDiff::Turb_lengthscale));
408  }
409 
410  return source_term;
411 }
constexpr amrex::Real CONST_GRAV
Definition: ERF_Constants.H:56
#define Rho_comp
Definition: ERF_IndexDefines.H:39
#define PrimKE_comp
Definition: ERF_IndexDefines.H:59
constexpr amrex::Real two
Definition: ERF_NumericalConstants.H:31
constexpr amrex::Real zero
Definition: ERF_NumericalConstants.H:29
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)
Definition: ERF_PBLModels.H:281
@ Theta_v
Definition: ERF_IndexDefines.H:250
@ Turb_lengthscale
Definition: ERF_IndexDefines.H:254
@ Mom_v
Definition: ERF_IndexDefines.H:249

Referenced by if().

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

◆ ComputeVerticalDerivativesPBL()

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 
)

Compute vertical derivatives of potential temperature and velocity for PBL models.

Parameters
ix-index
jy-index
kz-index
[in]uvelx-velocity
[in]vvely-velocity
[in]cell_dataconserved cell-center variables
[in]izminlower z-index limit
[in]izmaxupper z-index limit
[in]dz_invinverse physical distance spacings
[in]c_ext_dir_on_zloDirichlet condition on z-low face for cell data
[in]c_ext_dir_on_zhiDirichlet condition on z-high face for cell data
[in]u_ext_dir_on_zloDirichlet condition on z-low face for u-velocity
[in]u_ext_dir_on_zhiDirichlet condition on z-high face for u-velocity
[in]v_ext_dir_on_zloDirichlet condition on z-low face for v-velocity
[in]v_ext_dir_on_zhiDirichlet condition on z-high face for v-velocity
[out]dthetadzcomputed vertical derivative of potential temperature
[out]dudzcomputed vertical derivative of x-velocity
[out]dvdzcomputed vertical derivative of y-velocity
[in]moisture_indicesmoisture variable component indices
298 {
299  // ext_dir ghost values hold the value at the physical boundary, which is
300  // half a ghost-center spacing from the adjacent cell center. Use a
301  // two-point, first-order boundary-to-center difference with inverse
302  // distance 2/dz.
303  if ( k==izmax && c_ext_dir_on_zhi ) {
304  dthetadz = ( GetThetav(i,j,k+1,cell_data,moisture_indices)
305  -GetThetav(i,j,k ,cell_data,moisture_indices) )*dz_inv.dirichlet_hi;
306  } else if ( k==izmin && c_ext_dir_on_zlo ) {
307  dthetadz = ( GetThetav(i,j,k ,cell_data,moisture_indices)
308  -GetThetav(i,j,k-1,cell_data,moisture_indices) )*dz_inv.dirichlet_lo;
309  } else {
310  dthetadz = ( GetThetav(i,j,k+1,cell_data,moisture_indices)
311  -GetThetav(i,j,k-1,cell_data,moisture_indices) )*dz_inv.interior;
312  }
313 
314  if ( k==izmax && u_ext_dir_on_zhi ) {
315  dudz = myhalf*( uvel(i ,j,k+1) - uvel(i ,j,k)
316  +uvel(i+1,j,k+1) - uvel(i+1,j,k) )*dz_inv.dirichlet_hi;
317  } else if ( k==izmin && u_ext_dir_on_zlo ) {
318  dudz = myhalf*( uvel(i ,j,k) - uvel(i ,j,k-1)
319  +uvel(i+1,j,k) - uvel(i+1,j,k-1) )*dz_inv.dirichlet_lo;
320  } else {
321  dudz = myhalf*( uvel(i ,j,k+1) - uvel(i ,j,k-1)
322  +uvel(i+1,j,k+1) - uvel(i+1,j,k-1) )*dz_inv.interior;
323  }
324 
325  if ( k==izmax && v_ext_dir_on_zhi ) {
326  dvdz = myhalf*( vvel(i,j ,k+1) - vvel(i,j ,k)
327  +vvel(i,j+1,k+1) - vvel(i,j+1,k) )*dz_inv.dirichlet_hi;
328  } else if ( k==izmin && v_ext_dir_on_zlo ) {
329  dvdz = myhalf*( vvel(i,j ,k) - vvel(i,j ,k-1)
330  +vvel(i,j+1,k) - vvel(i,j+1,k-1) )*dz_inv.dirichlet_lo;
331  } else {
332  dvdz = myhalf*( vvel(i,j ,k+1) - vvel(i,j ,k-1)
333  +vvel(i,j+1,k+1) - vvel(i,j+1,k-1) )*dz_inv.interior;
334  }
335 }
AMREX_GPU_DEVICE AMREX_FORCE_INLINE amrex::Real GetThetav(const int &i, const int &j, const int &k, const amrex::Array4< amrex::Real const > &cell_data, const MoistureComponentIndices &moisture_indices)
Definition: ERF_MoistUtils.H:74
constexpr amrex::Real myhalf
Definition: ERF_NumericalConstants.H:34
amrex::Real dirichlet_hi
Definition: ERF_PBLModels.H:252
amrex::Real interior
Definition: ERF_PBLModels.H:250
amrex::Real dirichlet_lo
Definition: ERF_PBLModels.H:251

Referenced by ComputeDiffusivityMRF(), ComputeDiffusivityMYJ(), ComputeDiffusivityMYNN25(), ComputeDiffusivityMYNNEDMF(), ComputeDiffusivityYSU(), ComputeDiffusivityYSUNew(), and ComputeQKESourceTerms().

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