27static void run(
IbmSolver& s,
int ox,
int oy,
int oz,
int lnx,
int lny,
int lnz,
int forceLevel,
28 bool telescope, std::vector<double>& u, std::vector<double>& p,
int& teleCount) {
32 s.setAdvection(
false);
33 for (
int f = 0; f < 4; ++f)
34 s.setDomainBc(f, 1, 0, 0, 0);
35 s.setDomainBc(4, 2, 0, 0,
WIN);
36 s.setDomainBc(5, 3, 0, 0, 0);
37 s.setPressureLevels(4);
38 s.setPressurePcg(
true, 400, 1e-11);
39 s.setPressureTelescope(telescope);
41 s.setPressureTelescopeForceLevel(forceLevel);
42 s.setPressureGeometry(std::vector<double>((std::size_t)lnx * lny * lnz, 10.0));
43 s.setDensityMode(
true);
44 std::vector<double> rho((std::size_t)lnx * lny * lnz);
45 for (
int z = 0; z < lnz; ++z)
46 for (
int y = 0; y < lny; ++y)
47 for (
int x = 0; x < lnx; ++x)
48 rho[(std::size_t)x + (std::size_t)y * lnx + (std::size_t)z * lnx * lny] =
rhoAt(z + oz);
49 s.setField(
"rho", rho);
50 s.exchangeField(
"rho");
51 for (
int it = 0; it <
STEPS; ++it)
55 teleCount = s.pressureTelescopeCount();
58int main(
int argc,
char** argv) {
59 MPI_Init(&argc, &argv);
60 Kokkos::initialize(argc, argv);
61 int fail = 0, size = 1, rank = 0;
63 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
64 MPI_Comm_size(MPI_COMM_WORLD, &size);
65 peclet::core::decomp::BlockDecomposer<3> dec =
66 peclet::flow::CutcellMG::decomposition(
static_cast<std::size_t
>(size),
N,
N,
N);
67 auto blk = dec.block(rank);
68 const int ox = (int)blk.origin[0], oy = (
int)blk.origin[1], oz = (int)blk.origin[2];
69 const int lnx = (int)blk.size[0], lny = (
int)blk.size[1], lnz = (int)blk.size[2];
70 std::vector<double> uT, pT, uI, pI;
74 s.initMpi(
N,
N,
N, MPI_COMM_WORLD);
75 run(s, ox, oy, oz, lnx, lny, lnz, 1,
true, uT, pT, cT);
79 s.initMpi(
N,
N,
N, MPI_COMM_WORLD);
80 run(s, ox, oy, oz, lnx, lny, lnz, -1,
false, uI, pI, cI);
82 double du = 0, dp = 0, um = 0, pm = 0;
83 for (std::size_t i = 0; i < uT.size(); ++i) {
84 du = std::max(du, std::fabs(uT[i] - uI[i]));
85 um = std::max(um, std::fabs(uI[i]));
87 for (std::size_t i = 0; i < pT.size(); ++i) {
88 dp = std::max(dp, std::fabs(pT[i] - pI[i]));
89 pm = std::max(pm, std::fabs(pI[i]));
91 double l[4] = {du, dp, um, pm}, g[4];
92 MPI_Allreduce(l, g, 4, MPI_DOUBLE, MPI_MAX, MPI_COMM_WORLD);
94 MPI_Allreduce(&cT, &cTg, 1, MPI_INT, MPI_MAX, MPI_COMM_WORLD);
95 const double relU = g[0] / (g[2] + 1e-300), relP = g[1] / (g[3] + 1e-300);
98 const bool teleOk = (size == 1) || cTg >= 1;
101 " telescoped(force L1) vs in-place: rel du %.2e rel dp %.2e (tol %.0e) "
102 "telescopes %d |u| %.3e |p| %.3e (np=%d)\n",
103 relU, relP, tol, cTg, g[2], g[3], size);
104 if (!(relU <= tol) || !(relP <= tol) || !teleOk)
108 MPI_Allreduce(&fail, &totalFail, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD);
111 std::printf(
"OK (np=%d): variable-density outflow across a telescope point == in-place\n",
114 std::fprintf(stderr,
"FAILED (np=%d)\n", size);
118 return totalFail == 0 ? 0 : 1;
static void run(IbmSolver &s, int ox, int oy, int oz, int lnx, int lny, int lnz, int forceLevel, bool telescope, std::vector< double > &u, std::vector< double > &p, int &teleCount)