flow 0.4.0
Kokkos cut-cell IBM incompressible Navier-Stokes solver + pnm pore extraction
Loading...
Searching...
No Matches
mac_stencils.hpp
Go to the documentation of this file.
1
11#ifndef PECLET_FLOW_MAC_STENCILS_HPP
12#define PECLET_FLOW_MAC_STENCILS_HPP
13
14#include <Kokkos_Core.hpp>
15#include <type_traits>
16
17namespace peclet::flow {
18
19using SExec = Kokkos::DefaultExecutionSpace;
20using SMem = SExec::memory_space;
21using SField = Kokkos::View<double*, SMem>;
22using SConst = Kokkos::View<const double*, SMem>;
23
24struct I3 {
25 int x, y, z;
26};
27
28KOKKOS_INLINE_FUNCTION long L3(int x, int y, int z, I3 e) {
29 return static_cast<long>(x) + static_cast<long>(y) * e.x +
30 static_cast<long>(z) * static_cast<long>(e.x) * e.y;
31}
32
33// One Red-Black sweep colour of the implicit-diffusion smoother:
34// c[i] = (b[i] + beta*sum_neighbours) / (Ac + dcorr[i]). Call for colour 0 then 1.
35// Host backends take the line-sweep form (one (y,z) pencil per task, stride-2 x-loop at the
36// colour's parity — bit-identical, same-colour cells are independent); device keeps MDRange.
37inline void diffSmoothColor(SField c, SConst b, I3 e, I3 og, int g, double beta, double Ac,
38 int color, SConst dcorr) {
40 const bool hasD = (dcorr.extent(0) != 0);
41 if constexpr (std::is_same_v<typename SExec::memory_space, Kokkos::HostSpace>) {
42 const int nyi = e.y - 2 * g, nzi = e.z - 2 * g;
43 Kokkos::parallel_for(
44 "peclet::flow::diff", Kokkos::RangePolicy<SExec>(space, 0, (long)nyi * nzi),
45 KOKKOS_LAMBDA(long t) {
46 const int y = g + (int)(t % nyi), z = g + (int)(t / nyi);
47 const long sx = 1, sy = e.x, sz = static_cast<long>(e.x) * e.y;
48 const int P = (color + og.x + og.y + y + og.z + z) & 1;
49 for (int x = g + ((P ^ (g & 1)) & 1); x < e.x - g; x += 2) {
50 const long i = L3(x, y, z, e);
51 const double s =
52 c(i + sx) + c(i - sx) + c(i + sy) + c(i - sy) + c(i + sz) + c(i - sz);
53 c(i) = (b(i) + beta * s) / (Ac + (hasD ? dcorr(i) : 0.0));
54 }
55 });
56 return;
57 }
58 using MD = Kokkos::MDRangePolicy<SExec, Kokkos::Rank<3>>;
59 Kokkos::parallel_for(
60 "peclet::flow::diff", MD(space, {g, g, g}, {e.x - g, e.y - g, e.z - g}),
61 KOKKOS_LAMBDA(int x, int y, int z) {
62 if ((((x + og.x) + (y + og.y) + (z + og.z)) & 1) != color)
63 return;
64 const long i = L3(x, y, z, e), sx = 1, sy = e.x, sz = static_cast<long>(e.x) * e.y;
65 const double s = c(i + sx) + c(i - sx) + c(i + sy) + c(i - sy) + c(i + sz) + c(i - sz);
66 c(i) = (b(i) + beta * s) / (Ac + (hasD ? dcorr(i) : 0.0));
67 });
68}
69
70// diffSmoothColor + fused max|Δ| reduction over the swept colour (see ibmRbgsStencilColorDu):
71// runs as the second colour of a sweep when the momentum tolerance stop is active.
72inline double diffSmoothColorDu(SField c, SConst b, I3 e, I3 og, int g, double beta, double Ac,
73 int color, SConst dcorr) {
75 const bool hasD = (dcorr.extent(0) != 0);
76 double du = 0.0;
77 if constexpr (std::is_same_v<typename SExec::memory_space, Kokkos::HostSpace>) {
78 const int nyi = e.y - 2 * g, nzi = e.z - 2 * g;
79 Kokkos::parallel_reduce(
80 "peclet::flow::diff_du", Kokkos::RangePolicy<SExec>(space, 0, (long)nyi * nzi),
81 KOKKOS_LAMBDA(long t, double& m) {
82 const int y = g + (int)(t % nyi), z = g + (int)(t / nyi);
83 const long sx = 1, sy = e.x, sz = static_cast<long>(e.x) * e.y;
84 const int P = (color + og.x + og.y + y + og.z + z) & 1;
85 for (int x = g + ((P ^ (g & 1)) & 1); x < e.x - g; x += 2) {
86 const long i = L3(x, y, z, e);
87 const double s =
88 c(i + sx) + c(i - sx) + c(i + sy) + c(i - sy) + c(i + sz) + c(i - sz);
89 const double cn = (b(i) + beta * s) / (Ac + (hasD ? dcorr(i) : 0.0));
90 const double d = Kokkos::fabs(cn - c(i));
91 if (d > m)
92 m = d;
93 c(i) = cn;
94 }
95 },
96 Kokkos::Max<double>(du));
97 return du;
98 }
99 using MD = Kokkos::MDRangePolicy<SExec, Kokkos::Rank<3>>;
100 Kokkos::parallel_reduce(
101 "peclet::flow::diff_du", MD(space, {g, g, g}, {e.x - g, e.y - g, e.z - g}),
102 KOKKOS_LAMBDA(int x, int y, int z, double& m) {
103 if ((((x + og.x) + (y + og.y) + (z + og.z)) & 1) != color)
104 return;
105 const long i = L3(x, y, z, e), sx = 1, sy = e.x, sz = static_cast<long>(e.x) * e.y;
106 const double s = c(i + sx) + c(i - sx) + c(i + sy) + c(i - sy) + c(i + sz) + c(i - sz);
107 const double cn = (b(i) + beta * s) / (Ac + (hasD ? dcorr(i) : 0.0));
108 const double d = Kokkos::fabs(cn - c(i));
109 if (d > m)
110 m = d;
111 c(i) = cn;
112 },
113 Kokkos::Max<double>(du));
114 return du;
115}
116
117// One Red-Black sweep colour of the (unit-coefficient) Poisson smoother: phi[i] = (sum - d[i]) / 6.
118inline void poisSmoothColor(SField phi, SConst d, I3 e, I3 og, int g, int color) {
119 SExec space;
120 using MD = Kokkos::MDRangePolicy<SExec, Kokkos::Rank<3>>;
121 Kokkos::parallel_for(
122 "peclet::flow::pois", MD(space, {g, g, g}, {e.x - g, e.y - g, e.z - g}),
123 KOKKOS_LAMBDA(int x, int y, int z) {
124 if ((((x + og.x) + (y + og.y) + (z + og.z)) & 1) != color)
125 return;
126 const long i = L3(x, y, z, e), sx = 1, sy = e.x, sz = static_cast<long>(e.x) * e.y;
127 const double s =
128 phi(i + sx) + phi(i - sx) + phi(i + sy) + phi(i - sy) + phi(i + sz) + phi(i - sz);
129 phi(i) = (s - d(i)) / 6.0;
130 });
131}
132
133// MAC divergence d[i] = (u[i+sx]-u[i]) + (v[i+sy]-v[i]) + (w[i+sz]-w[i]) over inner cells.
134inline void divergence(SConst u, SConst v, SConst w, SField d, I3 e, int g) {
135 SExec space;
136 using MD = Kokkos::MDRangePolicy<SExec, Kokkos::Rank<3>>;
137 Kokkos::parallel_for(
138 "peclet::flow::diverg", MD(space, {g, g, g}, {e.x - g, e.y - g, e.z - g}),
139 KOKKOS_LAMBDA(int x, int y, int z) {
140 const long i = L3(x, y, z, e), sx = 1, sy = e.x, sz = static_cast<long>(e.x) * e.y;
141 d(i) = (u(i + sx) - u(i)) + (v(i + sy) - v(i)) + (w(i + sz) - w(i));
142 });
143}
144
145// Full Red-Black Gauss-Seidel sweep (both colours) of the Poisson smoother.
146inline void poisSweep(SField phi, SConst d, I3 e, I3 og, int g) {
147 poisSmoothColor(phi, d, e, og, g, 0);
148 poisSmoothColor(phi, d, e, og, g, 1);
149}
150
151} // namespace peclet::flow
152
153#endif // PECLET_FLOW_MAC_STENCILS_HPP
long L3(int x, int y, int z, I3 e)
void divergence(SConst u, SConst v, SConst w, SField d, I3 e, int g)
void diffSmoothColor(SField c, SConst b, I3 e, I3 og, int g, double beta, double Ac, int color, SConst dcorr)
double diffSmoothColorDu(SField c, SConst b, I3 e, I3 og, int g, double beta, double Ac, int color, SConst dcorr)
void ibmFillEntry(const OV &o, int list_idx, int c_idx, float sdf_c, const float sdf_n[6], int bc_type, const float *thEx)
Kokkos::View< const double *, SMem > SConst
void poisSmoothColor(SField phi, SConst d, I3 e, I3 og, int g, int color)
SExec::memory_space SMem
Kokkos::DefaultExecutionSpace SExec
Kokkos::View< double *, SMem > SField
void poisSweep(SField phi, SConst d, I3 e, I3 og, int g)