ERF
Energy Research and Forecasting: An Atmospheric Modeling Code
ERF_Utils.H File Reference
#include <utility>
#include "AMReX.H"
#include "AMReX_MultiFab.H"
#include "AMReX_BCRec.H"
#include "ERF_NumericalConstants.H"
#include "ERF_MicrophysicsConstants.H"
#include "ERF_DataStruct.H"
#include "ERF_IndexDefines.H"
#include "ERF_SurfaceLayer.H"
#include "ERF_FillPatcher.H"
#include "ERF_ImmersedWallCell.H"
#include "ERF_ReadBndryPlanes.H"
Include dependency graph for ERF_Utils.H:

Go to the source code of this file.

Classes

struct  RealBdyConsMaps
 

Enumerations

enum class  TimeLevelSel { Old , New , Interp }
 

Functions

AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real wrf_moisture_target (const amrex::Real rho, const amrex::Real q_n, const amrex::Real q_np1, const amrex::Real alpha) noexcept
 
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE bool wrf_bdy_has_separate_hydrometeors (const MoistureComponentIndices &moisture_indices) noexcept
 
int wrf_bdy_var_for_moisture_component (const int comp, const MoistureComponentIndices &moisture_indices, const bool use_wrf_bdy_qc_qi, const bool separate_hydrometeors=false)
 
RealBdyConsMaps real_bdy_cons_maps (const bool read_density, const MoistureComponentIndices &moisture_indices, const bool use_wrf_bdy_qc_qi, const bool separate_hydrometeors)
 
void rebalance_columns (amrex::MultiFab &rho, amrex::MultiFab &theta, const amrex::MultiFab &qt, const amrex::MultiFab &qv, const amrex::MultiFab *z_phys, const amrex::Geometry &geom, const bool &maintain_Th, bool use_sfc=false)
 
void ChopGrids2D (amrex::BoxArray &ba, const amrex::Box &domain, int target_size)
 
amrex::BoxArray ERFPostProcessBaseGrids (const amrex::Box &domain, bool decompose_in_z)
 
void cons_to_prim (const amrex::MultiFab &cons_state, amrex::MultiFab &S_prim, int ng)
 
void fill_wall_dist_ghost_cells (amrex::MultiFab &wdist, const amrex::Geometry &geom)
 
void make_qt (const amrex::MultiFab &cons_state, amrex::MultiFab &qt, int n_qstate_into_total)
 
void if_average_down (const amrex::MultiFab &S_fine, amrex::MultiFab &S_crse, const amrex::MultiFab &beta_fine, const amrex::MultiFab &beta_crse, const amrex::MultiFab &vol_fine, int scomp, int ncomp, const amrex::IntVect &ratio)
 
void immersed_wall_dist (amrex::MultiFab &wdist, const amrex::MultiFab &terrain_blank, const amrex::MultiFab &z_phys_nd, const amrex::MultiFab &z_phys_cc, const amrex::Box &domain, amrex::Real small_volfrac, amrex::MultiFab *wall_height=nullptr, const amrex::MultiFab *wall_height_crse=nullptr)
 
void make_ib_wall_face_masks (const amrex::MultiFab &terrain_blank, amrex::MultiFab &mask13, amrex::MultiFab &mask23, amrex::MultiFab &mask33, const amrex::Box &domain, amrex::Real small_volfrac, int spacing=0, amrex::Real dz=amrex::Real(1.0), amrex::Real z0=amrex::Real(0.1))
 
std::pair< int, amrex::Real > if_cf_surface_mismatch (const amrex::MultiFab &fine_tb, const amrex::BoxArray &fine_grids, const amrex::BoxArray &crse_grids, const amrex::DistributionMapping &crse_dmap, const amrex::Geometry &crse_geom, const amrex::IntVect &ratio, amrex::Real warn)
 
void make_J (const amrex::Geometry &geom, amrex::MultiFab &z_phys_nd, amrex::MultiFab &detJ_cc)
 
void make_areas (const amrex::Geometry &geom, amrex::MultiFab &z_phys_nd, amrex::MultiFab &ax, amrex::MultiFab &ay, amrex::MultiFab &az)
 
void make_zcc (const amrex::Geometry &geom, amrex::MultiFab &z_phys_nd, amrex::MultiFab &z_phys_cc)
 
void MomentumToVelocity (amrex::MultiFab &xvel_out, amrex::MultiFab &yvel_out, amrex::MultiFab &zvel_out, const amrex::MultiFab &cons_in, const amrex::MultiFab &xmom_in, const amrex::MultiFab &ymom_in, const amrex::MultiFab &zmom_in, const amrex::Box &domain, const amrex::Vector< amrex::BCRec > &domain_bcs_type_h, const amrex::MultiFab *c_vfrac=nullptr)
 
void VelocityToMomentum (const amrex::MultiFab &xvel_in, const amrex::IntVect &xvel_ngrow, const amrex::MultiFab &yvel_in, const amrex::IntVect &yvel_ngrow, const amrex::MultiFab &zvel_in, const amrex::IntVect &zvel_ngrow, const amrex::MultiFab &cons_in, amrex::MultiFab &xmom_out, amrex::MultiFab &ymom_out, amrex::MultiFab &zmom_out, const amrex::Box &domain, const amrex::Vector< amrex::BCRec > &domain_bcs_type_h, const amrex::MultiFab *c_vfrac=nullptr)
 
void ConvertForProjection (const amrex::MultiFab &den_div, const amrex::MultiFab &den_mlt, amrex::MultiFab &xmom, amrex::MultiFab &ymom, amrex::MultiFab &zmom, const amrex::Box &domain, const amrex::Vector< amrex::BCRec > &domain_bcs_type_h)
 
void compute_influx_outflux_bdy (amrex::FArrayBox &bdy_data_xlo, amrex::FArrayBox &bdy_data_xhi, amrex::FArrayBox &bdy_data_ylo, amrex::FArrayBox &bdy_data_yhi, amrex::Array< amrex::MultiFab *, AMREX_SPACEDIM > &area_vec, const amrex::Geometry &geom, amrex::Real &influx, amrex::Real &outflux, const int n)
 
void enforceInOutSolvability_bdy (const amrex::MultiFab &rho0, amrex::FArrayBox &bdy_data_xlo, amrex::FArrayBox &bdy_data_xhi, amrex::FArrayBox &bdy_data_ylo, amrex::FArrayBox &bdy_data_yhi, amrex::Array< amrex::MultiFab *, AMREX_SPACEDIM > &area_vec, const amrex::Geometry &geom, const amrex::Vector< amrex::BCRec > &domain_bcs_type_h)
 
void enforceInOutSolvability (int lev, amrex::Array< amrex::MultiFab *, AMREX_SPACEDIM > &vels_vec, amrex::Array< amrex::MultiFab *, AMREX_SPACEDIM > &area_vec, const amrex::Geometry &geom)
 
void realbdy_interior_bxs_xy (const amrex::Box &bx, const amrex::Box &domain, const int &width, amrex::Box &bx_xlo, amrex::Box &bx_xhi, amrex::Box &bx_ylo, amrex::Box &bx_yhi, const amrex::IntVect &ng_vect=amrex::IntVect(0, 0, 0), const bool get_int_ng=false)
 
void realbdy_bc_bxs_xy (const amrex::Box &bx, const amrex::Box &domain, const int &set_width, amrex::Box &bx_xlo, amrex::Box &bx_xhi, amrex::Box &bx_ylo, amrex::Box &bx_yhi, const amrex::IntVect &ng_vect=amrex::IntVect(0, 0, 0))
 
