flow 1.3.0
Kokkos cut-cell IBM incompressible Navier-Stokes solver + pnm pore extraction
Loading...
Searching...
No Matches
test_outflow_backflow.cpp
Go to the documentation of this file.
1// Outflow reversal census (IbmSolver::outflowBackflow) -- the detector for the one inflow/outflow
2// regime that is only conditionally energy-stable: reversed flow on a zero-gradient outflow face
3// with the backflow stabilization off (peclet-examples ISSUES.md "Inflow/outflow diverges to
4// NaN"). Plumbing gate on both grids' staggered path: a channel whose outlet is partly reversed
5// by the initial field reports the reversed half; a plain developing channel reports nothing.
6#include <cmath>
7#include <cstdio>
8#include <Kokkos_Core.hpp>
9#include <vector>
10
11#include "flow_ibm.hpp"
12
13namespace {
14int failures = 0;
15#define CHECK(cond) \
16 do { \
17 if (!(cond)) { \
18 std::fprintf(stderr, "CHECK failed: %s\n at %s:%d\n", #cond, __FILE__, __LINE__); \
19 ++failures; \
20 } \
21 } while (0)
22
23void configure(peclet::flow::IbmSolver& s, int nx, int ny, int nz, double U) {
24 s.setRho(1.0);
25 s.setMu(0.1);
26 s.setDt(0.01); // rho/dt dominates: one step leaves the imposed field nearly unchanged
27 s.setAdvection(true);
28 s.setDomainBc(0, 2, U, 0.0, 0.0); // -x inflow
29 s.setDomainBc(1, 3, 0.0, 0.0, 0.0); // +x outflow
30 s.setDomainBc(2, 1, 0.0, 0.0, 0.0);
31 s.setDomainBc(3, 1, 0.0, 0.0, 0.0);
32 s.setPressureLevels(3);
33 s.setPressurePcg(true, 100, 1e-8);
34 s.setPressureGeometry(std::vector<double>((std::size_t)nx * ny * nz, 1e30));
35}
36} // namespace
37
38int main(int argc, char** argv) {
39 Kokkos::initialize(argc, argv);
40 {
41 const int nx = 16, ny = 8, nz = 4;
42 const double U = 1.0;
43 // (1) partly reversed outlet: u = +3U in the upper half, -U in the lower half (net outgoing
44 // 2U*H/2 - U*H/2 > 0 so the projection keeps the lower half reversed), stabilization OFF ->
45 // the census reports the lower half and step() prints its warning once.
46 {
47 peclet::flow::IbmSolver s(nx, ny, nz);
48 configure(s, nx, ny, nz, U);
49 s.setBackflowStab(0.0);
50 std::vector<double> u((std::size_t)nx * ny * nz);
51 for (int z = 0; z < nz; ++z)
52 for (int y = 0; y < ny; ++y)
53 for (int x = 0; x < nx; ++x)
54 u[(std::size_t)x + (std::size_t)y * nx + (std::size_t)z * nx * ny] =
55 (y < ny / 2) ? -U : 3.0 * U;
56 s.setVelocity(0, u);
57 s.step();
58 const auto ob = s.outflowBackflow();
59 std::printf(
60 "[backflow] reversed outlet: max_reverse %.3f fraction %.3f energy_influx %.3e "
61 "(%ld / %ld faces)\n",
62 ob.maxReverse, ob.fraction, ob.energyInflux, ob.reversed, ob.total);
63 CHECK(ob.total == (long)ny * nz);
64 CHECK(ob.reversed > 0);
65 CHECK(ob.fraction > 0.3 && ob.fraction < 0.7);
66 CHECK(ob.maxReverse > 0.5 * U && ob.maxReverse < 1.5 * U);
67 CHECK(ob.energyInflux > 0.0);
68 }
69 // (2) the developing channel (uniform inlet, nothing reversed): all zeros, no warning.
70 {
71 peclet::flow::IbmSolver s(nx, ny, nz);
72 configure(s, nx, ny, nz, U);
73 for (int it = 0; it < 5; ++it)
74 s.step();
75 const auto ob = s.outflowBackflow();
76 std::printf("[backflow] developing channel: max_reverse %.3e fraction %.3f (%ld / %ld)\n",
77 ob.maxReverse, ob.fraction, ob.reversed, ob.total);
78 CHECK(ob.reversed == 0 && ob.maxReverse == 0.0 && ob.energyInflux == 0.0);
79 CHECK(ob.total == (long)ny * nz);
80 }
81 // (3) no outflow face at all (a periodic box): everything zero, total zero.
82 {
83 peclet::flow::IbmSolver s(nx, ny, nz);
84 s.setRho(1.0);
85 s.setMu(0.1);
86 s.setDt(0.01);
87 const auto ob = s.outflowBackflow();
88 CHECK(ob.total == 0 && ob.reversed == 0 && ob.maxReverse == 0.0);
89 }
90 if (failures == 0)
91 std::printf("[backflow] PASS (exec %s)\n", Kokkos::DefaultExecutionSpace::name());
92 else
93 std::fprintf(stderr, "[backflow] FAILED (%d checks)\n", failures);
94 }
95 Kokkos::finalize();
96 return failures == 0 ? 0 : 1;
97}
int main()
Definition dbg_scene.cpp:13
flow — host-facing Kokkos IBM Navier-Stokes solver (drop-in flow-style API).
static void configure(IbmSolver &s)
static constexpr double U
#define CHECK(cond)