ERF
Energy Research and Forecasting: An Atmospheric Modeling Code
ERF_Interpolation_Bilinear.H File Reference
#include "AMReX_GpuPrint.H"
#include "ERF_DataStruct.H"
Include dependency graph for ERF_Interpolation_Bilinear.H:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

AMREX_FORCE_INLINE AMREX_GPU_HOST_DEVICE int get_single_index (int i, int j, int k, int nx, int ny)
 
AMREX_FORCE_INLINE AMREX_GPU_HOST_DEVICE int clamp_interp_index (int idx, int npts)
 
AMREX_FORCE_INLINE AMREX_GPU_HOST_DEVICE int get_interp_index (amrex::Real x, amrex::Real x0, amrex::Real dx, int npts)
 
AMREX_FORCE_INLINE AMREX_GPU_HOST_DEVICE amrex::Real get_interp_weight (amrex::Real x, amrex::Real xlo, amrex::Real xhi)
 
AMREX_FORCE_INLINE AMREX_GPU_HOST_DEVICE void bilinear_interpolation (const amrex::Real *xvec, const amrex::Real *yvec, const amrex::Real *zvec, const amrex::Real dxvec, const amrex::Real dyvec, const int nx, const int ny, const int nz, const amrex::Real x, const amrex::Real y, const amrex::Real z, const amrex::Real *varvec, amrex::Real &tmp_var)
 
AMREX_GPU_DEVICE amrex::Real interpolate_from_coarse (const amrex::Array4< const amrex::Real > &crse, int n, amrex::Real x, amrex::Real y, amrex::Real z, const amrex::Real *prob_lo_crse, const amrex::Real *dx_crse)
 
AMREX_FORCE_INLINE AMREX_GPU_HOST_DEVICE void bilinear_interpolation_2d (const amrex::Real *xvec, const amrex::Real *yvec, const amrex::Real dxvec, const amrex::Real dyvec, const int nx, const int ny, amrex::Real x, amrex::Real y, const amrex::Real *varvec, amrex::Real &tmp_var)
 

Function Documentation

◆ bilinear_interpolation()

AMREX_FORCE_INLINE AMREX_GPU_HOST_DEVICE void bilinear_interpolation ( const amrex::Real *  xvec,
const amrex::Real *  yvec,
const amrex::Real *  zvec,
const amrex::Real  dxvec,
const amrex::Real  dyvec,
const int  nx,
const int  ny,
const int  nz,
const amrex::Real  x,
const amrex::Real  y,
const amrex::Real  z,
const amrex::Real *  varvec,
amrex::Real &  tmp_var 
)
61 {
62 
63  // Points outside the table, including heights below zvec[0], take the value at the
64  // nearest table edge; a negative z inside the table is interpolated like any other
65  amrex::Real x_interp = x;
66  amrex::Real y_interp = y;
67  amrex::Real z_interp = z;
68 
69  if (x_interp < xvec[0]) x_interp = xvec[0];
70  if (x_interp > xvec[nx-1]) x_interp = xvec[nx-1];
71 
72  if (y_interp < yvec[0]) y_interp = yvec[0];
73  if (y_interp > yvec[ny-1]) y_interp = yvec[ny-1];
74 
75  if (z_interp < zvec[0]) z_interp = zvec[0];
76  if (z_interp > zvec[nz-1]) z_interp = zvec[nz-1];
77 
78  int iloc = get_interp_index(x_interp, xvec[0], dxvec, nx);
79  int jloc = get_interp_index(y_interp, yvec[0], dyvec, ny);
80 
81  int kloc = 0;
82  if (nz > 1) {
83  kloc = nz - 2;
84  for (int k = 1; k < nz; ++k) {
85  if (zvec[k] >= z_interp) {
86  kloc = k - 1;
87  break;
88  }
89  }
90  }
91 
92  int ihi = (nx > 1) ? iloc + 1 : iloc;
93  int jhi = (ny > 1) ? jloc + 1 : jloc;
94  int khi = (nz > 1) ? kloc + 1 : kloc;
95 
96  amrex::Real xlo = xvec[iloc];
97  amrex::Real ylo = yvec[jloc];
98  amrex::Real zlo = zvec[kloc];
99 
100  amrex::Real w_x = get_interp_weight(x_interp, xlo, xvec[ihi]);
101  amrex::Real w_y = get_interp_weight(y_interp, ylo, yvec[jhi]);
102  amrex::Real w_z = get_interp_weight(z_interp, zlo, zvec[khi]);
103 
104  int ind0 = get_single_index(iloc,jloc,kloc,nx,ny);
105  int ind1 = get_single_index(ihi ,jloc,kloc,nx,ny);
106  int ind2 = get_single_index(ihi ,jhi ,kloc,nx,ny);
107  int ind3 = get_single_index(iloc,jhi ,kloc,nx,ny);
108  int ind4 = get_single_index(iloc,jloc,khi ,nx,ny);
109  int ind5 = get_single_index(ihi ,jloc,khi ,nx,ny);
110  int ind6 = get_single_index(ihi ,jhi ,khi ,nx,ny);
111  int ind7 = get_single_index(iloc,jhi ,khi ,nx,ny);
112 
113  tmp_var = (1-w_x)*(1-w_y)*(1-w_z)*varvec[ind0] + w_x*(1-w_y)*(1-w_z)*varvec[ind1] +
114  w_x*w_y*(1-w_z)*varvec[ind2] + (1-w_x)*w_y*(1-w_z)*varvec[ind3] +
115  (1-w_x)*(1-w_y)*w_z*varvec[ind4] + w_x*(1-w_y)*w_z*varvec[ind5] +
116  w_x*w_y*w_z*varvec[ind6] + (1-w_x)*w_y*w_z*varvec[ind7];
117 
118  //std::cout << "Variable value is " << tmp_var << "\n";
119 }
const int nx
Definition: ERF_InitCustomPertVels_CloudChamber.H:14
const int ny
Definition: ERF_InitCustomPertVels_CloudChamber.H:15
const int khi
Definition: ERF_InitCustomPert_Bubble.H:25
AMREX_FORCE_INLINE AMREX_GPU_HOST_DEVICE int get_interp_index(amrex::Real x, amrex::Real x0, amrex::Real dx, int npts)
Definition: ERF_Interpolation_Bilinear.H:37
AMREX_FORCE_INLINE AMREX_GPU_HOST_DEVICE int get_single_index(int i, int j, int k, int nx, int ny)
Definition: ERF_Interpolation_Bilinear.H:14
AMREX_FORCE_INLINE AMREX_GPU_HOST_DEVICE amrex::Real get_interp_weight(amrex::Real x, amrex::Real xlo, amrex::Real xhi)
Definition: ERF_Interpolation_Bilinear.H:48
amrex::Real Real
Definition: ERF_ShocInterface.H:19