void realbdy_compute_interior_ghost_rhs (const double &total_time, const double &delta_t, const double &start_bdy_time, const double &final_bdy_time, const double &bdy_time_interval, const amrex::Real &nudge_factor, int width, const amrex::Geometry &geom, amrex::Vector< amrex::MultiFab > &S_rhs, amrex::Vector< amrex::MultiFab > &S_cur_data, amrex::Vector< amrex::Vector< amrex::FArrayBox >> &bdy_data_xlo, amrex::Vector< amrex::Vector< amrex::FArrayBox >> &bdy_data_xhi, amrex::Vector< amrex::Vector< amrex::FArrayBox >> &bdy_data_ylo, amrex::Vector< amrex::Vector< amrex::FArrayBox >> &bdy_data_yhi, std::unique_ptr< ReadBndryPlanes > &m_r2d, const amrex::Real &c_p, const amrex::Real &rdOcp, const bool use_wrf_bdy_density, const amrex::Real &bdy_rho_nudge_factor)
 
void fine_compute_interior_ghost_rhs (const double &time, const double &delta_t, const int &width, const int &set_width, const amrex::Geometry &geom, ERFFillPatcher *FPr_c, ERFFillPatcher *FPr_u, ERFFillPatcher *FPr_v, ERFFillPatcher *FPr_w, amrex::Vector< amrex::BCRec > &domain_bcs_type, amrex::Vector< amrex::MultiFab > &S_rhs_f, amrex::Vector< amrex::MultiFab > &S_data_f)
 
void Time_Avg_Vel_atCC (double dt, double &t_avg_cnt, amrex::MultiFab *vel_t_avg, amrex::MultiFab &xvel, amrex::MultiFab &yvel, amrex::MultiFab &zvel)
 
void Accumulate_Interval_Means (double dt, double &t_mean_cnt, amrex::MultiFab *interval_means, amrex::MultiFab &xvel, amrex::MultiFab &yvel, amrex::MultiFab &zvel, amrex::MultiFab &cons)
 
AMREX_GPU_HOST AMREX_FORCE_INLINE void realbdy_compute_relaxation (const int &icomp, const int &num_var, const int &width, const amrex::GpuArray< amrex::Real, AMREX_SPACEDIM > &dx, const amrex::GpuArray< amrex::Real, AMREX_SPACEDIM > &ProbLo, const amrex::GpuArray< amrex::Real, AMREX_SPACEDIM > &ProbHi, const amrex::Real &F1, const amrex::Box &bx_xlo, const amrex::Box &bx_xhi, const amrex::Box &bx_ylo, const amrex::Box &bx_yhi, const amrex::Array4< const amrex::Real > &arr_xlo, const amrex::Array4< const amrex::Real > &arr_xhi, const amrex::Array4< const amrex::Real > &arr_ylo, const amrex::Array4< const amrex::Real > &arr_yhi, const amrex::Array4< const amrex::Real > &data_arr, const amrex::Array4< amrex::Real > &rhs_arr, const amrex::Real &c_p, const amrex::Real &rdOcp, const int bdy_moist_nudge_type=0)
 
AMREX_GPU_HOST AMREX_FORCE_INLINE void realbdy_compute_moisture_relaxation (const amrex::GpuArray< int, 6 > &moisture_comps, const int n_targets, const int &width, const amrex::GpuArray< amrex::Real, AMREX_SPACEDIM > &dx, const amrex::GpuArray< amrex::Real, AMREX_SPACEDIM > &ProbLo, const amrex::GpuArray< amrex::Real, AMREX_SPACEDIM > &ProbHi, const amrex::Real &F1, const amrex::Box &bx_xlo, const amrex::Box &bx_xhi, const amrex::Box &bx_ylo, const amrex::Box &bx_yhi, const amrex::Array4< const amrex::Real > &arr_xlo, const amrex::Array4< const amrex::Real > &arr_xhi, const amrex::Array4< const amrex::Real > &arr_ylo, const amrex::Array4< const amrex::Real > &arr_yhi, const amrex::Array4< const amrex::Real > &data_arr, const amrex::Array4< amrex::Real > &rhs_arr)
 
AMREX_GPU_HOST AMREX_FORCE_INLINE void realbdy_compute_moisture_relaxation (const amrex::GpuArray< int, 3 > &moisture_comps, const int &width, const amrex::GpuArray< amrex::Real, AMREX_SPACEDIM > &dx, const amrex::GpuArray< amrex::Real, AMREX_SPACEDIM > &ProbLo, const amrex::GpuArray< amrex::Real, AMREX_SPACEDIM > &ProbHi, const amrex::Real &F1, const amrex::Box &bx_xlo, const amrex::Box &bx_xhi, const amrex::Box &bx_ylo, const amrex::Box &bx_yhi, const amrex::Array4< const amrex::Real > &arr_xlo, const amrex::Array4< const amrex::Real > &arr_xhi, const amrex::Array4< const amrex::Real > &arr_ylo, const amrex::Array4< const amrex::Real > &arr_yhi, const amrex::Array4< const amrex::Real > &data_arr, const amrex::Array4< amrex::Real > &rhs_arr)
 
AMREX_GPU_HOST AMREX_FORCE_INLINE void ApplyMask (amrex::MultiFab &dst, const amrex::iMultiFab &imask, const int nghost=0)
 
AMREX_GPU_HOST AMREX_FORCE_INLINE void ApplyInvertedMask (amrex::MultiFab &dst, const amrex::iMultiFab &imask, const int nghost=0)
 
void thinbody_wall_dist (std::unique_ptr< amrex::MultiFab > &wdist, amrex::Vector< amrex::IntVect > &xfaces, amrex::Vector< amrex::IntVect > &yfaces, amrex::Vector< amrex::IntVect > &zfaces, const amrex::Geometry &geomdata, std::unique_ptr< amrex::MultiFab > &z_phys_cc)
 
void WeatherDataInterpolation (const double time)
 
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real quad_interp_1d (amrex::Real z, amrex::Real z0, amrex::Real p0, amrex::Real z1, amrex::Real p1, amrex::Real z2, amrex::Real p2)
 
TimeLevelSel select_time_level (double time, double t_old, double t_new)
 
amrex::Vector< amrex::MultiFab * > select_time_data (TimeLevelSel sel, amrex::MultiFab &old_mf, amrex::MultiFab &new_mf)
 

Enumeration Type Documentation

◆ TimeLevelSel

enum TimeLevelSel
strong

Which time level(s) a fillpatch at a given time should draw from.

Enumerator
Old 
New 
Interp 

Function Documentation

◆ Accumulate_Interval_Means()

void Accumulate_Interval_Means ( double  dt,
double &  t_mean_cnt,
amrex::MultiFab *  interval_means,
amrex::MultiFab &  xvel,
amrex::MultiFab &  yvel,
amrex::MultiFab &  zvel,
amrex::MultiFab &  cons 
)

Accumulate time-weighted cell-centered velocity/theta first and second moments.

Parameters
[in]dtaccumulation interval
[in,out]t_mean_cntaccumulated time
[in,out]interval_meansten-component moment storage
[in]xvelx-face velocity
[in]yvely-face velocity
[in]zvelz-face velocity
[in]consconserved cell-centered state

◆ ApplyInvertedMask()

AMREX_GPU_HOST AMREX_FORCE_INLINE void ApplyInvertedMask ( amrex::MultiFab &  dst,
const amrex::iMultiFab &  imask,
const int  nghost = 0 
)

Multiply a MultiFab by the inverse of an integer mask.

Parameters
[in,out]dstMultiFab to be masked.
[in]imaskInteger mask MultiFab.
[in]nghostNumber of ghost cells to include.
864 {
865  for (amrex::MFIter mfi(dst,amrex::TilingIfNotGPU()); mfi.isValid(); ++mfi)
866  {
867  const amrex::Box& bx = mfi.growntilebox(nghost);
868  if (bx.ok())
869  {
870  auto dstFab = dst.array(mfi);
871  const auto maskFab = imask.const_array(mfi);
872  ParallelFor(bx, [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept
873  {
874  dstFab(i,j,k) *= (1-maskFab(i,j,k));
875  });
876  }
877  }
878 }
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);})

