ERF
Energy Research and Forecasting: An Atmospheric Modeling Code
ERF_InitZLevels.cpp File Reference
#include <ERF_TerrainMetrics.H>
#include <ERF_Utils.H>
#include <AMReX_ParmParse.H>
#include <ERF_Constants.H>
#include <ERF_Interpolation_1D.H>
#include <cmath>
Include dependency graph for ERF_InitZLevels.cpp:

Functions

void init_zlevels (Vector< Vector< Real >> &zlevels_stag, Vector< Vector< Real >> &stretched_dz_h, Vector< Gpu::DeviceVector< Real >> &stretched_dz_d, Vector< Geometry > const &geom, Vector< IntVect > const &ref_ratio, const Real grid_stretching_ratio, const Real zsurf, const Real dz0)
 

Function Documentation

◆ init_zlevels()

void init_zlevels ( Vector< Vector< Real >> &  zlevels_stag,
Vector< Vector< Real >> &  stretched_dz_h,
Vector< Gpu::DeviceVector< Real >> &  stretched_dz_d,
Vector< Geometry > const &  geom,
Vector< IntVect > const &  ref_ratio,
const Real  grid_stretching_ratio,
const Real  zsurf,
const Real  dz0 
)
19 {
20  int max_level = zlevels_stag.size()-1;
21 
22  for (int lev = 0; lev <= max_level; lev++)
23  {
24  auto dx = geom[lev].CellSizeArray();
25  const Box& domain = geom[lev].Domain();
26  int nz = domain.length(2)+1; // staggered
27 
28  zlevels_stag[lev].resize(nz);
29 
30  stretched_dz_h[lev].resize(domain.length(2));
31 
32  if (grid_stretching_ratio == 0) {
33  // This is the default for z_levels
34  for (int k = 0; k < nz; k++)
35  {
36  zlevels_stag[lev][k] = k * dx[2];
37  }
38  for (int k = 0; k < nz-1; k++)
39  {
40  stretched_dz_h[lev][k] = dx[2];
41  }
42  } else if (lev == 0) {
43  // Create stretched grid based on initial dz and stretching ratio
44  zlevels_stag[lev][0] = zsurf;
45  Real dz = dz0;
46  stretched_dz_h[lev][0] = dz0;
47  Print() << "Stretched grid levels at level : " << lev << " is " << zsurf;
48  for (int k = 1; k < nz; k++)
49  {
50  zlevels_stag[lev][k] = zlevels_stag[lev][k-1] + dz;
51  if (k < nz-1) {
52  stretched_dz_h[lev][k] = dz;
53  }
54  Print() << " " << zlevels_stag[lev][k];
55  dz *= grid_stretching_ratio;
56  }
57  Print() << std::endl;
58  } else if (lev > 0) {
59  int rr = ref_ratio[lev-1][2];
60  expand_and_interpolate_1d(zlevels_stag[lev], zlevels_stag[lev-1], rr, false);
61  for (int k = 0; k < nz-1; k++)
62  {
63  stretched_dz_h[lev][k] = (zlevels_stag[lev][k+1] - zlevels_stag[lev][k]);
64  }
65  }
66  }
67 
68  // Try reading in terrain_z_levels, which allows arbitrarily spaced grid
69  // levels to be specified and will take precedence over the
70  // grid_stretching_ratio parameter
71  ParmParse pp("erf");
72  int n_zlevels = pp.countval("terrain_z_levels");
73  if (n_zlevels > 0)
74  {
75  int nz = geom[0].Domain().length(2)+1; // staggered
76  if (n_zlevels != nz) {
77  Print() << "You supplied " << n_zlevels << " staggered terrain_z_levels " << std::endl;
78  Print() << "but n_cell+1 in the z-direction is " << nz << std::endl;
79  Abort("You must specify a z_level for every value of k");
80  }
81 
82  if (grid_stretching_ratio > 0) {
83  Print() << "Note: Found terrain_z_levels, ignoring grid_stretching_ratio" << std::endl;
84  }
85 
86  pp.getarr("terrain_z_levels", zlevels_stag[0], 0, nz);
87 
88  // These levels should range from 0 at the surface to the height of the
89  // top of model domain (see the coordinate surface height, zeta, in
90  // Klemp 2011)
91  AMREX_ALWAYS_ASSERT(zlevels_stag[0][0] == 0);
92 
93  for (int lev = 1; lev <= max_level; lev++) {
94  int rr = ref_ratio[lev-1][2];
95  expand_and_interpolate_1d(zlevels_stag[lev], zlevels_stag[lev-1], rr, false);
96  }
97 
98  for (int lev = 0; lev <= max_level; lev++) {
99  int nz_zlevs = zlevels_stag[lev].size();
100  for (int k = 0; k < nz_zlevs-1; k++)
101  {
102  stretched_dz_h[lev][k] = (zlevels_stag[lev][k+1] - zlevels_stag[lev][k]);
103  }
104  }
105  }
106 
107  for (int lev = 0; lev <= max_level; lev++) {
108  stretched_dz_d[lev].resize(stretched_dz_h[lev].size());
109  Gpu::copy(Gpu::hostToDevice, stretched_dz_h[lev].begin(), stretched_dz_h[lev].end(), stretched_dz_d[lev].begin());
110  }
111 }
AMREX_FORCE_INLINE void expand_and_interpolate_1d(amrex::Vector< amrex::Real > &znew, const amrex::Vector< amrex::Real > &zorig, int refine_fac, bool destag=false)
Definition: ERF_Interpolation_1D.H:85
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real pp(amrex::Real y)
Definition: ERF_MicrophysicsUtils.H:230
amrex::Real Real
Definition: ERF_ShocInterface.H:16
real(c_double), private rr
Definition: ERF_module_mp_morr_two_moment.F90:223

Referenced by ERF::ERF_shared().

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