22#include <Kokkos_Core.hpp>
26#include "peclet/core/common/types.hpp"
27#include "peclet/core/decomp/block_decomposer.hpp"
29using peclet::core::IVec;
30using peclet::core::decomp::BlockDecomposer;
33static constexpr int N = 32,
STEPS = 20;
34static constexpr double RHO = 1.0,
MU = 0.1,
F = 1e-3,
DT = 20.0;
37 const double R =
rfrac *
N;
38 std::vector<double> sdf((std::size_t)
N *
N *
N);
39 const double cs[2] = {0.25 *
N, 0.75 *
N};
40 for (
int z = 0; z <
N; ++z)
41 for (
int y = 0; y <
N; ++y)
42 for (
int x = 0; x <
N; ++x) {
46 for (
double sz : cs) {
47 auto wrap = [](
double d) {
return d -
N * std::round(d /
N); };
48 const double dx = wrap(x -
sx), dy = wrap(y - sy), dz = wrap(z - sz);
49 best = std::min(
best, std::sqrt(dx * dx + dy * dy + dz * dz) - R);
51 sdf[(std::size_t)x + (std::size_t)y *
N + (std::size_t)z *
N *
N] =
best;
56static double epsAt(
int x,
int,
int z) {
57 return 0.6 + 0.25 * std::sin(2.0 *
M_PI * z /
N) + 0.05 * std::cos(2.0 *
M_PI * x /
N);
63 const auto b =
dec.block(rank);
64 const int ox = (int)b.origin[0], oy = (
int)b.origin[1], oz = (int)b.origin[2];
65 const int lnx = (int)b.size[0],
lny = (
int)b.size[1],
lnz = (int)b.size[2];
66 std::vector<double> l((std::size_t)
lnx *
lny *
lnz);
67 for (
int z = 0; z <
lnz; ++z)
68 for (
int y = 0; y <
lny; ++y)
69 for (
int x = 0; x <
lnx; ++x)
70 l[(std::size_t)x + (std::size_t)y *
lnx + (std::size_t)z *
lnx *
lny] =
71 g[(std::size_t)(x + ox) + (std::size_t)(y + oy) *
N + (std::size_t)(z + oz) *
N *
N];
76 const std::vector<double>&
leps) {
95 std::vector<double>
global;
97 global.assign((std::size_t)
N *
N *
N, 0.0);
98 for (
int r = 0; r < size; ++r) {
99 const auto b =
dec.block(r);
100 const int ox = (int)b.origin[0], oy = (
int)b.origin[1], oz = (int)b.origin[2];
101 const int lnx = (int)b.size[0],
lny = (
int)b.size[1],
lnz = (int)b.size[2];
102 std::vector<double>
buf;
108 else if (rank == 0) {
115 for (
int z = 0; z <
lnz; ++z)
116 for (
int y = 0; y <
lny; ++y)
118 &
global[(std::size_t)ox + (std::size_t)(y + oy) *
N + (std::size_t)(z + oz) *
N *
N],
119 &
buf[(std::size_t)y *
lnx + (std::size_t)z *
lnx *
lny],
120 (std::size_t)
lnx *
sizeof(
double));
127 Kokkos::initialize(
argc, argv);
128 int fail = 0, size = 1, rank = 0;
133 std::vector<double>
geps((std::size_t)
N *
N *
N);
134 for (
int z = 0; z <
N; ++z)
135 for (
int y = 0; y <
N; ++y)
136 for (
int x = 0; x <
N; ++x)
137 geps[(std::size_t)x + (std::size_t)y *
N + (std::size_t)z *
N *
N] =
epsAt(x, y, z);
142 std::vector<peclet::core::Real> w((std::size_t)
N *
N *
N, 1.0);
143 for (
int z = 0; z <
N; ++z)
144 for (
int y = 0; y <
N; ++y)
145 for (
int x = 0; x <
N; ++x)
146 if (x <
N / 3 || z <
N / 4)
147 w[(std::size_t)x + (std::size_t)y *
N + (std::size_t)z *
N *
N] = 5.0;
150 for (
int k = 0; k < 3; ++k)
151 resized |=
D1.block(rank).size[k] !=
D2.block(rank).size[k];
153 const auto b1 =
D1.block(rank);
157 for (
int it = 0; it <
STEPS / 2; ++it)
170 for (
int it = 0; it <
STEPS; ++it)
172 const std::vector<double>
ur = ref.getVelocity(0),
wr = ref.getVelocity(2);
173 double du = 0, dw = 0, mu = 0;
174 for (std::size_t i = 0; i <
ur.size(); ++i) {
175 du = std::max(du, std::fabs(
ud[i] -
ur[i]));
176 dw = std::max(dw, std::fabs(
wd[i] -
wr[i]));
177 mu = std::max(mu, std::fabs(
ur[i]));
179 const double rel = std::max(du, dw) / mu;
180 const double tol = (size == 1) ? 0.0 : 1e-6;
182 " np=%d: blocks resized %s; max|du|=%.3e max|dw|=%.3e (max|u| %.3e) rel=%.2e"
192 std::printf(
totalFail == 0 ?
"OK (np=%d): a porous redistribute leaves the solution unchanged\n"
193 :
"FAILED (np=%d)\n",
void setSolid(const std::vector< double > &sdfInner, bool cutcellPressure)
Host entry point: upload the inner SDF once and delegate.
void exchangeField(const std::string &name)
void setAdvection(bool on)
void setVelocityIterations(int it)
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 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 void configure(IbmSolver &s, const std::vector< double > &lsdf, const std::vector< double > &leps)
static double epsAt(int x, int, int z)
static constexpr double RHO
static constexpr double MU
static constexpr int STEPS
static std::vector< double > blockOf(const std::vector< double > &g, const BlockDecomposer< 3 > &dec, int rank)
static constexpr double DT
static constexpr double F
static std::vector< double > gatherGlobal(const std::vector< double > &local, const BlockDecomposer< 3 > &dec, int rank, int size)
static std::vector< double > packingSdf(double rfrac=0.18)