16#include <Kokkos_Core.hpp>
21#include "peclet/core/common/types.hpp"
22#include "peclet/core/decomp/block_decomposer.hpp"
24using peclet::core::IVec;
27static constexpr int N = 32,
STEPS = 30;
28static constexpr double RHO = 1.0,
MU = 0.1,
F = 1e-3,
DT = 20.0;
31 const double R =
rfrac *
N;
32 std::vector<double> sdf((std::size_t)
N *
N *
N);
33 const double cs[2] = {0.25 *
N, 0.75 *
N};
34 for (
int z = 0; z <
N; ++z)
35 for (
int y = 0; y <
N; ++y)
36 for (
int x = 0; x <
N; ++x) {
40 for (
double sz : cs) {
41 auto wrap = [](
double d) {
return d -
N * std::round(d /
N); };
42 const double dx = wrap(x -
sx), dy = wrap(y - sy), dz = wrap(z - sz);
43 best = std::min(
best, std::sqrt(dx * dx + dy * dy + dz * dz) - R);
45 sdf[(std::size_t)x + (std::size_t)y *
N + (std::size_t)z *
N *
N] =
best;
51static double muAt(
int x,
int y,
int) {
52 return MU * (1.2 + 0.5 * std::sin(2.0 *
M_PI * x /
N) * std::cos(2.0 *
M_PI * y /
N));
54static double rhoAt(
int,
int,
int z) {
55 return RHO * (1.0 + 0.4 * std::sin(2.0 *
M_PI * z /
N));
57static double epsAt(
int,
int,
int z) {
58 return 0.6 + 0.3 * std::sin(2.0 *
M_PI * z /
N);
61 auto wrap = [](
double d) {
return d -
N * std::round(d /
N); };
62 const double dx = wrap(x - 0.5 *
N), dy = wrap(y - 0.5 *
N), dz = wrap(z - 0.5 *
N);
63 return std::exp(-(dx * dx + dy * dy + dz * dz) / (2.0 * 16.0));
69 std::vector<double> v((std::size_t)
lnx *
lny *
lnz);
70 for (
int z = 0; z <
lnz; ++z)
71 for (
int y = 0; y <
lny; ++y)
72 for (
int x = 0; x <
lnx; ++x)
73 v[(std::size_t)x + (std::size_t)y *
lnx + (std::size_t)z *
lnx *
lny] =
74 f(x + ox, y + oy, z + oz);
84 int oy,
int oz,
int lnx,
int lny,
int lnz) {
130static std::vector<double>
gatherGlobal(
const std::vector<double>&
local,
int ox,
int oy,
int oz,
131 int lnx,
int lny,
int lnz,
int rank,
int size) {
132 std::vector<double>
global;
134 global.assign((std::size_t)
N *
N *
N, 0.0);
135 for (
int r = 0; r < size; ++r) {
139 for (
int z = 0; z <
lnz; ++z)
140 for (
int y = 0; y <
lny; ++y)
141 std::memcpy(&
global[(std::size_t)ox + (std::size_t)(y + oy) *
N +
142 (std::size_t)(z + oz) *
N *
N],
144 (std::size_t)
lnx *
sizeof(
double));
150 }
else if (rank == 0) {
155 for (
int z = 0; z <
meta[5]; ++z)
156 for (
int y = 0; y <
meta[4]; ++y)
157 std::memcpy(&
global[(std::size_t)
meta[0] + (std::size_t)(y +
meta[1]) *
N +
158 (std::size_t)(z +
meta[2]) *
N *
N],
160 (std::size_t)
meta[3] *
sizeof(
double));
167static double relErr(
const std::vector<double>& a,
const std::vector<double>& b) {
168 double md = 0,
mb = 0;
169 for (std::size_t i = 0; i < b.size(); ++i) {
170 md = std::max(
md, std::fabs(a[i] - b[i]));
171 mb = std::max(
mb, std::fabs(b[i]));
173 return md / (
mb + 1e-300);
178 Kokkos::initialize(
argc, argv);
181 int rank = 0, size = 1;
186 peclet::core::decomp::BlockDecomposer<3>
dec(
static_cast<std::size_t
>(size),
IVec<3>{
N,
N,
N});
187 auto blk =
dec.block(rank);
188 const int ox = (int)blk.origin[0], oy = (
int)blk.origin[1], oz = (int)blk.origin[2];
189 const int lnx = (int)blk.size[0],
lny = (
int)blk.size[1],
lnz = (int)blk.size[2];
191 for (
int z = 0; z <
lnz; ++z)
192 for (
int y = 0; y <
lny; ++y)
193 for (
int x = 0; x <
lnx; ++x)
194 lsdf[(std::size_t)x + (std::size_t)y *
lnx + (std::size_t)z *
lnx *
lny] =
195 gsdf[(std::size_t)(x + ox) + (std::size_t)(y + oy) *
N +
196 (std::size_t)(z + oz) *
N *
N];
198 const Config configs[] = {{
"varmu",
true,
false,
false,
false,
false},
199 {
"varrho",
false,
true,
false,
false,
false},
200 {
"porous",
false,
false,
true,
false,
false},
201 {
"scalar",
false,
false,
false,
true,
false},
202 {
"scalarbc",
false,
false,
false,
false,
true}};
209 for (
int it = 0; it <
STEPS; ++it)
212 std::vector<double> gc;
213 if (c.scalar || c.scalarBc)
217 double eu = -1, ec = -1;
221 for (
int it = 0; it <
STEPS; ++it)
224 const bool hasC = c.scalar || c.scalarBc;
226 ec =
relErr(gc, ref.getField(
"c"));
227 const double tol = (size == 1) ? 1e-12 : 5e-5;
229 std::printf(
" [%-8s np=%d] u rel=%.3e%s tol=%.0e %s\n", c.name, size,
eu,
230 hasC ? (std::string(
" c rel=") + std::to_string(ec)).c_str() :
"",
tol,
238 std::printf(
"MULTIPHYSICS MPI (np=%d): %s\n", size,
fail ?
"FAIL" :
"PASS");
void setSolid(const std::vector< double > &sdfInner, bool cutcellPressure)
Host entry point: upload the inner SDF once and delegate.
std::vector< double > getField(const std::string &name)
void setPropertyMode(bool variable, bool harmonic)
void exchangeField(const std::string &name)
void setAdvection(bool on)
void addScalar(const std::string &name, double D, int scheme, int iters, bool cutcell=false)
void setVelocityIterations(int it)
void setScalarBc(const std::string &name, int face, int type, double value)
void setPressureLevels(int levels)
void setField(const std::string &name, const std::vector< double > &v)
void setBodyForce(double fx, double fy, double fz)
Body force per unit volume, in the caller's units (e.g. a mean pressure gradient, or rho*g).
std::vector< double > getVelocity(int c)
void setPressurePcg(bool on, int maxit, double rtol)
void setDensityMode(bool variable)
void setMu(double m)
Dynamic viscosity, in the caller's units.
void setPorousContinuity(bool on)
void setRho(double r)
Fluid density, in the caller's units.
flow — host-facing Kokkos IBM Navier-Stokes solver (drop-in flow-style API).
static std::vector< double > blockOf(Fn f, int ox, int oy, int oz, int lnx, int lny, int lnz)
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 RHO
static constexpr double MU
static double rhoAt(int, int, int z)
static constexpr int STEPS
static constexpr double DT
static double muAt(int x, int y, int)
static constexpr double F
static double scalarAt(int x, int y, int z)
static void configure(IbmSolver &s, const Config &c, const std::vector< double > &lsdf, int ox, int oy, int oz, int lnx, int lny, int lnz)
static std::vector< double > packingSdf(double rfrac=0.18)
static double relErr(const std::vector< double > &a, const std::vector< double > &b)
static double epsAt(int, int, int z)