Referenced by ERF::FillForecastStateMultiFabs().

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

◆ bilinear_interpolation_2d()

AMREX_FORCE_INLINE AMREX_GPU_HOST_DEVICE void bilinear_interpolation_2d ( const amrex::Real *  xvec,
const amrex::Real *  yvec,
const amrex::Real  dxvec,
const amrex::Real  dyvec,
const int  nx,
const int  ny,
amrex::Real  x,
amrex::Real  y,
const amrex::Real *  varvec,
amrex::Real &  tmp_var 
)
172 {
173  if(x<xvec[0]) {
174  x = xvec[0];
175  }
176  if(x>xvec[nx-1]) {
177  x = xvec[nx-1];
178  }
179 
180  if(y<yvec[0]) {
181  y = yvec[0];
182  }
183  if(y>yvec[ny-1]) {
184  y = yvec[ny-1];
185  }
186 
187  int iloc = get_interp_index(x, xvec[0], dxvec, nx);
188  int jloc = get_interp_index(y, yvec[0], dyvec, ny);
189  int ihi = (nx > 1) ? iloc + 1 : iloc;
190  int jhi = (ny > 1) ? jloc + 1 : jloc;
191 
192  amrex::Real xlo = xvec[iloc];
193  amrex::Real ylo = yvec[jloc];
194 
195  amrex::Real w_x = get_interp_weight(x, xlo, xvec[ihi]);
196  amrex::Real w_y = get_interp_weight(y, ylo, yvec[jhi]);
197 
198  int ind0 = get_single_index(iloc,jloc,0,nx,ny);
199  int ind1 = get_single_index(ihi ,jloc,0,nx,ny);
200  int ind2 = get_single_index(ihi ,jhi ,0,nx,ny);
201  int ind3 = get_single_index(iloc,jhi ,0,nx,ny);
202 
203  tmp_var = (1-w_x)*(1-w_y)*varvec[ind0] + w_x*(1-w_y)*varvec[ind1] +
204  w_x*w_y*varvec[ind2] + (1-w_x)*w_y*varvec[ind3];
205 
206  //std::cout << "Variable value is " << tmp_var << "\n";
207 }

Referenced by ERF::FillSurfaceStateMultiFabs().

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

◆ clamp_interp_index()

