Block-Structured AMR Software Framework
AMReX_FilFC_3D_C.H
Go to the documentation of this file.
1 #ifndef AMREX_FILFC_3D_C_H_
2 #define AMREX_FILFC_3D_C_H_
3 #include <AMReX_Config.H>
4 
5 #include <AMReX_FArrayBox.H>
6 #include <AMReX_BCRec.H>
7 #include <AMReX_Geometry.H>
8 
9 namespace amrex {
10 
11 struct FilfcFace
12 {
14  void operator() (const IntVect& iv, Array4<Real> const& q,
15  const int dcomp, const int numcomp,
16  Box const& domain_box, const BCRec* bcr,
17  const int bcomp) const noexcept
18  {
19  const int i = iv[0];
20  const int j = iv[1];
21  const int k = iv[2];
22 
23  // Domain box is indexed according to the face currently treating
24  const IndexType &idxType = domain_box.ixType();
25  const auto& domain_lo = domain_box.loVect();
26  const auto& domain_hi = domain_box.hiVect();
27  const int ilo = domain_lo[0];
28  const int jlo = domain_lo[1];
29  const int klo = domain_lo[2];
30  const int ihi = domain_hi[0];
31  const int jhi = domain_hi[1];
32  const int khi = domain_hi[2];
33 
34  for (int n = dcomp; n < numcomp+dcomp; ++n)
35  {
36  const BCRec& bc = bcr[bcomp+n-dcomp];
37 
38  if (i == ilo)
39  {
40  // Enforce reflect_odd on the x domain face
41  if ((bc.lo(0) == BCType::reflect_odd) &&
42  (idxType.nodeCentered(0)) ) {
43  q(i,j,k,n) = 0.0;
44  }
45  }
46  else if (i < ilo)
47  {
48  switch (bc.lo(0)) {
49  case (BCType::foextrap):
50  {
51  q(i,j,k,n) = q(ilo,j,k,n);
52  break;
53  }
54  case (BCType::hoextrap):
55  {
56  if (i < ilo - 1)
57  {
58  q(i,j,k,n) = q(ilo,j,k,n);
59  }
60  // i == ilo-1
61  else
62  {
63  q(i,j,k,n) = (idxType.nodeCentered(0)) ? Real(2.0)*q(i+1,j,k,n) - q(i+2,j,k,n)
64  : Real(0.5)*(Real(3.)*q(i+1,j,k,n) - q(i+2,j,k,n));
65  }
66  break;
67  }
68  case (BCType::reflect_even):
69  {
70  q(i,j,k,n) = (idxType.nodeCentered(0)) ? q(2*ilo-i,j,k,n)
71  : q(2*ilo-i-1,j,k,n);
72  break;
73  }
74  case (BCType::reflect_odd):
75  {
76  q(i,j,k,n) = (idxType.nodeCentered(0)) ? -q(2*ilo-i,j,k,n)
77  : -q(2*ilo-i-1,j,k,n);
78  break;
79  }
80  default: { break; }
81  }
82  }
83  if (i == ihi)
84  {
85  // Enforce reflect_odd on the x domain face
86  if ((bc.hi(0) == BCType::reflect_odd) &&
87  (idxType.nodeCentered(0)) ) {
88  q(i,j,k,n) = 0.0;
89  }
90  }
91  else if (i > ihi)
92  {
93  switch (bc.hi(0)) {
94  case (BCType::foextrap):
95  {
96  q(i,j,k,n) = q(ihi,j,k,n);
97  break;
98  }
99  case (BCType::hoextrap):
100  {
101  if (i > ihi + 1)
102  {
103  q(i,j,k,n) = q(ilo,j,k,n);
104  }
105  // i == ihi+1
106  else
107  {
108  q(i,j,k,n) = (idxType.nodeCentered(0)) ? Real(2.0)*q(i-1,j,k,n) - q(i-2,j,k,n)
109  : Real(0.5)*(Real(3.)*q(i-1,j,k,n) - q(i-2,j,k,n));
110  }
111  break;
112  }
113  case (BCType::reflect_even):
114  {
115  q(i,j,k,n) = (idxType.nodeCentered(0)) ? q(2*ihi-i,j,k,n)
116  : q(2*ihi-i+1,j,k,n);
117  break;
118  }
119  case (BCType::reflect_odd):
120  {
121  q(i,j,k,n) = (idxType.nodeCentered(0)) ? -q(2*ihi-i,j,k,n)
122  : -q(2*ihi-i+1,j,k,n);
123  break;
124  }
125  default: { break; }
126  }
127  }
128 
129  if (j == jlo)
130  {
131  // Enforce reflect_odd on the y domain face
132  if ((bc.lo(1) == BCType::reflect_odd) &&
133  (idxType.nodeCentered(1)) ) {
134  q(i,j,k,n) = 0.0;
135  }
136  }
137  else if (j < jlo)
138  {
139  switch (bc.lo(1)) {
140  case (BCType::foextrap):
141  {
142  q(i,j,k,n) = q(i,jlo,k,n);
143  break;
144  }
145  case (BCType::hoextrap):
146  {
147  if (j < jlo - 1)
148  {
149  q(i,j,k,n) = q(i,jlo,k,n);
150  }
151  // j == jlo-1
152  else
153  {
154  q(i,j,k,n) = (idxType.nodeCentered(1)) ? Real(2.0)*q(i,j+1,k,n) - q(i,j+2,k,n)
155  : Real(0.5)*(Real(3.)*q(i,j+1,k,n) - q(i,j+2,k,n));
156  }
157  break;
158  }
159  case (BCType::reflect_even):
160  {
161  q(i,j,k,n) = (idxType.nodeCentered(1)) ? q(i,2*jlo-j,k,n)
162  : q(i,2*jlo-j-1,k,n);
163  break;
164  }
165  case (BCType::reflect_odd):
166  {
167  q(i,j,k,n) = (idxType.nodeCentered(1)) ? -q(i,2*jlo-j,k,n)
168  : -q(i,2*jlo-j-1,k,n);
169  break;
170  }
171  default: { break; }
172  }
173  }
174  else if (j == jhi)
175  {
176  // Enforce reflect_odd on the y domain face
177  if ((bc.hi(1) == BCType::reflect_odd) &&
178  (idxType.nodeCentered(1)) ) {
179  q(i,j,k,n) = 0.0;
180  }
181  }
182  else if (j > jhi)
183  {
184  switch (bc.hi(1)) {
185  case (BCType::foextrap):
186  {
187  q(i,j,k,n) = q(i,jhi,k,n);
188  break;
189  }
190  case (BCType::hoextrap):
191  {
192  if (j > jhi + 1)
193  {
194  q(i,j,k,n) = q(i,jhi,k,n);
195  }
196  // j == jhi+1
197  else
198  {
199  q(i,j,k,n) = (idxType.nodeCentered(1)) ? Real(2.0)*q(i,j-1,k,n) - q(i,j-2,k,n)
200  : Real(0.5)*(Real(3.)*q(i,j-1,k,n) - q(i,j-2,k,n));
201  }
202  break;
203  }
204  case (BCType::reflect_even):
205  {
206  q(i,j,k,n) = (idxType.nodeCentered(1)) ? q(i,2*jhi-j,k,n)
207  : q(i,2*jhi-j+1,k,n);
208  break;
209  }
210  case (BCType::reflect_odd):
211  {
212  q(i,j,k,n) = (idxType.nodeCentered(1)) ? -q(i,2*jhi-j,k,n)
213  : -q(i,2*jhi-j+1,k,n);
214  break;
215  }
216  default: { break; }
217  }
218  }
219 
220  if (k == klo)
221  {
222  // Enforce reflect_odd on the z domain face
223  if ((bc.lo(2) == BCType::reflect_odd) &&
224  (idxType.nodeCentered(2)) ) {
225  q(i,j,k,n) = 0.0;
226  }
227  }
228  else if (k < klo)
229  {
230  switch (bc.lo(2)) {
231  case (BCType::foextrap):
232  {
233  q(i,j,k,n) = q(i,j,klo,n);
234  break;
235  }
236  case (BCType::hoextrap):
237  {
238  if (k < klo - 1)
239  {
240  q(i,j,k,n) = q(i,j,klo,n);
241  }
242  // k == klo-1
243  else
244  {
245  q(i,j,k,n) = (idxType.nodeCentered(2)) ? Real(2.0)*q(i,j,k+1,n) - q(i,j,k+2,n)
246  : Real(0.5)*(Real(3.)*q(i,j,k+1,n) - q(i,j,k+2,n));
247  }
248  break;
249  }
250  case (BCType::reflect_even):
251  {
252  q(i,j,k,n) = (idxType.nodeCentered(2)) ? q(i,j,2*klo-k,n)
253  : q(i,j,2*klo-k-1,n);
254  break;
255  }
256  case (BCType::reflect_odd):
257  {
258  q(i,j,k,n) = (idxType.nodeCentered(2)) ? -q(i,j,2*klo-k,n)
259  : -q(i,j,2*klo-k-1,n);
260  break;
261  }
262  default: { break; }
263  }
264  }
265  if (k == khi)
266  {
267  // Enforce reflect_odd on the z domain face
268  if ((bc.hi(2) == BCType::reflect_odd) &&
269  (idxType.nodeCentered(2)) ) {
270  q(i,j,k,n) = 0.0;
271  }
272  }
273  else if (k > khi)
274  {
275  switch (bc.hi(2)) {
276  case (BCType::foextrap):
277  {
278  q(i,j,k,n) = q(i,j,khi,n);
279  break;
280  }
281  case (BCType::hoextrap):
282  {
283  if (k > khi + 1)
284  {
285  q(i,j,k,n) = q(i,j,khi,n);
286  }
287  // k == khi+1
288  else
289  {
290  q(i,j,k,n) = (idxType.nodeCentered(2)) ? Real(2.0)*q(i,j,k-1,n) - q(i,j,k-2,n)
291  : Real(0.5)*(Real(3.)*q(i,j,k-1,n) - q(i,j,k-2,n));
292  }
293  break;
294  }
295  case (BCType::reflect_even):
296  {
297  q(i,j,k,n) = (idxType.nodeCentered(2)) ? q(i,j,2*khi-k,n)
298  : q(i,j,2*khi-k+1,n);
299  break;
300  }
301  case (BCType::reflect_odd):
302  {
303  q(i,j,k,n) = (idxType.nodeCentered(2)) ? -q(i,j,2*khi-k,n)
304  : -q(i,j,2*khi-k+1,n);
305  break;
306  }
307  default: { break; }
308  }
309  }
310  }
311  }
312 };
313 
314 }
315 
316 #endif
#define AMREX_FORCE_INLINE
Definition: AMReX_Extension.H:119
#define AMREX_GPU_HOST_DEVICE
Definition: AMReX_GpuQualifiers.H:20
Boundary Condition Records. Necessary information and functions for computing boundary conditions.
Definition: AMReX_BCRec.H:17
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE const int * hi() const &noexcept
Return high-end boundary data.
Definition: AMReX_BCRec.H:106
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE const int * lo() const &noexcept
Return low-end boundary data.
Definition: AMReX_BCRec.H:100
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE bool nodeCentered() const noexcept
True if the IndexTypeND is NODE based in all directions.
Definition: AMReX_IndexType.H:107
AMREX_GPU_HOST_DEVICE constexpr AMREX_FORCE_INLINE CellIndex ixType(int dir) const noexcept
Returns the CellIndex in direction dir.
Definition: AMReX_IndexType.H:116
Definition: AMReX_Amr.cpp:49
Definition: AMReX_Array4.H:61
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void operator()(const IntVect &iv, Array4< Real > const &q, const int dcomp, const int numcomp, Box const &domain_box, const BCRec *bcr, const int bcomp) const noexcept
Definition: AMReX_FilFC_1D_C.H:14