flow
Kokkos cut-cell IBM incompressible Navier-Stokes solver + pnm pore extraction
Loading...
Searching...
No Matches
mac_transfer.hpp
Go to the documentation of this file.
1
8#ifndef PECLET_FLOW_MAC_TRANSFER_HPP
9#define PECLET_FLOW_MAC_TRANSFER_HPP
10
11#include <Kokkos_Core.hpp>
12#include <Kokkos_MathematicalFunctions.hpp>
13
14namespace peclet::flow {
15
16using TExec = Kokkos::DefaultExecutionSpace;
17using TMem = TExec::memory_space;
18using TField = Kokkos::View<double*, TMem>;
19using TConst = Kokkos::View<const double*, TMem>;
20
21struct T3 {
22 int x, y, z;
23};
24
25// Averaging restriction: coarse[ic] = mean of the ratio^3 fine cells it covers.
26inline void restrict_(TField coarse, TConst fine, T3 cext, T3 fext, int g, T3 cinner, T3 ratio) {
27 TExec space;
28 using MD = Kokkos::MDRangePolicy<TExec, Kokkos::Rank<3>>;
29 Kokkos::parallel_for(
30 "peclet::flow::restrict", MD(space, {0, 0, 0}, {cinner.x, cinner.y, cinner.z}),
31 KOKKOS_LAMBDA(int icx, int icy, int icz) {
32 const long fsy = fext.x, fsz = static_cast<long>(fext.x) * fext.y;
33 double sum = 0.0;
34 for (int dz = 0; dz < ratio.z; ++dz)
35 for (int dy = 0; dy < ratio.y; ++dy)
36 for (int dx = 0; dx < ratio.x; ++dx) {
37 const int fx = ratio.x * icx + dx + g, fy = ratio.y * icy + dy + g,
38 fz = ratio.z * icz + dz + g;
39 sum += fine(static_cast<long>(fx) + static_cast<long>(fy) * fsy +
40 static_cast<long>(fz) * fsz);
41 }
42 const long ci = static_cast<long>(icx + g) + static_cast<long>(icy + g) * cext.x +
43 static_cast<long>(icz + g) * static_cast<long>(cext.x) * cext.y;
44 coarse(ci) = sum / static_cast<double>(ratio.x * ratio.y * ratio.z);
45 });
46}
47
48KOKKOS_INLINE_FUNCTION double trilerp(TConst c, double x, double y, double z, T3 cext) {
49 const double fx = Kokkos::floor(x), fy = Kokkos::floor(y), fz = Kokkos::floor(z);
50 const double wx = x - fx, wy = y - fy, wz = z - fz;
51 const int x0 = (int)fx, y0 = (int)fy, z0 = (int)fz;
52 const long sy = cext.x, sz = static_cast<long>(cext.x) * cext.y;
53 auto F = [&](int xx, int yy, int zz) {
54 return c(static_cast<long>(xx) + static_cast<long>(yy) * sy + static_cast<long>(zz) * sz);
55 };
56 const double c00 = F(x0, y0, z0) * (1 - wx) + F(x0 + 1, y0, z0) * wx;
57 const double c10 = F(x0, y0 + 1, z0) * (1 - wx) + F(x0 + 1, y0 + 1, z0) * wx;
58 const double c01 = F(x0, y0, z0 + 1) * (1 - wx) + F(x0 + 1, y0, z0 + 1) * wx;
59 const double c11 = F(x0, y0 + 1, z0 + 1) * (1 - wx) + F(x0 + 1, y0 + 1, z0 + 1) * wx;
60 const double c0 = c00 * (1 - wy) + c10 * wy;
61 const double c1 = c01 * (1 - wy) + c11 * wy;
62 return c0 * (1 - wz) + c1 * wz;
63}
64
65// Trilinear prolongation of the coarse correction, ADDED to the fine field (coarse ghost
66// pre-filled).
67inline void prolong(TField fine, TConst coarse, T3 fext, T3 cext, int g, T3 finner, T3 ratio) {
68 TExec space;
69 using MD = Kokkos::MDRangePolicy<TExec, Kokkos::Rank<3>>;
70 Kokkos::parallel_for(
71 "peclet::flow::prolong", MD(space, {0, 0, 0}, {finner.x, finner.y, finner.z}),
72 KOKKOS_LAMBDA(int ifx, int ify, int ifz) {
73 const double cx = ratio.x == 2 ? 0.5 * ifx - 0.25 + g : (double)(ifx + g);
74 const double cy = ratio.y == 2 ? 0.5 * ify - 0.25 + g : (double)(ify + g);
75 const double cz = ratio.z == 2 ? 0.5 * ifz - 0.25 + g : (double)(ifz + g);
76 const long fi = static_cast<long>(ifx + g) + static_cast<long>(ify + g) * fext.x +
77 static_cast<long>(ifz + g) * static_cast<long>(fext.x) * fext.y;
78 fine(fi) += trilerp(coarse, cx, cy, cz, cext);
79 });
80}
81
82// Projection velocity correction: u -= grad(phi) on the staggered faces, over inner cells.
83inline void correct(TField u, TField v, TField w, TConst phi, T3 e, int g) {
84 TExec space;
85 using MD = Kokkos::MDRangePolicy<TExec, Kokkos::Rank<3>>;
86 Kokkos::parallel_for(
87 "peclet::flow::correct", MD(space, {g, g, g}, {e.x - g, e.y - g, e.z - g}),
88 KOKKOS_LAMBDA(int x, int y, int z) {
89 const long i = static_cast<long>(x) + static_cast<long>(y) * e.x +
90 static_cast<long>(z) * static_cast<long>(e.x) * e.y;
91 const long sx = 1, sy = e.x, sz = static_cast<long>(e.x) * e.y;
92 u(i) -= phi(i) - phi(i - sx);
93 v(i) -= phi(i) - phi(i - sy);
94 w(i) -= phi(i) - phi(i - sz);
95 });
96}
97
98} // namespace peclet::flow
99
100#endif // PECLET_FLOW_MAC_TRANSFER_HPP
void correct(TField u, TField v, TField w, TConst phi, T3 e, int g)
Kokkos::DefaultExecutionSpace TExec
Kokkos::View< const double *, TMem > TConst
TExec::memory_space TMem
void restrict_(TField coarse, TConst fine, T3 cext, T3 fext, int g, T3 cinner, T3 ratio)
Kokkos::View< double *, TMem > TField
void prolong(TField fine, TConst coarse, T3 fext, T3 cext, int g, T3 finner, T3 ratio)
double trilerp(TConst c, double x, double y, double z, T3 cext)
static constexpr double F