Referenced by add_thin_body_sources(), and ERF::project_velocity_tb().

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

◆ ApplyMask()

AMREX_GPU_HOST AMREX_FORCE_INLINE void ApplyMask ( amrex::MultiFab &  dst,
const amrex::iMultiFab &  imask,
const int  nghost = 0 
)
836 {
837  for (amrex::MFIter mfi(dst,amrex::TilingIfNotGPU()); mfi.isValid(); ++mfi)
838  {
839  const amrex::Box& bx = mfi.growntilebox(nghost);
840  if (bx.ok())
841  {
842  auto dstFab = dst.array(mfi);
843  const auto maskFab = imask.const_array(mfi);
844  ParallelFor(bx, [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept
845  {
846  dstFab(i,j,k) *= maskFab(i,j,k);
847  });
848  }
849  }
850 }

Referenced by ERF::FillIntermediatePatch(), and ERF::project_velocity_tb().

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

◆ ChopGrids2D()

void ChopGrids2D ( amrex::BoxArray &  ba,
const amrex::Box &  domain,
int  target_size 
)

◆ compute_influx_outflux_bdy()

void compute_influx_outflux_bdy ( amrex::FArrayBox &  bdy_data_xlo,
amrex::FArrayBox &  bdy_data_xhi,
amrex::FArrayBox &  bdy_data_ylo,
amrex::FArrayBox &  bdy_data_yhi,
amrex::Array< amrex::MultiFab *, AMREX_SPACEDIM > &  area_vec,
const amrex::Geometry &  geom,
amrex::Real &  influx,
amrex::Real &  outflux,
const int  n 
)

◆ cons_to_prim()

void cons_to_prim ( const amrex::MultiFab &  cons_state,
amrex::MultiFab &  S_prim,
int  ng 
)

Convert conservative state to primitive variables.

Parameters
[in]cons_stateConservative state MultiFab.
[out]S_primPrimitive state MultiFab.
[in]ngNumber of ghost cells.

◆ ConvertForProjection()

void ConvertForProjection ( const amrex::MultiFab &  den_div,
const amrex::MultiFab &  den_mlt,
amrex::MultiFab &  xmom,
amrex::MultiFab &  ymom,
amrex::MultiFab &  zmom,
const amrex::Box &  domain,
const amrex::Vector< amrex::BCRec > &  domain_bcs_type_h 
)

◆ enforceInOutSolvability()

void enforceInOutSolvability ( int  lev,
amrex::Array< amrex::MultiFab *, AMREX_SPACEDIM > &  vels_vec,
amrex::Array< amrex::MultiFab *, AMREX_SPACEDIM > &  area_vec,
const amrex::Geometry &  geom 
)

◆ enforceInOutSolvability_bdy()

void enforceInOutSolvability_bdy ( const amrex::MultiFab &  rho0,
amrex::FArrayBox &  bdy_data_xlo,
amrex::FArrayBox &  bdy_data_xhi,
amrex::FArrayBox &  bdy_data_ylo,
amrex::FArrayBox &  bdy_data_yhi,
amrex::Array< amrex::MultiFab *, AMREX_SPACEDIM > &  area_vec,
const amrex::Geometry &  geom,
const amrex::Vector< amrex::BCRec > &  domain_bcs_type_h 
)

◆ ERFPostProcessBaseGrids()

amrex::BoxArray ERFPostProcessBaseGrids ( const amrex::Box &  domain,
bool  decompose_in_z 
)

◆ fill_wall_dist_ghost_cells()

void fill_wall_dist_ghost_cells ( amrex::MultiFab &  wdist,
const amrex::Geometry &  geom 
)

Fill the ghost cells of the wall distance field, which is only computed on the valid region, so that operators reading from grown boxes do not see the sentinel value used to initialize it.

Parameters
[in,out]wdistMultiFab holding the wall distance.
[in]geomGeometry at this level.

◆ fine_compute_interior_ghost_rhs()

void fine_compute_interior_ghost_rhs ( const double &  time,
const double &  delta_t,
const int &  width,
const int &  set_width,
const amrex::Geometry &  geom,
ERFFillPatcher *  FPr_c,
ERFFillPatcher *  FPr_u,
ERFFillPatcher *  FPr_v,
ERFFillPatcher *  FPr_w,
amrex::Vector< amrex::BCRec > &  domain_bcs_type,
amrex::Vector< amrex::MultiFab > &  S_rhs_f,
amrex::Vector< amrex::MultiFab > &  S_data_f 
)

◆ if_average_down()

void if_average_down ( const amrex::MultiFab &  S_fine,
amrex::MultiFab &  S_crse,
const amrex::MultiFab &  beta_fine,
const amrex::MultiFab &  beta_crse,
const amrex::MultiFab &  vol_fine,
int  scomp,
int  ncomp,
const amrex::IntVect &  ratio 
)

Average down a cell-centred state over immersed-forcing levels (erf.if_average_down = fluid_mass). The fine cells are weighted by their fluid mass, (rho S)_c = rho_c * sum (1 - beta_f) V_f (rho S)_f / sum (1 - beta_f) V_f rho_f, with beta the solid fraction, V the fine cell volume (detJ / (m_x m_y), the weight the plain average carries in the state) and rho_c the coarse density: the fluid-volume-weighted mean of the fine density, sum (1 - beta_f) V_f rho_f / sum (1 - beta_f) V_f, when the density is in the component range, else the coarse cell's own. The coarse value is the fluid mean over the whole coarse cell (intensive), not the sum over the fine cells. Coarse cells that are solid on their own level, or with no fluid fine cell under them, keep their value. The plain average mixes the values of solid fine cells into coarse fluid cells.

Parameters
[in]S_fineFine state (unscaled).
[in,out]S_crseCoarse state (unscaled); the covered cells are written.
[in]beta_fineFine solid fraction (terrain_blanking).
[in]beta_crseCoarse solid fraction.
[in]vol_fineFine cell volume weight (any constant factor cancels).
[in]scompFirst component to average.
[in]ncompNumber of components.
[in]ratioRefinement ratio.

◆ if_cf_surface_mismatch()

std::pair<int, amrex::Real> if_cf_surface_mismatch ( const amrex::MultiFab &  fine_tb,
const amrex::BoxArray &  fine_grids,
const amrex::BoxArray &  crse_grids,
const amrex::DistributionMapping &  crse_dmap,
const amrex::Geometry &  crse_geom,
const amrex::IntVect &  ratio,
amrex::Real  warn 
)

Where the coarse and fine levels disagree on an immersed surface along the lateral coarse/fine faces of the fine level (erf.if_cf_mismatch_warning): the surface on a coarse cell's mid-plane leaves the coarse cell half solid over fine cells that are all solid and all fluid. For each coarse cell covered by the fine level and next to an uncovered one, the spread (max - min) of the fine solid fractions under it is formed; cells with a spread of at least warn are counted.

Parameters
[in]fine_tbfine solid fraction (terrain_blanking)
[in]fine_gridsfine BoxArray
[in]crse_gridscoarse BoxArray
[in]crse_dmapcoarse DistributionMapping
[in]crse_geomcoarse Geometry
[in]ratiorefinement ratio
[in]warnspread at or above which a cell is counted
Returns
the number of counted cells over all ranks, and the largest spread along those faces

◆ immersed_wall_dist()

void immersed_wall_dist ( amrex::MultiFab &  wdist,
const amrex::MultiFab &  terrain_blank,
const amrex::MultiFab &  z_phys_nd,
const amrex::MultiFab &  z_phys_cc,
const amrex::Box &  domain,
amrex::Real  small_volfrac,
amrex::MultiFab *  wall_height = nullptr,
const amrex::MultiFab *  wall_height_crse = nullptr 
)

RANS wall distance over terrain represented by immersed forcing with the fraction-stress wall law (erf.if_wall_form = fraction_stress): measured vertically from the surface itself, h = z_bot + beta dz of the wall cell (the partial cell, or the fluid cell on a solid cell; ERF_ImmersedWallCell.H), the wall cell at its fluid centroid (1 - beta) dz / 2 above it and every other cell at |z_cc - h|; a column without solid measures from the bottom of the domain. A box that does not see the surface of a column (a fine box inside the solid, or above the surface without reaching the bottom) measures from the coarser level's wall height.

Parameters
[out]wdistWall distance (valid cells; ghost cells are left untouched).
[in]terrain_blankCell-centred solid fraction.
[in]z_phys_ndNode heights.
[in]z_phys_ccCell-centre heights.
[in]domainIndex domain of the level.
[in]small_volfracSolid fraction below which a cell counts as fluid.
[out]wall_heightOptional: the height measured from in each column, on the level's BoxArray flattened to the bottom cell (same DistributionMapping).
[in]wall_height_crseOptional, fine levels: wall_height of the coarser level brought to this level's flattened BoxArray. Without it every box must hold whole columns.

◆ make_areas()

void make_areas ( const amrex::Geometry &  geom,
amrex::MultiFab &  z_phys_nd,
amrex::MultiFab &  ax,
amrex::MultiFab &  ay,
amrex::MultiFab &  az 
)

◆ make_ib_wall_face_masks()

void make_ib_wall_face_masks ( const amrex::MultiFab &  terrain_blank,
amrex::MultiFab &  mask13,
amrex::MultiFab &  mask23,
amrex::MultiFab &  mask33,
const amrex::Box &  domain,
amrex::Real  small_volfrac,
int  spacing = 0,
amrex::Real  dz = amrex::Real(1.0),
amrex::Real  z0 = amrex::Real(0.1) 
)

Wall-face masks of the fraction-stress wall law (erf.if_wall_form = fraction_stress): zero on the xz (yz) edge that is the bottom face of the wall cell of an x-face (y-face) column, the spacing factor on the face above it, one elsewhere. The vertical flux of x (y) momentum is multiplied by them, so no resolved flux crosses the wall face (see ERF_ImmersedWallCell.H).

Parameters
[in]terrain_blankCell-centred solid fraction; needs one more ghost cell than the masks.
[out]mask13On convert(ba, IntVect(1,0,1)), valid and ghost cells.
[out]mask23On convert(ba, IntVect(0,1,1)), valid and ghost cells.
[out]mask33On convert(ba, IntVect(0,0,1)): the same for the cell columns, applied to the vertical diffusive fluxes of theta and TKE (zero on the bottom face of the wall cell).
[in]domainIndex domain of the level.
[in]small_volfracSolid fraction below which a cell counts as fluid.
[in]spacingerf.if_wall_face_spacing (0 grid, 1 physical, 2 log): the face ABOVE the wall cell gets ib_wall::face_above_factor instead of one.
[in]dzCell height (constant-dz mesh).
[in]z0Roughness length of the wall law.

◆ make_J()

void make_J ( const amrex::Geometry &  geom,
amrex::MultiFab &  z_phys_nd,
amrex::MultiFab &  detJ_cc 
)

◆ make_qt()

void make_qt ( const amrex::MultiFab &  cons_state,
amrex::MultiFab &  qt,
int  n_qstate_into_total 
)

Compute total water mixing ratio from conservative state.

Parameters
[in]cons_stateConservative state MultiFab.
[out]qtMultiFab to store total water.
[in]n_qstate_into_totalNumber of components to include in total water.

◆ make_zcc()

void make_zcc ( const amrex::Geometry &  geom,
amrex::MultiFab &  z_phys_nd,
amrex::MultiFab &  z_phys_cc 
)

◆ MomentumToVelocity()

void MomentumToVelocity ( amrex::MultiFab &  xvel_out,
amrex::MultiFab &  yvel_out,
amrex::MultiFab &  zvel_out,
const amrex::MultiFab &  cons_in,
const amrex::MultiFab &  xmom_in,
const amrex::MultiFab &  ymom_in,
const amrex::MultiFab &  zmom_in,
const amrex::Box &  domain,
const amrex::Vector< amrex::BCRec > &  domain_bcs_type_h,
const amrex::MultiFab *  c_vfrac = nullptr 
)

◆ quad_interp_1d()

AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real quad_interp_1d ( amrex::Real  z,
amrex::Real  z0,
amrex::Real  p0,
amrex::Real  z1,
amrex::Real  p1,
amrex::Real  z2,
amrex::Real  p2 
)

Perform quadratic interpolation in one dimension.

Parameters
[in]zInterpolation coordinate.
[in]z0Coordinate of first point.
[in]p0Value at first point.
[in]z1Coordinate of second point.
[in]p1Value at second point.
[in]z2Coordinate of third point.
[in]p2Value at third point.
Returns
Interpolated value.
918 {
919  return p0 * ( (z - z1) * (z - z2) ) / ( (z0 - z1) * (z0 - z2) )
920  + p1 * ( (z - z0) * (z - z2) ) / ( (z1 - z0) * (z1 - z2) )
921  + p2 * ( (z - z0) * (z - z1) ) / ( (z2 - z0) * (z2 - z1) );
922 }
Real z0
Definition: ERF_InitCustomPertVels_ScalarAdvDiff.H:12
real(c_double), parameter p0
Definition: ERF_module_model_constants.F90:40

Referenced by compute_gradp_interpz().

Here is the caller graph for this function:

◆ real_bdy_cons_maps()

RealBdyConsMaps real_bdy_cons_maps ( const bool  read_density,
const MoistureComponentIndices &  moisture_indices,
const bool  use_wrf_bdy_qc_qi,
const bool  separate_hydrometeors 
)
inline
87 {
89  m.read.assign(NVAR_max, 0);
90  m.map.resize(NVAR_max);
91  m.bnd.resize(NVAR_max);
92  for (int comp = 0; comp < NVAR_max; ++comp) {
93  m.map[comp] = comp;
94  m.bnd[comp] = cons_bc_comp(comp);
95  }
96  m.read[Rho_comp] = read_density ? 1 : 0;
97  m.map [Rho_comp] = read_density ? RealBdyVars::R : Rho_comp;
98  m.read[RhoTheta_comp] = 1;
100  m.read[RhoQ1_comp] = 1;
102  for (int comp = 0; comp < NVAR_max; ++comp) {
103  const int bdy_var = wrf_bdy_var_for_moisture_component(
104  comp, moisture_indices, use_wrf_bdy_qc_qi, separate_hydrometeors);
105  if (bdy_var >= 0) {
106  m.map[comp] = bdy_var;
107  }
108  }
109  return m;
110 }
#define Rho_comp
Definition: ERF_IndexDefines.H:53
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE int cons_bc_comp(int n) noexcept
Definition: ERF_IndexDefines.H:140
#define RhoTheta_comp
Definition: ERF_IndexDefines.H:54
#define NVAR_max
Definition: ERF_IndexDefines.H:37
#define RhoQ1_comp
Definition: ERF_IndexDefines.H:66
int wrf_bdy_var_for_moisture_component(const int comp, const MoistureComponentIndices &moisture_indices, const bool use_wrf_bdy_qc_qi, const bool separate_hydrometeors=false)
Definition: ERF_Utils.H:44
@ R
Definition: ERF_IndexDefines.H:170
@ QV
Definition: ERF_IndexDefines.H:169
@ T
Definition: ERF_IndexDefines.H:168
Definition: ERF_Utils.H:76
amrex::Vector< int > map
Definition: ERF_Utils.H:78
amrex::Vector< int > bnd
Definition: ERF_Utils.H:79
amrex::Vector< int > read
Definition: ERF_Utils.H:77
Here is the call graph for this function:

◆ realbdy_bc_bxs_xy()

void realbdy_bc_bxs_xy ( const amrex::Box &  bx,
const amrex::Box &  domain,
const int &  set_width,
amrex::Box &  bx_xlo,
amrex::Box &  bx_xhi,
amrex::Box &  bx_ylo,
amrex::Box &  bx_yhi,
const amrex::IntVect &  ng_vect = amrex::IntVect(0, 0, 0) 
)

◆ realbdy_compute_interior_ghost_rhs()

void realbdy_compute_interior_ghost_rhs ( const double &  total_time,
const double &  delta_t,
const double &  start_bdy_time,
const double &  final_bdy_time,
const double &  bdy_time_interval,
const amrex::Real &  nudge_factor,
int  width,
const amrex::Geometry &  geom,
amrex::Vector< amrex::MultiFab > &  S_rhs,
amrex::Vector< amrex::MultiFab > &  S_cur_data,
amrex::Vector< amrex::Vector< amrex::FArrayBox >> &  bdy_data_xlo,
amrex::Vector< amrex::Vector< amrex::FArrayBox >> &  bdy_data_xhi,
amrex::Vector< amrex::Vector< amrex::FArrayBox >> &  bdy_data_ylo,
amrex::Vector< amrex::Vector< amrex::FArrayBox >> &  bdy_data_yhi,
std::unique_ptr< ReadBndryPlanes > &  m_r2d,
const amrex::Real &  c_p,
const amrex::Real &  rdOcp,
const bool  use_wrf_bdy_density,
const amrex::Real &  bdy_rho_nudge_factor 
)

◆ realbdy_compute_moisture_relaxation() [1/2]

AMREX_GPU_HOST AMREX_FORCE_INLINE void realbdy_compute_moisture_relaxation ( const amrex::GpuArray< int, 3 > &  moisture_comps,
const int &  width,
const amrex::GpuArray< amrex::Real, AMREX_SPACEDIM > &  dx,
const amrex::GpuArray< amrex::Real, AMREX_SPACEDIM > &  ProbLo,
const amrex::GpuArray< amrex::Real, AMREX_SPACEDIM > &  ProbHi,
const amrex::Real &  F1,
const amrex::Box &  bx_xlo,
const amrex::Box &  bx_xhi,
const amrex::Box &  bx_ylo,
const amrex::Box &  bx_yhi,
const amrex::Array4< const amrex::Real > &  arr_xlo,
const amrex::Array4< const amrex::Real > &  arr_xhi,
const amrex::Array4< const amrex::Real > &  arr_ylo,
const amrex::Array4< const amrex::Real > &  arr_yhi,
const amrex::Array4< const amrex::Real > &  data_arr,
const amrex::Array4< amrex::Real > &  rhs_arr 
)
818 {
819  const amrex::GpuArray<int,6> extended_comps = {
820  moisture_comps[0], moisture_comps[1], moisture_comps[2], -1, -1, -1};
822  extended_comps, 3, width, dx, ProbLo, ProbHi, F1,
823  bx_xlo, bx_xhi, bx_ylo, bx_yhi,
824  arr_xlo, arr_xhi, arr_ylo, arr_yhi, data_arr, rhs_arr);
825 }
const Real dx
Definition: ERF_InitCustomPert_ABL.H:44
AMREX_GPU_HOST AMREX_FORCE_INLINE void realbdy_compute_moisture_relaxation(const amrex::GpuArray< int, 6 > &moisture_comps, const int n_targets, const int &width, const amrex::GpuArray< amrex::Real, AMREX_SPACEDIM > &dx, const amrex::GpuArray< amrex::Real, AMREX_SPACEDIM > &ProbLo, const amrex::GpuArray< amrex::Real, AMREX_SPACEDIM > &ProbHi, const amrex::Real &F1, const amrex::Box &bx_xlo, const amrex::Box &bx_xhi, const amrex::Box &bx_ylo, const amrex::Box &bx_yhi, const amrex::Array4< const amrex::Real > &arr_xlo, const amrex::Array4< const amrex::Real > &arr_xhi, const amrex::Array4< const amrex::Real > &arr_ylo, const amrex::Array4< const amrex::Real > &arr_yhi, const amrex::Array4< const amrex::Real > &data_arr, const amrex::Array4< amrex::Real > &rhs_arr)
Definition: ERF_Utils.H:705
Here is the call graph for this function:

