ERF
Energy Research and Forecasting: An Atmospheric Modeling Code
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
ERF_MakeGradP.cpp File Reference
#include <AMReX_MultiFab.H>
#include <AMReX_ArrayLim.H>
#include <AMReX_EB_Slopes_K.H>
#include "AMReX_BCRec.H"
#include "ERF.H"
#include "ERF_SrcHeaders.H"
#include "ERF_DataStruct.H"
#include "ERF_Utils.H"
#include "ERF_EB.H"
Include dependency graph for ERF_MakeGradP.cpp:

Functions

void make_gradp_pert (int level, const SolverChoice &solverChoice, const Geometry &geom, MultiFab &S_data, MultiFab &p0, std::unique_ptr< MultiFab > &z_phys_nd, std::unique_ptr< MultiFab > &z_phys_cc, Vector< MultiFab > &gradp)
 
void compute_gradp (const MultiFab &p, const Geometry &geom, std::unique_ptr< MultiFab > &z_phys_nd, std::unique_ptr< MultiFab > &z_phys_cc, Vector< MultiFab > &gradp, const SolverChoice &solverChoice)
 

Function Documentation

◆ compute_gradp()

void compute_gradp ( const MultiFab &  p,
const Geometry &  geom,
std::unique_ptr< MultiFab > &  z_phys_nd,
std::unique_ptr< MultiFab > &  z_phys_cc,
Vector< MultiFab > &  gradp,
const SolverChoice solverChoice 
)
73 {
74  const bool l_use_terrain_fitted_coords = (solverChoice.mesh_type != MeshType::ConstantDz);
75 
76  const Box domain = geom.Domain();
77  const int domain_klo = domain.smallEnd(2);
78  const int domain_khi = domain.bigEnd(2);
79 
80  const GpuArray<Real, AMREX_SPACEDIM> dxInv = geom.InvCellSizeArray();
81 
82  // *****************************************************************************
83  // Take gradient of relevant quantity (p0, pres, or pert_pres = pres - p0)
84  // *****************************************************************************
85  for ( MFIter mfi(p); mfi.isValid(); ++mfi)
86  {
87  Box tbx = mfi.nodaltilebox(0);
88  Box tby = mfi.nodaltilebox(1);
89  Box tbz = mfi.nodaltilebox(2);
90 
91  // We don't compute gpz on the bottom or top domain boundary
92  if (tbz.smallEnd(2) == domain_klo) {
93  tbz.growLo(2,-1);
94  }
95  if (tbz.bigEnd(2) == domain_khi+1) {
96  tbz.growHi(2,-1);
97  }
98 
99  // Terrain metrics
100  const Array4<const Real>& z_nd_arr = z_phys_nd->const_array(mfi);
101  const Array4<const Real>& z_cc_arr = z_phys_cc->const_array(mfi);
102 
103  const Array4<const Real>& p_arr = p.const_array(mfi);
104 
105  const Array4< Real>& gpx_arr = gradp[GpVars::gpx].array(mfi);
106  const Array4< Real>& gpy_arr = gradp[GpVars::gpy].array(mfi);
107  const Array4< Real>& gpz_arr = gradp[GpVars::gpz].array(mfi);
108 
109  ParallelFor(tbx, [=] AMREX_GPU_DEVICE(int i, int j, int k) noexcept
110  {
111  //Note : mx/my == 1, so no map factor needed here
112  Real gpx = dxInv[0] * (p_arr(i,j,k) - p_arr(i-1,j,k));
113 
114  if (l_use_terrain_fitted_coords) {
115  Real met_h_xi = (z_cc_arr(i,j,k) - z_cc_arr(i-1,j,k)) * dxInv[0];
116 
117  Real dz_phys_hi, dz_phys_lo;
118  Real gpz_lo, gpz_hi;
119  if (k==domain_klo) {
120  dz_phys_hi = z_cc_arr(i ,j,k+1) - z_cc_arr(i ,j,k );
121  dz_phys_lo = z_cc_arr(i-1,j,k+1) - z_cc_arr(i-1,j,k );
122  gpz_hi = (p_arr(i ,j,k+1) - p_arr(i ,j,k )) / dz_phys_hi;
123  gpz_lo = (p_arr(i-1,j,k+1) - p_arr(i-1,j,k )) / dz_phys_lo;
124  } else if (k==domain_khi) {
125  dz_phys_hi = z_cc_arr(i ,j,k ) - z_cc_arr(i ,j,k-1);
126  dz_phys_lo = z_cc_arr(i-1,j,k ) - z_cc_arr(i-1,j,k-1);
127  gpz_hi = (p_arr(i ,j,k ) - p_arr(i ,j,k-1)) / dz_phys_hi;
128  gpz_lo = (p_arr(i-1,j,k ) - p_arr(i-1,j,k-1)) / dz_phys_lo;
129  } else {
130  dz_phys_hi = z_cc_arr(i ,j,k+1) - z_cc_arr(i ,j,k-1);
131  dz_phys_lo = z_cc_arr(i-1,j,k+1) - z_cc_arr(i-1,j,k-1);
132  gpz_hi = (p_arr(i ,j,k+1) - p_arr(i ,j,k-1)) / dz_phys_hi;
133  gpz_lo = (p_arr(i-1,j,k+1) - p_arr(i-1,j,k-1)) / dz_phys_lo;
134  }
135  Real gpx_metric = met_h_xi * 0.5 * (gpz_hi + gpz_lo);
136  gpx -= gpx_metric;
137  }
138  gpx_arr(i,j,k) = gpx;
139  });
140 
141  ParallelFor(tby, [=] AMREX_GPU_DEVICE(int i, int j, int k) noexcept
142  {
143  //Note : mx/my == 1, so no map factor needed here
144  Real gpy = dxInv[1] * (p_arr(i,j,k) - p_arr(i,j-1,k));
145 
146  if (l_use_terrain_fitted_coords) {
147  Real met_h_eta = (z_cc_arr(i,j,k) - z_cc_arr(i,j-1,k)) * dxInv[1];
148 
149  Real dz_phys_hi, dz_phys_lo;
150  Real gpz_lo, gpz_hi;
151  if (k==domain_klo) {
152  dz_phys_hi = z_cc_arr(i,j ,k+1) - z_cc_arr(i,j ,k );
153  dz_phys_lo = z_cc_arr(i,j-1,k+1) - z_cc_arr(i,j-1,k );
154  gpz_hi = (p_arr(i,j ,k+1) - p_arr(i,j ,k )) / dz_phys_hi;
155  gpz_lo = (p_arr(i,j-1,k+1) - p_arr(i,j-1,k )) / dz_phys_lo;
156  } else if (k==domain_khi) {
157  dz_phys_hi = z_cc_arr(i,j ,k ) - z_cc_arr(i,j ,k-1);
158  dz_phys_lo = z_cc_arr(i,j-1,k ) - z_cc_arr(i,j-1,k-1);
159  gpz_hi = (p_arr(i,j ,k ) - p_arr(i,j ,k-1)) / dz_phys_hi;
160  gpz_lo = (p_arr(i,j-1,k ) - p_arr(i,j-1,k-1)) / dz_phys_lo;
161  } else {
162  dz_phys_hi = z_cc_arr(i,j ,k+1) - z_cc_arr(i,j ,k-1);
163  dz_phys_lo = z_cc_arr(i,j-1,k+1) - z_cc_arr(i,j-1,k-1);
164  gpz_hi = (p_arr(i,j ,k+1) - p_arr(i,j ,k-1)) / dz_phys_hi;
165  gpz_lo = (p_arr(i,j-1,k+1) - p_arr(i,j-1,k-1)) / dz_phys_lo;
166  }
167  Real gpy_metric = met_h_eta * 0.5 * (gpz_hi + gpz_lo);
168  gpy -= gpy_metric;
169  } // l_use_terrain_fitted_coords
170 
171  gpy_arr(i,j,k) = gpy;
172  });
173 
174  ParallelFor(tbz, [=] AMREX_GPU_DEVICE(int i, int j, int k) noexcept
175  {
176  Real met_h_zeta = (l_use_terrain_fitted_coords) ? Compute_h_zeta_AtKface(i, j, k, dxInv, z_nd_arr) : 1;
177  gpz_arr(i,j,k) = dxInv[2] * ( p_arr(i,j,k)-p_arr(i,j,k-1) ) / met_h_zeta;
178  });
179  } // mfi
180 }
AMREX_GPU_DEVICE AMREX_FORCE_INLINE amrex::Real Compute_h_zeta_AtKface(const int &i, const int &j, const int &k, const amrex::GpuArray< amrex::Real, AMREX_SPACEDIM > &cellSizeInv, const amrex::Array4< const amrex::Real > &z_nd)
Definition: ERF_TerrainMetrics.H:182
@ gpz
Definition: ERF_IndexDefines.H:152
@ gpy
Definition: ERF_IndexDefines.H:151
@ gpx
Definition: ERF_IndexDefines.H:150
static MeshType mesh_type
Definition: ERF_DataStruct.H:665

