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 #include <AMReX_MLNodeLinOp_K.H>
11 
12 namespace amrex {
13 
14 namespace nodelap_detail {
15 
16 #if (BL_USE_FLOAT)
17  constexpr float eps = 1.e-30_rt;
18 #else
19  constexpr double eps = 1.e-100_rt;
20 #endif
21  constexpr Real almostone = Real(1.) - Real(100.)*std::numeric_limits<Real>::epsilon();
22  constexpr Real almostzero = Real(1.) - almostone;
23 
24 }
25 
26 inline void
27 mlndlap_scale_neumann_bc (Real s, Box const& bx, Array4<Real> const& rhs, Box const& nddom,
29  GpuArray<LinOpBCType,AMREX_SPACEDIM> const& hibc) noexcept
30 {
31  for (int idim = 0; idim < AMREX_SPACEDIM; ++idim) {
32  if (lobc[idim] == LinOpBCType::Neumann || lobc[idim] == LinOpBCType::inflow) {
33  Box const& blo = amrex::bdryLo(bx, idim);
34  if (blo.smallEnd(idim) == nddom.smallEnd(idim)) {
36  {
37  rhs(i,j,k) *= s;
38  });
39  }
40  }
41  if (hibc[idim] == LinOpBCType::Neumann || hibc[idim] == LinOpBCType::inflow) {
42  Box const& bhi = amrex::bdryHi(bx, idim);
43  if (bhi.bigEnd(idim) == nddom.bigEnd(idim)) {
45  {
46  rhs(i,j,k) *= s;
47  });
48  }
49  }
50  }
51 }
52 
53 inline void
54 mlndlap_impose_neumann_bc (Box const& bx, Array4<Real> const& rhs, Box const& nddom,
56  GpuArray<LinOpBCType,AMREX_SPACEDIM> const& hibc) noexcept
57 {
58  mlndlap_scale_neumann_bc(2.0, bx, rhs, nddom, lobc, hibc);
59 }
60 
61 inline void
62 mlndlap_unimpose_neumann_bc (Box const& bx, Array4<Real> const& rhs, Box const& nddom,
64  GpuArray<LinOpBCType,AMREX_SPACEDIM> const& hibc) noexcept
65 {
66  mlndlap_scale_neumann_bc(0.5, bx, rhs, nddom, lobc, hibc);
67 }
68 
69 }
70 
71 #if (AMREX_SPACEDIM == 1)
72 #include <AMReX_MLNodeLap_1D_K.H>
73 #elif (AMREX_SPACEDIM == 2)
74 #include <AMReX_MLNodeLap_2D_K.H>
75 #else
76 #include <AMReX_MLNodeLap_3D_K.H>
77 #endif
78 
79 namespace amrex {
80 
82 void mlndlap_normalize_sten (int i, int j, int k, Array4<Real> const& x,
83  Array4<Real const> const& sten,
84  Array4<int const> const& msk, Real s0_norm0) noexcept
85 {
86  if (!msk(i,j,k) && std::abs(sten(i,j,k,0)) > s0_norm0) {
87  x(i,j,k) /= sten(i,j,k,0);
88  }
89 }
90 
92 void mlndlap_jacobi_sten (int i, int j, int k, Array4<Real> const& sol,
93  Real Ax, Array4<Real const> const& rhs,
94  Array4<Real const> const& sten,
95  Array4<int const> const& msk) noexcept
96 {
97  if (msk(i,j,k)) {
98  sol(i,j,k) = Real(0.0);
99  } else if (sten(i,j,k,0) != Real(0.0)) {
100  sol(i,j,k) += Real(2./3.) * (rhs(i,j,k) - Ax) / sten(i,j,k,0);
101  }
102 }
103 
105 void mlndlap_jacobi_sten (Box const& bx, Array4<Real> const& sol,
106  Array4<Real const> const& Ax,
107  Array4<Real const> const& rhs,
108  Array4<Real const> const& sten,
109  Array4<int const> const& msk) noexcept
110 {
111  amrex::LoopConcurrent(bx, [=] (int i, int j, int k) noexcept
112  {
113  if (msk(i,j,k)) {
114  sol(i,j,k) = Real(0.0);
115  } else if (sten(i,j,k,0) != Real(0.0)) {
116  sol(i,j,k) += Real(2./3.) * (rhs(i,j,k) - Ax(i,j,k)) / sten(i,j,k,0);
117  }
118  });
119 }
120 
122 bool mlndlap_any_fine_sync_cells (Box const& bx, Array4<int const> const& msk, int fine_flag) noexcept
123 {
124  const auto lo = amrex::lbound(bx);
125  const auto hi = amrex::ubound(bx);
126  for (int k = lo.z; k <= hi.z; ++k) {
127  for (int j = lo.y; j <= hi.y; ++j) {
128  for (int i = lo.x; i <= hi.x; ++i) {
129  if (msk(i,j,k) == fine_flag) { return true; }
130  }}}
131  return false;
132 }
133 
134 }
135 
136 #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_HOST_DEVICE
Definition: AMReX_GpuQualifiers.H:20
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
constexpr Real almostzero
Definition: AMReX_MLNodeLap_K.H:22
constexpr double eps
Definition: AMReX_MLNodeLap_K.H:19
constexpr Real almostone
Definition: AMReX_MLNodeLap_K.H:21
Definition: AMReX_Amr.cpp:49
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:27
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:92
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE T abs(const GpuComplex< T > &a_z) noexcept
Return the absolute value of a complex number.
Definition: AMReX_GpuComplex.H:356
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:54
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:122
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:62
AMREX_GPU_HOST_DEVICE AMREX_ATTRIBUTE_FLATTEN_FOR void LoopConcurrent(Dim3 lo, Dim3 hi, F const &f) noexcept
Definition: AMReX_Loop.H:150
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:82
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_Array.H:34