flow
Kokkos cut-cell IBM incompressible Navier-Stokes solver + pnm pore extraction
Loading...
Searching...
No Matches
test_fou_operator.cpp
Go to the documentation of this file.
1// Consistency of the implicit-FOU advection operator (sadv::fou_operator) with the explicit FOU
2// flux (sadv::advect_fou): the 7-point operator coefficients applied to a field PHI must equal
3// dt*advect_fou(PHI) per cell. Also checks fou_operator_aniso(s=1) == fou_operator and that the
4// operator is diagonally dominant (cC >= sum|off|). Runs on any Kokkos backend.
5#include <cmath>
6#include <cstdio>
7#include <Kokkos_Core.hpp>
8#include <random>
9#include <vector>
10
12
13using namespace sadv;
14using Mem = Kokkos::DefaultExecutionSpace::memory_space;
15using DView = Kokkos::View<double*, Mem>;
16using CView = Kokkos::View<const double*, Mem>;
17
18int main(int argc, char** argv) {
19 Kokkos::initialize(argc, argv);
20 int status = 0;
21 {
22 const int g = 2, inx = 14, iny = 12, inz = 10;
23 const int ex = inx + 2 * g, ey = iny + 2 * g, ez = inz + 2 * g;
24 const std::size_t n = (std::size_t)ex * ey * ez;
25 const double dt = 0.3;
26
27 std::mt19937 rng(6);
28 std::uniform_real_distribution<double> uf(-1.0, 1.0);
29 std::vector<double> hU(n), hV(n), hW(n), hP(n);
30 for (std::size_t i = 0; i < n; ++i) {
31 hU[i] = uf(rng);
32 hV[i] = uf(rng);
33 hW[i] = uf(rng);
34 hP[i] = uf(rng);
35 }
36 auto up = [&](const char* nm, std::vector<double>& h) {
37 DView v(nm, n);
38 auto m = Kokkos::create_mirror_view(v);
39 for (std::size_t i = 0; i < n; ++i)
40 m(i) = h[i];
41 Kokkos::deep_copy(v, m);
42 return v;
43 };
44 DView U = up("U", hU), V = up("V", hV), W = up("W", hW), P = up("P", hP);
45
46 const long ninner = (long)inx * iny * inz;
47 DView resid("resid", ninner); // |LHS-RHS| (operator vs explicit flux) + aniso diff
48 const int comp = 1;
49 Kokkos::parallel_for(
50 "fou_op", Kokkos::RangePolicy<Kokkos::DefaultExecutionSpace>(0, ninner),
51 KOKKOS_LAMBDA(long c) {
52 const int lx = (int)(c % inx), ly = (int)((c / inx) % iny),
53 lz = (int)(c / ((long)inx * iny));
54 const int x = lx + g, y = ly + g, z = lz + g;
55 ViewAcc Ua{CView(U), ex, ey}, Va{CView(V), ex, ey}, Wa{CView(W), ex, ey},
56 Pa{CView(P), ex, ey};
57 double cC = 0, cxm = 0, cxp = 0, cym = 0, cyp = 0, czm = 0, czp = 0;
58 fou_operator(comp, x, y, z, Ua, Va, Wa, dt, cC, cxm, cxp, cym, cyp, czm, czp);
59 // also aniso with s=1 must match
60 double aC = 0, axm = 0, axp = 0, aym = 0, ayp = 0, azm = 0, azp = 0;
61 fou_operator_aniso(comp, x, y, z, Ua, Va, Wa, dt, 1.0, 1.0, 1.0, aC, axm, axp, aym, ayp,
62 azm, azp);
63 long sx = 1, sy = ex, sz = (long)ex * ey, i = (long)x + (long)y * ex + (long)z * sz;
64 double lhs = cC * Pa(x, y, z) + cxm * P(i - sx) + cxp * P(i + sx) + cym * P(i - sy) +
65 cyp * P(i + sy) + czm * P(i - sz) + czp * P(i + sz);
66 double rhs = dt * advect_fou(comp, x, y, z, Ua, Va, Wa, Pa);
67 double anisoDiff = Kokkos::fabs(aC - cC) + Kokkos::fabs(axm - cxm) +
68 Kokkos::fabs(axp - cxp) + Kokkos::fabs(aym - cym) +
69 Kokkos::fabs(ayp - cyp) + Kokkos::fabs(azm - czm) +
70 Kokkos::fabs(azp - czp);
71 // cC - sum|off| = dt*div(advecting velocity) (exact identity); >= 0 only for a div-free
72 // field (as in the real solver). With random velocity here it can be negative — not a
73 // defect.
74 resid(c) = Kokkos::fabs(lhs - rhs) + anisoDiff;
75 });
76 auto hr = Kokkos::create_mirror_view(resid);
77 Kokkos::deep_copy(hr, resid);
78 int bad = 0;
79 double maxr = 0;
80 for (long c = 0; c < ninner; ++c) {
81 if (hr(c) > 1e-12 * (1 + std::fabs(hr(c))))
82 ++bad;
83 if (hr(c) > maxr)
84 maxr = hr(c);
85 }
86 if (bad) {
87 std::fprintf(stderr, "FAIL: %ld/%ld cells operator != dt*advect_fou (max %.2e)\n", (long)bad,
88 ninner, maxr);
89 status = 1;
90 }
91 if (!status)
92 std::printf(
93 "[fou_operator] PASS: operator == dt*advect_fou and aniso(s=1)==fou_operator (%ld cells, "
94 "exec %s)\n",
95 ninner, Kokkos::DefaultExecutionSpace::name());
96 }
97 Kokkos::finalize();
98 return status;
99}
void fou_operator_aniso(int comp, int x, int y, int z, A U, A V, A W, double dt, double sx, double sy, double sz, double &cC, double &cxm, double &cxp, double &cym, double &cyp, double &czm, double &czp)
void fou_operator(int comp, int x, int y, int z, A U, A V, A W, double dt, double &cC, double &cxm, double &cxp, double &cym, double &cyp, double &czm, double &czp)
double advect_fou(int comp, int x, int y, int z, A U, A V, A W, A PHI)
flow — portable (Kokkos) staggered MAC momentum advection (Koren TVD + FOU).
Kokkos::DefaultExecutionSpace::memory_space Mem
Kokkos::View< const double *, Mem > CView
Kokkos::View< double *, Mem > DView
int main(int argc, char **argv)
Kokkos::View< const double *, Mem > CView