flow
Kokkos cut-cell IBM incompressible Navier-Stokes solver + pnm pore extraction
Loading...
Searching...
No Matches
test_bc.cpp
Go to the documentation of this file.
1// Correctness of the Kokkos domain BC ghost fills (peclet::flow::bcVelocityComp / bcOutflowComp /
2// bcZeroOpenness) vs host replication, over several (axis, side, comp, fold) cases. The BC only
3// touches the boundary face + ghost cells; we compare the whole field. Runs on any Kokkos backend.
4#include <cmath>
5#include <cstdio>
6#include <Kokkos_Core.hpp>
7#include <random>
8#include <vector>
9
10#include "mac_bc.hpp"
11
12using namespace peclet::flow;
13
14static void hostVel(std::vector<double>& f, B3 ext, int g, int a, int s, int comp, double wall,
15 int fold) {
16 int dims[3] = {ext.x, ext.y, ext.z};
17 long st[3] = {1, ext.x, (long)ext.x * ext.y};
18 int b = (a + 1) % 3, c = (a + 2) % 3;
19 long sa = st[a], sb = st[b], sc = st[c];
20 int na = dims[a], bf = (s == 0) ? g : (na - g);
21 for (int p0 = 0; p0 < dims[b]; ++p0)
22 for (int p1 = 0; p1 < dims[c]; ++p1) {
23 long base = (long)p0 * sb + (long)p1 * sc;
24 auto at = [&](int ia) -> double& { return f[base + (long)ia * sa]; };
25 if (comp == a) {
26 at(bf) = wall;
27 if (s == 0)
28 for (int ia = 0; ia < g; ++ia)
29 at(ia) = 2.0 * wall - at(2 * bf - ia);
30 else
31 for (int ia = na - g + 1; ia < na; ++ia)
32 at(ia) = 2.0 * wall - at(2 * bf - ia);
33 } else if (fold) {
34 if (s == 0)
35 for (int ia = 0; ia < g; ++ia)
36 at(ia) = 0.0;
37 else
38 for (int ia = na - g; ia < na; ++ia)
39 at(ia) = 0.0;
40 } else {
41 if (s == 0)
42 for (int ia = 0; ia < g; ++ia)
43 at(ia) = 2.0 * wall - at(2 * bf - 1 - ia);
44 else
45 for (int ia = na - g; ia < na; ++ia)
46 at(ia) = 2.0 * wall - at(2 * bf - 1 - ia);
47 }
48 }
49}
50static void hostZeroOpen(std::vector<double>& oa, B3 ext, int g, int a, int s) {
51 int dims[3] = {ext.x, ext.y, ext.z};
52 long st[3] = {1, ext.x, (long)ext.x * ext.y};
53 int b = (a + 1) % 3, c = (a + 2) % 3, bf = (s == 0) ? g : (dims[a] - g);
54 for (int p0 = 0; p0 < dims[b]; ++p0)
55 for (int p1 = 0; p1 < dims[c]; ++p1)
56 oa[(long)p0 * st[b] + (long)p1 * st[c] + (long)bf * st[a]] = 0.0;
57}
58
59int main(int argc, char** argv) {
60 Kokkos::initialize(argc, argv);
61 int status = 0;
62 {
63 const int g = 2;
64 B3 ext{12, 10, 8};
65 const std::size_t n = (std::size_t)ext.x * ext.y * ext.z;
66 std::mt19937 rng(44);
67 std::uniform_real_distribution<double> uf(-1.0, 1.0);
68 std::vector<double> base(n);
69 for (auto& x : base)
70 x = uf(rng);
71
72 auto up = [&](std::vector<double>& h) {
73 BField v("v", n);
74 auto m = Kokkos::create_mirror_view(v);
75 for (std::size_t i = 0; i < n; ++i)
76 m(i) = h[i];
77 Kokkos::deep_copy(v, m);
78 return v;
79 };
80 auto get = [&](BField v) {
81 std::vector<double> o(n);
82 auto m = Kokkos::create_mirror_view(v);
83 Kokkos::deep_copy(m, v);
84 for (std::size_t i = 0; i < n; ++i)
85 o[i] = m(i);
86 return o;
87 };
88 auto close = [](double x, double y) {
89 return std::fabs(x - y) <= 1e-12 * (1.0 + std::fabs(y));
90 };
91
92 int bad = 0, cases = 0;
93 // velocity BC: all axes, both sides, normal + tangential, fold 0/1
94 for (int a = 0; a < 3; ++a)
95 for (int s = 0; s < 2; ++s)
96 for (int comp = 0; comp < 3; ++comp)
97 for (int fold = 0; fold < 2; ++fold) {
98 std::vector<double> h = base;
99 BField d = up(h);
100 const double wall = 0.37;
101 bcVelocityComp(d, ext, g, a, s, comp, wall, fold);
102 hostVel(h, ext, g, a, s, comp, wall, fold);
103 auto gd = get(d);
104 for (std::size_t i = 0; i < n; ++i)
105 if (!close(gd[i], h[i]))
106 ++bad;
107 ++cases;
108 }
109 // wall openness
110 for (int a = 0; a < 3; ++a)
111 for (int s = 0; s < 2; ++s) {
112 std::vector<double> h = base;
113 BField d = up(h);
114 bcZeroOpenness(d, ext, g, a, s);
115 hostZeroOpen(h, ext, g, a, s);
116 auto gd = get(d);
117 for (std::size_t i = 0; i < n; ++i)
118 if (!close(gd[i], h[i]))
119 ++bad;
120 ++cases;
121 }
122
123 if (bad) {
124 std::fprintf(stderr, "FAIL: %d mismatches across %d BC cases\n", bad, cases);
125 status = 1;
126 } else
127 std::printf(
128 "[mac_bc] PASS: %d BC cases (velocity normal/tangential/fold + wall openness) match host "
129 "(exec: %s)\n",
130 cases, BExec::name());
131 }
132 Kokkos::finalize();
133 return status;
134}
flow — portable (Kokkos) native per-face domain boundary conditions for the MAC grid.
void bcZeroOpenness(BField oa, B3 ext, int g, int a, int s)
Definition mac_bc.hpp:250
void bcVelocityComp(BField f, B3 ext, int g, int a, int s, int comp, double wall, int fold, BField prof=BField(), int prof_nc=0)
Definition mac_bc.hpp:38
Kokkos::View< double *, BMem > BField
Definition mac_bc.hpp:19
int main(int argc, char **argv)
Definition test_bc.cpp:59
static void hostZeroOpen(std::vector< double > &oa, B3 ext, int g, int a, int s)
Definition test_bc.cpp:50
static void hostVel(std::vector< double > &f, B3 ext, int g, int a, int s, int comp, double wall, int fold)
Definition test_bc.cpp:14