Block-Structured AMR Software Framework
 
Loading...
Searching...
No Matches
AMReX_MLNodeTensorLap_2D_K.H
Go to the documentation of this file.
1#ifndef AMREX_MLNODETENSORLAP_2D_K_H_
2#define AMREX_MLNODETENSORLAP_2D_K_H_
3#include <AMReX_Config.H>
4
5namespace amrex {
6
7namespace mlndts_detail {
8
10 Real ts_interp_line_x (Array4<Real const> const& crse, int ic, int jc) noexcept
11 {
12 return (crse(ic,jc,0)+crse(ic+1,jc,0))*Real(0.5);
13 }
14
16 Real ts_interp_line_y (Array4<Real const> const& crse, int ic, int jc) noexcept
17 {
18 return (crse(ic,jc,0)+crse(ic,jc+1,0))*Real(0.5);
19 }
20
22 Real ts_interp_face_xy (Array4<Real const> const& crse, int ic, int jc) noexcept
23 {
24 return (ts_interp_line_y(crse,ic ,jc ) +
25 ts_interp_line_y(crse,ic+1,jc ) +
26 ts_interp_line_x(crse,ic ,jc ) +
27 ts_interp_line_x(crse,ic ,jc+1)) * Real(0.25);
28 }
29}
30
32void mlndtslap_interpadd (int i, int j, int, Array4<Real> const& fine,
33 Array4<Real const> const& crse, Array4<int const> const& msk) noexcept
34{
35 using namespace mlndts_detail;
36
37 if (!msk(i,j,0)) {
38 int ic = amrex::coarsen(i,2);
39 int jc = amrex::coarsen(j,2);
40 bool i_is_odd = (ic*2 != i);
41 bool j_is_odd = (jc*2 != j);
42 if (i_is_odd && j_is_odd) {
43 // Node on a X-Y face
44 fine(i,j,0) += ts_interp_face_xy(crse,ic,jc);
45 } else if (i_is_odd) {
46 // Node on X line
47 fine(i,j,0) += ts_interp_line_x(crse,ic,jc);
48 } else if (j_is_odd) {
49 // Node on Y line
50 fine(i,j,0) += ts_interp_line_y(crse,ic,jc);
51 } else {
52 // Node coincident with coarse node
53 fine(i,j,0) += crse(ic,jc,0);
54 }
55 }
56}
57
59void mlndtslap_semi_interpadd (int i, int j, int, Array4<Real> const& fine,
60 Array4<Real const> const& crse, Array4<int const> const& msk,
61 int semi_dir) noexcept
62{
63 using namespace mlndts_detail;
64
65 if (!msk(i,j,0)) {
66 if (semi_dir == 0) {
67 int jc = amrex::coarsen(j,2);
68 bool j_is_odd = (jc*2 != j);
69 if (j_is_odd) {
70 // Node on Y line
71 fine(i,j,0) += ts_interp_line_y(crse,i,jc);
72 } else {
73 // Node coincident with coarse node
74 fine(i,j,0) += crse(i,jc,0);
75 }
76 } else {
77 int ic = amrex::coarsen(i,2);
78 bool i_is_odd = (ic*2 != i);
79 if (i_is_odd) {
80 // Node on X line
81 fine(i,j,0) += ts_interp_line_x(crse,ic,j);
82 } else {
83 // Node coincident with coarse node
84 fine(i,j,0) += crse(ic,j,0);
85 }
86 }
87 }
88}
89
91void mlndtslap_adotx (int i, int j, int k, Array4<Real> const& y, Array4<Real const> const& x,
92 Array4<int const> const& msk, GpuArray<Real,3> const& s) noexcept
93{
94 if (msk(i,j,k)) {
95 y(i,j,k) = Real(0.0);
96 } else {
97 y(i,j,k) = s[0] * (x(i-1,j,0) + x(i+1,j,0))
98 + s[2] * (x(i,j-1,0) + x(i,j+1,0))
99 - Real(2.)*(s[0]+s[2]) * x(i,j,0)
100 + Real(0.5)*s[1] * (x(i-1,j-1,0) + x(i+1,j+1,0) - x(i-1,j+1,0) - x(i+1,j-1,0));
101 }
102}
103
105void mlndtslap_gauss_seidel (int i, int j, int k, Array4<Real> const& sol,
106 Array4<Real const> const& rhs, Array4<int const> const& msk,
107 GpuArray<Real,3> const& s) noexcept
108{
109 if (msk(i,j,k)) {
110 sol(i,j,k) = 0.0;
111 } else {
112 constexpr Real omega = Real(1.25);
113 Real s0 = Real(-2.)*(s[0]+s[2]);
114 Real Ax = s[0] * (sol(i-1,j,0) + sol(i+1,j,0))
115 + s[2] * (sol(i,j-1,0) + sol(i,j+1,0))
116 + s0 * sol(i,j,0)
117 + Real(0.5)*s[1] * (sol(i-1,j-1,0) + sol(i+1,j+1,0) - sol(i-1,j+1,0) - sol(i+1,j-1,0));
118 sol(i,j,k) += (rhs(i,j,k) - Ax) * (omega/s0);
119 }
120}
121
122#if defined(AMREX_USE_HYPRE) && (AMREX_SPACEDIM > 1)
123
124template <typename HypreInt, typename AtomicInt>
125void mlndtslap_fill_ijmatrix_cpu (Box const& ndbx,
126 Array4<AtomicInt const> const& gid,
127 Array4<int const> const& lid,
128 HypreInt* const ncols, HypreInt* const cols, Real* const mat, // NOLINT(readability-non-const-parameter)
129 GpuArray<Real,3> const& s) noexcept
130{
131 constexpr auto gidmax = std::numeric_limits<AtomicInt>::max();
132 HypreInt nelems = 0;
133 amrex::LoopOnCpu(ndbx, [&] (int i, int j, int k) noexcept
134 {
135 if (lid(i,j,k) >= 0)
136 {
137 HypreInt nelems_old = nelems;
138
139 cols[nelems] = gid(i,j,k);
140 mat[nelems] = Real(-2.)*(s[0]+s[2]);
141 ++nelems;
142
143 if (gid(i-1,j-1,k) < gidmax) {
144 cols[nelems] = gid(i-1,j-1,k);
145 mat[nelems] = Real(0.5)*s[1];
146 ++nelems;
147 }
148
149 if (gid(i,j-1,k) < gidmax) {
150 cols[nelems] = gid(i,j-1,k);
151 mat[nelems] = s[2];
152 ++nelems;
153 }
154
155 if (gid(i+1,j-1,k) < gidmax) {
156 cols[nelems] = gid(i+1,j-1,k);
157 mat[nelems] = Real(-0.5)*s[1];
158 ++nelems;
159 }
160
161 if (gid(i-1,j,k) < gidmax) {
162 cols[nelems] = gid(i-1,j,k);
163 mat[nelems] = s[0];
164 ++nelems;
165 }
166
167 if (gid(i+1,j,k) < gidmax) {
168 cols[nelems] = gid(i+1,j,k);
169 mat[nelems] = s[0];
170 ++nelems;
171 }
172
173 if (gid(i-1,j+1,k) < gidmax) {
174 cols[nelems] = gid(i-1,j+1,k);
175 mat[nelems] = Real(-0.5)*s[1];
176 ++nelems;
177 }
178
179 if (gid(i,j+1,k) < gidmax) {
180 cols[nelems] = gid(i,j+1,k);
181 mat[nelems] = s[2];
182 ++nelems;
183 }
184
185 if (gid(i+1,j+1,k) < gidmax) {
186 cols[nelems] = gid(i+1,j+1,k);
187 mat[nelems] = Real(0.5)*s[1];
188 ++nelems;
189 }
190
191 ncols[lid(i,j,k)] = nelems - nelems_old;
192 }
193 });
194}
195
196#ifdef AMREX_USE_GPU
197template <typename HypreInt, typename AtomicInt>
199void mlndtslap_fill_ijmatrix_gpu (const int ps, const int i, const int j, const int k,
200 const int offset, Box const& ndbx,
201 Array4<AtomicInt const> const& gid,
202 Array4<int const> const& lid,
203 HypreInt* const ncols, HypreInt* const cols, Real* const mat,
204 GpuArray<Real,3> const& s) noexcept
205{
206 if (lid(i,j,k) >= 0)
207 {
208 constexpr auto gidmax = std::numeric_limits<AtomicInt>::max();
209
210 if (offset == 0) {
211 cols[ps] = gid(i,j,k);
212 mat[ps] = Real(-2.)*(s[0]+s[2]);
213 int nc = 1;
214 if (gid(i-1,j-1,k) < gidmax) { ++nc; }
215 if (gid(i ,j-1,k) < gidmax) { ++nc; }
216 if (gid(i+1,j-1,k) < gidmax) { ++nc; }
217 if (gid(i-1,j ,k) < gidmax) { ++nc; }
218 if (gid(i+1,j ,k) < gidmax) { ++nc; }
219 if (gid(i-1,j+1,k) < gidmax) { ++nc; }
220 if (gid(i ,j+1,k) < gidmax) { ++nc; }
221 if (gid(i+1,j+1,k) < gidmax) { ++nc; }
222 ncols[lid(i,j,k)] = nc;
223 }
224 else if (offset == 1 && gid(i-1,j-1,k) < gidmax) {
225 cols[ps] = gid(i-1,j-1,k);
226 mat[ps] = Real(0.5)*s[1];
227 }
228 else if (offset == 2 && gid(i ,j-1,k) < gidmax) {
229 cols[ps] = gid(i ,j-1,k);
230 mat[ps] = s[2];
231 }
232 else if (offset == 3 && gid(i+1,j-1,k) < gidmax) {
233 cols[ps] = gid(i+1,j-1,k);
234 mat[ps] = Real(-0.5)*s[1];
235 }
236 else if (offset == 4 && gid(i-1,j ,k) < gidmax) {
237 cols[ps] = gid(i-1,j ,k);
238 mat[ps] = s[0];
239 }
240 else if (offset == 5 && gid(i+1,j ,k) < gidmax) {
241 cols[ps] = gid(i+1,j ,k);
242 mat[ps] = s[0];
243 }
244 else if (offset == 6 && gid(i-1,j+1,k) < gidmax) {
245 cols[ps] = gid(i-1,j+1,k);
246 mat[ps] = Real(-0.5)*s[1];
247 }
248 else if (offset == 7 && gid(i ,j+1,k) < gidmax) {
249 cols[ps] = gid(i ,j+1,k);
250 mat[ps] = s[2];
251 }
252 else if (offset == 8 && gid(i+1,j+1,k) < gidmax) {
253 cols[ps] = gid(i+1,j+1,k);
254 mat[ps] = Real(0.5)*s[1];
255 }
256 }
257}
258#endif
259
260#endif
261
262}
263
264#endif
#define AMREX_FORCE_INLINE
Definition AMReX_Extension.H:119
#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
Array4< Real > fine
Definition AMReX_InterpFaceRegister.cpp:90
Array4< Real const > crse
Definition AMReX_InterpFaceRegister.cpp:92
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE Real ts_interp_line_x(Array4< Real const > const &crse, int ic, int jc) noexcept
Definition AMReX_MLNodeTensorLap_2D_K.H:10
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE Real ts_interp_line_y(Array4< Real const > const &crse, int ic, int jc) noexcept
Definition AMReX_MLNodeTensorLap_2D_K.H:16
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE Real ts_interp_face_xy(Array4< Real const > const &crse, int ic, int jc) noexcept
Definition AMReX_MLNodeTensorLap_2D_K.H:22
Definition AMReX_Amr.cpp:49
AMREX_ATTRIBUTE_FLATTEN_FOR void LoopOnCpu(Dim3 lo, Dim3 hi, F const &f) noexcept
Definition AMReX_Loop.H:355
BoxND< AMREX_SPACEDIM > Box
Definition AMReX_BaseFwd.H:27
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void mlndtslap_adotx(int i, int j, int k, Array4< Real > const &y, Array4< Real const > const &x, Array4< int const > const &msk, GpuArray< Real, 3 > const &s) noexcept
Definition AMReX_MLNodeTensorLap_2D_K.H:91
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void mlndtslap_gauss_seidel(int i, int j, int k, Array4< Real > const &sol, Array4< Real const > const &rhs, Array4< int const > const &msk, GpuArray< Real, 3 > const &s) noexcept
Definition AMReX_MLNodeTensorLap_2D_K.H:105
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE BoxND< dim > coarsen(const BoxND< dim > &b, int ref_ratio) noexcept
Coarsen BoxND by given (positive) refinement ratio. NOTE: if type(dir) = CELL centered: lo <- lo/rati...
Definition AMReX_Box.H:1304
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void mlndtslap_semi_interpadd(int, int, int, Array4< Real > const &, Array4< Real const > const &, Array4< int const > const &, int) noexcept
Definition AMReX_MLNodeTensorLap_1D_K.H:13
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void mlndtslap_interpadd(int, int, int, Array4< Real > const &, Array4< Real const > const &, Array4< int const > const &) noexcept
Definition AMReX_MLNodeTensorLap_1D_K.H:8
Definition AMReX_Array4.H:61
Definition AMReX_Array.H:34