AMREX_FORCE_INLINE AMREX_GPU_HOST_DEVICE int clamp_interp_index ( int  idx,
int  npts 
)
25 {
26  if (npts <= 1) {
27  return 0;
28  }
29 
30  return amrex::max(0, amrex::min(idx, npts - 2));
31 }
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE int idx(int i, int j, int k, int nx, int ny)
Definition: ERF_InitForEnsemble.cpp:404

Referenced by get_interp_index().

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

◆ get_interp_index()

AMREX_FORCE_INLINE AMREX_GPU_HOST_DEVICE int get_interp_index ( amrex::Real  x,
amrex::Real  x0,
amrex::Real  dx,
int  npts 
)
38 {
39  if (npts <= 1) {
40  return 0;
41  }
42 
43  return clamp_interp_index(static_cast<int>(std::floor((x - x0) / dx)), npts);
44 }
const Real dx
Definition: ERF_InitCustomPert_ABL.H:44
AMREX_FORCE_INLINE AMREX_GPU_HOST_DEVICE int clamp_interp_index(int idx, int npts)
Definition: ERF_Interpolation_Bilinear.H:24

Referenced by bilinear_interpolation(), and bilinear_interpolation_2d().

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

◆ get_interp_weight()

AMREX_FORCE_INLINE AMREX_GPU_HOST_DEVICE amrex::Real get_interp_weight ( amrex::Real  x,
amrex::Real  xlo,
amrex::Real  xhi 
)
49 {
50  return (xhi > xlo) ? (x - xlo) / (xhi - xlo) : amrex::Real(0);
51 }

Referenced by bilinear_interpolation(), and bilinear_interpolation_2d().

Here is the caller graph for this function:

◆ get_single_index()

AMREX_FORCE_INLINE AMREX_GPU_HOST_DEVICE int get_single_index ( int  i,
int  j,
int  k,
int  nx,
int  ny 
)

Bilinear interpolation routines. There are different versions for different scenarios that take in a different argument list

16 {
17 
18  int si = k*nx*ny + j*nx + i;
19  return si;
20 }

Referenced by bilinear_interpolation(), and bilinear_interpolation_2d().

Here is the caller graph for this function:

◆ interpolate_from_coarse()

AMREX_GPU_DEVICE amrex::Real interpolate_from_coarse ( const amrex::Array4< const amrex::Real > &  crse,
int  n,
amrex::Real  x,
amrex::Real  y,
amrex::Real  z,
const amrex::Real *  prob_lo_crse,
const amrex::Real *  dx_crse 
)
inline
128 {
129  // Convert to coarse grid index space
130  amrex::Real ic_real = (x - prob_lo_crse[0]) / dx_crse[0];
131  amrex::Real jc_real = (y - prob_lo_crse[1]) / dx_crse[1];
132  amrex::Real kc_real = (z - prob_lo_crse[2]) / dx_crse[2];
133 
134  int ic = static_cast<int>(amrex::Math::floor(ic_real));
135  int jc = static_cast<int>(amrex::Math::floor(jc_real));
136  int kc = static_cast<int>(amrex::Math::floor(kc_real));
137 
138  amrex::Real dx = ic_real - ic;
139  amrex::Real dy = jc_real - jc;
140  amrex::Real dz = kc_real - kc;
141 
142  // Trilinear interpolation
143  amrex::Real v000 = crse(ic, jc, kc, n);
144  amrex::Real v100 = crse(ic + 1, jc, kc, n);
145  amrex::Real v010 = crse(ic, jc + 1, kc, n);
146  amrex::Real v110 = crse(ic + 1, jc + 1, kc, n);
147  amrex::Real v001 = crse(ic, jc, kc + 1, n);
148  amrex::Real v101 = crse(ic + 1, jc, kc + 1, n);
149  amrex::Real v011 = crse(ic, jc + 1, kc + 1, n);
150  amrex::Real v111 = crse(ic + 1, jc + 1, kc + 1, n);
151 
152  amrex::Real v = v000 * (1 - dx) * (1 - dy) * (1 - dz) +
153  v100 * dx * (1 - dy) * (1 - dz) +
154  v010 * (1 - dx) * dy * (1 - dz) +
155  v110 * dx * dy * (1 - dz) +
156  v001 * (1 - dx) * (1 - dy) * dz +
157  v101 * dx * (1 - dy) * dz +
158  v011 * (1 - dx) * dy * dz +
159  v111 * dx * dy * dz;
160 
161  return v;
162 }
const Real dy
Definition: ERF_InitCustomPert_ABL.H:45
@ dz
Definition: ERF_AdvanceWDM6.cpp:273