ERF
Energy Research and Forecasting: An Atmospheric Modeling Code
ERF_TerrainMetrics.H
Go to the documentation of this file.
1 #ifndef ERF_TERRAIN_METRIC_H_
2 #define ERF_TERRAIN_METRIC_H_
3 
4 #include <AMReX.H>
5 #include <AMReX_Geometry.H>
6 #include <AMReX_MultiFab.H>
7 #include <ERF_IndexDefines.H>
8 #include <cmath>
10 
11 /**
12  * Routine to define default z_phys_nd and z_phys_cc
13  */
14 void
15 init_default_zphys (int lev, const amrex::Geometry& geom,
16  amrex::MultiFab& z_phys_nd, amrex::MultiFab& z_phys_cc,
17  amrex::Real z_offset = zero);
18 
19 /**
20  * The cells of a (cell-centered) BoxArray as boxes that are never stacked on each other:
21  * wherever a box sits on the top face of another, the run of cells in z that the two belong
22  * to becomes a single box. Returns ba itself when no two boxes of ba are stacked.
23  *
24  * @param[in] ba cell-centered BoxArray
25  */
26 amrex::BoxArray
27 join_boxes_stacked_in_z (const amrex::BoxArray& ba);
28 
29 /**
30  * Utility routines for constructing terrain metric terms
31  */
32 
33 // Declare functions for ERF.cpp
34 /**
35  * Initialize staggered z-levels and stretched vertical spacing.
36  *
37  * @param[out] zlevels_stag Staggered z-levels.
38  * @param[out] stretched_dz_h Host stretched vertical spacing.
39  * @param[out] stretched_dz_d Device stretched vertical spacing.
40  * @param[in] geom Geometry information.
41  * @param[in] ref_ratio Refinement ratios.
42  * @param[in] grid_stretching_ratio Ratio for grid stretching; zero with a positive dz0
43  * solves for the ratio that closes on the domain top.
44  * @param[in] dz0 Initial vertical spacing.
45  */
46 void
47 init_zlevels (amrex::Vector<amrex::Vector<amrex::Real>>& zlevels_stag,
48  amrex::Vector<amrex::Vector<amrex::Real>>& stretched_dz_h,
49  amrex::Vector<amrex::Gpu::DeviceVector<amrex::Real>>& stretched_dz_d,
50  amrex::Vector<amrex::Geometry> const& geom,
51  amrex::Vector<amrex::IntVect> const& ref_ratio,
52  const amrex::Real grid_stretching_ratio,
53  const amrex::Real dz0);
54 
55 /**
56  * How the terrain-fitted mesh on a fine level is built when erf.terrain_smoothing != 0.
57  *
58  * The STF and Sullivan TF transformations are not defined on a level that does not
59  * reach the top of the domain, so on a fine level we instead start from the mesh
60  * interpolated from the coarse level. A caller that has done that interpolation --
61  * and, for Transform, has also written the fine-resolution terrain into the k=0 slab
62  * and saved the pre-overwrite field -- says so by passing anything other than None.
63  * Every other caller keeps the historical behavior of aborting, because it has not
64  * prepared z_phys_nd in a way this path can use.
65  */
66 enum struct FineTerrain {
67  None, //!< caller has not prepared a fine mesh from the coarse level
68  Interpolate, //!< use the coordinates interpolated from the coarse level as-is
69  Transform //!< add the fine terrain as a correction that decays with height
70 };
71 
72 /**
73  * Read erf.amr_terrain_refinement and translate it into a FineTerrain.
74  *
75  * Aborts on any value other than "interpolate" or "transform" so that a typo cannot
76  * silently select a path that leaves the fine mesh untransformed.
77  */
80 
81 /**
82  * Construct terrain-fitted coordinates.
83  *
84  * @param[in] lev Level index.
85  * @param[in] geom Geometry information.
86  * @param[out] z_phys_nd Nodal physical height field.
87  * @param[in] z_levels_h Host z-levels.
88  * @param[in] phys_bc_type Physical boundary condition types.
89  * @param[in] fine_terrain How a fine level with terrain_smoothing != 0 is to be built.
90  * @param[in] z_phys_interp Mesh interpolated from the coarse level before the fine
91  * terrain was written into the k=0 slab; required by, and
92  * only used for, FineTerrain::Transform.
93  */
94 void
95 make_terrain_fitted_coords (int lev, const amrex::Geometry& geom,
96  amrex::MultiFab& z_phys_nd,
97  amrex::Vector<amrex::Real> const& z_levels_h,
98  amrex::GpuArray<ERF_BC, AMREX_SPACEDIM*2>& phys_bc_type,
99  FineTerrain fine_terrain = FineTerrain::None,
100  amrex::MultiFab const* z_phys_interp = nullptr);
101 
102 /** Verify that a fitted mesh is horizontally flat and follows z_levels_h. */
103 void
105  const amrex::MultiFab& z_phys_nd,
106  const amrex::Vector<amrex::Real>& z_levels_h);
107 
108 /** Abort unless z_phys_nd is the same at every node of the top of the domain. */
109 void
111  const amrex::Geometry& geom,
112  const amrex::MultiFab& z_phys_nd);
113 
114 /**
115  * Initialize the terrain grid mapping.
116  *
117  * @param[in] lev Level index.
118  * @param[in] geom Geometry information.
119  * @param[out] z_phys_nd Nodal physical height field.
120  * @param[in] z_levels_h Host z-levels.
121  * @param[in] fine_terrain How a fine level with terrain_smoothing != 0 is to be built.
122  * @param[in] z_phys_interp Mesh interpolated from the coarse level; see above.
123  */
124 void
125 init_which_terrain_grid (int lev, const amrex::Geometry& geom,
126  amrex::MultiFab& z_phys_nd,
127  amrex::Vector<amrex::Real> const& z_levels_h,
128  FineTerrain fine_terrain = FineTerrain::None,
129  amrex::MultiFab const* z_phys_interp = nullptr);
130 
131 /**
132  * Finish the terrain-fitted mesh on a fine level whose interior was set by
133  * interpolation from the coarse level (erf.terrain_smoothing != 0).
134  *
135  * For FineTerrain::Transform this adds the fine-resolution terrain as a correction
136  * that decays linearly to zero at the top of the fine grids. For both modes it then
137  * fills the nodes outside the lateral domain boundary and the layer below the
138  * surface, which init_which_terrain_grid()'s BTF branch would otherwise have filled.
139  *
140  * @param[in] lev Level index.
141  * @param[in] geom Geometry information.
142  * @param[in,out] z_phys_nd Nodal physical height field.
143  * @param[in] z_levels_h Host z-levels.
144  * @param[in] fine_terrain Interpolate or Transform.
145  * @param[in] z_phys_interp Mesh interpolated from the coarse level; see above.
146  */
147 void
148 init_fine_terrain_grid (int lev, const amrex::Geometry& geom,
149  amrex::MultiFab& z_phys_nd,
150  amrex::Vector<amrex::Real> const& z_levels_h,
151  FineTerrain fine_terrain,
152  amrex::MultiFab const* z_phys_interp);
153 
154 // Compute the min dz at cell center with terrain
155 /**
156  * Compute the minimum vertical spacing with terrain.
157  *
158  * @param[in] z_phys_nd Nodal physical height field.
159  * @return Minimum vertical grid spacing.
160  */
162 get_dzmin_terrain (amrex::MultiFab& z_phys_nd);
163 
164 /**
165  * Re-derive the stretched vertical spacing at one level from the nominal z-levels.
166  *
167  * init_zlevels() fills both zlevels_stag and stretched_dz_* together, but
168  * zlevels_stag can be replaced after construction (init_from_wrfinput() does this
169  * when erf.avg_grid_faces_to_nodes = false, and restart reads it back from the
170  * checkpoint). Call this whenever zlevels_stag[lev] changes so that the cell
171  * heights never drift out of sync with the levels they are supposed to describe.
172  *
173  * @param[in] lev Level index.
174  * @param[in] zlevels_stag Staggered z-levels (the source of truth).
175  * @param[out] stretched_dz_h Host stretched vertical spacing.
176  * @param[out] stretched_dz_d Device stretched vertical spacing.
177  */
178 void
180  amrex::Vector<amrex::Vector<amrex::Real>> const& zlevels_stag,
181  amrex::Vector<amrex::Vector<amrex::Real>>& stretched_dz_h,
182  amrex::Vector<amrex::Gpu::DeviceVector<amrex::Real>>& stretched_dz_d);
183 
184 //*****************************************************************************************
185 // Compute terrain metric terms at cell-center
186 //*****************************************************************************************
187 // Metric is at cell center
188 /**
189  * Compute the zeta metric term at the cell center.
190  *
191  * @param[in] i x-index
192  * @param[in] j y-index
193  * @param[in] k z-index
194  * @param[in] cellSizeInv Inverse cell spacing.
195  * @param[in] z_nd Nodal physical height field.
196  * @return Zeta metric term.
197  */
198 AMREX_GPU_HOST_DEVICE
199 AMREX_FORCE_INLINE
201 Compute_h_zeta_AtCellCenter (const int &i, const int &j, const int &k,
202  const amrex::GpuArray<amrex::Real, AMREX_SPACEDIM>& cellSizeInv,
203  const amrex::Array4<const amrex::Real>& z_nd)
204 {
205  amrex::Real dzInv = cellSizeInv[2];
206  amrex::Real met_h_zeta = fourth * dzInv *
207  ( z_nd(i+1,j,k+1) + z_nd(i+1,j+1,k+1) + z_nd(i,j,k+1) + z_nd(i,j+1,k+1)
208  - z_nd(i+1,j,k ) - z_nd(i+1,j+1,k ) - z_nd(i,j,k ) - z_nd(i,j+1,k ) );
209  return met_h_zeta;
210 }
211 
212 // Metric is at cell center
213 /**
214  * Compute the xi metric term at the cell center.
215  *
216  * @param[in] i x-index
217  * @param[in] j y-index
218  * @param[in] k z-index
219  * @param[in] cellSizeInv Inverse cell spacing.
220  * @param[in] z_nd Nodal physical height field.
221  * @return Xi metric term.
222  */
223 AMREX_GPU_HOST_DEVICE
224 AMREX_FORCE_INLINE
226 Compute_h_xi_AtCellCenter (const int &i, const int &j, const int &k,
227  const amrex::GpuArray<amrex::Real, AMREX_SPACEDIM>& cellSizeInv,
228  const amrex::Array4<const amrex::Real>& z_nd)
229 {
230  amrex::Real dxInv = cellSizeInv[0];
231  amrex::Real met_h_xi = fourth * dxInv *
232  ( z_nd(i+1,j,k) + z_nd(i+1,j+1,k) + z_nd(i+1,j,k+1) + z_nd(i+1,j+1,k+1)
233  - z_nd(i ,j,k) - z_nd(i ,j+1,k) - z_nd(i ,j,k+1) - z_nd(i ,j+1,k+1) );
234  return met_h_xi;
235 }
236 
237 // Metric is at cell center
238 /**
239  * Compute the eta metric term at the cell center.
240  *
241  * @param[in] i x-index
242  * @param[in] j y-index
243  * @param[in] k z-index
244  * @param[in] cellSizeInv Inverse cell spacing.
245  * @param[in] z_nd Nodal physical height field.
246  * @return Eta metric term.
247  */
248 AMREX_GPU_HOST_DEVICE
249 AMREX_FORCE_INLINE
251 Compute_h_eta_AtCellCenter (const int &i, const int &j, const int &k,
252  const amrex::GpuArray<amrex::Real, AMREX_SPACEDIM>& cellSizeInv,
253  const amrex::Array4<const amrex::Real>& z_nd)
254 {
255  amrex::Real dyInv = cellSizeInv[1];
256  amrex::Real met_h_eta = fourth * dyInv *
257  ( z_nd(i,j+1,k) + z_nd(i+1,j+1,k) + z_nd(i,j+1,k+1) + z_nd(i+1,j+1,k+1)
258  - z_nd(i,j ,k) - z_nd(i+1,j ,k) - z_nd(i,j ,k+1) - z_nd(i+1,j ,k+1) );
259  return met_h_eta;
260 }
261 
262 
263 //*****************************************************************************************
264 // Compute terrain metric terms at face-centers
265 //*****************************************************************************************
266 // Metric coincides with U location
267 /**
268  * Compute the zeta metric term at the i-face.
269  *
270  * @param[in] i x-index
271  * @param[in] j y-index
272  * @param[in] k z-index
273  * @param[in] cellSizeInv Inverse cell spacing.
274  * @param[in] z_nd Nodal physical height field.
275  * @return Zeta metric term.
276  */
277 AMREX_GPU_DEVICE
278 AMREX_FORCE_INLINE
280 Compute_h_zeta_AtIface (const int &i, const int &j, const int &k,
281  const amrex::GpuArray<amrex::Real, AMREX_SPACEDIM>& cellSizeInv,
282  const amrex::Array4<const amrex::Real>& z_nd)
283 {
284  amrex::Real met_h_zeta = myhalf * cellSizeInv[2] * ( (z_nd(i,j ,k+1) - z_nd(i,j ,k))
285  + (z_nd(i,j+1,k+1) - z_nd(i,j+1,k)) );
286  return met_h_zeta;
287 }
288 
289 // Metric coincides with U location
290 /**
291  * Compute the xi metric term at the i-face.
292  *
293  * @param[in] i x-index
294  * @param[in] j y-index
295  * @param[in] k z-index
296  * @param[in] cellSizeInv Inverse cell spacing.
297  * @param[in] z_nd Nodal physical height field.
298  * @return Xi metric term.
299  */
300 AMREX_GPU_HOST_DEVICE
301 AMREX_FORCE_INLINE
303 Compute_h_xi_AtIface (const int &i, const int &j, const int &k,
304  const amrex::GpuArray<amrex::Real, AMREX_SPACEDIM>& cellSizeInv,
305  const amrex::Array4<const amrex::Real>& z_nd)
306 {
307  amrex::Real met_h_xi = amrex::Real(0.125) * cellSizeInv[0] * (
308  (z_nd(i+1,j ,k ) - z_nd(i-1,j ,k )) + (z_nd(i+1,j ,k+1) - z_nd(i-1,j ,k+1)) +
309  (z_nd(i+1,j+1,k ) - z_nd(i-1,j+1,k )) + (z_nd(i+1,j+1,k+1) - z_nd(i-1,j+1,k+1)) );
310  return met_h_xi;
311 }
312 
313 // Metric coincides with U location
314 /**
315  * Compute the eta metric term at the i-face.
316  *
317  * @param[in] i x-index
318  * @param[in] j y-index
319  * @param[in] k z-index
320  * @param[in] cellSizeInv Inverse cell spacing.
321  * @param[in] z_nd Nodal physical height field.
322  * @return Eta metric term.
323  */
324 AMREX_GPU_DEVICE
325 AMREX_FORCE_INLINE
327 Compute_h_eta_AtIface (const int &i, const int &j, const int &k,
328  const amrex::GpuArray<amrex::Real, AMREX_SPACEDIM>& cellSizeInv,
329  const amrex::Array4<const amrex::Real>& z_nd)
330 {
331  amrex::Real met_h_eta = myhalf * cellSizeInv[1] * ( (z_nd(i,j+1,k ) - z_nd(i,j,k ))
332  + (z_nd(i,j+1,k+1) - z_nd(i,j,k+1)) );
333  return met_h_eta;
334 }
335 
336 // Metric coincides with V location
337 /**
338  * Compute the zeta metric term at the j-face.
339  *
340  * @param[in] i x-index
341  * @param[in] j y-index
342  * @param[in] k z-index
343  * @param[in] cellSizeInv Inverse cell spacing.
344  * @param[in] z_nd Nodal physical height field.
345  * @return Zeta metric term.
346  */
347 AMREX_GPU_DEVICE
348 AMREX_FORCE_INLINE
350 Compute_h_zeta_AtJface (const int &i, const int &j, const int &k,
351  const amrex::GpuArray<amrex::Real, AMREX_SPACEDIM>& cellSizeInv,
352  const amrex::Array4<const amrex::Real>& z_nd)
353 {
354  amrex::Real met_h_zeta = myhalf * cellSizeInv[2] * ( (z_nd(i ,j,k+1) - z_nd(i ,j,k ))
355  + (z_nd(i+1,j,k+1) - z_nd(i+1,j,k )) );
356  return met_h_zeta;
357 }
358 
359 // Metric coincides with V location
360 /**
361  * Compute the xi metric term at the j-face.
362  *
363  * @param[in] i x-index
364  * @param[in] j y-index
365  * @param[in] k z-index
366  * @param[in] cellSizeInv Inverse cell spacing.
367  * @param[in] z_nd Nodal physical height field.
368  * @return Xi metric term.
369  */
370 AMREX_GPU_DEVICE
371 AMREX_FORCE_INLINE
373 Compute_h_xi_AtJface (const int &i, const int &j, const int &k,
374  const amrex::GpuArray<amrex::Real, AMREX_SPACEDIM>& cellSizeInv,
375  const amrex::Array4<const amrex::Real>& z_nd)
376 {
377  amrex::Real met_h_xi = myhalf * cellSizeInv[0] * ( (z_nd(i+1,j,k ) - z_nd(i,j,k ))
378  + (z_nd(i+1,j,k+1) - z_nd(i,j,k+1)) );
379  return met_h_xi;
380 }
381 
382 // Metric coincides with V location
383 /**
384  * Compute the eta metric term at the j-face.
385  *
386  * @param[in] i x-index
387  * @param[in] j y-index
388  * @param[in] k z-index
389  * @param[in] cellSizeInv Inverse cell spacing.
390  * @param[in] z_nd Nodal physical height field.
391  * @return Eta metric term.
392  */
393 AMREX_GPU_HOST_DEVICE
394 AMREX_FORCE_INLINE
396 Compute_h_eta_AtJface (const int &i, const int &j, const int &k,
397  const amrex::GpuArray<amrex::Real, AMREX_SPACEDIM>& cellSizeInv,
398  const amrex::Array4<const amrex::Real>& z_nd)
399 {
400  amrex::Real met_h_eta = amrex::Real(0.125) * cellSizeInv[1] *
401  ( (z_nd(i ,j+1,k ) - z_nd(i ,j-1,k )) + (z_nd(i ,j+1,k+1) - z_nd(i ,j-1,k+1)) +
402  (z_nd(i+1,j+1,k ) - z_nd(i+1,j-1,k )) + (z_nd(i+1,j+1,k+1) - z_nd(i+1,j-1,k+1)) );
403  return met_h_eta;
404 }
405 
406 // Metric coincides with K location
407 /**
408  * Compute the zeta metric term at the k-face.
409  *
410  * @param[in] i x-index
411  * @param[in] j y-index
412  * @param[in] k z-index
413  * @param[in] cellSizeInv Inverse cell spacing.
414  * @param[in] z_nd Nodal physical height field.
415  * @return Zeta metric term.
416  */
417 AMREX_GPU_HOST_DEVICE
418 AMREX_FORCE_INLINE
420 Compute_h_zeta_AtKface (const int &i, const int &j, const int &k,
421  const amrex::GpuArray<amrex::Real, AMREX_SPACEDIM>& cellSizeInv,
422  const amrex::Array4<const amrex::Real>& z_nd)
423 {
424  amrex::Real met_h_zeta = amrex::Real(0.125) * cellSizeInv[2] *
425  ( (z_nd(i ,j ,k+1) - z_nd(i ,j ,k-1)) + (z_nd(i+1,j ,k+1) - z_nd(i+1,j ,k-1)) +
426  (z_nd(i ,j+1,k+1) - z_nd(i ,j+1,k-1)) + (z_nd(i+1,j+1,k+1) - z_nd(i+1,j+1,k-1)) );
427  return met_h_zeta;
428 }
429 
430 // Metric coincides with K location
431 /**
432  * Compute the xi metric term at the k-face.
433  *
434  * @param[in] i x-index
435  * @param[in] j y-index
436  * @param[in] k z-index
437  * @param[in] cellSizeInv Inverse cell spacing.
438  * @param[in] z_nd Nodal physical height field.
439  * @return Xi metric term.
440  */
441 AMREX_GPU_HOST_DEVICE
442 AMREX_FORCE_INLINE
444 Compute_h_xi_AtKface (const int &i, const int &j, const int &k,
445  const amrex::GpuArray<amrex::Real, AMREX_SPACEDIM>& cellSizeInv,
446  const amrex::Array4<const amrex::Real>& z_nd)
447 {
448  amrex::Real met_h_xi = myhalf * cellSizeInv[0] * ( (z_nd(i+1,j ,k) - z_nd(i,j ,k))
449  + (z_nd(i+1,j+1,k) - z_nd(i,j+1,k)) );
450  return met_h_xi;
451 }
452 
453 // Metric coincides with K location
454 /**
455  * Compute the eta metric term at the k-face.
456  *
457  * @param[in] i x-index
458  * @param[in] j y-index
459  * @param[in] k z-index
460  * @param[in] cellSizeInv Inverse cell spacing.
461  * @param[in] z_nd Nodal physical height field.
462  * @return Eta metric term.
463  */
464 AMREX_GPU_HOST_DEVICE
465 AMREX_FORCE_INLINE
467 Compute_h_eta_AtKface (const int &i, const int &j, const int &k,
468  const amrex::GpuArray<amrex::Real, AMREX_SPACEDIM>& cellSizeInv,
469  const amrex::Array4<const amrex::Real>& z_nd)
470 {
471  amrex::Real met_h_eta = myhalf * cellSizeInv[1] * ( (z_nd(i ,j+1,k) - z_nd(i ,j,k))
472  + (z_nd(i+1,j+1,k) - z_nd(i+1,j,k)) );
473  return met_h_eta;
474 }
475 
476 
477 //*****************************************************************************************
478 // Compute terrain metric terms at edge-centers
479 //*****************************************************************************************
480 // -- EdgeCenterK --
481 
482 // Metric is at edge and center Z (red pentagon)
483 /**
484  * Compute the zeta metric term at the k-edge center.
485  *
486  * @param[in] i x-index
487  * @param[in] j y-index
488  * @param[in] k z-index
489  * @param[in] cellSizeInv Inverse cell spacing.
490  * @param[in] z_nd Nodal physical height field.
491  * @return Zeta metric term.
492  */
493 AMREX_GPU_DEVICE
494 AMREX_FORCE_INLINE
496 Compute_h_zeta_AtEdgeCenterK (const int &i, const int &j, const int &k,
497  const amrex::GpuArray<amrex::Real, AMREX_SPACEDIM>& cellSizeInv,
498  const amrex::Array4<const amrex::Real>& z_nd)
499 {
500  amrex::Real dzInv = cellSizeInv[2];
501  amrex::Real met_h_zeta = dzInv * (z_nd(i,j,k+1) - z_nd(i,j,k));
502  return met_h_zeta;
503 }
504 
505 // Metric is at edge and center Z (red pentagon)
506 /**
507  * Compute the xi metric term at the k-edge center.
508  *
509  * @param[in] i x-index
510  * @param[in] j y-index
511  * @param[in] k z-index
512  * @param[in] cellSizeInv Inverse cell spacing.
513  * @param[in] z_nd Nodal physical height field.
514  * @return Xi metric term.
515  */
516 AMREX_GPU_DEVICE
517 AMREX_FORCE_INLINE
519 Compute_h_xi_AtEdgeCenterK (const int &i, const int &j, const int &k,
520  const amrex::GpuArray<amrex::Real, AMREX_SPACEDIM>& cellSizeInv,
521  const amrex::Array4<const amrex::Real>& z_nd)
522 {
523  amrex::Real dxInv = cellSizeInv[0];
524  amrex::Real met_h_xi = fourth * dxInv *
525  ( z_nd(i+1,j,k) + z_nd(i+1,j,k+1)
526  - z_nd(i-1,j,k) - z_nd(i-1,j,k+1) );
527  return met_h_xi;
528 }
529 
530 // Metric is at edge and center Z (red pentagon)
531 /**
532  * Compute the eta metric term at the k-edge center.
533  *
534  * @param[in] i x-index
535  * @param[in] j y-index
536  * @param[in] k z-index
537  * @param[in] cellSizeInv Inverse cell spacing.
538  * @param[in] z_nd Nodal physical height field.
539  * @return Eta metric term.
540  */
541 AMREX_GPU_DEVICE
542 AMREX_FORCE_INLINE
544 Compute_h_eta_AtEdgeCenterK (const int &i, const int &j, const int &k,
545  const amrex::GpuArray<amrex::Real, AMREX_SPACEDIM>& cellSizeInv,
546  const amrex::Array4<const amrex::Real>& z_nd)
547 {
548  amrex::Real dyInv = cellSizeInv[1];
549  amrex::Real met_h_eta = fourth * dyInv *
550  ( z_nd(i,j+1,k) + z_nd(i,j+1,k+1)
551  - z_nd(i,j-1,k) - z_nd(i,j-1,k+1) );
552  return met_h_eta;
553 }
554 
555 // -- EdgeCenterJ --
556 
557 // Metric is at edge and center Y (magenta cross)
558 /**
559  * Compute the zeta metric term at the j-edge center.
560  *
561  * @param[in] i x-index
562  * @param[in] j y-index
563  * @param[in] k z-index
564  * @param[in] cellSizeInv Inverse cell spacing.
565  * @param[in] z_nd Nodal physical height field.
566  * @return Zeta metric term.
567  */
568 AMREX_GPU_DEVICE
569 AMREX_FORCE_INLINE
571 Compute_h_zeta_AtEdgeCenterJ (const int &i, const int &j, const int &k,
572  const amrex::GpuArray<amrex::Real, AMREX_SPACEDIM>& cellSizeInv,
573  const amrex::Array4<const amrex::Real>& z_nd)
574 {
575  amrex::Real dzInv = cellSizeInv[2];
576  amrex::Real met_h_zeta = fourth * dzInv * ( z_nd(i,j,k+1) + z_nd(i,j+1,k+1)
577  - z_nd(i,j,k-1) - z_nd(i,j+1,k-1) );
578  return met_h_zeta;
579 }
580 
581 // Metric is at edge and center Y (magenta cross)
582 /**
583  * Compute the xi metric term at the j-edge center.
584  *
585  * @param[in] i x-index
586  * @param[in] j y-index
587  * @param[in] k z-index
588  * @param[in] cellSizeInv Inverse cell spacing.
589  * @param[in] z_nd Nodal physical height field.
590  * @return Xi metric term.
591  */
592 AMREX_GPU_DEVICE
593 AMREX_FORCE_INLINE
595 Compute_h_xi_AtEdgeCenterJ (const int &i, const int &j, const int &k,
596  const amrex::GpuArray<amrex::Real, AMREX_SPACEDIM>& cellSizeInv,
597  const amrex::Array4<const amrex::Real>& z_nd)
598 {
599  amrex::Real dxInv = cellSizeInv[0];
600  amrex::Real met_h_xi = fourth * dxInv *
601  ( z_nd(i+1,j+1,k) + z_nd(i+1,j ,k)
602  - z_nd(i-1,j+1,k) - z_nd(i-1,j ,k) );
603  return met_h_xi;
604 }
605 
606 // Metric is at edge and center Y (magenta cross)
607 /**
608  * Compute the eta metric term at the j-edge center.
609  *
610  * @param[in] i x-index
611  * @param[in] j y-index
612  * @param[in] k z-index
613  * @param[in] cellSizeInv Inverse cell spacing.
614  * @param[in] z_nd Nodal physical height field.
615  * @return Eta metric term.
616  */
617 AMREX_GPU_DEVICE
618 AMREX_FORCE_INLINE
620 Compute_h_eta_AtEdgeCenterJ (const int &i, const int &j, const int &k,
621  const amrex::GpuArray<amrex::Real, AMREX_SPACEDIM>& cellSizeInv,
622  const amrex::Array4<const amrex::Real>& z_nd)
623 {
624  amrex::Real dyInv = cellSizeInv[1];
625  amrex::Real met_h_eta = dyInv * ( z_nd(i,j+1,k) - z_nd(i,j,k) );
626  return met_h_eta;
627 }
628 
629 // -- EdgeCenterI --
630 
631 // Metric is at edge and center X (purple hexagon)
632 /**
633  * Compute the zeta metric term at the i-edge center.
634  *
635  * @param[in] i x-index
636  * @param[in] j y-index
637  * @param[in] k z-index
638  * @param[in] cellSizeInv Inverse cell spacing.
639  * @param[in] z_nd Nodal physical height field.
640  * @return Zeta metric term.
641  */
642 AMREX_GPU_DEVICE
643 AMREX_FORCE_INLINE
645 Compute_h_zeta_AtEdgeCenterI (const int &i, const int &j, const int &k,
646  const amrex::GpuArray<amrex::Real, AMREX_SPACEDIM>& cellSizeInv,
647  const amrex::Array4<const amrex::Real>& z_nd)
648 {
649  amrex::Real dzInv = cellSizeInv[2];
650  amrex::Real met_h_zeta = fourth * dzInv * ( z_nd(i,j,k+1) + z_nd(i+1,j,k+1)
651  - z_nd(i,j,k-1) - z_nd(i+1,j,k-1) );
652  return met_h_zeta;
653 }
654 
655 // Metric is at edge and center X (purple hexagon)
656 /**
657  * Compute the xi metric term at the i-edge center.
658  *
659  * @param[in] i x-index
660  * @param[in] j y-index
661  * @param[in] k z-index
662  * @param[in] cellSizeInv Inverse cell spacing.
663  * @param[in] z_nd Nodal physical height field.
664  * @return Xi metric term.
665  */
666 AMREX_GPU_DEVICE
667 AMREX_FORCE_INLINE
669 Compute_h_xi_AtEdgeCenterI (const int &i, const int &j, const int &k,
670  const amrex::GpuArray<amrex::Real, AMREX_SPACEDIM>& cellSizeInv,
671  const amrex::Array4<const amrex::Real>& z_nd)
672 {
673  amrex::Real dxInv = cellSizeInv[0];
674  amrex::Real met_h_xi = dxInv * ( z_nd(i+1,j,k) - z_nd(i,j,k) );
675  return met_h_xi;
676 }
677 
678 // Metric is at edge and center X (purple hexagon)
679 /**
680  * Compute the eta metric term at the i-edge center.
681  *
682  * @param[in] i x-index
683  * @param[in] j y-index
684  * @param[in] k z-index
685  * @param[in] cellSizeInv Inverse cell spacing.
686  * @param[in] z_nd Nodal physical height field.
687  * @return Eta metric term.
688  */
689 AMREX_GPU_DEVICE
690 AMREX_FORCE_INLINE
692 Compute_h_eta_AtEdgeCenterI (const int &i, const int &j, const int &k,
693  const amrex::GpuArray<amrex::Real, AMREX_SPACEDIM>& cellSizeInv,
694  const amrex::Array4<const amrex::Real>& z_nd)
695 {
696  amrex::Real dyInv = cellSizeInv[1];
697  amrex::Real met_h_eta = fourth * dyInv *
698  ( z_nd(i+1,j+1,k) + z_nd(i,j+1,k)
699  - z_nd(i+1,j-1,k) - z_nd(i,j-1,k) );
700  return met_h_eta;
701 }
702 
703 // Relative height above terrain surface at cell center from z_nd (nodal absolute height)
704 /**
705  * Compute the physical height at the cell center.
706  *
707  * @param[in] i x-index
708  * @param[in] j y-index
709  * @param[in] k z-index
710  * @param[in] z_nd Nodal physical height field.
711  * @return Physical height at cell center.
712  */
713 AMREX_GPU_DEVICE
714 AMREX_FORCE_INLINE
716 Compute_Z_AtCellCenter (const int &i, const int &j, const int &k,
717  const amrex::Array4<const amrex::Real>& z_nd)
718 {
719  const amrex::Real z_cc = amrex::Real(0.125)*( z_nd(i ,j ,k) + z_nd(i ,j ,k+1)
720  + z_nd(i+1,j ,k) + z_nd(i+1,j ,k+1)
721  + z_nd(i ,j+1,k) + z_nd(i ,j+1,k+1)
722  + z_nd(i+1,j+1,k) + z_nd(i+1,j+1,k+1));
723 
724  return z_cc;
725 }
726 
727 // Relative height above terrain surface at cell center from z_nd (nodal absolute height)
728 /**
729  * Compute the physical height at the W-face.
730  *
731  * @param[in] i x-index
732  * @param[in] j y-index
733  * @param[in] k z-index
734  * @param[in] z_nd Nodal physical height field.
735  * @return Physical height at W-face.
736  */
737 AMREX_GPU_HOST_DEVICE
738 AMREX_FORCE_INLINE
740 Compute_Z_AtWFace (const int &i, const int &j, const int &k,
741  const amrex::Array4<const amrex::Real>& z_nd)
742 {
743  const amrex::Real z_wf = fourth*( z_nd(i ,j ,k) + z_nd(i+1,j ,k)
744  + z_nd(i ,j+1,k) + z_nd(i+1,j+1,k) );
745 
746  return z_wf;
747 }
748 
749 // Relative height above terrain surface at cell center from z_nd (nodal absolute height)
750 /**
751  * Compute the relative height above the terrain surface at the cell center.
752  *
753  * @param[in] i x-index
754  * @param[in] j y-index
755  * @param[in] k z-index
756  * @param[in] z_nd Nodal physical height field.
757  * @return Relative height at cell center.
758  */
759 AMREX_GPU_HOST_DEVICE
760 AMREX_FORCE_INLINE
762 Compute_Zrel_AtCellCenter (const int &i, const int &j, const int &k,
763  const amrex::Array4<const amrex::Real>& z_nd)
764 {
765  const amrex::Real z_cc = amrex::Real(0.125)*( z_nd(i ,j ,k) + z_nd(i ,j ,k+1) +
766  + z_nd(i+1,j ,k) + z_nd(i+1,j ,k+1)
767  + z_nd(i ,j+1,k) + z_nd(i ,j+1,k+1)
768  + z_nd(i+1,j+1,k) + z_nd(i+1,j+1,k+1));
769 
770  // Note: we assume the z_nd array spans from the bottom to top of the domain
771  // i.e. no domain decomposition across processors in vertical direction
772  const amrex::Real z0_cc = fourth*( z_nd(i ,j ,0) + z_nd(i ,j+1,0)
773  + z_nd(i+1,j ,0) + z_nd(i+1,j+1,0));
774 
775  return (z_cc - z0_cc);
776 }
777 
778 
779 //*****************************************************************************************
780 // Contravariant velocity computation
781 //*****************************************************************************************
782 
783 // Define omega given u,v and w (4th order)
784 /**
785  * Compute the contravariant vertical velocity omega from w.
786  *
787  * @param[in] i x-index
788  * @param[in] j y-index
789  * @param[in] k z-index
790  * @param[in] w Vertical velocity.
791  * @param[in] u_arr X-velocity array.
792  * @param[in] v_arr Y-velocity array.
793  * @param[in] mf_u X-velocity map factor.
794  * @param[in] mf_v Y-velocity map factor.
795  * @param[in] z_nd Nodal physical height field.
796  * @param[in] dxInv Inverse cell spacing.
797  * @return Contravariant vertical velocity.
798  */
799 AMREX_GPU_DEVICE
800 AMREX_FORCE_INLINE
802 OmegaFromW (int& i, int& j, int& k, amrex::Real w,
803  const amrex::Array4<const amrex::Real>& u_arr,
804  const amrex::Array4<const amrex::Real>& v_arr,
805  const amrex::Array4<const amrex::Real>& mf_u,
806  const amrex::Array4<const amrex::Real>& mf_v,
807  const amrex::Array4<const amrex::Real>& z_nd,
808  const amrex::GpuArray<amrex::Real, AMREX_SPACEDIM>& dxInv)
809 {
810  // This is dh/dxi at hi and lo edges
811  amrex::Real z_x_p2 = Compute_Z_AtWFace(i+2,j,k,z_nd);
812  amrex::Real z_x_p1 = Compute_Z_AtWFace(i+1,j,k,z_nd);
813  amrex::Real z_x_m1 = Compute_Z_AtWFace(i-1,j,k,z_nd);
814  amrex::Real z_x_m2 = Compute_Z_AtWFace(i-2,j,k,z_nd);
815  amrex::Real met_xi = (amrex::Real(1.0/amrex::Real(12.0))*(z_x_m2 - z_x_p2)
816  + amrex::Real(8.0/amrex::Real(12.0))*(z_x_p1 - z_x_m1)) * dxInv[0];
817 
818  // This is dh/deta at hi and lo edges
819  amrex::Real z_y_p2 = Compute_Z_AtWFace(i,j+2,k,z_nd);
820  amrex::Real z_y_p1 = Compute_Z_AtWFace(i,j+1,k,z_nd);
821  amrex::Real z_y_m1 = Compute_Z_AtWFace(i,j-1,k,z_nd);
822  amrex::Real z_y_m2 = Compute_Z_AtWFace(i,j-2,k,z_nd);
823  amrex::Real met_eta = (amrex::Real(1.0/amrex::Real(12.0))*(z_y_m2 - z_y_p2)
824  + amrex::Real(8.0/amrex::Real(12.0))*(z_y_p1 - z_y_m1)) * dxInv[1];
825 
826  // Use extrapolation instead of interpolation if at the bottom boundary
827  amrex::Real u_hi = (k == 0) ? amrex::Real(1.5) * u_arr(i+1,j ,k ) - myhalf * u_arr(i+1,j ,k+1) :
828  myhalf * ( u_arr(i+1,j ,k-1) + u_arr(i+1,j ,k ) );
829  amrex::Real u_lo = (k == 0) ? amrex::Real(1.5) * u_arr(i ,j ,k ) - myhalf * u_arr(i ,j ,k+1) :
830  myhalf * ( u_arr(i ,j ,k-1) + u_arr(i ,j ,k ) );
831  amrex::Real mf_u_hi = mf_u(i+1,j,0);
832  amrex::Real mf_u_lo = mf_u(i ,j,0);
833 
834  amrex::Real v_hi = (k == 0) ? amrex::Real(1.5) * v_arr(i ,j+1,k ) - myhalf * v_arr(i ,j+1,k+1) :
835  myhalf * ( v_arr(i ,j+1,k-1) + v_arr(i ,j+1,k ) );
836  amrex::Real v_lo = (k == 0) ? amrex::Real(1.5) * v_arr(i ,j ,k ) - myhalf * v_arr(i ,j ,k+1) :
837  myhalf * ( v_arr(i ,j ,k-1) + v_arr(i ,j ,k ) );
838  amrex::Real mf_v_hi = mf_v(i,j+1,0);
839  amrex::Real mf_v_lo = mf_v(i,j ,0);
840 
841  amrex::Real u_met = met_xi * myhalf * ( u_hi*mf_u_hi + u_lo*mf_u_lo );
842  amrex::Real v_met = met_eta * myhalf * ( v_hi*mf_v_hi + v_lo*mf_v_lo );
843 
844  amrex::Real omega = w - u_met - v_met;
845  return omega;
846 }
847 
848 // Define w given u and v arrays and scalar omega (4th order)
849 /**
850  * Compute the vertical velocity w from the contravariant omega.
851  *
852  * @param[in] i x-index
853  * @param[in] j y-index
854  * @param[in] k z-index
855  * @param[in] omega Contravariant vertical velocity.
856  * @param[in] u_arr X-velocity array.
857  * @param[in] v_arr Y-velocity array.
858  * @param[in] mf_u X-velocity map factor.
859  * @param[in] mf_v Y-velocity map factor.
860  * @param[in] z_nd Nodal physical height field.
861  * @param[in] dxInv Inverse cell spacing.
862  * @return Vertical velocity w.
863  */
864 AMREX_GPU_DEVICE
865 AMREX_FORCE_INLINE
867 WFromOmega (int& i, int& j, int& k, amrex::Real omega,
868  const amrex::Array4<const amrex::Real>& u_arr,
869  const amrex::Array4<const amrex::Real>& v_arr,
870  const amrex::Array4<const amrex::Real>& mf_u,
871  const amrex::Array4<const amrex::Real>& mf_v,
872  const amrex::Array4<const amrex::Real>& z_nd,
873  const amrex::GpuArray<amrex::Real, AMREX_SPACEDIM>& dxInv)
874 {
875  // This is dh/dxi at hi and lo edges
876  amrex::Real z_x_p2 = Compute_Z_AtWFace(i+2,j,k,z_nd);
877  amrex::Real z_x_p1 = Compute_Z_AtWFace(i+1,j,k,z_nd);
878  amrex::Real z_x_m1 = Compute_Z_AtWFace(i-1,j,k,z_nd);
879  amrex::Real z_x_m2 = Compute_Z_AtWFace(i-2,j,k,z_nd);
880  amrex::Real met_xi = (amrex::Real(1.0/amrex::Real(12.0))*(z_x_m2 - z_x_p2)
881  + amrex::Real(8.0/amrex::Real(12.0))*(z_x_p1 - z_x_m1)) * dxInv[0];
882 
883  // This is dh/deta at hi and lo edges
884  amrex::Real z_y_p2 = Compute_Z_AtWFace(i,j+2,k,z_nd);
885  amrex::Real z_y_p1 = Compute_Z_AtWFace(i,j+1,k,z_nd);
886  amrex::Real z_y_m1 = Compute_Z_AtWFace(i,j-1,k,z_nd);
887  amrex::Real z_y_m2 = Compute_Z_AtWFace(i,j-2,k,z_nd);
888  amrex::Real met_eta = (amrex::Real(1.0/amrex::Real(12.0))*(z_y_m2 - z_y_p2)
889  + amrex::Real(8.0/amrex::Real(12.0))*(z_y_p1 - z_y_m1)) * dxInv[1];
890 
891  // Use extrapolation instead of interpolation if at the bottom boundary
892  amrex::Real u_hi = (k == 0) ? amrex::Real(1.5) * u_arr(i+1,j ,k ) - myhalf * u_arr(i+1,j ,k+1) :
893  myhalf * ( u_arr(i+1,j ,k-1) + u_arr(i+1,j ,k ) );
894  amrex::Real u_lo = (k == 0) ? amrex::Real(1.5) * u_arr(i ,j ,k ) - myhalf * u_arr(i ,j ,k+1) :
895  myhalf * ( u_arr(i ,j ,k-1) + u_arr(i ,j ,k ) );
896  amrex::Real mf_u_hi = mf_u(i+1,j,0);
897  amrex::Real mf_u_lo = mf_u(i ,j,0);
898 
899  amrex::Real v_hi = (k == 0) ? amrex::Real(1.5) * v_arr(i ,j+1,k ) - myhalf * v_arr(i ,j+1,k+1) :
900  myhalf * ( v_arr(i ,j+1,k-1) + v_arr(i ,j+1,k ) );
901  amrex::Real v_lo = (k == 0) ? amrex::Real(1.5) * v_arr(i ,j ,k ) - myhalf * v_arr(i ,j ,k+1) :
902  myhalf * ( v_arr(i ,j ,k-1) + v_arr(i ,j ,k ) );
903  amrex::Real mf_v_hi = mf_v(i,j+1,0);
904  amrex::Real mf_v_lo = mf_v(i,j ,0);
905 
906  amrex::Real u_met = met_xi * myhalf * ( u_hi*mf_u_hi + u_lo*mf_u_lo );
907  amrex::Real v_met = met_eta * myhalf * ( v_hi*mf_v_hi + v_lo*mf_v_lo );
908 
909  amrex::Real w = omega + u_met + v_met;
910  return w;
911 }
912 
913 //
914 // NOTE: 2nd order kept here for debugging purposes
915 //
916 
917 # if 0
918 // Define omega given u,v and w (2nd order)
919 /**
920  * Compute the contravariant vertical velocity omega from w (2nd order).
921  *
922  * @param[in] i x-index
923  * @param[in] j y-index
924  * @param[in] k z-index
925  * @param[in] w Vertical velocity.
926  * @param[in] u_arr X-velocity array.
927  * @param[in] v_arr Y-velocity array.
928  * @param[in] mf_u X-velocity map factor.
929  * @param[in] mf_v Y-velocity map factor.
930  * @param[in] z_nd Nodal physical height field.
931  * @param[in] dxInv Inverse cell spacing.
932  * @return Contravariant vertical velocity.
933  */
934 AMREX_GPU_DEVICE
935 AMREX_FORCE_INLINE
937 OmegaFromW (int& i, int& j, int& k, amrex::Real w,
938  const amrex::Array4<const amrex::Real>& u_arr,
939  const amrex::Array4<const amrex::Real>& v_arr,
940  const amrex::Array4<const amrex::Real>& mf_u,
941  const amrex::Array4<const amrex::Real>& mf_v,
942  const amrex::Array4<const amrex::Real>& z_nd,
943  const amrex::GpuArray<amrex::Real, AMREX_SPACEDIM>& dxInv)
944 {
945  // This is dh/dxi at hi and lo edges
946  amrex::Real z_x_h = Compute_Z_AtWFace(i+1,j,k,z_nd);
947  amrex::Real z_x_l = Compute_Z_AtWFace(i-1,j,k,z_nd);
948  amrex::Real met_xi = myhalf * (z_x_h - z_x_l) * dxInv[0];
949 
950  // This is dh/deta at hi and lo edges
951  amrex::Real z_y_h = Compute_Z_AtWFace(i,j+1,k,z_nd);
952  amrex::Real z_y_l = Compute_Z_AtWFace(i,j-1,k,z_nd);
953  amrex::Real met_eta = myhalf * (z_y_h - z_y_l) * dxInv[1];
954 
955  // Use extrapolation instead of interpolation if at the bottom boundary
956  amrex::Real u_hi = (k == 0) ? amrex::Real(1.5) * u_arr(i+1,j ,k ) - myhalf * u_arr(i+1,j ,k+1) :
957  myhalf * ( u_arr(i+1,j ,k-1) + u_arr(i+1,j ,k ) );
958  amrex::Real u_lo = (k == 0) ? amrex::Real(1.5) * u_arr(i ,j ,k ) - myhalf * u_arr(i ,j ,k+1) :
959  myhalf * ( u_arr(i ,j ,k-1) + u_arr(i ,j ,k ) );
960  amrex::Real mf_u_hi = mf_u(i+1,j,0);
961  amrex::Real mf_u_lo = mf_u(i ,j,0);
962 
963  amrex::Real v_hi = (k == 0) ? amrex::Real(1.5) * v_arr(i ,j+1,k ) - myhalf * v_arr(i ,j+1,k+1) :
964  myhalf * ( v_arr(i ,j+1,k-1) + v_arr(i ,j+1,k ) );
965  amrex::Real v_lo = (k == 0) ? amrex::Real(1.5) * v_arr(i ,j ,k ) - myhalf * v_arr(i ,j ,k+1) :
966  myhalf * ( v_arr(i ,j ,k-1) + v_arr(i ,j ,k ) );
967  amrex::Real mf_v_hi = mf_v(i,j+1,0);
968  amrex::Real mf_v_lo = mf_v(i,j ,0);
969 
970  amrex::Real u_met = met_xi * myhalf * ( u_hi*mf_u_hi + u_lo*mf_u_lo );
971  amrex::Real v_met = met_eta * myhalf * ( v_hi*mf_v_hi + v_lo*mf_v_lo );
972 
973  amrex::Real omega = w - u_met - v_met;
974  return omega;
975 }
976 
977 // Define w given u and v arrays and scalar omega (2nd order)
978 /**
979  * Compute the vertical velocity w from the contravariant omega (2nd order).
980  *
981  * @param[in] i x-index
982  * @param[in] j y-index
983  * @param[in] k z-index
984  * @param[in] omega Contravariant vertical velocity.
985  * @param[in] u_arr X-velocity array.
986  * @param[in] v_arr Y-velocity array.
987  * @param[in] mf_u X-velocity map factor.
988  * @param[in] mf_v Y-velocity map factor.
989  * @param[in] z_nd Nodal physical height field.
990  * @param[in] dxInv Inverse cell spacing.
991  * @return Vertical velocity w.
992  */
993 AMREX_GPU_DEVICE
994 AMREX_FORCE_INLINE
996 WFromOmega (int& i, int& j, int& k, amrex::Real omega,
997  const amrex::Array4<const amrex::Real>& u_arr,
998  const amrex::Array4<const amrex::Real>& v_arr,
999  const amrex::Array4<const amrex::Real>& mf_u,
1000  const amrex::Array4<const amrex::Real>& mf_v,
1001  const amrex::Array4<const amrex::Real>& z_nd,
1002  const amrex::GpuArray<amrex::Real, AMREX_SPACEDIM>& dxInv)
1003 {
1004  // This is dh/dxi at hi and lo edges
1005  amrex::Real z_x_h = Compute_Z_AtWFace(i+1,j,k,z_nd);
1006  amrex::Real z_x_l = Compute_Z_AtWFace(i-1,j,k,z_nd);
1007  amrex::Real met_xi = myhalf * (z_x_h - z_x_l) * dxInv[0];
1008 
1009  // This is dh/deta at hi and lo edges
1010  amrex::Real z_y_h = Compute_Z_AtWFace(i,j+1,k,z_nd);
1011  amrex::Real z_y_l = Compute_Z_AtWFace(i,j-1,k,z_nd);
1012  amrex::Real met_eta = myhalf * (z_y_h - z_y_l) * dxInv[1];
1013 
1014  // Use extrapolation instead of interpolation if at the bottom boundary
1015  amrex::Real u_hi = (k == 0) ? amrex::Real(1.5) * u_arr(i+1,j ,k ) - myhalf * u_arr(i+1,j ,k+1) :
1016  myhalf * ( u_arr(i+1,j ,k-1) + u_arr(i+1,j ,k ) );
1017  amrex::Real u_lo = (k == 0) ? amrex::Real(1.5) * u_arr(i ,j ,k ) - myhalf * u_arr(i ,j ,k+1) :
1018  myhalf * ( u_arr(i ,j ,k-1) + u_arr(i ,j ,k ) );
1019  amrex::Real mf_u_hi = mf_u(i+1,j,0);
1020  amrex::Real mf_u_lo = mf_u(i ,j,0);
1021 
1022  amrex::Real v_hi = (k == 0) ? amrex::Real(1.5) * v_arr(i ,j+1,k ) - myhalf * v_arr(i ,j+1,k+1) :
1023  myhalf * ( v_arr(i ,j+1,k-1) + v_arr(i ,j+1,k ) );
1024  amrex::Real v_lo = (k == 0) ? amrex::Real(1.5) * v_arr(i ,j ,k ) - myhalf * v_arr(i ,j ,k+1) :
1025  myhalf * ( v_arr(i ,j ,k-1) + v_arr(i ,j ,k ) );
1026  amrex::Real mf_v_hi = mf_v(i,j+1,0);
1027  amrex::Real mf_v_lo = mf_v(i,j ,0);
1028 
1029  amrex::Real u_met = met_xi * myhalf * ( u_hi*mf_u_hi + u_lo*mf_u_lo );
1030  amrex::Real v_met = met_eta * myhalf * ( v_hi*mf_v_hi + v_lo*mf_v_lo );
1031 
1032  amrex::Real w = omega + u_met + v_met;
1033  return w;
1034 }
1035 #endif
1036 
1037 
1038 //*****************************************************************************************
1039 // Rotate scalar flux vector and stress tensor for MOST
1040 //*****************************************************************************************
1041 /**
1042  * Rotate a scalar flux vector into terrain-following coordinates.
1043  *
1044  * @param[in] i x-index
1045  * @param[in] j y-index
1046  * @param[in] klo z-index
1047  * @param[in] flux Scalar flux value.
1048  * @param[in] dxInv Inverse cell spacing.
1049  * @param[in] zphys_arr Physical height field.
1050  * @param[out] phi1_arr Rotated flux component 1.
1051  * @param[out] phi2_arr Rotated flux component 2.
1052  * @param[out] phi3_arr Rotated flux component 3.
1053  */
1054 AMREX_GPU_DEVICE
1055 AMREX_FORCE_INLINE
1056 void
1057 rotate_scalar_flux (const int& i,
1058  const int& j,
1059  const int& klo,
1060  const int& /*dir*/,
1061  const amrex::Real& flux,
1062  const amrex::GpuArray<amrex::Real, AMREX_SPACEDIM>& dxInv,
1063  const amrex::Array4<const amrex::Real>& zphys_arr,
1064  const amrex::Array4<amrex::Real>& phi1_arr,
1065  const amrex::Array4<amrex::Real>& phi2_arr,
1066  const amrex::Array4<amrex::Real>& phi3_arr)
1067 {
1068  amrex::Real h_xi = Compute_h_xi_AtCellCenter(i, j, klo, dxInv, zphys_arr);
1069  amrex::Real h_eta = Compute_h_eta_AtCellCenter(i, j, klo, dxInv, zphys_arr);
1070  amrex::Real InvNorm = one / std::sqrt(one + h_xi*h_xi + h_eta*h_eta);
1071  phi1_arr(i,j,klo) = -h_xi * flux * InvNorm;
1072  phi2_arr(i,j,klo) = -h_eta * flux * InvNorm;
1073  phi3_arr(i,j,klo) = flux * InvNorm;
1074 }
1075 
1076 /**
1077  * Rotate the stress tensor for the MOST model.
1078  *
1079  * @param[in] i x-index
1080  * @param[in] j y-index
1081  * @param[in] klo z-index
1082  * @param[in] flux Flux value used for rotation.
1083  * @param[in] dxInv Inverse cell spacing.
1084  * @param[in] zphys_arr Physical height field.
1085  * @param[in] u_arr X-velocity array.
1086  * @param[in] v_arr Y-velocity array.
1087  * @param[in] w_arr Z-velocity array.
1088  * @param[out] tau11_arr Stress component tau11.
1089  * @param[out] tau22_arr Stress component tau22.
1090  * @param[out] tau33_arr Stress component tau33.
1091  * @param[out] tau12_arr Stress component tau12.
1092  * @param[out] tau21_arr Stress component tau21.
1093  * @param[out] tau13_arr Stress component tau13.
1094  * @param[out] tau31_arr Stress component tau31.
1095  * @param[out] tau23_arr Stress component tau23.
1096  * @param[out] tau32_arr Stress component tau32.
1097  */
1098 AMREX_GPU_DEVICE
1099 AMREX_FORCE_INLINE
1100 void
1101 rotate_stress_tensor (const int& i,
1102  const int& j,
1103  const int& klo,
1104  const int& /*dir*/,
1105  const amrex::Real& flux,
1106  const amrex::GpuArray<amrex::Real, AMREX_SPACEDIM>& dxInv,
1107  const amrex::Array4<const amrex::Real>& zphys_arr,
1108  const amrex::Array4<const amrex::Real>& u_arr,
1109  const amrex::Array4<const amrex::Real>& v_arr,
1110  const amrex::Array4<const amrex::Real>& w_arr,
1111  const amrex::Array4<amrex::Real>& /*tau11_arr*/,
1112  const amrex::Array4<amrex::Real>& /*tau22_arr*/,
1113  const amrex::Array4<amrex::Real>& /*tau33_arr*/,
1114  const amrex::Array4<amrex::Real>& /*tau12_arr*/,
1115  const amrex::Array4<amrex::Real>& /*tau21_arr*/,
1116  const amrex::Array4<amrex::Real>& tau13_arr,
1117  const amrex::Array4<amrex::Real>& tau31_arr,
1118  const amrex::Array4<amrex::Real>& tau23_arr,
1119  const amrex::Array4<amrex::Real>& tau32_arr)
1120 {
1121  // Unit-normal vector
1122  amrex::Array1D<amrex::Real,0,2> n_hat;
1123 
1124  // Unit-tangent vectors
1125  amrex::Array1D<amrex::Real,0,2> u_t_hat;
1126 
1127  // Final basis vector for right-hand coord sys
1128  amrex::Array1D<amrex::Real,0,2> a_hat;
1129 
1130  // Rotation matrix
1131  amrex::Array2D<amrex::Real,0,2,0,2> R_mat;
1132 
1133  // Metric data
1134  amrex::Real h_xi = Compute_h_xi_AtIface(i, j, klo, dxInv, zphys_arr);
1135  amrex::Real h_eta = Compute_h_eta_AtIface(i, j, klo, dxInv, zphys_arr);
1136  amrex::Real h_zeta = Compute_h_zeta_AtIface(i, j, klo, dxInv, zphys_arr);
1137 
1138  // Populate the inward normal vector
1139  amrex::Real Inormn = one/std::sqrt(one + h_xi*h_xi + h_eta*h_eta);
1140  n_hat(0) = -Inormn*h_xi; n_hat(1) = -Inormn*h_eta; n_hat(2) = Inormn;
1141 
1142  // Populate the u_t vector (u_t = u - (u \cdot n)n)
1143  amrex::Real u = u_arr(i,j,klo);
1144  amrex::Real v = fourth * ( v_arr(i ,j,klo) + v_arr(i ,j+1,klo)
1145  + v_arr(i-1,j,klo) + v_arr(i-1,j+1,klo) );
1146  amrex::Real w = myhalf * ( w_arr(i ,j,klo) + w_arr(i-1,j ,klo) );
1147  amrex::Real u_dot_n = n_hat(0)*u + n_hat(1)*v + n_hat(2)*w;
1148  u_t_hat(0) = u - u_dot_n*n_hat(0);
1149  u_t_hat(1) = v - u_dot_n*n_hat(1);
1150  u_t_hat(2) = w - u_dot_n*n_hat(2);
1151  amrex::Real Norm_u_t = u_t_hat(0)*u_t_hat(0)
1152  + u_t_hat(1)*u_t_hat(1)
1153  + u_t_hat(2)*u_t_hat(2);
1154 
1155  // NOTE: the direction of the tangential velocity is undefined when that
1156  // velocity vanishes (a quiescent surface cell, or flow normal to the
1157  // terrain), so we cannot normalize. Leaving u_t_hat as the zero vector
1158  // is the only rotation-invariant choice, and it is the right limit for
1159  // a quiescent cell since the flux vanishes with the surface wind too.
1160  amrex::Real Inorm_u_t = (Norm_u_t > zero) ? one/std::sqrt(Norm_u_t) : zero;
1161  for (int icol(0); icol<3; ++icol) {
1162  u_t_hat(icol) *= Inorm_u_t;
1163  }
1164 
1165  // Populate the a_hat = n_hat X u_t_hat vector
1166  a_hat(0) = n_hat(1)*u_t_hat(2) - n_hat(2)*u_t_hat(1);
1167  a_hat(1) = -(n_hat(0)*u_t_hat(2) - n_hat(2)*u_t_hat(0));
1168  a_hat(2) = n_hat(0)*u_t_hat(1) - n_hat(1)*u_t_hat(0);
1169 
1170  // Copy column vectors into R_mat
1171  // NOTE: basis vectors form rows of R_mat
1172  int icol = 0;
1173  for (int jrow(0); jrow<3; ++jrow) {
1174  R_mat(icol,jrow) = u_t_hat(jrow);
1175  }
1176  icol = 1;
1177  for (int jrow(0); jrow<3; ++jrow) {
1178  R_mat(icol,jrow) = a_hat(jrow);
1179  }
1180  icol = 2;
1181  for (int jrow(0); jrow<3; ++jrow) {
1182  R_mat(icol,jrow) = n_hat(jrow);
1183  }
1184 
1185  // Body-fixed stresses
1186  amrex::Real T11 = two*R_mat(0,0)*R_mat(2,0)*flux;
1187  amrex::Real T22 = two*R_mat(0,1)*R_mat(2,1)*flux;
1188  //amrex::Real T33 = two*R_mat(0,2)*R_mat(2,2)*flux;
1189  amrex::Real T12 = (R_mat(0,0)*R_mat(2,1) + R_mat(2,0)*R_mat(0,1))*flux;
1190  amrex::Real T13 = (R_mat(0,0)*R_mat(2,2) + R_mat(0,2)*R_mat(2,0))*flux;
1191  amrex::Real T23 = (R_mat(0,2)*R_mat(2,1) + R_mat(0,1)*R_mat(2,2))*flux;
1192 
1193  // Populate the stress tensor (apply JT)
1194  // NOTE: We cannot set the stresses that do not live at the
1195  // bottom face --- e.g., tau11/22/33/12/21.
1196  tau13_arr(i,j,klo) = -h_xi*T11 - h_eta*T12 + T13;
1197  tau31_arr(i,j,klo) = h_zeta*T13;
1198 
1199  tau23_arr(i,j,klo) = -h_xi*T12 - h_eta*T22 + T23;
1200  tau32_arr(i,j,klo) = h_zeta*T23;
1201 }
1202 #endif
amrex::GpuArray< Real, AMREX_SPACEDIM > dxInv
Definition: ERF_InitCustomPertVels_ParticleTests.H:17
const int klo
Definition: ERF_InitCustomPert_KE.H:9
Dimensionless numeric literals and pure mathematical constants.
constexpr amrex::Real two
Definition: ERF_NumericalConstants.H:38
constexpr amrex::Real one
Definition: ERF_NumericalConstants.H:37
constexpr amrex::Real fourth
Definition: ERF_NumericalConstants.H:42
constexpr amrex::Real zero
Definition: ERF_NumericalConstants.H:36
constexpr amrex::Real myhalf
Definition: ERF_NumericalConstants.H:41
Real w
Definition: ERF_Plotfile2DInterpolator.cpp:23
amrex::Real Real
Definition: ERF_ShocInterface.H:19
AMREX_GPU_DEVICE AMREX_FORCE_INLINE amrex::Real OmegaFromW(int &i, int &j, int &k, amrex::Real w, const amrex::Array4< const amrex::Real > &u_arr, const amrex::Array4< const amrex::Real > &v_arr, const amrex::Array4< const amrex::Real > &mf_u, const amrex::Array4< const amrex::Real > &mf_v, const amrex::Array4< const amrex::Real > &z_nd, const amrex::GpuArray< amrex::Real, AMREX_SPACEDIM > &dxInv)
Definition: ERF_TerrainMetrics.H:802
AMREX_GPU_DEVICE AMREX_FORCE_INLINE amrex::Real Compute_h_eta_AtEdgeCenterJ(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:620
AMREX_GPU_DEVICE AMREX_FORCE_INLINE amrex::Real Compute_h_xi_AtEdgeCenterK(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:519
void init_zlevels(amrex::Vector< amrex::Vector< amrex::Real >> &zlevels_stag, amrex::Vector< amrex::Vector< amrex::Real >> &stretched_dz_h, amrex::Vector< amrex::Gpu::DeviceVector< amrex::Real >> &stretched_dz_d, amrex::Vector< amrex::Geometry > const &geom, amrex::Vector< amrex::IntVect > const &ref_ratio, const amrex::Real grid_stretching_ratio, const amrex::Real dz0)
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real Compute_h_xi_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:444
AMREX_GPU_DEVICE AMREX_FORCE_INLINE amrex::Real Compute_h_xi_AtEdgeCenterJ(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:595
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real Compute_h_eta_AtJface(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:396
AMREX_GPU_DEVICE AMREX_FORCE_INLINE amrex::Real Compute_h_zeta_AtEdgeCenterJ(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:571
AMREX_GPU_DEVICE AMREX_FORCE_INLINE void rotate_scalar_flux(const int &i, const int &j, const int &klo, const int &, const amrex::Real &flux, const amrex::GpuArray< amrex::Real, AMREX_SPACEDIM > &dxInv, const amrex::Array4< const amrex::Real > &zphys_arr, const amrex::Array4< amrex::Real > &phi1_arr, const amrex::Array4< amrex::Real > &phi2_arr, const amrex::Array4< amrex::Real > &phi3_arr)
Definition: ERF_TerrainMetrics.H:1057
AMREX_GPU_DEVICE AMREX_FORCE_INLINE amrex::Real Compute_h_zeta_AtEdgeCenterK(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:496
AMREX_GPU_DEVICE AMREX_FORCE_INLINE amrex::Real Compute_h_zeta_AtEdgeCenterI(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:645
void validate_flat_terrain(int lev, const amrex::MultiFab &z_phys_nd, const amrex::Vector< amrex::Real > &z_levels_h)
FineTerrain
Definition: ERF_TerrainMetrics.H:66
@ Transform
add the fine terrain as a correction that decays with height
@ None
caller has not prepared a fine mesh from the coarse level
@ Interpolate
use the coordinates interpolated from the coarse level as-is
void validate_flat_top(int lev, const amrex::Geometry &geom, const amrex::MultiFab &z_phys_nd)
AMREX_GPU_DEVICE AMREX_FORCE_INLINE amrex::Real Compute_Z_AtCellCenter(const int &i, const int &j, const int &k, const amrex::Array4< const amrex::Real > &z_nd)
Definition: ERF_TerrainMetrics.H:716
FineTerrain which_fine_terrain()
Definition: ERF_TerrainMetrics.cpp:528
void init_which_terrain_grid(int lev, const amrex::Geometry &geom, amrex::MultiFab &z_phys_nd, amrex::Vector< amrex::Real > const &z_levels_h, FineTerrain fine_terrain=FineTerrain::None, amrex::MultiFab const *z_phys_interp=nullptr)
amrex::BoxArray join_boxes_stacked_in_z(const amrex::BoxArray &ba)
void init_fine_terrain_grid(int lev, const amrex::Geometry &geom, amrex::MultiFab &z_phys_nd, amrex::Vector< amrex::Real > const &z_levels_h, FineTerrain fine_terrain, amrex::MultiFab const *z_phys_interp)
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real Compute_h_xi_AtCellCenter(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:226
AMREX_GPU_DEVICE AMREX_FORCE_INLINE amrex::Real Compute_h_zeta_AtIface(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:280
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real Compute_h_eta_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:467
AMREX_GPU_HOST_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:420
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real Compute_Zrel_AtCellCenter(const int &i, const int &j, const int &k, const amrex::Array4< const amrex::Real > &z_nd)
Definition: ERF_TerrainMetrics.H:762
AMREX_GPU_DEVICE AMREX_FORCE_INLINE amrex::Real Compute_h_xi_AtJface(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:373
void update_stretched_dz(int lev, amrex::Vector< amrex::Vector< amrex::Real >> const &zlevels_stag, amrex::Vector< amrex::Vector< amrex::Real >> &stretched_dz_h, amrex::Vector< amrex::Gpu::DeviceVector< amrex::Real >> &stretched_dz_d)
void make_terrain_fitted_coords(int lev, const amrex::Geometry &geom, amrex::MultiFab &z_phys_nd, amrex::Vector< amrex::Real > const &z_levels_h, amrex::GpuArray< ERF_BC, AMREX_SPACEDIM *2 > &phys_bc_type, FineTerrain fine_terrain=FineTerrain::None, amrex::MultiFab const *z_phys_interp=nullptr)
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real Compute_Z_AtWFace(const int &i, const int &j, const int &k, const amrex::Array4< const amrex::Real > &z_nd)
Definition: ERF_TerrainMetrics.H:740
amrex::Real get_dzmin_terrain(amrex::MultiFab &z_phys_nd)
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real Compute_h_eta_AtCellCenter(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:251
AMREX_GPU_DEVICE AMREX_FORCE_INLINE amrex::Real Compute_h_eta_AtEdgeCenterK(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:544
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real Compute_h_zeta_AtCellCenter(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:201
AMREX_GPU_DEVICE AMREX_FORCE_INLINE amrex::Real Compute_h_eta_AtIface(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:327
AMREX_GPU_DEVICE AMREX_FORCE_INLINE amrex::Real Compute_h_xi_AtEdgeCenterI(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:669
AMREX_GPU_DEVICE AMREX_FORCE_INLINE amrex::Real Compute_h_zeta_AtJface(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:350
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real Compute_h_xi_AtIface(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:303
AMREX_GPU_DEVICE AMREX_FORCE_INLINE void rotate_stress_tensor(const int &i, const int &j, const int &klo, const int &, const amrex::Real &flux, const amrex::GpuArray< amrex::Real, AMREX_SPACEDIM > &dxInv, const amrex::Array4< const amrex::Real > &zphys_arr, const amrex::Array4< const amrex::Real > &u_arr, const amrex::Array4< const amrex::Real > &v_arr, const amrex::Array4< const amrex::Real > &w_arr, const amrex::Array4< amrex::Real > &, const amrex::Array4< amrex::Real > &, const amrex::Array4< amrex::Real > &, const amrex::Array4< amrex::Real > &, const amrex::Array4< amrex::Real > &, const amrex::Array4< amrex::Real > &tau13_arr, const amrex::Array4< amrex::Real > &tau31_arr, const amrex::Array4< amrex::Real > &tau23_arr, const amrex::Array4< amrex::Real > &tau32_arr)
Definition: ERF_TerrainMetrics.H:1101
AMREX_GPU_DEVICE AMREX_FORCE_INLINE amrex::Real Compute_h_eta_AtEdgeCenterI(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:692
void init_default_zphys(int lev, const amrex::Geometry &geom, amrex::MultiFab &z_phys_nd, amrex::MultiFab &z_phys_cc, amrex::Real z_offset=zero)
AMREX_GPU_DEVICE AMREX_FORCE_INLINE amrex::Real WFromOmega(int &i, int &j, int &k, amrex::Real omega, const amrex::Array4< const amrex::Real > &u_arr, const amrex::Array4< const amrex::Real > &v_arr, const amrex::Array4< const amrex::Real > &mf_u, const amrex::Array4< const amrex::Real > &mf_v, const amrex::Array4< const amrex::Real > &z_nd, const amrex::GpuArray< amrex::Real, AMREX_SPACEDIM > &dxInv)
Definition: ERF_TerrainMetrics.H:867
@ omega
Definition: ERF_Morrison.H:57