Referenced by make_gradp_pert(), and ERF::WritePlotFile().

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

◆ make_gradp_pert()

void make_gradp_pert ( int  level,
const SolverChoice solverChoice,
const Geometry &  geom,
MultiFab &  S_data,
MultiFab &  p0,
std::unique_ptr< MultiFab > &  z_phys_nd,
std::unique_ptr< MultiFab > &  z_phys_cc,
Vector< MultiFab > &  gradp 
)

Function for computing the pressure gradient

Parameters
[in]levellevel of resolution
[in]geomgeometry container at this level
[in]S_datacurrent solution
[in]p0base ststa pressure
[in]z_phys_ndz on nodes
[in]z_phys_ccz on cell centers
[out]gradppressure gradient
34 {
35  const bool l_use_moisture = (solverChoice.moisture_type != MoistureType::None);
36  //
37  // Note that we only recompute gradp if compressible;
38  // if anelastic then we have computed gradp in the projection
39  // and we can reuse it, no need to recompute it
40  //
41  if (solverChoice.anelastic[level] == 0)
42  {
43  MultiFab p(S_data.boxArray(), S_data.DistributionMap(), 1, 1);
44 
45  // *****************************************************************************
46  // Compute pressure or perturbataional pressure
47  // *****************************************************************************
48  for ( MFIter mfi(S_data); mfi.isValid(); ++mfi)
49  {
50  Box gbx = mfi.tilebox(); gbx.grow(IntVect(1,1,1));
51  if (gbx.smallEnd(2) < 0) gbx.setSmall(2,0);
52  const Array4<const Real>& cell_data = S_data.array(mfi);
53  const Array4<const Real>& p0_arr = p0.const_array(mfi);
54  const Array4< Real>& pptemp_arr = p.array(mfi);
55  ParallelFor(gbx, [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept
56  {
57  Real qv_for_p = (l_use_moisture) ? cell_data(i,j,k,RhoQ1_comp)/cell_data(i,j,k,Rho_comp) : 0.0;
58  pptemp_arr(i,j,k) = getPgivenRTh(cell_data(i,j,k,RhoTheta_comp),qv_for_p) - p0_arr(i,j,k);
59  });
60  }
61 
62  compute_gradp(p,geom,z_phys_nd,z_phys_cc,gradp,solverChoice);
63  }
64 }
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real getPgivenRTh(const amrex::Real rhotheta, const amrex::Real qv=0.)
Definition: ERF_EOS.H:84
#define Rho_comp
Definition: ERF_IndexDefines.H:36
#define RhoTheta_comp
Definition: ERF_IndexDefines.H:37
#define RhoQ1_comp
Definition: ERF_IndexDefines.H:42
void compute_gradp(const MultiFab &p, const Geometry &geom, std::unique_ptr< MultiFab > &z_phys_nd, std::unique_ptr< MultiFab > &z_phys_cc, Vector< MultiFab > &gradp, const SolverChoice &solverChoice)
Definition: ERF_MakeGradP.cpp:67
real(c_double), parameter p0
Definition: ERF_module_model_constants.F90:40
amrex::Vector< int > anelastic
Definition: ERF_DataStruct.H:681
MoistureType moisture_type
Definition: ERF_DataStruct.H:761
Here is the call graph for this function: