19#include <Kokkos_Core.hpp>
33 std::fprintf(stderr, "CHECK failed: %s\n at %s:%d\n", #cond, __FILE__, __LINE__); \
39double maxAbsDiff(
const std::vector<double>& a,
const std::vector<double>& b) {
40 if (a.size() != b.size())
43 for (std::size_t i = 0; i < a.size(); ++i) {
44 const double d = std::abs(a[i] - b[i]);
52 std::vector<double>
C,
u,
v,
w, P;
57 st.C =
s.getField(
"C");
58 st.u =
s.getVelocity(0);
59 st.v =
s.getVelocity(1);
60 st.w =
s.getVelocity(2);
61 st.P =
s.getPressure();
65double diff(
const State& a,
const State& b) {
76std::unique_ptr<IbmSolver> makeScene(
int n,
bool solid,
bool timing,
bool worklist) {
77 auto s = std::make_unique<IbmSolver>(n, n, n);
80 const double R = 0.3 *
n;
81 std::vector<double>
sdf((std::size_t)n * n * n, 10.0);
83 const double Rs = 0.16 *
n;
84 for (
int k = 0;
k <
n; ++
k)
85 for (
int j = 0;
j <
n; ++
j)
86 for (
int i = 0;
i <
n; ++
i) {
88 for (
int a = 0;
a < 2; ++
a)
89 for (
int b = 0;
b < 2; ++
b)
90 for (
int c = 0;
c < 2; ++
c) {
91 const double cx = (0.25 + 0.5 *
a) * n, cy = (0.25 + 0.5 * b) *
n,
92 cz = (0.25 + 0.5 *
c) * n;
93 const double dx =
i + 0.5 - cx,
dy =
j + 0.5 - cy,
dz =
k + 0.5 - cz;
94 best = std::fmin(best, std::sqrt(dx * dx + dy * dy + dz * dz) - Rs);
96 sdf[(std::size_t)i + (std::size_t)
j *
n + (std::size_t)k * n * n] = best;
98 s->setSolid(sdf,
true);
100 s->setPressureGeometry(sdf);
103 s->setVofWorklist(worklist);
104 s->setVofCurvatureWorklist(worklist);
105 std::vector<double>
C((std::size_t)n * n * n, 0.0);
106 for (
int k = 0;
k <
n; ++
k)
107 for (
int j = 0;
j <
n; ++
j)
108 for (
int i = 0;
i <
n; ++
i) {
109 const double dx =
i + 0.5 - 0.5 *
n - 0.13,
dy =
j + 0.5 - 0.5 *
n - 0.27,
110 dz =
k + 0.5 - 0.5 *
n - 0.11;
112 const double r = std::sqrt(dx * dx + dy * dy + dz * dz);
113 C[(std::size_t)i + (std::size_t)
j *
n + (std::size_t)k * n * n] =
114 std::fmin(1.0, std::fmax(0.0, 0.5 - (r - R)));
117 s->setPropertyModel(
"rho", ClosureKind::LinearMix,
"C",
"", {1.0, 9.0});
118 s->setPropertyModel(
"mu", ClosureKind::LinearMix,
"C",
"", {0.005, 0.045});
119 s->setSurfaceTension(2.0);
120 s->enableVofMomentum(1.0, 10.0);
121 s->setPropertyModel(
"force_z", ClosureKind::LinearMix,
"C",
"", {-0.01, -0.09});
122 s->setPressureChebyshev(
true, 300, 1e-12);
123 s->setDt(0.4 *
s->capillaryDt());
125 s->setVofTiming(
true);
129State
run(
int n,
bool solid,
bool timing,
bool worklist,
int steps) {
130 auto s = makeScene(n, solid, timing, worklist);
131 for (
int i = 0;
i <
steps; ++
i)
137int main(
int argc,
char** argv) {
138 Kokkos::initialize(argc, argv);
140 const int n = 24, steps = 30;
141 for (
int solid = 0; solid < 2; ++solid) {
142 const char* tag = solid ?
"cut-cell" :
"all-fluid";
143 const State off =
run(n, solid,
false,
true, steps);
144 const State on =
run(n, solid,
true,
true, steps);
145 const double d1 = diff(off, on);
146 std::printf(
"T1/T2 %-9s timers OFF vs ON max|d| = %.3e\n", tag, d1);
148 const State nowl =
run(n, solid,
false,
false, steps);
149 const double d2 = diff(off, nowl);
150 std::printf(
"T3 %-9s worklists ON vs OFF max|d| = %.3e\n", tag, d2);
154 auto s = makeScene(n,
false,
true,
true);
155 for (
int i = 0; i < 10; ++i)
157 const auto& v = s->vofTimingReport();
158 const auto& k = s->vofKernelTiming();
159 const auto& q = s->vofCurvatureTiming();
161 "T4 steps %ld momAdvect %.4f s curvature %.4f s csf %.4f s "
162 "[recon %.4f fluxes %.4f sweep %.4f exch %.4f]\n",
163 v.steps, v.momAdvect, v.curvature, v.csf, k.reconstruct, k.fluxes, k.sweep, k.exchange);
164 CHECK(v.steps == 10);
165 CHECK(v.momAdvect > 0.0);
166 CHECK(v.curvature > 0.0);
168 CHECK(k.sweeps == 30);
169 CHECK(k.reconstruct > 0.0 && k.fluxes > 0.0 && k.sweep > 0.0);
171 CHECK(k.reconstruct + k.fluxes + k.sweep + k.clip + k.exchange + k.freeze <=
172 v.momAdvect * 1.02 + 1e-6);
174 "T4 curvature passes: compact %.4f planes %.4f height %.4f fallback %.4f "
175 "census %.4f (%ld calls)\n",
176 q.compact, q.planes, q.height, q.fallback, q.census, q.calls);
177 CHECK(q.calls == 10);
178 CHECK(q.planes > 0.0 && q.height > 0.0);
179 CHECK(q.compact + q.planes + q.height + q.fallback + q.census <= v.curvature * 1.02 + 1e-6);
180 s->setVofTiming(
false);
181 const auto& z = s->vofTimingReport();
182 CHECK(z.steps == 0 && z.momAdvect == 0.0);
flow — host-facing Kokkos IBM Navier-Stokes solver (drop-in flow-style API).
static double maxAbsDiff(const std::vector< double > &a, const std::vector< double > &b)