flow
Kokkos cut-cell IBM incompressible Navier-Stokes solver + pnm pore extraction
Loading...
Searching...
No Matches
test_field_registry.cpp
Go to the documentation of this file.
1// Field registry on the flow Solver — the named directory of cell fields (multiphysics container).
2// Verifies the built-in fields are adopted, a user field allocates + round-trips through the inner
3// region (scatterInner/gatherInner), and fieldView aliases the live buffer.
4#include <cstdio>
5#include <Kokkos_Core.hpp>
6#include <vector>
7
8#include "flow_ibm.hpp"
9
10namespace {
11int failures = 0;
12#define CHECK(cond) \
13 do { \
14 if (!(cond)) { \
15 std::fprintf(stderr, "CHECK failed: %s\n at %s:%d\n", #cond, __FILE__, __LINE__); \
16 ++failures; \
17 } \
18 } while (0)
19
20void run() {
22 const int nx = 6, ny = 5, nz = 4;
23 IbmSolver s(nx, ny, nz);
24
25 // Built-in members are registered.
26 CHECK(s.hasField("u") && s.hasField("v") && s.hasField("w"));
27 CHECK(s.hasField("p") && s.hasField("sdf"));
28 CHECK(!s.hasField("temperature"));
29 auto names = s.fieldNames();
30 CHECK(names.size() == 5); // u,v,w,p,sdf; sorted
31 CHECK(names.front() == "p");
32
33 // Add a user field: zero-initialised, then x-fastest inner round-trip.
34 s.addField("temperature");
35 CHECK(s.hasField("temperature"));
36 std::vector<double> in((std::size_t)nx * ny * nz);
37 for (std::size_t i = 0; i < in.size(); ++i)
38 in[i] = 1.0 + (double)i;
39 s.setField("temperature", in);
40 auto out = s.getField("temperature");
41 CHECK(out.size() == in.size());
42 bool exact = true;
43 for (std::size_t i = 0; i < in.size(); ++i)
44 exact = exact && (out[i] == in[i]);
45 CHECK(exact);
46
47 // fieldView aliases the live buffer: mutate a ghost-included element, gatherInner unaffected at
48 // ghosts but inner cell (g,g,g) maps to inner index 0.
49 auto fv = s.fieldView("temperature");
50 const auto bs = s.blockShape();
51 const int g = s.ghostWidth();
52 const long ex = bs[0], ey = bs[1];
53 // inner (0,0,0) lives at flat (g + g*ex + g*ex*ey)
54 const long inner0 = g + (long)g * ex + (long)g * ex * ey;
55 auto h = Kokkos::create_mirror_view(fv);
56 Kokkos::deep_copy(h, fv);
57 CHECK(h(inner0) == in[0]);
58 h(inner0) = 123.0;
59 Kokkos::deep_copy(fv, h);
60 CHECK(s.getField("temperature")[0] == 123.0);
61
62 // Idempotent add: existing data preserved.
63 s.addField("temperature");
64 CHECK(s.getField("temperature")[0] == 123.0);
65}
66} // namespace
67
68int main(int argc, char** argv) {
69 Kokkos::initialize(argc, argv);
70 run();
71 Kokkos::finalize();
72 if (failures == 0) {
73 std::printf("OK\n");
74 return 0;
75 }
76 std::fprintf(stderr, "%d failure(s)\n", failures);
77 return 1;
78}
flow — host-facing Kokkos IBM Navier-Stokes solver (drop-in flow-style API).
int main(int argc, char **argv)
#define CHECK(cond)
static int run(int bc)