ERF
Energy Research and Forecasting: An Atmospheric Modeling Code
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);
30  InterpType_V interp_prim_v(cell_prim);
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);
37  UPWIND3 interp_prim_UPW3(cell_prim);
38 
39  const amrex::Box xbx = amrex::surroundingNodes(bx,0);
40  const amrex::Box ybx = amrex::surroundingNodes(bx,1);
41  const amrex::Box zbx = amrex::surroundingNodes(bx,2);
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 (icell=0; icell<ncells_h; ++icell) {
56  if (cellflag(i-icell-1,j,k).isCovered()) {
57  break;
58  }
59  }
60  }
61  else if (avg_xmom(i,j,k)<0.)
62  {
63  for (icell=0; icell<ncells_h; ++icell) {
64  if (cellflag(i+icell,j,k).isCovered()) {
65  break;
66  }
67  }
68  }
69 
70  // Interpolate the scalar variable (cell_prim) using the highest-order scheme
71 
72  const int prim_index = cons_index - 1;
73  amrex::Real interpx(0.);
74 
75  if (icell==ncells_h-1) {
76  interp_prim_h.InterpolateInX(i,j,k,prim_index,interpx,avg_xmom(i,j,k),horiz_upw_frac);
77  } else {
78  if (icell==1) {
79  interp_prim_CEN2.InterpolateInX(i,j,k,prim_index,interpx,avg_xmom(i,j,k),horiz_upw_frac);
80  } else if (icell==2) {
81  interp_prim_UPW3.InterpolateInX(i,j,k,prim_index,interpx,avg_xmom(i,j,k),horiz_upw_frac);
82  }
83  }
84  (flx_arr[0])(i,j,k,cons_index) = avg_xmom(i,j,k) * interpx;
85  }
86  else
87  {
88  (flx_arr[0])(i,j,k,cons_index) = 0.;
89  }
90  });
91 
92  amrex::ParallelFor(ybx, ncomp,[=] AMREX_GPU_DEVICE (int i, int j, int k, int n) noexcept
93  {
94  const int cons_index = icomp + n;
95 
96  if ( ay_arr(i,j,k) > 0. )
97  {
98  // Find the highest upwind order based on the cell flag
99 
100  int jcell = 0;
101 
102  if (avg_ymom(i,j,k)>0.)
103  {
104  for (jcell=0; jcell<ncells_h; ++jcell) {
105  if (cellflag(i,j-jcell-1,k).isCovered()) {
106  break;
107  }
108  }
109  }
110  else if (avg_ymom(i,j,k)<0.)
111  {
112  for (jcell=0; jcell<ncells_h; ++jcell) {
113  if (cellflag(i,j+jcell,k).isCovered()) {
114  break;
115  }
116  }
117  }
118 
119  // Interpolate the scalar variable (cell_prim) using the highest-order scheme
120 
121  const int prim_index = cons_index - 1;
122  amrex::Real interpy(0.);
123 
124  if (jcell==ncells_h-1) {
125  interp_prim_h.InterpolateInY(i,j,k,prim_index,interpy,avg_ymom(i,j,k),horiz_upw_frac);
126  } else {
127  if (jcell==1) {
128  interp_prim_CEN2.InterpolateInY(i,j,k,prim_index,interpy,avg_ymom(i,j,k),horiz_upw_frac);
129  } else if (jcell==2) {
130  interp_prim_UPW3.InterpolateInY(i,j,k,prim_index,interpy,avg_ymom(i,j,k),horiz_upw_frac);
131  }
132  }
133  (flx_arr[1])(i,j,k,cons_index) = avg_ymom(i,j,k) * interpy;
134  }
135  else
136  {
137  (flx_arr[1])(i,j,k,cons_index) = 0.;
138  }
139  });
140 
141  amrex::ParallelFor(zbx, ncomp,[=] AMREX_GPU_DEVICE (int i, int j, int k, int n) noexcept
142  {
143  const int cons_index = icomp + n;
144 
145  if ( az_arr(i,j,k) > 0. )
146  {
147  // Find the highest upwind order based on the cell flag
148 
149  int kcell = 0;
150 
151  if (avg_zmom(i,j,k)>0.)
152  {
153  for (kcell=0; kcell<ncells_v; ++kcell) {
154  if (cellflag(i,j,k-kcell-1).isCovered()) {
155  break;
156  }
157  }
158  }
159  else if (avg_zmom(i,j,k)<0.)
160  {
161  for (kcell=0; kcell<ncells_v; ++kcell) {
162  if (cellflag(i,j,k+kcell).isCovered()) {
163  break;
164  }
165  }
166  }
167 
168  // Interpolate the scalar variable (cell_prim) using the highest-order scheme
169 
170  const int prim_index = cons_index - 1;
171  amrex::Real interpz(0.);
172 
173  if (kcell==ncells_v-1) {
174  interp_prim_v.InterpolateInZ(i,j,k,prim_index,interpz,avg_zmom(i,j,k),vert_upw_frac);
175  } else {
176  if (kcell==1) {
177  interp_prim_CEN2.InterpolateInZ(i,j,k,prim_index,interpz,avg_zmom(i,j,k),vert_upw_frac);
178  } else if (kcell==2) {
179  interp_prim_UPW3.InterpolateInZ(i,j,k,prim_index,interpz,avg_zmom(i,j,k),vert_upw_frac);
180  }
181  }
182  (flx_arr[2])(i,j,k,cons_index) = avg_zmom(i,j,k) * interpz;
183  }
184  else
185  {
186  (flx_arr[2])(i,j,k,cons_index) = 0.;
187  }
188  });
189 }
190 
191 
192 /**
193  * When terrain_type == TerreinType::EB,
194  * Wrapper function for templating the vertical advective tendency w/ spatial order > 2.
195  */
196 template<typename InterpType_H>
197 void
198 EBAdvectionSrcForScalarsVert (const amrex::Box& bx,
199  const int& ncomp, const int& icomp,
200  const amrex::GpuArray<const amrex::Array4<amrex::Real>, AMREX_SPACEDIM> flx_arr,
201  const amrex::Array4<const amrex::Real>& cell_prim,
202  const amrex::Array4<const amrex::Real>& avg_xmom,
203  const amrex::Array4<const amrex::Real>& avg_ymom,
204  const amrex::Array4<const amrex::Real>& avg_zmom,
205  const amrex::Array4<const amrex::EBCellFlag>& cellflag,
206  const amrex::Array4<const amrex::Real>& ax_arr,
207  const amrex::Array4<const amrex::Real>& ay_arr,
208  const amrex::Array4<const amrex::Real>& az_arr,
209  const amrex::Real horiz_upw_frac,
210  const amrex::Real vert_upw_frac,
211  const AdvType vert_adv_type)
212 {
213  switch(vert_adv_type) {
215  EBAdvectionSrcForScalarsWrapper<InterpType_H,CENTERED2>(bx, ncomp, icomp,
216  flx_arr, cell_prim,
217  avg_xmom, avg_ymom, avg_zmom,
218  cellflag, ax_arr, ay_arr, az_arr,
219  horiz_upw_frac, vert_upw_frac);
220  break;
221  case AdvType::Upwind_3rd:
222  EBAdvectionSrcForScalarsWrapper<InterpType_H,UPWIND3>(bx, ncomp, icomp,
223  flx_arr, cell_prim,
224  avg_xmom, avg_ymom, avg_zmom,
225  cellflag, ax_arr, ay_arr, az_arr,
226  horiz_upw_frac, vert_upw_frac);
227  break;
229  EBAdvectionSrcForScalarsWrapper<InterpType_H,CENTERED4>(bx, ncomp, icomp,
230  flx_arr, cell_prim,
231  avg_xmom, avg_ymom, avg_zmom,
232  cellflag, ax_arr, ay_arr, az_arr,
233  horiz_upw_frac, vert_upw_frac);
234  break;
235  case AdvType::Upwind_5th:
236  EBAdvectionSrcForScalarsWrapper<InterpType_H,UPWIND5>(bx, ncomp, icomp,
237  flx_arr, cell_prim,
238  avg_xmom, avg_ymom, avg_zmom,
239  cellflag, ax_arr, ay_arr, az_arr,
240  horiz_upw_frac, vert_upw_frac);
241  break;
243  EBAdvectionSrcForScalarsWrapper<InterpType_H,CENTERED6>(bx, ncomp, icomp,
244  flx_arr, cell_prim,
245  avg_xmom, avg_ymom, avg_zmom,
246  cellflag, ax_arr, ay_arr, az_arr,
247  horiz_upw_frac, vert_upw_frac);
248  break;
249  default:
250  AMREX_ASSERT_WITH_MESSAGE(false, "Unknown vertical advection scheme!");
251  }
252 }
253 
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:198
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:191
@ Centered_4th
@ Centered_6th
@ Centered_2nd
Definition: ERF_Interpolation_UPW.H:10
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 amrex::Real) const
Definition: ERF_Interpolation_UPW.H:55
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 amrex::Real) const
Definition: ERF_Interpolation_UPW.H:36
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 amrex::Real) const
Definition: ERF_Interpolation_UPW.H:17
Definition: ERF_Interpolation_UPW.H:95
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 amrex::Real upw_frac) 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 amrex::Real upw_frac) const
Definition: ERF_Interpolation_UPW.H:102
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 amrex::Real upw_frac) const
Definition: ERF_Interpolation_UPW.H:156