◆ realbdy_compute_moisture_relaxation() [2/2]

AMREX_GPU_HOST AMREX_FORCE_INLINE void realbdy_compute_moisture_relaxation ( const amrex::GpuArray< int, 6 > &  moisture_comps,
const int  n_targets,
const int &  width,
const amrex::GpuArray< amrex::Real, AMREX_SPACEDIM > &  dx,
const amrex::GpuArray< amrex::Real, AMREX_SPACEDIM > &  ProbLo,
const amrex::GpuArray< amrex::Real, AMREX_SPACEDIM > &  ProbHi,
const amrex::Real &  F1,
const amrex::Box &  bx_xlo,
const amrex::Box &  bx_xhi,
const amrex::Box &  bx_ylo,
const amrex::Box &  bx_yhi,
const amrex::Array4< const amrex::Real > &  arr_xlo,
const amrex::Array4< const amrex::Real > &  arr_xhi,
const amrex::Array4< const amrex::Real > &  arr_ylo,
const amrex::Array4< const amrex::Real > &  arr_yhi,
const amrex::Array4< const amrex::Real > &  data_arr,
const amrex::Array4< amrex::Real > &  rhs_arr 
)

Apply Davies relaxation to explicitly mapped moisture components. Target component n corresponds to state component moisture_comps[n].

