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)
 
void update_stretched_dz (int lev, Vector< Vector< Real >> const &zlevels_stag, Vector< Vector< Real >> &stretched_dz_h, Vector< Gpu::DeviceVector< Real >> &stretched_dz_d)
 

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 
)

Initialize staggered z-levels and grid spacing for all levels.

Parameters
[out]zlevels_stagStaggered z-level coordinates.
[out]stretched_dz_hHost-side cell heights in z.
[out]stretched_dz_dDevice-side cell heights in z.
[in]geomGeometry describing the domain.
[in]ref_ratioRefinement ratios between levels.
[in]grid_stretching_ratioRatio used for stretching the vertical grid.
[in]zsurfHeight of the surface.
[in]dz0Initial cell height at the surface.
31 {
32  int max_level = zlevels_stag.size()-1;
33 
34  for (int lev = 0; lev <= max_level; lev++)
35  {
36  auto dx = geom[lev].CellSizeArray();
37  const Box& domain = geom[lev].Domain();
38  int nz = domain.length(2);
39 
40  zlevels_stag[lev].resize(nz+1);
41 
42  stretched_dz_h[lev].resize(domain.length(2));
43 
44  if (grid_stretching_ratio == 0) {
45  // This is the default for z_levels
46  for (int k = 0; k < nz+1; k++)
47  {
48  zlevels_stag[lev][k] = k * dx[2];
49  }
50  for (int k = 0; k < nz; k++)
51  {
52  stretched_dz_h[lev][k] = dx[2];
53  }
54  } else if (lev == 0) {
55  // Create stretched grid based on initial dz and stretching ratio
56  zlevels_stag[lev][0] = zsurf;
57  Real dz = dz0;
58  Print() << "Stretched grid levels at level : " << lev << " is " << zsurf;
59  for (int k = 1; k < nz+1; k++)
60  {
61  stretched_dz_h[lev][k-1] = dz;
62  zlevels_stag[lev][k] = zlevels_stag[lev][k-1] + dz;
63  Print() << " " << zlevels_stag[lev][k];
64  dz *= grid_stretching_ratio;
65  }
66  Print() << std::endl;
67  } else if (lev > 0) {
68  int rr = ref_ratio[lev-1][2];
69  expand_and_interpolate_1d(zlevels_stag[lev], zlevels_stag[lev-1], rr, false);
70  for (int k = 0; k < nz; k++)
71  {
72  stretched_dz_h[lev][k] = (zlevels_stag[lev][k+1] - zlevels_stag[lev][k]);
73  }
74  }
75  }
76 
77  // Try reading in terrain_z_levels, which allows arbitrarily spaced grid
78  // levels to be specified and will take precedence over the
79  // grid_stretching_ratio parameter
80  ParmParse pp("erf");
81  int n_zlevels = pp.countval("terrain_z_levels");
82  if (n_zlevels > 0)
83  {
84  int nz = geom[0].Domain().length(2);
85  if (n_zlevels != nz+1) {
86  Print() << "You supplied " << n_zlevels << " staggered terrain_z_levels " << std::endl;
87  Print() << "but n_cell+1 in the z-direction is " << nz+1 << std::endl;
88  Abort("You must specify a z_level for every value of k");
89  }
90 
91  if (grid_stretching_ratio > 0) {
92  Print() << "Note: Found terrain_z_levels, ignoring grid_stretching_ratio" << std::endl;
93  }
94 
95  pp.getarr("terrain_z_levels", zlevels_stag[0], 0, nz+1);
96 
97  // These levels should range from 0 at the surface to the height of the
98  // top of model domain (see the coordinate surface height, zeta, in
99  // Klemp 2011)
100  AMREX_ALWAYS_ASSERT(zlevels_stag[0][0] == 0);
101 
102  for (int lev = 1; lev <= max_level; lev++) {
103  int rr = ref_ratio[lev-1][2];
104  expand_and_interpolate_1d(zlevels_stag[lev], zlevels_stag[lev-1], rr, false);
105  }
106 
107  for (int lev = 0; lev <= max_level; lev++) {
108  int nz_zlevs = zlevels_stag[lev].size();
109  for (int k = 0; k < nz_zlevs-1; k++)
110  {
111  stretched_dz_h[lev][k] = (zlevels_stag[lev][k+1] - zlevels_stag[lev][k]);
112  }
113  }
114  }
115 
116  for (int lev = 0; lev <= max_level; lev++) {
117  stretched_dz_d[lev].resize(stretched_dz_h[lev].size());
118  Gpu::copy(Gpu::hostToDevice, stretched_dz_h[lev].begin(), stretched_dz_h[lev].end(), stretched_dz_d[lev].begin());
119  }
120 }
ParmParse pp("prob")
const Real dx
Definition: ERF_InitCustomPert_ABL.H:44
AMREX_ALWAYS_ASSERT(bx.length()[2]==khi+1)
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:89
amrex::Real Real
Definition: ERF_ShocInterface.H:19
@ dz
Definition: ERF_AdvanceWDM6.cpp:270
real(c_double), private rr
Definition: ERF_module_mp_morr_two_moment.F90:224

Referenced by ERF::ERF_shared().

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

◆ update_stretched_dz()

void update_stretched_dz ( int  lev,
Vector< Vector< Real >> const &  zlevels_stag,
Vector< Vector< Real >> &  stretched_dz_h,
Vector< Gpu::DeviceVector< Real >> &  stretched_dz_d 
)

Re-derive the cell heights at one level from the nominal staggered z-levels.

Parameters
[in]levLevel index.
[in]zlevels_stagStaggered z-level coordinates.
[out]stretched_dz_hHost-side cell heights in z.
[out]stretched_dz_dDevice-side cell heights in z.
135 {
136  AMREX_ALWAYS_ASSERT(lev < static_cast<int>(zlevels_stag.size()));
137  AMREX_ALWAYS_ASSERT(lev < static_cast<int>(stretched_dz_h.size()));
138  AMREX_ALWAYS_ASSERT(lev < static_cast<int>(stretched_dz_d.size()));
139 
140  const int nz = static_cast<int>(zlevels_stag[lev].size()) - 1;
141  AMREX_ALWAYS_ASSERT(nz > 0);
142 
143  stretched_dz_h[lev].resize(nz);
144  for (int k = 0; k < nz; k++) {
145  stretched_dz_h[lev][k] = zlevels_stag[lev][k+1] - zlevels_stag[lev][k];
146  }
147 
148  stretched_dz_d[lev].resize(nz);
149  Gpu::copy(Gpu::hostToDevice, stretched_dz_h[lev].begin(), stretched_dz_h[lev].end(),
150  stretched_dz_d[lev].begin());
151 }

Referenced by ERF::ReadCheckpointFile().

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