ERF
Energy Research and Forecasting: An Atmospheric Modeling Code
ERF_Utils.cpp File Reference
#include "ERF_Utils.H"
Include dependency graph for ERF_Utils.cpp:

Functions

void cons_to_prim (const MultiFab &cons_state, MultiFab &S_prim, int ng)
 
void fill_wall_dist_ghost_cells (MultiFab &wdist, const Geometry &geom)
 
void make_qt (const MultiFab &cons_state, MultiFab &qt, int n_qstate_into_total)
 

Function Documentation

◆ cons_to_prim()

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

Convert conservative variables to primitive variables.

Parameters
[in]cons_stateMultiFab containing conservative state variables
[out]S_primMultiFab to be filled with primitive state variables
[in]ngNumber of ghost cells
14 {
15  BL_PROFILE("cons_to_prim()");
16 
17  int ncomp_prim = S_prim.nComp();
18 
19 #ifdef _OPENMP
20 #pragma omp parallel if (amrex::Gpu::notInLaunchRegion())
21 #endif
22  for (MFIter mfi(cons_state,TilingIfNotGPU()); mfi.isValid(); ++mfi)
23  {
24  const Box& gbx = mfi.growntilebox(ng);
25  const Array4<const Real>& cons_arr = cons_state.array(mfi);
26  const Array4< Real>& prim_arr = S_prim.array(mfi);
27 
28  //
29  // We may need > one ghost cells of prim in order to compute higher order advective terms
30  //
31  amrex::ParallelFor(gbx, [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept
32  {
33  Real rho = cons_arr(i,j,k,Rho_comp);
34  Real rho_theta = cons_arr(i,j,k,RhoTheta_comp);
35  prim_arr(i,j,k,PrimTheta_comp) = rho_theta / rho;
36  for (int n = 1; n < ncomp_prim; ++n) {
37  prim_arr(i,j,k,PrimTheta_comp + n) = cons_arr(i,j,k,RhoTheta_comp + n) / rho;
38  }
39  });
40  } // mfi
41 }
#define Rho_comp
Definition: ERF_IndexDefines.H:39
#define RhoTheta_comp
Definition: ERF_IndexDefines.H:40
#define PrimTheta_comp
Definition: ERF_IndexDefines.H:58
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::Real Real
Definition: ERF_ShocInterface.H:19
@ rho
Definition: ERF_Kessler.H:24
@ ng
Definition: ERF_Morrison.H:49

Referenced by ERF::advance_dycore(), ERF::compute_max_buoyancy_gradp_diagnostic(), and ERF::Write3DPlotFile().

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

◆ fill_wall_dist_ghost_cells()

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

Fill the ghost cells of the wall distance field.

The wall distance is only computed on the valid region of each box (whether from the analytic shortcuts, the Poisson solve, or the thin-body correction), so without this the ghost cells still hold the large sentinel value they were initialized with. Any operator that reads wall distance from a grown box – e.g. the RANS Dirichlet-k boundary condition in SurfaceLayer::update_fluxes – would then propagate that sentinel into the state.

Ghost cells shared with a neighboring box or across a periodic boundary are filled by FillBoundary; ghost cells outside the domain in a non-periodic direction are filled by zero-order extrapolation. Note that the analytic wall distances vary only with k, so the extrapolation is exact in those cases.

Parameters
[in,out]wdistMultiFab holding the wall distance
[in]geomGeometry at this level
65 {
66  BL_PROFILE("fill_wall_dist_ghost_cells()");
67 
68  wdist.FillBoundary(geom.periodicity());
69 
70  const Box& domain = geom.Domain();
71  const auto dom_lo = amrex::lbound(domain);
72  const auto dom_hi = amrex::ubound(domain);
73 
74  const GpuArray<int,AMREX_SPACEDIM> is_per = {AMREX_D_DECL(geom.isPeriodic(0),
75  geom.isPeriodic(1),
76  geom.isPeriodic(2))};
77 
78  for (MFIter mfi(wdist); mfi.isValid(); ++mfi)
79  {
80  const Box& gbx = mfi.fabbox();
81  const Array4<Real>& d_arr = wdist.array(mfi);
82 
83  //
84  // Note that the cells we read from are always inside the domain in
85  // every non-periodic direction, hence already filled, and are disjoint
86  // from the cells we write to.
87  //
88  ParallelFor(gbx, [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept
89  {
90  const int ii = (is_per[0]) ? i : amrex::min(amrex::max(i,dom_lo.x),dom_hi.x);
91  const int jj = (is_per[1]) ? j : amrex::min(amrex::max(j,dom_lo.y),dom_hi.y);
92  const int kk = (is_per[2]) ? k : amrex::min(amrex::max(k,dom_lo.z),dom_hi.z);
93  if (ii != i || jj != j || kk != k) {
94  d_arr(i,j,k) = d_arr(ii,jj,kk);
95  }
96  });
97  } // mfi
98 }

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

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

◆ make_qt()

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

Compute the total water mixing ratio from conservative variables.

Parameters
[in]cons_stateMultiFab containing conservative state variables
[out]qtMultiFab to store the total water mixing ratio
[in]n_qstate_into_totalNumber of moisture components to include in the total
109 {
110  BL_PROFILE("make_qt()");
111 
112  // All moisture models are guaranteed to have RhoQ1_comp.
113  MultiFab::Copy(qt, cons_state, RhoQ1_comp, 0, 1, qt.nGrowVect());
114 
115  for (int n = 1; n < n_qstate_into_total; ++n) {
116  MultiFab::Add(qt, cons_state, RhoQ1_comp+n, 0, 1, qt.nGrowVect());
117  }
118 
119  MultiFab::Divide(qt, cons_state, Rho_comp, 0, 1, qt.nGrowVect());
120 }
#define RhoQ1_comp
Definition: ERF_IndexDefines.H:45
@ qt
Definition: ERF_Kessler.H:29

Referenced by ERF::compute_max_buoyancy_gradp_diagnostic(), ERF::compute_max_pressure_gradient_diagnostic(), and ERF::Write3DPlotFile().

Here is the caller graph for this function: