30#include <Kokkos_Core.hpp>
36#include "peclet/core/common/types.hpp"
37#include "peclet/core/decomp/block_decomposer.hpp"
41static constexpr int N = 32,
STEPS = 3;
42static constexpr std::size_t
GCELLS = (std::size_t)
N *
N *
N;
43static constexpr double U_SUP = 0.02;
46static std::vector<double>
blobs() {
47 std::vector<double> f(
GCELLS, 0.0);
48 for (
int z = 0; z <
N; ++z)
49 for (
int y = 0; y <
N; ++y)
50 for (
int x = 0; x <
N; ++x) {
52 for (
int i = 0; i < 6; ++i) {
53 const double dx = x + 0.5 - (i + 0.5) *
N / 6.0, dy = y + 0.5 - 12.0, dz = z + 0.5 - 10.0;
54 s += 0.5 * std::exp(-(dx * dx + dy * dy + dz * dz) / 8.0);
56 f[(std::size_t)x + (std::size_t)y *
N + (std::size_t)z *
N *
N] = s;
61static std::vector<double>
slice(
const std::vector<double>& g,
int ox,
int oy,
int oz,
int lnx,
63 std::vector<double> l((std::size_t)
lnx *
lny *
lnz);
64 for (
int z = 0; z <
lnz; ++z)
65 for (
int y = 0; y <
lny; ++y)
66 for (
int x = 0; x <
lnx; ++x)
67 l[(std::size_t)x + (std::size_t)y *
lnx + (std::size_t)z *
lnx *
lny] =
68 g[(std::size_t)(x + ox) + (std::size_t)(y + oy) *
N + (std::size_t)(z + oz) *
N *
N];
88static std::vector<double>
gatherGlobal(
const std::vector<double>&
local,
int ox,
int oy,
int oz,
89 int lnx,
int lny,
int lnz,
int rank,
int size) {
90 std::vector<double>
global;
93 for (
int r = 0; r < size; ++r) {
97 for (
int z = 0; z <
lnz; ++z)
98 for (
int y = 0; y <
lny; ++y)
99 std::memcpy(&
global[(std::size_t)ox + (std::size_t)(y + oy) *
N +
100 (std::size_t)(z + oz) *
N *
N],
102 (std::size_t)
lnx *
sizeof(
double));
108 }
else if (rank == 0) {
113 for (
int z = 0; z <
meta[5]; ++z)
114 for (
int y = 0; y <
meta[4]; ++y)
115 std::memcpy(&
global[(std::size_t)
meta[0] + (std::size_t)(y +
meta[1]) *
N +
116 (std::size_t)(z +
meta[2]) *
N *
N],
118 (std::size_t)
meta[3] *
sizeof(
double));
125static double maxAbsDiff(
const std::vector<double>& a,
const std::vector<double>& b) {
127 for (std::size_t i = 0; i < b.size(); ++i) {
128 const double d = std::fabs(a[i] - b[i]);
135static double maxAbs(
const std::vector<double>& a) {
138 m = std::fmax(m, std::fabs(v));
141static double mean(
const std::vector<double>& a) {
145 return s / (
double)a.size();
150 Kokkos::initialize(
argc, argv);
153 int rank = 0, size = 1;
156 auto dec = peclet::flow::CutcellMG::decomposition(
static_cast<std::size_t
>(size),
N,
N,
N);
157 auto blk =
dec.block(rank);
158 const int ox = (int)blk.origin[0], oy = (
int)blk.origin[1], oz = (int)blk.origin[2];
159 const int lnx = (int)blk.size[0],
lny = (
int)blk.size[1],
lnz = (int)blk.size[2];
162 std::printf(
"SUPERFICIAL VELOCITY MPI np=%d grid %d^3 block %dx%dx%d\n", size,
N,
lnx,
lny,
164 const std::vector<double>
fg =
blobs();
172 for (
int it = 0; it <
STEPS; ++it)
175 std::vector<double>
gu[3];
176 for (
int c = 0; c < 3; ++c)
183 for (
int it = 0; it <
STEPS; ++it) {
185 std::vector<double> u = ref.getVelocity(0);
189 ref.setVelocity(0, u);
191 double du = 0,
umag = 0;
192 for (
int c = 0; c < 3; ++c) {
193 du = std::fmax(du,
maxAbsDiff(
gu[c], ref.getVelocity(c)));
196 const double tol = (size == 1 ? 1e-13 : 1e-11) *
umag;
198 std::printf(
" [driver np=%d] max|du| = %.3e (tol %.1e) max|u| = %.3e %s\n", size, du,
tol,
201 const bool okM = dm <= 1e-13 *
umag;
202 std::printf(
" [mean np=%d] |<u> - U| = %.3e %s\n", size, dm,
okM ?
"OK" :
"FAIL");
203 const bool okA = std::fabs(
shift) > 1e-3;
204 std::printf(
" [active np=%d] last shift = %.6e %s\n", size,
shift,
okA ?
"OK" :
"FAIL");
220 }
catch (
const std::runtime_error&) {
223 int t = threw ? 1 : 0, all = 0;
226 std::printf(
" [refuse np=%d] wall-bounded axis %s %s\n", size,
227 all ?
"raised" :
"was ACCEPTED", all ?
"OK" :
"FAIL");
232 std::printf(
"SUPERFICIAL VELOCITY MPI (np=%d): %s\n", size,
fail ?
"FAIL" :
"PASS");
void setDomainBc(int face, int type, double vx, double vy, double vz)
void setPressureGeometry(const std::vector< double > &sdfInner)
void setField(const std::string &name, const std::vector< double > &v)
double lastSuperficialVelocityShift() const
The shift the last step() applied (caller's velocity units; 0 when off).
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 setRho(double r)
Fluid density, in the caller's units.
void setSuperficialVelocity(bool on, int axis, double velocity)
Hold the SUPERFICIAL velocity along a periodic axis: at the end of every step() one uniform shift is ...
flow — host-facing Kokkos IBM Navier-Stokes solver (drop-in flow-style API).
static double maxAbs(const std::vector< double > &a)
static constexpr double U_SUP
static void build(IbmSolver &s, std::size_t cells)
static void configure(IbmSolver &s, const std::vector< double > &forceLocal)
static double mean(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 std::vector< double > blobs()
static constexpr std::size_t GCELLS