42#include <Kokkos_Core.hpp>
48#include "peclet/core/common/types.hpp"
49#include "peclet/core/decomp/block_decomposer.hpp"
53static constexpr int N = 32,
STEPS = 2;
54static constexpr std::size_t
GCELLS = (std::size_t)
N *
N *
N;
64static std::vector<double>
blobs(
int line) {
65 std::vector<double> f(
GCELLS, 0.0);
66 const double pl[3] = {10.0, 16.0, 22.0};
67 for (
int z = 0; z <
N; ++z)
68 for (
int y = 0; y <
N; ++y)
69 for (
int x = 0; x <
N; ++x) {
70 const double c[3] = {x + 0.5, y + 0.5, z + 0.5};
71 const int a = (line + 1) % 3, b = (line + 2) % 3;
73 for (
int i = 0; i < 6; ++i)
75 for (
double pb : pl) {
76 const double dl = c[line] - (i + 0.5) *
N / 6.0,
da = c[a] -
pa, db = c[b] -
pb;
77 s += -12.0 * std::exp(-(
dl *
dl +
da *
da + db * db));
79 f[(std::size_t)x + (std::size_t)y *
N + (std::size_t)z *
N *
N] = s;
84static std::vector<double>
slice(
const std::vector<double>& g,
int ox,
int oy,
int oz,
int lnx,
86 std::vector<double> l((std::size_t)
lnx *
lny *
lnz);
87 for (
int z = 0; z <
lnz; ++z)
88 for (
int y = 0; y <
lny; ++y)
89 for (
int x = 0; x <
lnx; ++x)
90 l[(std::size_t)x + (std::size_t)y *
lnx + (std::size_t)z *
lnx *
lny] =
91 g[(std::size_t)(x + ox) + (std::size_t)(y + oy) *
N + (std::size_t)(z + oz) *
N *
N];
97 static const char* fn[3] = {
"force_x",
"force_y",
"force_z"};
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) *
N +
121 (std::size_t)(z + oz) *
N *
N],
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]) *
N +
137 (std::size_t)(z +
meta[2]) *
N *
N],
139 (std::size_t)
meta[3] *
sizeof(
double));
147static double maxAbsDiff(
const std::vector<double>& a,
const std::vector<double>& b) {
149 for (std::size_t i = 0; i < b.size(); ++i) {
150 const double d = std::fabs(a[i] - b[i]);
157static double maxAbs(
const std::vector<double>& a) {
160 m = std::fmax(m, std::fabs(v));
166 Kokkos::initialize(
argc, argv);
169 int rank = 0, size = 1;
173 auto dec = peclet::flow::CutcellMG::decomposition(
static_cast<std::size_t
>(size),
N,
N,
N);
174 auto blk =
dec.block(rank);
175 const int ox = (int)blk.origin[0], oy = (
int)blk.origin[1], oz = (int)blk.origin[2];
176 const int lnx = (int)blk.size[0],
lny = (
int)blk.size[1],
lnz = (int)blk.size[2];
177 bool cut[3] = {
false,
false,
false};
178 for (
const auto& sz :
dec.sizes())
179 for (
int a = 0; a < 3; ++a)
183 std::printf(
"CELLFORCE MPI np=%d grid %d^3 block %dx%dx%d cut axes: %s%s%s\n", size,
N,
184 lnx,
lny,
lnz, cut[0] ?
"x" :
"", cut[1] ?
"y" :
"", cut[2] ?
"z" :
"");
195 }
catch (
const std::runtime_error& e) {
201 int t = threw ? 1 : 0, all = 0;
203 const bool ok = all == 1 && what.find(
"init_mpi") != std::string::npos;
205 std::printf(
" [order np=%d] set_pressure_geometry -> init_mpi %s %s\n", size,
206 threw ?
"raised" :
"was ACCEPTED (the rank-local pressure solve)",
213 const Config configs[] = {{
"forced-x", 0,
false}, {
"var-y", 1,
true}};
215 const std::vector<double>
fg =
blobs(c.comp);
220 for (
int it = 0; it <
STEPS; ++it)
222 std::vector<double>
gu[3];
223 for (
int comp = 0; comp < 3; ++comp)
225 const std::vector<double>
gp =
230 ref.setPressureGeometry(std::vector<double>(
GCELLS, 10.0));
232 for (
int it = 0; it <
STEPS; ++it)
234 double du = 0,
umag = 0;
235 for (
int comp = 0; comp < 3; ++comp) {
236 du = std::fmax(du,
maxAbsDiff(
gu[comp], ref.getVelocity(comp)));
240 const double pmag =
maxAbs(ref.getPressure());
241 const double utol = (size == 1) ? 0.0 : std::fmax(1e-15, 1e-11 *
umag);
242 const double ptol = (size == 1) ? 0.0 : std::fmax(1e-12, 1e-11 *
pmag);
245 std::printf(
" [%-8s np=%d] du=%.3e dp=%.3e (tol %.1e/%.1e) max|u|=%.3e max|p|=%.3e %s\n",
253 std::printf(
"CELLFORCE MPI (np=%d): %s\n", size,
fail ?
"FAIL" :
"PASS");
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 setPressurePcg(bool on, int maxit, double rtol)
void setDensityMode(bool variable)
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 > gatherGlobal(const std::vector< double > &local, int ox, int oy, int oz, int lnx, int lny, int lnz, int rank, int size)
static constexpr int STEPS
static double maxAbsDiff(const std::vector< double > &a, const std::vector< double > &b)
static std::vector< double > slice(const std::vector< double > &g, int ox, int oy, int oz, int lnx, int lny, int lnz)
static void configure(IbmSolver &s, const Config &c, const std::vector< double > &forceLocal)
static constexpr std::size_t GCELLS
static std::vector< double > blobs()