Block-Structured AMR Software Framework
AMReX_MLNodeLap_K.H
Go to the documentation of this file.
1 #ifndef AMREX_MLNODELAP_K_H_
2 #define AMREX_MLNODELAP_K_H_
3 #include <AMReX_Config.H>
4 
5 #include <AMReX_FArrayBox.H>
6 #include <AMReX_LO_BCTYPES.H>
7 #ifdef AMREX_USE_EB
8 #include <AMReX_EBCellFlag.H>
9 #endif
10 
11 namespace amrex {
12 
13 namespace nodelap_detail {
14 
15  struct GetNode {
16  AMREX_GPU_DEVICE Dim3 operator() (Dim3 const& lo, Dim3 const& len, int& offset)
17  {
18  Dim3 node;
19  constexpr int nsten = AMREX_D_TERM(3,*3,*3);
20  int icell = offset / nsten;
21  node.z = icell / (len.x*len.y);
22  node.y = (icell - node.z*(len.x*len.y)) / len.x;
23  node.x = (icell - node.z*(len.x*len.y)) - node.y*len.x;
24  node.x += lo.x;
25  node.y += lo.y;
26  node.z += lo.z;
27  offset -= icell*nsten;
28  return node;
29  }
30  };
31 
32  struct GetNode2 {
34  {
35  // In 2D the offsets are
36  // 6 7 8
37  // 4 0 5
38  // 1 2 3
39  constexpr int nstenhalf = AMREX_SPACEDIM == 2 ? 4 : 13;
40  if (offset == 0) {
41  return node;
42  } else {
43  if (offset <= nstenhalf) { --offset; }
44  Dim3 node2;
45  node2.z = offset / 9;
46  node2.y = (offset - node2.z*9) / 3;
47  node2.x = (offset - node2.z*9) - node2.y*3;
48  AMREX_D_TERM(node2.x += node.x-1;,
49  node2.y += node.y-1;,
50  node2.z += node.z-1);
51  return node2;
52  }
53  }
54  };
55 
56  constexpr int crse_cell = 0; // Do NOT change the values
57  constexpr int fine_cell = 1;
58  constexpr int crse_node = 0;
59  constexpr int crse_fine_node = 1;
60  constexpr int fine_node = 2;
61 #if (BL_USE_FLOAT)
62  constexpr float eps = 1.e-30_rt;
63 #else
64  constexpr double eps = 1.e-100_rt;
65 #endif
66  constexpr Real almostone = Real(1.) - Real(100.)*std::numeric_limits<Real>::epsilon();
67  constexpr Real almostzero = Real(1.) - almostone;
68 
69 }
70 
71 inline void
72 mlndlap_scale_neumann_bc (Real s, Box const& bx, Array4<Real> const& rhs, Box const& nddom,
74  GpuArray<LinOpBCType,AMREX_SPACEDIM> const& hibc) noexcept
75 {
76  for (int idim = 0; idim < AMREX_SPACEDIM; ++idim) {
77  if (lobc[idim] == LinOpBCType::Neumann || lobc[idim] == LinOpBCType::inflow) {
78  Box const& blo = amrex::bdryLo(bx, idim);
79  if (blo.smallEnd(idim) == nddom.smallEnd(idim)) {
81  {
82  rhs(i,j,k) *= s;
83  });
84  }
85  }
86  if (hibc[idim] == LinOpBCType::Neumann || hibc[idim] == LinOpBCType::inflow) {
87  Box const& bhi = amrex::bdryHi(bx, idim);
88  if (bhi.bigEnd(idim) == nddom.bigEnd(idim)) {
90  {
91  rhs(i,j,k) *= s;
92  });
93  }
94  }
95  }
96 }
97 
98 inline void
99 mlndlap_impose_neumann_bc (Box const& bx, Array4<Real> const& rhs, Box const& nddom,
101  GpuArray<LinOpBCType,AMREX_SPACEDIM> const& hibc) noexcept
102 {
103  mlndlap_scale_neumann_bc(2.0, bx, rhs, nddom, lobc, hibc);
104 }
105 
106 inline void
107 mlndlap_unimpose_neumann_bc (Box const& bx, Array4<Real> const& rhs, Box const& nddom,
109  GpuArray<LinOpBCType,AMREX_SPACEDIM> const& hibc) noexcept
110 {
111  mlndlap_scale_neumann_bc(0.5, bx, rhs, nddom, lobc, hibc);
112 }
113 
114 }
115 
116 #if (AMREX_SPACEDIM == 1)
117 #include <AMReX_MLNodeLap_1D_K.H>
118 #elif (AMREX_SPACEDIM == 2)
119 #include <AMReX_MLNodeLap_2D_K.H>
120 #else
121 #include <AMReX_MLNodeLap_3D_K.H>
122 #endif
123 
124 namespace amrex {
125 
126 template <typename T>
127 void mlndlap_fillbc_cc (Box const& vbx, Array4<T> const& sigma, Box const& domain,
130 {
131  GpuArray<bool,AMREX_SPACEDIM> bflo{{AMREX_D_DECL(bclo[0] != LinOpBCType::Periodic,
132  bclo[1] != LinOpBCType::Periodic,
133  bclo[2] != LinOpBCType::Periodic)}};
134  GpuArray<bool,AMREX_SPACEDIM> bfhi{{AMREX_D_DECL(bchi[0] != LinOpBCType::Periodic,
135  bchi[1] != LinOpBCType::Periodic,
136  bchi[2] != LinOpBCType::Periodic)}};
137  mlndlap_bc_doit(vbx, sigma, domain, bflo, bfhi);
138 }
139 
140 template <typename T>
141 void mlndlap_applybc (Box const& vbx, Array4<T> const& phi, Box const& domain,
144 {
145  GpuArray<bool,AMREX_SPACEDIM> bflo{{AMREX_D_DECL(bclo[0] == LinOpBCType::Neumann ||
146  bclo[0] == LinOpBCType::inflow,
147  bclo[1] == LinOpBCType::Neumann ||
148  bclo[1] == LinOpBCType::inflow,
149  bclo[2] == LinOpBCType::Neumann ||
150  bclo[2] == LinOpBCType::inflow)}};
151  GpuArray<bool,AMREX_SPACEDIM> bfhi{{AMREX_D_DECL(bchi[0] == LinOpBCType::Neumann ||
152  bchi[0] == LinOpBCType::inflow,
153  bchi[1] == LinOpBCType::Neumann ||
154  bchi[1] == LinOpBCType::inflow,
155  bchi[2] == LinOpBCType::Neumann ||
156  bchi[2] == LinOpBCType::inflow)}};
157  mlndlap_bc_doit(vbx, phi, domain, bflo, bfhi);
158 }
159 
161 void mlndlap_normalize_sten (int i, int j, int k, Array4<Real> const& x,
162  Array4<Real const> const& sten,
163  Array4<int const> const& msk, Real s0_norm0) noexcept
164 {
165  if (!msk(i,j,k) && std::abs(sten(i,j,k,0)) > s0_norm0) {
166  x(i,j,k) /= sten(i,j,k,0);
167  }
168 }
169 
171 void mlndlap_jacobi_sten (int i, int j, int k, Array4<Real> const& sol,
172  Real Ax, Array4<Real const> const& rhs,
173  Array4<Real const> const& sten,
174  Array4<int const> const& msk) noexcept
175 {
176  if (msk(i,j,k)) {
177  sol(i,j,k) = Real(0.0);
178  } else if (sten(i,j,k,0) != Real(0.0)) {
179  sol(i,j,k) += Real(2./3.) * (rhs(i,j,k) - Ax) / sten(i,j,k,0);
180  }
181 }
182 
184 void mlndlap_jacobi_sten (Box const& bx, Array4<Real> const& sol,
185  Array4<Real const> const& Ax,
186  Array4<Real const> const& rhs,
187  Array4<Real const> const& sten,
188  Array4<int const> const& msk) noexcept
189 {
190  amrex::LoopConcurrent(bx, [=] (int i, int j, int k) noexcept
191  {
192  if (msk(i,j,k)) {
193  sol(i,j,k) = Real(0.0);
194  } else if (sten(i,j,k,0) != Real(0.0)) {
195  sol(i,j,k) += Real(2./3.) * (rhs(i,j,k) - Ax(i,j,k)) / sten(i,j,k,0);
196  }
197  });
198 }
199 
201 bool mlndlap_any_fine_sync_cells (Box const& bx, Array4<int const> const& msk, int fine_flag) noexcept
202 {
203  const auto lo = amrex::lbound(bx);
204  const auto hi = amrex::ubound(bx);
205  for (int k = lo.z; k <= hi.z; ++k) {
206  for (int j = lo.y; j <= hi.y; ++j) {
207  for (int i = lo.x; i <= hi.x; ++i) {
208  if (msk(i,j,k) == fine_flag) { return true; }
209  }}}
210  return false;
211 }
212 
213 }
214 
215 #endif
#define AMREX_FORCE_INLINE
Definition: AMReX_Extension.H:119
#define AMREX_HOST_DEVICE_PARALLEL_FOR_3D(...)
Definition: AMReX_GpuLaunch.nolint.H:54
#define AMREX_GPU_DEVICE
Definition: AMReX_GpuQualifiers.H:18
#define AMREX_GPU_HOST_DEVICE
Definition: AMReX_GpuQualifiers.H:20
Array4< int const > offset
Definition: AMReX_HypreMLABecLap.cpp:1089
#define AMREX_D_TERM(a, b, c)
Definition: AMReX_SPACE.H:129
#define AMREX_D_DECL(a, b, c)
Definition: AMReX_SPACE.H:104
AMREX_GPU_HOST_DEVICE const IntVectND< dim > & smallEnd() const &noexcept
Get the smallend of the BoxND.
Definition: AMReX_Box.H:105
AMREX_GPU_HOST_DEVICE const IntVectND< dim > & bigEnd() const &noexcept
Get the bigend.
Definition: AMReX_Box.H:116
#define abs(x)
Definition: complex-type.h:85
constexpr int fine_cell
Definition: AMReX_MLNodeLap_K.H:57
constexpr int fine_node
Definition: AMReX_MLNodeLap_K.H:60
constexpr int crse_node
Definition: AMReX_MLNodeLap_K.H:58
constexpr Real almostzero
Definition: AMReX_MLNodeLap_K.H:67
constexpr int crse_cell
Definition: AMReX_MLNodeLap_K.H:56
constexpr int crse_fine_node
Definition: AMReX_MLNodeLap_K.H:59
constexpr double eps
Definition: AMReX_MLNodeLap_K.H:64
constexpr Real almostone
Definition: AMReX_MLNodeLap_K.H:66
Definition: AMReX_Amr.cpp:49
void mlndlap_bc_doit(Box const &vbx, Array4< T > const &a, Box const &domain, GpuArray< bool, AMREX_SPACEDIM > const &bflo, GpuArray< bool, AMREX_SPACEDIM > const &bfhi) noexcept
Definition: AMReX_MLNodeLap_1D_K.H:110
void mlndlap_scale_neumann_bc(Real s, Box const &bx, Array4< Real > const &rhs, Box const &nddom, GpuArray< LinOpBCType, AMREX_SPACEDIM > const &lobc, GpuArray< LinOpBCType, AMREX_SPACEDIM > const &hibc) noexcept
Definition: AMReX_MLNodeLap_K.H:72
void mlndlap_fillbc_cc(Box const &vbx, Array4< T > const &sigma, Box const &domain, GpuArray< LinOpBCType, AMREX_SPACEDIM > bclo, GpuArray< LinOpBCType, AMREX_SPACEDIM > bchi) noexcept
Definition: AMReX_MLNodeLap_K.H:127
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void mlndlap_jacobi_sten(int i, int j, int k, Array4< Real > const &sol, Real Ax, Array4< Real const > const &rhs, Array4< Real const > const &sten, Array4< int const > const &msk) noexcept
Definition: AMReX_MLNodeLap_K.H:171
void mlndlap_impose_neumann_bc(Box const &bx, Array4< Real > const &rhs, Box const &nddom, GpuArray< LinOpBCType, AMREX_SPACEDIM > const &lobc, GpuArray< LinOpBCType, AMREX_SPACEDIM > const &hibc) noexcept
Definition: AMReX_MLNodeLap_K.H:99
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE BoxND< dim > bdryLo(const BoxND< dim > &b, int dir, int len=1) noexcept
Returns the edge-centered BoxND (in direction dir) defining the low side of BoxND b.
Definition: AMReX_Box.H:1502
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE Dim3 ubound(Array4< T > const &a) noexcept
Definition: AMReX_Array4.H:315
AMREX_FORCE_INLINE bool mlndlap_any_fine_sync_cells(Box const &bx, Array4< int const > const &msk, int fine_flag) noexcept
Definition: AMReX_MLNodeLap_K.H:201
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE Dim3 lbound(Array4< T > const &a) noexcept
Definition: AMReX_Array4.H:308
void mlndlap_unimpose_neumann_bc(Box const &bx, Array4< Real > const &rhs, Box const &nddom, GpuArray< LinOpBCType, AMREX_SPACEDIM > const &lobc, GpuArray< LinOpBCType, AMREX_SPACEDIM > const &hibc) noexcept
Definition: AMReX_MLNodeLap_K.H:107
AMREX_GPU_HOST_DEVICE AMREX_ATTRIBUTE_FLATTEN_FOR void LoopConcurrent(Dim3 lo, Dim3 hi, F const &f) noexcept
Definition: AMReX_Loop.H:149
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void mlndlap_normalize_sten(int i, int j, int k, Array4< Real > const &x, Array4< Real const > const &sten, Array4< int const > const &msk, Real s0_norm0) noexcept
Definition: AMReX_MLNodeLap_K.H:161
void mlndlap_applybc(Box const &vbx, Array4< T > const &phi, Box const &domain, GpuArray< LinOpBCType, AMREX_SPACEDIM > bclo, GpuArray< LinOpBCType, AMREX_SPACEDIM > bchi) noexcept
Definition: AMReX_MLNodeLap_K.H:141
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE BoxND< dim > bdryHi(const BoxND< dim > &b, int dir, int len=1) noexcept
Returns the edge-centered BoxND (in direction dir) defining the high side of BoxND b.
Definition: AMReX_Box.H:1525
Definition: AMReX_Array4.H:61
Definition: AMReX_Dim3.H:12
int x
Definition: AMReX_Dim3.H:12
int z
Definition: AMReX_Dim3.H:12
int y
Definition: AMReX_Dim3.H:12
Definition: AMReX_Array.H:33
Definition: AMReX_MLNodeLap_K.H:32
AMREX_GPU_DEVICE Dim3 operator()(int offset, Dim3 const &node)
Definition: AMReX_MLNodeLap_K.H:33
Definition: AMReX_MLNodeLap_K.H:15
AMREX_GPU_DEVICE Dim3 operator()(Dim3 const &lo, Dim3 const &len, int &offset)
Definition: AMReX_MLNodeLap_K.H:16