723 {
724  const amrex::IntVect iv = bx_xlo.type();
725  const amrex::Real ioff = (iv[0] == 1) ? zero : myhalf;
726  const amrex::Real joff = (iv[1] == 1) ? zero : myhalf;
727 
728  amrex::ParallelFor(bx_xlo, bx_xhi,
729  [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept
730  {
731  const amrex::Real x = ProbLo[0] + (i + ioff) * dx[0];
732  const amrex::Real y = ProbLo[1] + (j + joff) * dx[1];
733  const amrex::Real x_end = ProbLo[0] + width * dx[0];
734  const amrex::Real y_end = ProbLo[1] + width * dx[1];
735  const amrex::Real y_strt = ProbHi[1] - width * dx[1];
736  const amrex::Real xi = (x_end - x) / (x_end - ProbLo[0]);
737  const amrex::Real eta_lo = (y < y_end) ? (y_end - y) / (y_end - ProbLo[1]) : amrex::Real(0.0);
738  const amrex::Real eta_hi = (y > y_strt) ? (y - y_strt) / (ProbHi[1] - y_strt) : amrex::Real(0.0);
739  const amrex::Real factor = amrex::max(xi*xi, amrex::max(eta_lo,eta_hi)*amrex::max(eta_lo,eta_hi)) * F1;
740  for (int n = 0; n < n_targets; ++n) {
741  const int comp = moisture_comps[n];
742  if (comp >= 0) {
743  rhs_arr(i,j,k,comp) += factor * (arr_xlo(i,j,k,n) - data_arr(i,j,k,comp));
744  }
745  }
746  },
747  [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept
748  {
749  const amrex::Real x = ProbLo[0] + (i + ioff) * dx[0];
750  const amrex::Real y = ProbLo[1] + (j + joff) * dx[1];
751  const amrex::Real x_strt = ProbHi[0] - width * dx[0];
752  const amrex::Real y_end = ProbLo[1] + width * dx[1];
753  const amrex::Real y_strt = ProbHi[1] - width * dx[1];
754  const amrex::Real xi = (x - x_strt) / (ProbHi[0] - x_strt);
755  const amrex::Real eta_lo = (y < y_end) ? (y_end - y) / (y_end - ProbLo[1]) : amrex::Real(0.0);
756  const amrex::Real eta_hi = (y > y_strt) ? (y - y_strt) / (ProbHi[1] - y_strt) : amrex::Real(0.0);
757  const amrex::Real eta = amrex::max(eta_lo,eta_hi);
758  const amrex::Real factor = amrex::max(xi*xi, eta*eta) * F1;
759  for (int n = 0; n < n_targets; ++n) {
760  const int comp = moisture_comps[n];
761  if (comp >= 0) {
762  rhs_arr(i,j,k,comp) += factor * (arr_xhi(i,j,k,n) - data_arr(i,j,k,comp));
763  }
764  }
765  });
766 
767  amrex::ParallelFor(bx_ylo, bx_yhi,
768  [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept
769  {
770  const amrex::Real y = ProbLo[1] + (j + joff) * dx[1];
771  const amrex::Real y_end = ProbLo[1] + width * dx[1];
772  const amrex::Real eta = (y_end - y) / (y_end - ProbLo[1]);
773  const amrex::Real factor = eta*eta * F1;
774  for (int n = 0; n < n_targets; ++n) {
775  const int comp = moisture_comps[n];
776  if (comp >= 0) {
777  rhs_arr(i,j,k,comp) += factor * (arr_ylo(i,j,k,n) - data_arr(i,j,k,comp));
778  }
779  }
780  },
781  [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept
782  {
783  const amrex::Real y = ProbLo[1] + (j + joff) * dx[1];
784  const amrex::Real y_strt = ProbHi[1] - width * dx[1];
785  const amrex::Real eta = (y - y_strt) / (ProbHi[1] - y_strt);
786  const amrex::Real factor = eta*eta * F1;
787  for (int n = 0; n < n_targets; ++n) {
788  const int comp = moisture_comps[n];
789  if (comp >= 0) {
790  rhs_arr(i,j,k,comp) += factor * (arr_yhi(i,j,k,n) - data_arr(i,j,k,comp));
791  }
792  }
793  });
794 }
constexpr amrex::Real zero
Definition: ERF_NumericalConstants.H:36
constexpr amrex::Real myhalf
Definition: ERF_NumericalConstants.H:41
amrex::Real Real
Definition: ERF_ShocInterface.H:19

Referenced by realbdy_compute_moisture_relaxation().

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

◆ realbdy_compute_relaxation()

AMREX_GPU_HOST AMREX_FORCE_INLINE void realbdy_compute_relaxation ( const int &  icomp,
const int &  num_var,
const int &  width,
const amrex::GpuArray< amrex::Real, AMREX_SPACEDIM > &  dx,
const amrex::GpuArray< amrex::Real, AMREX_SPACEDIM > &  ProbLo,
const amrex::GpuArray< amrex::Real, AMREX_SPACEDIM > &  ProbHi,
const amrex::Real &  F1,
const amrex::Box &  bx_xlo,
const amrex::Box &  bx_xhi,
const amrex::Box &  bx_ylo,
const amrex::Box &  bx_yhi,
const amrex::Array4< const amrex::Real > &  arr_xlo,
const amrex::Array4< const amrex::Real > &  arr_xhi,
const amrex::Array4< const amrex::Real > &  arr_ylo,
const amrex::Array4< const amrex::Real > &  arr_yhi,
const amrex::Array4< const amrex::Real > &  data_arr,
const amrex::Array4< amrex::Real > &  rhs_arr,
const amrex::Real &  c_p,
const amrex::Real &  rdOcp,
const int  bdy_moist_nudge_type = 0 
)

Compute the nudging relaxation

Parameters
[in]delta_ttime step
[in]icompcomponent offset
[in]num_varnumber of variables to loop
[in]widthwidth of wrf bdy file
[in]dom_lolow bound of domain
[in]dom_hihigh bound of domain
[in]F1drift relaxation parameter
[in]bx_xlobox for low x relaxation
[in]bx_xhibox for high x relaxation
[in]bx_ylobox for low y relaxation
[in]bx_yhibox for high y relaxation
[in]arr_xloarray for low x relaxation
[in]arr_xhiarray for high x relaxation
[in]arr_yloarray for low y relaxation
[in]arr_yhiarray for high y relaxation
[in]data_arrdata array
[out]rhs_arrRHS array
511 {
512  amrex::IntVect iv = bx_xlo.type();
513  amrex::Real ioff = (iv[0]==1) ? zero : myhalf;
514  amrex::Real joff = (iv[1]==1) ? zero : myhalf;
515 
516  // These are defined in ERF_Constants.H
517  amrex::Real l_rdOcp = rdOcp;
518  amrex::Real cond_fac = lcond / c_p; // condensation
519  amrex::Real sub_fac = lsub / c_p; // sublimation
520 
521  int nq = num_var;
522 
523  amrex::ParallelFor( bx_xlo, bx_xhi,
524  [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept
525  {
526  // Corners with x boxes
527  amrex::Real x = ProbLo[0] + (i + ioff) * dx[0];
528  amrex::Real y = ProbLo[1] + (j + joff) * dx[1];
529  amrex::Real x_end = ProbLo[0] + width * dx[0];
530  amrex::Real y_end = ProbLo[1] + width * dx[1];
531  amrex::Real y_strt = ProbHi[1] - width * dx[1];
532  amrex::Real xi = (x_end - x) / (x_end - ProbLo[0]);
533  amrex::Real eta_lo = (y < y_end ) ? (y_end - y) / (y_end - ProbLo[1]) : zero;
534  amrex::Real eta_hi = (y > y_strt) ? (y - y_strt) / (ProbHi[1] - y_strt) : zero;
535  amrex::Real eta = std::max(eta_lo,eta_hi);
536  amrex::Real Factor = std::max(xi*xi,eta*eta) * F1;
537 
538  if (icomp == RhoQ1_comp)
539  {
540  amrex::Real exner_pi = getExnergivenRTh(data_arr(i,j,k,RhoTheta_comp),l_rdOcp,
541  data_arr(i,j,k,RhoQ1_comp)/data_arr(i,j,k,Rho_comp));
542 
543  // qv
544  amrex::Real delta = arr_xlo(i,j,k,0) - data_arr(i,j,k,icomp);
545  rhs_arr(i,j,k,icomp) += Factor*delta;
546 
547  if (bdy_moist_nudge_type==2) {
548  // NOTE: we only operate on qv (above), qc and qi here; the
549  // precipitating species (qr/qs/qg) are left untouched.
550 
551  // qc and heat source term due to evaporation
552  delta = -data_arr(i,j,k,RhoQ2_comp); // This effectively nudges to 0
553  rhs_arr(i,j,k,RhoQ2_comp ) += Factor * delta;
554  rhs_arr(i,j,k,RhoTheta_comp) += Factor * delta * cond_fac / exner_pi;
555 
556  // qi and heat source term due to sublimation
557  if (nq > 3) { // nq > 3 guarantees that RhoQ3 is ice
558  delta = -data_arr(i,j,k,RhoQ3_comp); // This effectively nudges to 0
559  rhs_arr(i,j,k,RhoQ3_comp ) += Factor * delta;
560  rhs_arr(i,j,k,RhoTheta_comp) += Factor * delta * sub_fac / exner_pi;
561  }
562  } // moist_nudge_type
563  } else {
564  for (int n = 0; n < nq; n++) {
565  amrex::Real delta = arr_xlo(i,j,k,n) - data_arr(i,j,k,n+icomp);
566  rhs_arr(i,j,k,n+icomp) += Factor*delta;
567  }
568  }
569  },
570  [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept
571  {
572  // Corners with x boxes
573  amrex::Real x = ProbLo[0] + (i + ioff) * dx[0];
574  amrex::Real y = ProbLo[1] + (j + joff) * dx[1];
575  amrex::Real x_strt = ProbHi[0] - width * dx[0];
576  amrex::Real y_strt = ProbHi[1] - width * dx[1];
577  amrex::Real y_end = ProbLo[1] + width * dx[1];
578  amrex::Real xi = (x - x_strt) / (ProbHi[0] - x_strt);
579  amrex::Real eta_lo = (y < y_end ) ? (y_end - y) / (y_end - ProbLo[1]) : zero;
580  amrex::Real eta_hi = (y > y_strt) ? (y - y_strt) / (ProbHi[1] - y_strt) : zero;
581  amrex::Real eta = std::max(eta_lo,eta_hi);
582  amrex::Real Factor = std::max(xi*xi,eta*eta) * F1;
583 
584  if (icomp == RhoQ1_comp)
585  {
586  amrex::Real exner_pi = getExnergivenRTh(data_arr(i,j,k,RhoTheta_comp),l_rdOcp,
587  data_arr(i,j,k,RhoQ1_comp)/data_arr(i,j,k,Rho_comp));
588 
589  // qv
590  amrex::Real delta = arr_xhi(i,j,k,0) - data_arr(i,j,k,icomp);
591  rhs_arr(i,j,k,icomp) += Factor*delta;
592 
593  if (bdy_moist_nudge_type==2) {
594  // NOTE: we only operate on qv (above), qc and qi here; the
595  // precipitating species (qr/qs/qg) are left untouched.
596 
597  // qc and heat source term due to evaporation
598  delta = -data_arr(i,j,k,RhoQ2_comp); // This effectively nudges to 0
599  rhs_arr(i,j,k,RhoQ2_comp ) += Factor*delta;
600  rhs_arr(i,j,k,RhoTheta_comp) += Factor * delta * cond_fac / exner_pi;
601 
602  // qi and heat source term due to sublimation
603  if (nq > 3) { // nq > 3 guarantees that RhoQ3 is ice
604  delta = -data_arr(i,j,k,RhoQ3_comp); // This effectively nudges to 0
605  rhs_arr(i,j,k,RhoQ3_comp ) += Factor * delta;
606  rhs_arr(i,j,k,RhoTheta_comp) += Factor * delta * sub_fac / exner_pi;
607  }
608  } // moist_nudge_type
609  } else {
610  for (int n = 0; n < nq; n++) {
611  amrex::Real delta = arr_xhi(i,j,k,n) - data_arr(i,j,k,n+icomp);
612  rhs_arr(i,j,k,n+icomp) += Factor*delta;
613  }
614  }
615  });
616 
617  amrex::ParallelFor( bx_ylo, bx_yhi,
618  [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept
619  {
620  // No corners for y boxes
621  amrex::Real y = ProbLo[1] + (j + joff) * dx[1];
622  amrex::Real y_end = ProbLo[1] + width * dx[1];
623  amrex::Real eta = (y_end - y) / (y_end - ProbLo[1]);
624  amrex::Real Factor = eta*eta * F1;
625 
626  if (icomp == RhoQ1_comp)
627  {
628  amrex::Real exner_pi = getExnergivenRTh(data_arr(i,j,k,RhoTheta_comp),l_rdOcp,
629  data_arr(i,j,k,RhoQ1_comp)/data_arr(i,j,k,Rho_comp));
630  // qv
631  amrex::Real delta = arr_ylo(i,j,k,0) - data_arr(i,j,k,icomp);
632  rhs_arr(i,j,k,icomp) += Factor*delta;
633 
634  if (bdy_moist_nudge_type==2) {
635  // NOTE: we only operate on qv (above), qc and qi here; the
636  // precipitating species (qr/qs/qg) are left untouched.
637 
638  // qc and heat source term due to evaporation
639  delta = -data_arr(i,j,k,RhoQ2_comp); // This effectively nudges to 0
640  rhs_arr(i,j,k,RhoQ2_comp ) += Factor*delta;
641  rhs_arr(i,j,k,RhoTheta_comp) += Factor * delta * cond_fac / exner_pi;
642 
643  // qi and heat source term due to sublimation
644  if (nq > 3) { // nq > 3 guarantees that RhoQ3 is ice
645  delta = -data_arr(i,j,k,RhoQ3_comp); // This effectively nudges to 0
646  rhs_arr(i,j,k,RhoQ3_comp ) += Factor * delta;
647  rhs_arr(i,j,k,RhoTheta_comp) += Factor * delta * sub_fac / exner_pi;
648  }
649  } // moist_nudge_type
650  } else {
651  for (int n = 0; n < nq; n++) {
652  amrex::Real delta = arr_ylo(i,j,k,n) - data_arr(i,j,k,n+icomp);
653  rhs_arr(i,j,k,n+icomp) += Factor*delta;
654  }
655  }
656  },
657  [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept
658  {
659  // No corners for y boxes
660  amrex::Real y = ProbLo[1] + (j + joff) * dx[1];
661  amrex::Real y_strt = ProbHi[1] - width * dx[1];
662  amrex::Real eta = (y - y_strt) / (ProbHi[1] - y_strt);
663  amrex::Real Factor = eta*eta * F1;
664 
665  if (icomp == RhoQ1_comp)
666  {
667  amrex::Real exner_pi = getExnergivenRTh(data_arr(i,j,k,RhoTheta_comp),l_rdOcp,
668  data_arr(i,j,k,RhoQ1_comp)/data_arr(i,j,k,Rho_comp));
669  // qv
670  amrex::Real delta = arr_yhi(i,j,k,0) - data_arr(i,j,k,icomp);
671  rhs_arr(i,j,k,icomp) += Factor*delta;
672 
673  if (bdy_moist_nudge_type==2) {
674  // NOTE: we only operate on qv (above), qc and qi here; the
675  // precipitating species (qr/qs/qg) are left untouched.
676 
677  // qc and heat source term due to evaporation
678  delta = -data_arr(i,j,k,RhoQ2_comp); // This effectively nudges to 0
679  rhs_arr(i,j,k,RhoQ2_comp ) += Factor * delta;
680  rhs_arr(i,j,k,RhoTheta_comp) += Factor * delta * cond_fac / exner_pi;
681 
682  // qi and heat source term due to sublimation
683  if (nq > 3) { // nq > 3 guarantees that RhoQ3 is ice
684  delta = -data_arr(i,j,k,RhoQ3_comp); // This effectively nudges to 0
685  rhs_arr(i,j,k,RhoQ3_comp ) += Factor * delta;
686  rhs_arr(i,j,k,RhoTheta_comp) += Factor * delta * sub_fac / exner_pi;
687  }
688  } // moist_nudge_type
689  } else {
690  for (int n = 0; n < nq; n++) {
691  amrex::Real delta = arr_yhi(i,j,k,n) - data_arr(i,j,k,n+icomp);
692  rhs_arr(i,j,k,n+icomp) += Factor*delta;
693  }
694  }
695  });
696 }
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real getExnergivenRTh(const amrex::Real rhotheta, const amrex::Real rdOcp, const amrex::Real qv=amrex::Real(0))
Definition: ERF_EOS.H:156
#define RhoQ2_comp
Definition: ERF_IndexDefines.H:67
#define RhoQ3_comp
Definition: ERF_IndexDefines.H:68
const Real rdOcp
Definition: ERF_InitCustomPert_ABL.H:72
constexpr amrex::Real lsub
Definition: ERF_MicrophysicsConstants.H:111
constexpr amrex::Real lcond
Definition: ERF_MicrophysicsConstants.H:109

Referenced by realbdy_compute_interior_ghost_rhs().

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

◆ realbdy_interior_bxs_xy()

void realbdy_interior_bxs_xy ( const amrex::Box &  bx,
const amrex::Box &  domain,
const int &  width,
amrex::Box &  bx_xlo,
amrex::Box &  bx_xhi,
amrex::Box &  bx_ylo,
amrex::Box &  bx_yhi,
const amrex::IntVect &  ng_vect = amrex::IntVect(0, 0, 0),
const bool  get_int_ng = false 
)

◆ rebalance_columns()

void rebalance_columns ( amrex::MultiFab &  rho,
amrex::MultiFab &  theta,
const amrex::MultiFab &  qt,
const amrex::MultiFab &  qv,
const amrex::MultiFab *  z_phys,
const amrex::Geometry &  geom,
const bool &  maintain_Th,
bool  use_sfc = false 
)

◆ select_time_data()

amrex::Vector<amrex::MultiFab*> select_time_data ( TimeLevelSel  sel,
amrex::MultiFab &  old_mf,
amrex::MultiFab &  new_mf 
)
inline

The pair of MultiFabs to hand to an AMReX FillPatch routine for a given time-level selection. When only one time level is wanted it is passed twice, so that AMReX's own comparison of the (rounded) times can never bring in the other one.

Parameters
[in]selwhich time level(s) to use
[in]old_mfdata at the old time
[in]new_mfdata at the new time
968 {
969  if (sel == TimeLevelSel::Old) { return {&old_mf, &old_mf}; }
970  if (sel == TimeLevelSel::New) { return {&new_mf, &new_mf}; }
971  return {&old_mf, &new_mf};
972 }

Referenced by ERF::FillCoarseFineGhostsForImplicit(), ERF::FillIntermediatePatch(), ERF::FillPatchCrseLevel(), and ERF::FillPatchFineLevel().

Here is the caller graph for this function:

◆ select_time_level()

TimeLevelSel select_time_level ( double  time,
double  t_old,
double  t_new 
)
inline

Decide whether data at time "time" should come from the old-time data, the new-time data, or an interpolation between the two.

This is done in double precision, before any cast to Real, and with a single tolerance at both ends. The tolerance is a small fraction of (t_new - t_old), but never smaller than a few ulps of the times themselves, since those carry roundoff proportional to their magnitude – which matters once the time is large (e.g. months measured in seconds).

Times outside [t_old, t_new] are clamped to the nearer end rather than extrapolated. If t_old == t_new (to within the tolerance), Old is returned.

Parameters
[in]timetime at which data are requested
[in]t_oldold time of the level
[in]t_newnew time of the level
947 {
948  const double t_mag = std::max({std::abs(time), std::abs(t_old), std::abs(t_new)});
949  const double tol = std::max(1.e-8 * std::abs(t_new - t_old),
950  16.0 * std::numeric_limits<double>::epsilon() * t_mag);
951 
952  if (time <= t_old + tol) { return TimeLevelSel::Old; }
953  if (time >= t_new - tol) { return TimeLevelSel::New; }
954  return TimeLevelSel::Interp;
955 }
real(c_double), parameter epsilon
Definition: ERF_module_model_constants.F90:12

Referenced by ERF::cf_zface_coarse_at(), ERF::FillCoarseFineGhostsForImplicit(), ERF::FillIntermediatePatch(), ERF::FillPatchCrseLevel(), and ERF::FillPatchFineLevel().

Here is the caller graph for this function:

◆ thinbody_wall_dist()

void thinbody_wall_dist ( std::unique_ptr< amrex::MultiFab > &  wdist,
amrex::Vector< amrex::IntVect > &  xfaces,
amrex::Vector< amrex::IntVect > &  yfaces,
amrex::Vector< amrex::IntVect > &  zfaces,
const amrex::Geometry &  geomdata,
std::unique_ptr< amrex::MultiFab > &  z_phys_cc 
)

Compute the distance to thin-body walls.

Parameters
[out]wdistMultiFab to store wall distances.
[in]xfacesIndices of x-faces forming walls.
[in]yfacesIndices of y-faces forming walls.
[in]zfacesIndices of z-faces forming walls.
[in]geomdataGeometry used for physical distance.
[in]z_phys_ccCell-centered physical height.

◆ Time_Avg_Vel_atCC()

void Time_Avg_Vel_atCC ( double  dt,
double &  t_avg_cnt,
amrex::MultiFab *  vel_t_avg,
amrex::MultiFab &  xvel,
amrex::MultiFab &  yvel,
amrex::MultiFab &  zvel 
)

◆ VelocityToMomentum()

void VelocityToMomentum ( const amrex::MultiFab &  xvel_in,
const amrex::IntVect &  xvel_ngrow,
const amrex::MultiFab &  yvel_in,
const amrex::IntVect &  yvel_ngrow,
const amrex::MultiFab &  zvel_in,
const amrex::IntVect &  zvel_ngrow,
const amrex::MultiFab &  cons_in,
amrex::MultiFab &  xmom_out,
amrex::MultiFab &  ymom_out,
amrex::MultiFab &  zmom_out,
const amrex::Box &  domain,
const amrex::Vector< amrex::BCRec > &  domain_bcs_type_h,
const amrex::MultiFab *  c_vfrac = nullptr 
)

◆ WeatherDataInterpolation()

void WeatherDataInterpolation ( const double  time)

Referenced by ERF::Evolve(), and ERF::init_stuff().

Here is the caller graph for this function:

◆ wrf_bdy_has_separate_hydrometeors()

AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE bool wrf_bdy_has_separate_hydrometeors ( const MoistureComponentIndices &  moisture_indices)
noexcept

True when ERF carries all five hydrometeor mass species separately.

36 {
37  return moisture_indices.qc >= 0 && moisture_indices.qi >= 0 &&
38  moisture_indices.qr >= 0 && moisture_indices.qs >= 0 &&
39  moisture_indices.qg >= 0;
40 }
int qs
snow
Definition: ERF_DataStruct.H:266
int qr
rain
Definition: ERF_DataStruct.H:265
int qi
cloud ice
Definition: ERF_DataStruct.H:264
int qc
cloud liquid water
Definition: ERF_DataStruct.H:263
int qg
graupel
Definition: ERF_DataStruct.H:267

Referenced by ERF::InitData_post(), and ERF::timeStep().

Here is the caller graph for this function:

◆ wrf_bdy_var_for_moisture_component()

int wrf_bdy_var_for_moisture_component ( const int  comp,
const MoistureComponentIndices &  moisture_indices,
const bool  use_wrf_bdy_qc_qi,
const bool  separate_hydrometeors = false 
)
inline

Map an active conserved moisture component to its real-boundary field.

48 {
49  if (comp == moisture_indices.qv) { return RealBdyVars::QV; }
50  if (use_wrf_bdy_qc_qi) {
51  if (comp == moisture_indices.qc) { return RealBdyVars::QC; }
52  if (moisture_indices.qi >= 0 && comp == moisture_indices.qi) {
53  return RealBdyVars::QI;
54  }
55  if (separate_hydrometeors) {
56  if (comp == moisture_indices.qr) { return RealBdyHydrometeorVars::QR; }
57  if (comp == moisture_indices.qs) { return RealBdyHydrometeorVars::QS; }
58  if (comp == moisture_indices.qg) { return RealBdyHydrometeorVars::QG; }
59  }
60  }
61  return -1;
62 }
@ QG
Definition: ERF_IndexDefines.H:184
@ QR
Definition: ERF_IndexDefines.H:182
@ QS
Definition: ERF_IndexDefines.H:183
@ QC
Definition: ERF_IndexDefines.H:171
@ QI
Definition: ERF_IndexDefines.H:172
int qv
water vapor
Definition: ERF_DataStruct.H:262

Referenced by real_bdy_cons_maps().

Here is the caller graph for this function:

◆ wrf_moisture_target()

AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real wrf_moisture_target ( const amrex::Real  rho,
const amrex::Real  q_n,
const amrex::Real  q_np1,
const amrex::Real  alpha 
)
noexcept

Build one density-weighted, nonnegative WRF moisture target.

26 {
27  const amrex::Real q = (one - alpha) * q_n + alpha * q_np1;
28  return rho * amrex::max(q, amrex::Real(0.0));
29 }
constexpr amrex::Real one
Definition: ERF_NumericalConstants.H:37
@ rho
Definition: ERF_Kessler.H:25
@ alpha
Definition: ERF_SLM.H:151
@ q
Definition: ERF_WSM6.H:294