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