22 const double k = 2.0 * M_PI /
N;
23 auto hu = Kokkos::create_mirror_view(s.
u());
24 auto hv = Kokkos::create_mirror_view(s.
v());
25 auto hw = Kokkos::create_mirror_view(s.
w());
26 Kokkos::deep_copy(hu, s.
u());
27 Kokkos::deep_copy(hv, s.
v());
28 Kokkos::deep_copy(hw, s.
w());
29 u0.assign((
size_t)e.x * e.y * e.z, 0.0);
30 v0.assign(u0.size(), 0.0);
31 for (
int cz = 0; cz <
N; ++cz)
32 for (
int cy = 0; cy <
N; ++cy)
33 for (
int cx = 0; cx <
N; ++cx) {
34 long i = (long)(cx +
G) + (long)(cy +
G) * e.x + (long)(cz +
G) * (long)e.x * e.y;
35 double ux = cx, uy = cy + 0.5;
36 double vx = cx + 0.5, vy = cy;
37 hu(i) = std::cos(k * ux) * std::sin(k * uy);
38 hv(i) = -std::sin(k * vx) * std::cos(k * vy);
43 Kokkos::deep_copy(s.
u(), hu);
44 Kokkos::deep_copy(s.
v(), hv);
45 Kokkos::deep_copy(s.
w(), hw);
48int main(
int argc,
char** argv) {
49 Kokkos::initialize(argc, argv);
53 const double nu = 0.1, dt = 0.05;
54 const int nsteps = 10;
55 const double k = 2.0 * M_PI /
N;
56 const double Lambda = 4.0 * (1.0 - std::cos(k));
57 const double fStep = 1.0 / (1.0 + dt * nu * Lambda);
58 const double fExpect = std::pow(fStep, nsteps);
66 std::vector<double> u0, v0;
68 const double a0 = s.
l2(s.
u());
69 for (
int it = 0; it < nsteps; ++it)
71 const double a1 = s.
l2(s.
u());
72 const double ratio = a1 / a0;
73 const double divmax = s.
maxDivU();
76 auto hu = Kokkos::create_mirror_view(s.
u());
77 Kokkos::deep_copy(hu, s.
u());
79 double num = 0, den = 0;
80 for (
int cz = 0; cz <
N; ++cz)
81 for (
int cy = 0; cy <
N; ++cy)
82 for (
int cx = 0; cx <
N; ++cx) {
83 long i = (long)(cx + 2) + (long)(cy + 2) * e.x + (long)(cz + 2) * (long)e.x * e.y;
84 double pred = u0[i] * ratio;
85 num += (hu(i) - pred) * (hu(i) - pred);
88 double profErr = std::sqrt(num / den);
90 const double rateErr = std::fabs(ratio - fExpect) / fExpect;
92 "[sdflow_tg] STOKES: ratio=%.6f expected=%.6f (rel err %.2e); max|div|=%.2e; profile "
94 ratio, fExpect, rateErr, divmax, profErr);
96 std::fprintf(stderr,
"FAIL: decay rate off\n");
100 std::fprintf(stderr,
"FAIL: divergence not zero\n");
103 if (profErr > 5e-3) {
104 std::fprintf(stderr,
"FAIL: profile not preserved\n");
115 sMg.setAdvection(
true);
116 sMg.setPressureMultigrid(
true, 6);
120 std::vector<double> u0, v0;
123 const double a0 = sMg.l2(sMg.u());
124 for (
int it = 0; it < nsteps; ++it) {
128 const double ratio = sMg.l2(sMg.u()) / a0;
129 const double divMg = sMg.maxDivU(), divRb = sRb.
maxDivU();
130 const double rateErr = std::fabs(ratio - fExpect) / fExpect;
132 "[sdflow_tg] NS: ratio=%.6f expected=%.6f (rel err %.2e); max|div| MG(6 V-cyc)=%.2e "
133 "vs RB-GS(80 sweeps)=%.2e\n",
134 ratio, fExpect, rateErr, divMg, divRb);
135 if (rateErr > 5e-2) {
136 std::fprintf(stderr,
"FAIL: NS decay too far from TG\n");
140 std::fprintf(stderr,
"FAIL: MG divergence too large\n");
143 if (!(divMg < divRb)) {
144 std::fprintf(stderr,
"FAIL: MG did not beat RB-GS\n");
150 std::printf(
"[sdflow_tg] PASS: assembled Kokkos NS step reproduces Taylor-Green (exec: %s)\n",
151 Kokkos::DefaultExecutionSpace::name());