ERF
Energy Research and Forecasting: An Atmospheric Modeling Code
ERF_Interpolation.H
Go to the documentation of this file.
1 #ifndef ERF_INTERPOLATE_H_
2 #define ERF_INTERPOLATE_H_
3 
4 #include "ERF_DataStruct.H"
8 
9 /**
10  * Interpolation operators used in construction of advective fluxes using
11  * non-WENO centered/upwind schemes.
12  */
13 
14 AMREX_GPU_HOST_DEVICE
15 AMREX_FORCE_INLINE
16 bool
17 isSupportedInterpolationAdvType (const AdvType adv_type) noexcept
18 {
19  return adv_type == AdvType::Centered_2nd ||
20  adv_type == AdvType::Upwind_3rd ||
21  adv_type == AdvType::Centered_4th ||
22  adv_type == AdvType::Upwind_5th ||
23  adv_type == AdvType::Centered_6th;
24 }
25 
26 AMREX_GPU_DEVICE
27 AMREX_FORCE_INLINE
30  amrex::Real diff1, amrex::Real diff2, amrex::Real diff3,
31  amrex::Real scaled_upw, const AdvType adv_type)
32 {
33  AMREX_ALWAYS_ASSERT_WITH_MESSAGE(
35  "interpolatedVal only supports Centered_2nd, Upwind_3rd, Centered_4th, Upwind_5th, and Centered_6th");
36 
37  amrex::Real myInterpolatedVal(amrex::Real(0));
38  if (adv_type == AdvType::Centered_2nd) {
39  myInterpolatedVal = myhalf * avg1;
40  } else if (adv_type == AdvType::Upwind_3rd) {
41  myInterpolatedVal = (amrex::Real(7.0)/amrex::Real(12.0))*avg1 -(amrex::Real(1)/amrex::Real(12.0))*avg2 + (scaled_upw/amrex::Real(12.0))*(diff2 - amrex::Real(3)*diff1);
42  } else if (adv_type == AdvType::Centered_4th) {
43  myInterpolatedVal = (amrex::Real(7.0)/amrex::Real(12.0))*avg1 -(amrex::Real(1)/amrex::Real(12.0))*avg2;
44  } else if (adv_type == AdvType::Upwind_5th) {
45  myInterpolatedVal = (amrex::Real(37.0)/amrex::Real(60.0))*avg1 -(amrex::Real(2)/amrex::Real(15.0))*avg2 +(amrex::Real(1)/amrex::Real(60.0))*avg3
46  -(scaled_upw/amrex::Real(60.0))*(diff3 - amrex::Real(5.0)*diff2 + amrex::Real(10.0)*diff1);
47  } else if (adv_type == AdvType::Centered_6th) {
48  myInterpolatedVal = (amrex::Real(37.0)/amrex::Real(60.0))*avg1 -(amrex::Real(2)/amrex::Real(15.0))*avg2 +(amrex::Real(1)/amrex::Real(60.0))*avg3;
49  } else {
50  AMREX_ALWAYS_ASSERT_WITH_MESSAGE(
51  false,
52  "interpolatedVal only supports Centered_2nd, Upwind_3rd, Centered_4th, Upwind_5th, and Centered_6th");
53  }
54  return myInterpolatedVal;
55 }
56 
57 AMREX_GPU_DEVICE
58 AMREX_FORCE_INLINE
60 InterpolateInX (int i, int j, int k, const amrex::Array4<const amrex::Real>& qty,
61  int qty_index, amrex::Real upw, const AdvType adv_type)
62 {
63 
64  if (adv_type == AdvType::Centered_2nd) {
65  return myhalf * (qty(i,j,k,qty_index) + qty(i-1,j,k,qty_index));
66  } else {
67 
68  amrex::Real avg1 = amrex::Real(0); amrex::Real avg2 = amrex::Real(0); amrex::Real avg3 = amrex::Real(0);
69  amrex::Real diff1 = amrex::Real(0); amrex::Real diff2 = amrex::Real(0); amrex::Real diff3 = amrex::Real(0);
70  amrex::Real scaled_upw = amrex::Real(0);
71  //
72  // The value that comes in has not been normalized so we do that here
73  if (upw != amrex::Real(0)) { scaled_upw = (upw > 0) ? amrex::Real(1) : -amrex::Real(1); }
74 
75  avg1 = (qty(i, j, k, qty_index) + qty(i-1, j, k, qty_index));
76  diff1 = (qty(i, j, k, qty_index) - qty(i-1, j, k, qty_index));
77  avg2 = (qty(i+1, j, k, qty_index) + qty(i-2, j, k, qty_index));
78  diff2 = (qty(i+1, j, k, qty_index) - qty(i-2, j, k, qty_index));
79  if (adv_type == AdvType::Upwind_5th || adv_type == AdvType::Centered_6th)
80  {
81  avg3 = (qty(i+2, j, k, qty_index) + qty(i-3, j, k, qty_index));
82  diff3 = (qty(i+2, j, k, qty_index) - qty(i-3, j, k, qty_index));
83  }
84  return interpolatedVal(avg1,avg2,avg3,diff1,diff2,diff3,scaled_upw,adv_type);
85  }
86 }
87 
88 AMREX_GPU_DEVICE
89 AMREX_FORCE_INLINE
91 InterpolateInY (int i, int j, int k, const amrex::Array4<const amrex::Real>& qty,
92  int qty_index, amrex::Real upw, const AdvType adv_type)
93 {
94  if (adv_type == AdvType::Centered_2nd) {
95  return myhalf * (qty(i,j,k,qty_index) + qty(i,j-1,k,qty_index));
96  } else {
97 
98  amrex::Real avg1; amrex::Real avg2; amrex::Real avg3 = amrex::Real(0);
99  amrex::Real diff1; amrex::Real diff2; amrex::Real diff3 = amrex::Real(0);
100  amrex::Real scaled_upw = amrex::Real(0);
101 
102  // The value that comes in has not been normalized so we do that here
103  if (upw != amrex::Real(0)) { scaled_upw = (upw > 0) ? amrex::Real(1) : -amrex::Real(1); }
104 
105  avg1 = (qty(i, j , k, qty_index) + qty(i, j-1, k, qty_index));
106  diff1 = (qty(i, j , k, qty_index) - qty(i, j-1, k, qty_index));
107  avg2 = (qty(i, j+1, k, qty_index) + qty(i, j-2, k, qty_index));
108  diff2 = (qty(i, j+1, k, qty_index) - qty(i, j-2, k, qty_index));
109  if (adv_type == AdvType::Upwind_5th || adv_type == AdvType::Centered_6th)
110  {
111  avg3 = (qty(i, j+2, k, qty_index) + qty(i, j-3, k, qty_index));
112  diff3 = (qty(i, j+2, k, qty_index) - qty(i, j-3, k, qty_index));
113  }
114  return interpolatedVal(avg1,avg2,avg3,diff1,diff2,diff3,scaled_upw,adv_type);
115  }
116 }
117 
118 AMREX_GPU_DEVICE
119 AMREX_FORCE_INLINE
121 InterpolateInZ (int i, int j, int k, const amrex::Array4<const amrex::Real>& qty,
122  int qty_index, amrex::Real upw, const AdvType adv_type)
123 {
124  if (adv_type == AdvType::Centered_2nd) {
125  return myhalf * (qty(i,j,k,qty_index) + qty(i,j,k-1,qty_index));
126  } else {
127 
128  amrex::Real avg1 = amrex::Real(0); amrex::Real avg2 = amrex::Real(0); amrex::Real avg3 = amrex::Real(0);
129  amrex::Real diff1 = amrex::Real(0); amrex::Real diff2 = amrex::Real(0); amrex::Real diff3 = amrex::Real(0);
130  amrex::Real scaled_upw = amrex::Real(0);
131  // The value that comes in has not been normalized so we do that here
132  if (upw != amrex::Real(0)) { scaled_upw = (upw > 0) ? amrex::Real(1) : -amrex::Real(1); }
133 
134  avg1 = (qty(i, j, k , qty_index) + qty(i, j, k-1, qty_index));
135  diff1 = (qty(i, j, k , qty_index) - qty(i, j, k-1, qty_index));
136  avg2 = (qty(i, j, k+1, qty_index) + qty(i, j, k-2, qty_index));
137  diff2 = (qty(i, j, k+1, qty_index) - qty(i, j, k-2, qty_index));
138  if (adv_type == AdvType::Upwind_5th || adv_type == AdvType::Centered_6th)
139  {
140  avg3 = (qty(i, j, k+2, qty_index) + qty(i, j, k-3, qty_index));
141  diff3 = (qty(i, j, k+2, qty_index) - qty(i, j, k-3, qty_index));
142  }
143  return interpolatedVal(avg1,avg2,avg3,diff1,diff2,diff3,scaled_upw,adv_type);
144  }
145 }
146 
147 AMREX_GPU_DEVICE
148 AMREX_FORCE_INLINE
150 InterpolatePertFromCell (int i, int j, int k,
151  const amrex::Array4<const amrex::Real>& qty,
152  int qty_index, amrex::Real upw, Coord coordDir,
153  const AdvType adv_type, const amrex::Array4<const amrex::Real>& r0_arr)
154 {
155  // Reconstruct the perturbation qty - r0_arr, so both averages and
156  // differences must be formed from perturbation quantities.
157  amrex::Real avg1 = amrex::Real(0); amrex::Real avg2 = amrex::Real(0); amrex::Real avg3 = amrex::Real(0);
158  amrex::Real diff1 = amrex::Real(0); amrex::Real diff2 = amrex::Real(0); amrex::Real diff3 = amrex::Real(0);
159  amrex::Real scaled_upw = amrex::Real(0);
160 
161  // The value that comes in has not been normalized so we do that here
162  if (upw != amrex::Real(0)) { scaled_upw = (upw > 0) ? amrex::Real(1) : -amrex::Real(1); }
163 
164  if (coordDir == Coord::x) {
165  avg1 = (qty(i , j, k, qty_index) + qty(i-1, j, k, qty_index));
166  avg1 -= (r0_arr(i,j,k) + r0_arr(i-1,j,k));
167  diff1 = (qty(i , j, k, qty_index) - qty(i-1, j, k, qty_index));
168  diff1 -= (r0_arr(i,j,k) - r0_arr(i-1,j,k));
169  if (adv_type != AdvType::Centered_2nd)
170  {
171  avg2 = (qty(i+1, j, k, qty_index) + qty(i-2, j, k, qty_index));
172  avg2 -= (r0_arr(i+1,j,k) + r0_arr(i-2,j,k));
173  diff2 = (qty(i+1, j, k, qty_index) - qty(i-2, j, k, qty_index));
174  diff2 -= (r0_arr(i+1,j,k) - r0_arr(i-2,j,k));
175  }
176  if (adv_type == AdvType::Upwind_5th || adv_type == AdvType::Centered_6th)
177  {
178  avg3 = (qty(i+2, j, k, qty_index) + qty(i-3, j, k, qty_index));
179  avg3 -= (r0_arr(i+2,j,k) + r0_arr(i-3,j,k));
180  diff3 = (qty(i+2, j, k, qty_index) - qty(i-3, j, k, qty_index));
181  diff3 -= (r0_arr(i+2,j,k) - r0_arr(i-3,j,k));
182  }
183  } else if (coordDir == Coord::y) {
184  avg1 = (qty(i, j , k, qty_index) + qty(i, j-1, k, qty_index));
185  avg1 -= (r0_arr(i,j,k) + r0_arr(i,j-1,k));
186  diff1 = (qty(i, j , k, qty_index) - qty(i, j-1, k, qty_index));
187  diff1 -= (r0_arr(i,j,k) - r0_arr(i,j-1,k));
188  if (adv_type != AdvType::Centered_2nd)
189  {
190  avg2 = (qty(i, j+1, k, qty_index) + qty(i, j-2, k, qty_index));
191  avg2 -= (r0_arr(i,j+1,k) + r0_arr(i,j-2,k));
192  diff2 = (qty(i, j+1, k, qty_index) - qty(i, j-2, k, qty_index));
193  diff2 -= (r0_arr(i,j+1,k) - r0_arr(i,j-2,k));
194  }
195  if (adv_type == AdvType::Upwind_5th || adv_type == AdvType::Centered_6th)
196  {
197  avg3 = (qty(i, j+2, k, qty_index) + qty(i, j-3, k, qty_index));
198  avg3 -= (r0_arr(i,j+2,k) + r0_arr(i,j-3,k));
199  diff3 = (qty(i, j+2, k, qty_index) - qty(i, j-3, k, qty_index));
200  diff3 -= (r0_arr(i,j+2,k) - r0_arr(i,j-3,k));
201  }
202  } else {
203  avg1 = (qty(i, j, k , qty_index) + qty(i, j, k-1, qty_index));
204  diff1 = (qty(i, j, k , qty_index) - qty(i, j, k-1, qty_index));
205  avg1 -= (r0_arr(i,j,k) + r0_arr(i,j,k-1));
206  diff1 -= (r0_arr(i,j,k) - r0_arr(i,j,k-1));
207 
208  if (adv_type != AdvType::Centered_2nd)
209  {
210  avg2 = (qty(i, j, k+1, qty_index) + qty(i, j, k-2, qty_index));
211  diff2 = (qty(i, j, k+1, qty_index) - qty(i, j, k-2, qty_index));
212  avg2 -= (r0_arr(i,j,k+1) + r0_arr(i,j,k-2));
213  diff2 -= (r0_arr(i,j,k+1) - r0_arr(i,j,k-2));
214  }
215  if (adv_type == AdvType::Upwind_5th || adv_type == AdvType::Centered_6th)
216  {
217  avg3 = (qty(i, j, k+2, qty_index) + qty(i, j, k-3, qty_index));
218  diff3 = (qty(i, j, k+2, qty_index) - qty(i, j, k-3, qty_index));
219  avg3 -= (r0_arr(i,j,k+2) + r0_arr(i,j,k-3));
220  diff3 -= (r0_arr(i,j,k+2) - r0_arr(i,j,k-3));
221  }
222  }
223 
224  return interpolatedVal(avg1,avg2,avg3,diff1,diff2,diff3,scaled_upw,adv_type);
225 }
226 
227 AMREX_GPU_DEVICE
228 AMREX_FORCE_INLINE
230 InterpolateDensityPertFromCellToFace (int i, int j, int k, const amrex::Array4<const amrex::Real>& cons_in,
231  amrex::Real upw, Coord coordDir, const AdvType adv_type,
232  const amrex::Array4<const amrex::Real>& r0_arr)
233 {
234  return InterpolatePertFromCell(i, j, k, cons_in, Rho_comp, upw, coordDir, adv_type, r0_arr);
235 }
236 #endif
constexpr amrex::Real myhalf
Definition: ERF_Constants.H:11
Coord
Definition: ERF_DataStruct.H:92
#define Rho_comp
Definition: ERF_IndexDefines.H:36
AdvType
Definition: ERF_IndexDefines.H:255
@ Centered_4th
@ Centered_6th
@ Centered_2nd
AMREX_GPU_DEVICE AMREX_FORCE_INLINE amrex::Real InterpolateInZ(int i, int j, int k, const amrex::Array4< const amrex::Real > &qty, int qty_index, amrex::Real upw, const AdvType adv_type)
Definition: ERF_Interpolation.H:121
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE bool isSupportedInterpolationAdvType(const AdvType adv_type) noexcept
Definition: ERF_Interpolation.H:17
AMREX_GPU_DEVICE AMREX_FORCE_INLINE amrex::Real InterpolatePertFromCell(int i, int j, int k, const amrex::Array4< const amrex::Real > &qty, int qty_index, amrex::Real upw, Coord coordDir, const AdvType adv_type, const amrex::Array4< const amrex::Real > &r0_arr)
Definition: ERF_Interpolation.H:150
AMREX_GPU_DEVICE AMREX_FORCE_INLINE amrex::Real InterpolateDensityPertFromCellToFace(int i, int j, int k, const amrex::Array4< const amrex::Real > &cons_in, amrex::Real upw, Coord coordDir, const AdvType adv_type, const amrex::Array4< const amrex::Real > &r0_arr)
Definition: ERF_Interpolation.H:230
AMREX_GPU_DEVICE AMREX_FORCE_INLINE amrex::Real interpolatedVal(amrex::Real avg1, amrex::Real avg2, amrex::Real avg3, amrex::Real diff1, amrex::Real diff2, amrex::Real diff3, amrex::Real scaled_upw, const AdvType adv_type)
Definition: ERF_Interpolation.H:29
AMREX_GPU_DEVICE AMREX_FORCE_INLINE amrex::Real InterpolateInY(int i, int j, int k, const amrex::Array4< const amrex::Real > &qty, int qty_index, amrex::Real upw, const AdvType adv_type)
Definition: ERF_Interpolation.H:91
AMREX_GPU_DEVICE AMREX_FORCE_INLINE amrex::Real InterpolateInX(int i, int j, int k, const amrex::Array4< const amrex::Real > &qty, int qty_index, amrex::Real upw, const AdvType adv_type)
Definition: ERF_Interpolation.H:60
amrex::Real Real
Definition: ERF_ShocInterface.H:19