ERF
Energy Research and Forecasting: An Atmospheric Modeling Code
ERF_EBIFTerrain.H
Go to the documentation of this file.
1 #ifndef ERF_TERRAIN_IF_H_
2 #define ERF_TERRAIN_IF_H_
3 
4 #include <AMReX_Array.H>
5 #include <AMReX_EB2_IF_Base.H>
6 
7 #include <cmath>
8 #include <algorithm>
9 
10 // For all implicit functions, >0: body; =0: boundary; <0: fluid
11 
12 class TerrainIF
13  : amrex::GPUable
14 {
15 public:
16 
17  TerrainIF (amrex::FArrayBox const& a_z_terrain, amrex::Geometry const& a_geom,
18  amrex::Gpu::DeviceVector<amrex::Real>& a_dz_stretched)
19  : terr_arr(a_z_terrain.const_array()),
20  dz_s(a_dz_stretched.data()),
21  dx(a_geom.CellSize(0)),
22  dy(a_geom.CellSize(1)),
23  dz(a_geom.CellSize(2)),
24  prob_lo_x(a_geom.ProbLo(0)),
25  prob_lo_y(a_geom.ProbLo(1)),
26  prob_lo_z(a_geom.ProbLo(2))
27  {}
28 
29  AMREX_GPU_HOST_DEVICE inline
30  amrex::Real operator() (AMREX_D_DECL(amrex::Real x, amrex::Real y, amrex::Real z))
31  const noexcept
32  {
33  const int i1 = static_cast<int>(std::floor((x-prob_lo_x) / dx));
34  const int j1 = static_cast<int>(std::floor((y-prob_lo_y) / dy));
35  const int k1 = static_cast<int>(std::floor((z-prob_lo_z) / dz));
36 
37  const int i2 = i1+1;
38  const int j2 = j1+1;
39 
40  amrex::Real x1 = prob_lo_x + i1*dx;
41  amrex::Real y1 = prob_lo_y + j1*dy;
42  amrex::Real z1 = prob_lo_z + k1*dz;
43 
44  amrex::Real x2 = prob_lo_x + i2*dx;
45  amrex::Real y2 = prob_lo_y + j2*dy;
46 
47  amrex::Real remainder_z = (z - z1)/dz;
48 
49  amrex::Real z_stretched = prob_lo_z;
50 
51  for (int kk = 0; kk < k1; ++kk) {
52  z_stretched += dz_s[kk];
53  }
54  z_stretched += remainder_z * dz_s[k1];
55 
56  // Do bilinear interpolation of the terrain surface
57  amrex::Real denom = (x2-x1)*(y2-y1);
58  amrex::Real w_11 = (x2-x)*(y2-y)/denom;
59  amrex::Real w_12 = (x2-x)*(y-y1)/denom;
60  amrex::Real w_21 = (x-x1)*(y2-y)/denom;
61  amrex::Real w_22 = (x-x1)*(y-y1)/denom;
62 
63  amrex::Real terr_z = w_11*terr_arr(i1,j1,0) + w_12*terr_arr(i1,j2,0) + w_21*terr_arr(i2,j1,0) + w_22*terr_arr(i2,j2,0);
64 
65  return -(z_stretched - terr_z);
66  }
67 
68  AMREX_GPU_HOST_DEVICE
69  inline amrex::Real operator() (const amrex::RealArray& p) const noexcept
70  {
71  return this->operator() (AMREX_D_DECL(p[0], p[1], p[2]));
72  }
73 
74 protected:
75  amrex::Array4<amrex::Real const> terr_arr;
76  amrex::Real const* dz_s;
77  amrex::Real dx, dy, dz;
78  amrex::Real prob_lo_x, prob_lo_y, prob_lo_z;
79 };
80 
81 #endif
Definition: ERF_EBIFTerrain.H:14
amrex::Real prob_lo_x
Definition: ERF_EBIFTerrain.H:78
amrex::Real dy
Definition: ERF_EBIFTerrain.H:77
TerrainIF(amrex::FArrayBox const &a_z_terrain, amrex::Geometry const &a_geom, amrex::Gpu::DeviceVector< amrex::Real > &a_dz_stretched)
Definition: ERF_EBIFTerrain.H:17
amrex::Array4< amrex::Real const > terr_arr
Definition: ERF_EBIFTerrain.H:75
amrex::Real const * dz_s
Definition: ERF_EBIFTerrain.H:76
amrex::Real prob_lo_y
Definition: ERF_EBIFTerrain.H:78
amrex::Real dx
Definition: ERF_EBIFTerrain.H:77
amrex::Real prob_lo_z
Definition: ERF_EBIFTerrain.H:78
AMREX_GPU_HOST_DEVICE amrex::Real operator()(AMREX_D_DECL(amrex::Real x, amrex::Real y, amrex::Real z)) const noexcept
Definition: ERF_EBIFTerrain.H:30
amrex::Real dz
Definition: ERF_EBIFTerrain.H:77