ERF
Energy Research and Forecasting: An Atmospheric Modeling Code
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
ERF_EBAdvectionSrcForScalars.H
Go to the documentation of this file.
1 #include <ERF_IndexDefines.H>
2 #include <ERF_Interpolation.H>
3 
4 #include <iostream>
5 #include <fstream>
6 #include <AMReX_Vector.H>
7 
8 /**
9  * When terrain_type == TerreinType::EB,
10  * Wrapper function for computing the advective tendency w/ spatial order > 2
11  */
12 template<typename InterpType_H, typename InterpType_V>
13 void
14 EBAdvectionSrcForScalarsWrapper (const amrex::Box& bx,
15  const int& ncomp, const int& icomp,
16  const amrex::GpuArray<const amrex::Array4<amrex::Real>, AMREX_SPACEDIM> flx_arr,
17  const amrex::Array4<const amrex::Real>& cell_prim,
18  const amrex::Array4<const amrex::Real>& avg_xmom,
19  const amrex::Array4<const amrex::Real>& avg_ymom,
20  const amrex::Array4<const amrex::Real>& avg_zmom,
21  const amrex::Array4<const amrex::EBCellFlag>& cellflag,
22  const amrex::Array4<const amrex::Real>& ax_arr,
23  const amrex::Array4<const amrex::Real>& ay_arr,
24  const amrex::Array4<const amrex::Real>& az_arr,
25  const amrex::Real horiz_upw_frac,
26  const amrex::Real vert_upw_frac)
27 {
28  // Instantiate structs for vert/horiz interp
29  InterpType_H interp_prim_h(cell_prim, horiz_upw_frac);
30  InterpType_V interp_prim_v(cell_prim, vert_upw_frac);
31 
32  const int ncells_h = interp_prim_h.GetUpwindCellNumber();
33  const int ncells_v = interp_prim_v.GetUpwindCellNumber();
34 
35  // Instantiate structs for lower-order vert/horiz interp
36  CENTERED2 interp_prim_CEN2(cell_prim, 0);
37  UPWIND3 interp_prim_UPW3(cell_prim, horiz_upw_frac);
38 
39  const amrex::Box xbx = amrex::surroundingNodes(bx,0).grow(amrex::IntVect(0, 1, 1));
40  const amrex::Box ybx = amrex::surroundingNodes(bx,1).grow(amrex::IntVect(1, 0, 1));
41  const amrex::Box zbx = amrex::surroundingNodes(bx,2).grow(amrex::IntVect(1, 1, 0));
42 
43  amrex::ParallelFor(xbx, ncomp,[=] AMREX_GPU_DEVICE (int i, int j, int k, int n) noexcept
44  {
45  const int cons_index = icomp + n;
46 
47  if ( ax_arr(i,j,k) > 0. ) // Do we need a threshold value for the area fraction to avoid infinitesimal fractions?
48  {
49  // Find the highest upwind order based on the cell flag
50 
51  int icell = 0;
52 
53  if (avg_xmom(i,j,k)>0.)
54  {
55  for (int ii=0; ii<ncells_h; ++ii) {
56  if (cellflag(i-ii-1,j,k).isCovered()) {
57  break;
58  }
59  icell++;
60  }
61  }
62  else if (avg_xmom(i,j,k)<0.)
63  {
64  for (int ii=0; ii<ncells_h; ++ii) {
65  if (cellflag(i+ii,j,k).isCovered()) {
66  break;
67  }
68  icell++;
69  }
70  }
71 
72  // Interpolate the scalar variable (cell_prim) using the highest-order scheme
73 
74  const int prim_index = cons_index - 1;
75  amrex::Real interpx(0.);
76 
77  if (icell==ncells_h) {
78  interp_prim_h.InterpolateInX(i,j,k,prim_index,interpx,avg_xmom(i,j,k));
79  } else {
80  if (icell==1) {
81  interp_prim_CEN2.InterpolateInX(i,j,k,prim_index,interpx,avg_xmom(i,j,k));
82  } else if (icell==2) {
83  interp_prim_UPW3.InterpolateInX(i,j,k,prim_index,interpx,avg_xmom(i,j,k));
84  }
85  }
86  (flx_arr[0])(i,j,k,cons_index) = avg_xmom(i,j,k) * interpx;
87  }
88  else
89  {
90  (flx_arr[0])(i,j,k,cons_index) = 0.;
91  }
92  });
93 
94  amrex::ParallelFor(ybx, ncomp,[=] AMREX_GPU_DEVICE (int i, int j, int k, int n) noexcept
95  {
96  const int cons_index = icomp + n;
97 
98  if ( ay_arr(i,j,k) > 0. )
99  {
100  // Find the highest upwind order based on the cell flag
101 
102  int jcell = 0;
103 
104  if (avg_ymom(i,j,k)>0.)
105  {
106  for (int jj=0; jj<ncells_h; ++jj) {
107  if (cellflag(i,j-jj-1,k).isCovered()) {
108  break;
109  }
110  jcell++;
111  }
112  }
113  else if (avg_ymom(i,j,k)<0.)
114  {
115  for (int jj=0; jj<ncells_h; ++jj) {
116  if (cellflag(i,j+jj,k).isCovered()) {
117  break;
118  }
119  jcell++;
120  }
121  }
122 
123  // Interpolate the scalar variable (cell_prim) using the highest-order scheme
124 
125  const int prim_index = cons_index - 1;
126  amrex::Real interpy(0.);
127 
128  if (jcell==ncells_h) {
129  interp_prim_h.InterpolateInY(i,j,k,prim_index,interpy,avg_ymom(i,j,k));
130  } else {
131  if (jcell==1) {
132  interp_prim_CEN2.InterpolateInY(i,j,k,prim_index,interpy,avg_ymom(i,j,k));
133  } else if (jcell==2) {
134  interp_prim_UPW3.InterpolateInY(i,j,k,prim_index,interpy,avg_ymom(i,j,k));
135  }
136  }
137  (flx_arr[1])(i,j,k,cons_index) = avg_ymom(i,j,k) * interpy;
138  }
139  else
140  {
141  (flx_arr[1])(i,j,k,cons_index) = 0.;
142  }
143  });
144 
145  interp_prim_UPW3.SetUpwinding(vert_upw_frac);
146 
147  amrex::ParallelFor(zbx, ncomp,[=] AMREX_GPU_DEVICE (int i, int j, int k, int n) noexcept
148  {
149  const int cons_index = icomp + n;
150 
151  if ( az_arr(i,j,k) > 0. )
152  {
153  // Find the highest upwind order based on the cell flag
154 
155  int kcell = 0;
156 
157  if (avg_zmom(i,j,k)>0.)
158  {
159  for (int kk=0; kk<ncells_v; ++kk) {
160  if (cellflag(i,j,k-kk-1).isCovered()) {
161  break;
162  }
163  kcell++;
164  }
165  }
166  else if (avg_zmom(i,j,k)<0.)
167  {
168  for (int kk=0; kk<ncells_v; ++kk) {
169  if (cellflag(i,j,k+kk).isCovered()) {
170  break;
171  }
172  kcell++;
173  }
174  }
175 
176  // Interpolate the scalar variable (cell_prim) using the highest-order scheme
177 
178  const int prim_index = cons_index - 1;
179  amrex::Real interpz(0.);
180 
181  if (kcell==ncells_v) {
182  interp_prim_v.InterpolateInZ(i,j,k,prim_index,interpz,avg_zmom(i,j,k));
183  } else {
184  if (kcell==1) {
185  interp_prim_CEN2.InterpolateInZ(i,j,k,prim_index,interpz,avg_zmom(i,j,k));
186  } else if (kcell==2) {
187  interp_prim_UPW3.InterpolateInZ(i,j,k,prim_index,interpz,avg_zmom(i,j,k));
188  }
189  }
190  (flx_arr[2])(i,j,k,cons_index) = avg_zmom(i,j,k) * interpz;
191  }
192  else
193  {
194  (flx_arr[2])(i,j,k,cons_index) = 0.;
195  }
196  });
197 }
198 
199 
200 /**
201  * When terrain_type == TerreinType::EB,
202  * Wrapper function for templating the vertical advective tendency w/ spatial order > 2.
203  */
204 template<typename InterpType_H>
205 void
206 EBAdvectionSrcForScalarsVert (const amrex::Box& bx,
207  const int& ncomp, const int& icomp,
208  const amrex::GpuArray<const amrex::Array4<amrex::Real>, AMREX_SPACEDIM> flx_arr,
209  const amrex::Array4<const amrex::Real>& cell_prim,
210  const amrex::Array4<const amrex::Real>& avg_xmom,
211  const amrex::Array4<const amrex::Real>& avg_ymom,
212  const amrex::Array4<const amrex::Real>& avg_zmom,
213  const amrex::Array4<const amrex::EBCellFlag>& cellflag,
214  const amrex::Array4<const amrex::Real>& ax_arr,
215  const amrex::Array4<const amrex::Real>& ay_arr,
216  const amrex::Array4<const amrex::Real>& az_arr,
217  const amrex::Real horiz_upw_frac,
218  const amrex::Real vert_upw_frac,
219  const AdvType vert_adv_type)
220 {
221  switch(vert_adv_type) {
223  EBAdvectionSrcForScalarsWrapper<InterpType_H,CENTERED2>(bx, ncomp, icomp,
224  flx_arr, cell_prim,
225  avg_xmom, avg_ymom, avg_zmom,
226  cellflag, ax_arr, ay_arr, az_arr,
227  horiz_upw_frac, vert_upw_frac);
228  break;
229  case AdvType::Upwind_3rd:
230  EBAdvectionSrcForScalarsWrapper<InterpType_H,UPWIND3>(bx, ncomp, icomp,
231  flx_arr, cell_prim,
232  avg_xmom, avg_ymom, avg_zmom,
233  cellflag, ax_arr, ay_arr, az_arr,
234  horiz_upw_frac, vert_upw_frac);
235  break;
237  EBAdvectionSrcForScalarsWrapper<InterpType_H,CENTERED4>(bx, ncomp, icomp,
238  flx_arr, cell_prim,
239  avg_xmom, avg_ymom, avg_zmom,
240  cellflag, ax_arr, ay_arr, az_arr,
241  horiz_upw_frac, vert_upw_frac);
242  break;
243  case AdvType::Upwind_5th:
244  EBAdvectionSrcForScalarsWrapper<InterpType_H,UPWIND5>(bx, ncomp, icomp,
245  flx_arr, cell_prim,
246  avg_xmom, avg_ymom, avg_zmom,
247  cellflag, ax_arr, ay_arr, az_arr,
248  horiz_upw_frac, vert_upw_frac);
249  break;
251  EBAdvectionSrcForScalarsWrapper<InterpType_H,CENTERED6>(bx, ncomp, icomp,
252  flx_arr, cell_prim,
253  avg_xmom, avg_ymom, avg_zmom,
254  cellflag, ax_arr, ay_arr, az_arr,
255  horiz_upw_frac, vert_upw_frac);
256  break;
257  default:
258  AMREX_ASSERT_WITH_MESSAGE(false, "Unknown vertical advection scheme!");
259  }
260 }
261 
const Box zbx
Definition: ERF_DiffSetup.H:23
const Box xbx
Definition: ERF_DiffSetup.H:21
const Box ybx
Definition: ERF_DiffSetup.H:22
void EBAdvectionSrcForScalarsVert(const amrex::Box &bx, const int &ncomp, const int &icomp, const amrex::GpuArray< const amrex::Array4< amrex::Real >, AMREX_SPACEDIM > flx_arr, const amrex::Array4< const amrex::Real > &cell_prim, const amrex::Array4< const amrex::Real > &avg_xmom, const amrex::Array4< const amrex::Real > &avg_ymom, const amrex::Array4< const amrex::Real > &avg_zmom, const amrex::Array4< const amrex::EBCellFlag > &cellflag, const amrex::Array4< const amrex::Real > &ax_arr, const amrex::Array4< const amrex::Real > &ay_arr, const amrex::Array4< const amrex::Real > &az_arr, const amrex::Real horiz_upw_frac, const amrex::Real vert_upw_frac, const AdvType vert_adv_type)
Definition: ERF_EBAdvectionSrcForScalars.H:206
void EBAdvectionSrcForScalarsWrapper(const amrex::Box &bx, const int &ncomp, const int &icomp, const amrex::GpuArray< const amrex::Array4< amrex::Real >, AMREX_SPACEDIM > flx_arr, const amrex::Array4< const amrex::Real > &cell_prim, const amrex::Array4< const amrex::Real > &avg_xmom, const amrex::Array4< const amrex::Real > &avg_ymom, const amrex::Array4< const amrex::Real > &avg_zmom, const amrex::Array4< const amrex::EBCellFlag > &cellflag, const amrex::Array4< const amrex::Real > &ax_arr, const amrex::Array4< const amrex::Real > &ay_arr, const amrex::Array4< const amrex::Real > &az_arr, const amrex::Real horiz_upw_frac, const amrex::Real vert_upw_frac)
Definition: ERF_EBAdvectionSrcForScalars.H:14
AdvType
Definition: ERF_IndexDefines.H:221
@ Centered_4th
@ Centered_6th
@ Centered_2nd
Definition: ERF_Interpolation_UPW.H:10
AMREX_GPU_DEVICE AMREX_FORCE_INLINE void InterpolateInY(const int &i, const int &j, const int &k, const int &qty_index, amrex::Real &val_lo, amrex::Real) const
Definition: ERF_Interpolation_UPW.H:36
AMREX_GPU_DEVICE AMREX_FORCE_INLINE void InterpolateInZ(const int &i, const int &j, const int &k, const int &qty_index, amrex::Real &val_lo, amrex::Real) const
Definition: ERF_Interpolation_UPW.H:54
AMREX_GPU_DEVICE AMREX_FORCE_INLINE void InterpolateInX(const int &i, const int &j, const int &k, const int &qty_index, amrex::Real &val_lo, amrex::Real) const
Definition: ERF_Interpolation_UPW.H:18
Definition: ERF_Interpolation_UPW.H:93
AMREX_GPU_DEVICE AMREX_FORCE_INLINE void InterpolateInZ(const int &i, const int &j, const int &k, const int &qty_index, amrex::Real &val_lo, amrex::Real upw_lo) const
Definition: ERF_Interpolation_UPW.H:155
void SetUpwinding(amrex::Real upw_frac)
Definition: ERF_Interpolation_UPW.H:199
AMREX_GPU_DEVICE AMREX_FORCE_INLINE void InterpolateInY(const int &i, const int &j, const int &k, const int &qty_index, amrex::Real &val_lo, amrex::Real upw_lo) const
Definition: ERF_Interpolation_UPW.H:129
AMREX_GPU_DEVICE AMREX_FORCE_INLINE void InterpolateInX(const int &i, const int &j, const int &k, const int &qty_index, amrex::Real &val_lo, amrex::Real upw_lo) const
Definition: ERF_Interpolation_UPW.H:103