29#include <Kokkos_Core.hpp>
33#include "peclet/core/common/types.hpp"
34#include "peclet/core/decomp/block_decomposer.hpp"
39static constexpr int NX = 16,
NY = 16,
NZ = 32;
54 const double cx =
NX / 2.0 + 0.137, cy =
NY / 2.0 - 0.311;
55 const double cz = c.walls ?
NZ / 4.0 + 0.241 :
NZ / 2.0 + 0.241;
58 for (
int j = 0; j < NS; ++j)
59 for (
int i = 0; i < NS; ++i) {
60 const double px = x + (i + 0.5) / NS - cx, py = y + (j + 0.5) / NS - cy;
61 const double r2 =
RDROP *
RDROP - px * px - py * py;
64 const double h = std::sqrt(r2);
65 const double lo = std::fmax(cz - h, (
double)z), hi = std::fmin(cz + h, (
double)z + 1);
69 return acc / (NS * NS);
74 std::vector<double> v((std::size_t)
lnx *
lny *
lnz);
75 for (
int z = 0; z <
lnz; ++z)
76 for (
int y = 0; y <
lny; ++y)
77 for (
int x = 0; x <
lnx; ++x)
78 v[(std::size_t)x + (std::size_t)y *
lnx + (std::size_t)z *
lnx *
lny] =
79 f(x + ox, y + oy, z + oz);
100 s.
setVof(
blockOf([&](
int x,
int y,
int z) {
return colourAt(c, x, y, z); }, ox, oy, oz,
lnx,
lny,
109static std::vector<double>
gatherGlobal(
const std::vector<double>&
local,
int ox,
int oy,
int oz,
110 int lnx,
int lny,
int lnz,
int rank,
int size) {
111 std::vector<double>
global;
114 for (
int r = 0; r < size; ++r) {
118 for (
int z = 0; z <
lnz; ++z)
119 for (
int y = 0; y <
lny; ++y)
120 std::memcpy(&
global[(std::size_t)ox + (std::size_t)(y + oy) *
NX +
121 (std::size_t)(z + oz) *
NX *
NY],
123 (std::size_t)
lnx *
sizeof(
double));
129 }
else if (rank == 0) {
134 for (
int z = 0; z <
meta[5]; ++z)
135 for (
int y = 0; y <
meta[4]; ++y)
136 std::memcpy(&
global[(std::size_t)
meta[0] + (std::size_t)(y +
meta[1]) *
NX +
137 (std::size_t)(z +
meta[2]) *
NX *
NY],
139 (std::size_t)
meta[3] *
sizeof(
double));
145static double maxDiff(
const std::vector<double>& a,
const std::vector<double>& b) {
147 for (std::size_t i = 0; i < b.size(); ++i)
148 m = std::fmax(m, std::fabs(a[i] - b[i]));
151static long countBitDiff(
const std::vector<double>& a,
const std::vector<double>& b,
double& mx) {
154 for (std::size_t i = 0; i < b.size(); ++i)
157 mx = std::fmax(mx, std::fabs(a[i] - b[i]));
161static double maxAbs(
const std::vector<double>& v) {
164 m = std::fmax(m, std::fabs(x));
170 Kokkos::initialize(
argc, argv);
173 int rank = 0, size = 1;
177 auto dec = peclet::flow::CutcellMG::decomposition(
static_cast<std::size_t
>(size),
NX,
NY,
NZ);
178 auto blk =
dec.block(rank);
179 const int ox = (int)blk.origin[0], oy = (
int)blk.origin[1], oz = (int)blk.origin[2];
180 const int lnx = (int)blk.size[0],
lny = (
int)blk.size[1],
lnz = (int)blk.size[2];
181 const int gn[3] = {
NX,
NY,
NZ};
182 bool cut[3] = {
false,
false,
false};
183 for (
const auto& sz :
dec.sizes())
184 for (
int a = 0; a < 3; ++a)
185 if ((
int)sz[a] != gn[a])
189 "VOF SURFACE TENSION MPI np=%d grid %dx%dx%d block %dx%dx%d cut axes: %s%s%s\n", size,
190 NX,
NY,
NZ,
lnx,
lny,
lnz, cut[0] ?
"x" :
"", cut[1] ?
"y" :
"", cut[2] ?
"z" :
"");
193 {
"exact-walls-z",
true,
true},
194 {
"drop-per",
false,
false},
195 {
"drop-walls-z",
true,
false}};
198 if (size > 1 && !cut[2]) {
200 std::printf(
" [%-14s np=%d] FAIL — the decomposition does NOT cut z\n", c.name, size);
208 for (
int k = 0; k < 10; ++k)
217 std::vector<double> g[6];
218 const char* fn[6] = {
"u",
"v",
"w",
"P",
"C",
"kappa"};
225 const std::vector<double>
gb =
231 for (
int k = 0; k < 10; ++k)
233 std::vector<double> r[6] = {ref.getVelocity(0), ref.getVelocity(1), ref.getVelocity(2),
234 ref.getPressure(), ref.getVof(), ref.getVofCurvature()};
236 for (
int i = 0; i < 6; ++i)
238 double dkb = 0.0,
dkk = 0.0;
243 " [%-14s np=%d] max|u| = %.4e du %.2e dv %.2e dw %.2e dP %.2e"
244 " dC %.2e dkappa %.2e\n",
245 c.name, size,
gmax, d[0], d[1], d[2], d[3], d[4], d[5]);
255 std::printf(
" FAIL — the curvature BRANCH is decomposition-dependent (%ld cells)\n",
259 if (size == 1 &&
nkk != 0) {
260 std::printf(
" FAIL — kappa is not bitwise at np = 1 (%ld cells, max |d| %.3e)\n",
273 const double tol = c.walls ? 1e-8 : 1e-13;
275 std::printf(
" FAIL — the exactness gate is above %.0e (%.3e)\n",
tol,
gmax);
280 const double tolU = (size == 1) ? 0.0 : 1e-12;
281 const double tolP = (size == 1) ? 0.0 : 1e-9;
282 const double tolC = (size == 1) ? 0.0 : 1e-12;
283 const double tolK = (size == 1) ? 0.0 : 1e-12;
285 std::printf(
" FAIL — kappa differs by more than the colour's own floor (%.2e)\n",
291 " FAIL — the distributed step does not match the single-rank reference"
292 " (tolerances u %.0e P %.0e C %.0e)\n",
300 std::printf(
"%s\n",
fail ?
"FAILED" :
"PASSED");
void setVofKappaConstant(double kappa)
kappa is a PHYSICAL curvature, 1/length (the internal field is 1/h; see vof_curvature()).
std::vector< double > getVofCurvature()
The interface curvature kappa = 2H in the caller's units, i.e.
void setDomainBc(int face, int type, double vx, double vy, double vz)
std::vector< double > getVof()
void setPropertyModel(const std::string &target, ClosureKind kind, const std::string &in0, const std::string &in1, const std::vector< double > ¶ms)
void setSurfaceTension(double sigma)
std::vector< double > getVofCurvatureBranch()
void setPressureChebyshev(bool on, int maxit, double rtol)
double capillaryDt()
The Brackbill capillary limit in the CALLER's time unit.
void setVof(const std::vector< double > &c)
void setPressureGeometry(const std::vector< double > &sdfInner)
std::vector< double > getVelocity(int c)
void setMu(double m)
Dynamic viscosity, in the caller's units.
void setVelocityResidualTolerance(double rtol)
void setRho(double r)
Fluid density, in the caller's units.
std::vector< double > getPressure()
flow — host-facing Kokkos IBM Navier-Stokes solver (drop-in flow-style API).
static double maxAbs(const std::vector< double > &v)
static std::vector< double > blockOf(Fn f, int ox, int oy, int oz, int lnx, int lny, int lnz)
static constexpr double SIGMA
static double maxDiff(const std::vector< double > &a, const std::vector< double > &b)
static std::vector< double > gatherGlobal(const std::vector< double > &local, int ox, int oy, int oz, int lnx, int lny, int lnz, int rank, int size)
static constexpr double MU
static long countBitDiff(const std::vector< double > &a, const std::vector< double > &b, double &mx)
static constexpr double RHO_G
static double colourAt(const Config &c, int x, int y, int z)
static constexpr double RHO_L
static constexpr std::size_t GCELLS
static void configure(IbmSolver &s, const Config &c, int ox, int oy, int oz, int lnx, int lny, int lnz)
static constexpr double RDROP