31#include <Kokkos_Core.hpp>
35#include "peclet/core/common/types.hpp"
36#include "peclet/core/decomp/block_decomposer.hpp"
40static constexpr int NX = 16,
NY = 16,
NZ = 32;
51static const double UNIF[3] = {1.0, 0.6, -0.4};
57 double m[3] = {0.6, -0.5, 0.62456};
58 const double l1 = std::fabs(m[0]) + std::fabs(m[1]) + std::fabs(m[2]);
61 const double alpha = 0.5 * (m[0] *
NX + m[1] *
NY + m[2] *
NZ);
62 return peclet::flow::vof::plicVolume(m[0], m[1], m[2], alpha - (m[0] * x + m[1] * y + m[2] * z));
65 return 5e-2 * std::sin(2 *
M_PI * (z + 0.5) /
NZ);
70 std::vector<double> v((std::size_t)
lnx *
lny *
lnz);
71 for (
int z = 0; z <
lnz; ++z)
72 for (
int y = 0; y <
lny; ++y)
73 for (
int x = 0; x <
lnx; ++x)
74 v[(std::size_t)x + (std::size_t)y *
lnx + (std::size_t)z *
lnx *
lny] =
75 f(x + ox, y + oy, z + oz);
82 s.
setMu(c.walls ? 0.0 : 0.05);
97 const std::size_t nc = (std::size_t)
lnx *
lny *
lnz;
100 std::vector<double>(nc,
UNIF[2]));
103static std::vector<double>
gatherGlobal(
const std::vector<double>&
local,
int ox,
int oy,
int oz,
104 int lnx,
int lny,
int lnz,
int rank,
int size) {
105 std::vector<double>
global;
108 for (
int r = 0; r < size; ++r) {
112 for (
int z = 0; z <
lnz; ++z)
113 for (
int y = 0; y <
lny; ++y)
114 std::memcpy(&
global[(std::size_t)ox + (std::size_t)(y + oy) *
NX +
115 (std::size_t)(z + oz) *
NX *
NY],
117 (std::size_t)
lnx *
sizeof(
double));
123 }
else if (rank == 0) {
128 for (
int z = 0; z <
meta[5]; ++z)
129 for (
int y = 0; y <
meta[4]; ++y)
130 std::memcpy(&
global[(std::size_t)
meta[0] + (std::size_t)(y +
meta[1]) *
NX +
131 (std::size_t)(z +
meta[2]) *
NX *
NY],
133 (std::size_t)
meta[3] *
sizeof(
double));
139static double maxAbsDiff(
const std::vector<double>& a,
const std::vector<double>& b) {
144 for (std::size_t i = 0; i < b.size(); ++i) {
145 const double d = std::fabs(a[i] - b[i]);
152static double maxAbs(
const std::vector<double>& a) {
155 m = std::fmax(m, std::fabs(v));
158static double maxAbsDev(
const std::vector<double>& a,
double r) {
161 m = std::fmax(m, std::fabs(v - r));
168static std::vector<double>
demean(std::vector<double> v) {
172 const double m = s / (
double)v.size();
177static double sumOf(
const std::vector<double>& a) {
186 Kokkos::initialize(
argc, argv);
189 int rank = 0, size = 1;
193 auto dec = peclet::flow::CutcellMG::decomposition(
static_cast<std::size_t
>(size),
NX,
NY,
NZ);
194 auto blk =
dec.block(rank);
195 const int ox = (int)blk.origin[0], oy = (
int)blk.origin[1], oz = (int)blk.origin[2];
196 const int lnx = (int)blk.size[0],
lny = (
int)blk.size[1],
lnz = (int)blk.size[2];
197 const int gn[3] = {
NX,
NY,
NZ};
198 bool cut[3] = {
false,
false,
false};
199 for (
const auto& sz :
dec.sizes())
200 for (
int a = 0; a < 3; ++a)
201 if ((
int)sz[a] != gn[a])
204 std::printf(
"VOF MOMENTUM MPI np=%d grid %dx%dx%d block %dx%dx%d cut axes: %s%s%s\n", size,
208 const Config configs[] = {{
"walls-z",
true, 1000.0, 0.2, 10},
209 {
"shear-per",
false, 10.0, 0.2, 40}};
212 if (size > 1 && !cut[2]) {
214 std::printf(
" [%-9s np=%d] FAIL — the decomposition does NOT cut z\n", c.name, size);
229 for (
int comp = 0; comp < 3; ++comp)
237 for (
int it = 1; it < c.steps; ++it)
243 std::vector<double>
gu[3],
gua[3];
244 for (
int comp = 0; comp < 3; ++comp) {
249 const std::vector<double>
gp =
251 const std::vector<double> gc =
256 std::printf(
" [%-9s np=%d] uniform-velocity identity on the advection: %.17g%s\n",
257 c.name, size,
ident,
ident == 0.0 ?
" (BITWISE, all ranks)" :
"");
258 if (!(
ident == 0.0)) {
259 std::printf(
" [%-9s np=%d] FAIL — the identity is not exact under decomposition\n",
265 for (
int it = 0; it < c.steps; ++it)
267 double du = 0,
umag = 0,
dua = 0;
268 for (
int comp = 0; comp < 3; ++comp) {
269 du = std::fmax(du,
maxAbsDiff(
gu[comp], ref.getVelocity(comp)));
273 const double dp = c.walls ?
maxAbsDiff(
gp, ref.getPressure())
276 const double pmag =
maxAbs(ref.getPressure());
277 const double drift = (
v1 -
v0) /
v0;
278 const double utol = (size == 1) ? 0.0 : std::fmax(1e-12, 1e-11 *
umag);
279 const double ptol = (size == 1) ? 0.0 : std::fmax(1e-12, 1e-11 *
pmag);
280 const double ctol = (size == 1) ? 0.0 : 1e-11;
282 " [%-9s np=%d] du %.3e du_adv %.3e (tol %.1e, |u| %.2e) dp %.3e (tol %.1e, "
283 "|P| %.2e) dC %.3e (tol %.1e) dV/V %+.3e\n",
284 c.name, size, du,
dua,
utol,
umag, dp,
ptol,
pmag,
dc,
ctol, drift);
286 std::printf(
" [%-9s np=%d] FAIL — distributed vs single-rank\n", c.name, size);
289 if (!c.walls && !(std::fabs(drift) < 1e-11)) {
290 std::printf(
" [%-9s np=%d] FAIL — colour volume drift %.3e\n", c.name, size, drift);
297 std::printf(
fail ?
"FAILED\n" :
"OK\n");
void setDomainBc(int face, int type, double vx, double vy, double vz)
std::vector< double > getVofAdvectedVelocity(int c)
void setAdvection(bool on)
void uploadVelocity(const std::vector< double > &uu, const std::vector< double > &vv, const std::vector< double > &ww)
Upload an initial velocity field in the caller's PHYSICAL units (converted per component to the index...
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 enableVofMomentum(double rhoGasPhys, double rhoLiquidPhys)
rhoGas / rhoLiquid are PHYSICAL densities, the same numbers the rho closure is given.
void setVof(const std::vector< double > &c)
void setPressureGeometry(const std::vector< double > &sdfInner)
void setField(const std::string &name, const std::vector< double > &v)
std::vector< double > getVelocity(int c)
void setMu(double m)
Dynamic viscosity, in the caller's units.
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 > &a)
static std::vector< double > demean(std::vector< double > v)
static const double UNIF[3]
static std::vector< double > blockOf(Fn f, int ox, int oy, int oz, int lnx, int lny, int lnz)
static double forceXAt(int, int, int z)
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 double maxAbsDev(const std::vector< double > &a, double r)
static double maxAbsDiff(const std::vector< double > &a, const std::vector< double > &b)
static double sumOf(const std::vector< double > &a)
static double colourAt(int x, int y, int z)
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)