16#include <Kokkos_Core.hpp>
20#include "../synthetic_sdf.hpp"
33bool poreLess(
const Pore& a,
const Pore& b) {
41bool poreEq(
const Pore& a,
const Pore& b, std::array<float, 3> spc) {
42 return a.
radius == b.
radius && std::fabs(a.
x - b.
x) <= 1e-5f * spc[0] &&
43 std::fabs(a.
y - b.
y) <= 1e-5f * spc[1] && std::fabs(a.
z - b.
z) <= 1e-5f * spc[2];
48int runCase(
const char* name, std::array<int, 3> gd, std::array<float, 3> org,
49 std::array<float, 3> spc,
const SdfFn& sdfAt, MPI_Comm comm) {
50 int rank = 0, size = 1;
51 MPI_Comm_rank(comm, &rank);
52 MPI_Comm_size(comm, &size);
54 std::array<int, 3> bo{}, bs{};
56 std::vector<float> local(std::size_t(bs[0]) * bs[1] * bs[2]);
57 for (
int z = 0;
z < bs[2]; ++
z)
58 for (
int y = 0;
y < bs[1]; ++
y)
59 for (
int x = 0;
x < bs[0]; ++
x)
60 local[(std::size_t(z) * bs[1] + y) * bs[0] +
x] =
61 sdfAt(bo[0] + x, bo[1] + y, bo[2] + z, gd);
66 BlockMeta meta{{bo[0], bo[1], bo[2]}, {bs[0], bs[1], bs[2]}};
74 const std::size_t n = std::size_t(gd[0]) * gd[1] * gd[2];
75 std::vector<float> full(n);
76 for (
int z = 0;
z < gd[2]; ++
z)
77 for (
int y = 0;
y < gd[1]; ++
y)
78 for (
int x = 0;
x < gd[0]; ++
x)
79 full[(std::size_t(z) * gd[1] + y) * gd[0] +
x] = sdfAt(x, y, z, gd);
83 std::vector<int> segG(n, -999);
85 for (
int r = 0; r < size; ++r) {
86 const auto& m = metas[r];
87 for (
int z = 0;
z < m.s[2]; ++
z)
88 for (
int y = 0;
y < m.s[1]; ++
y)
89 for (
int x = 0;
x < m.s[0]; ++
x)
90 segG[(std::size_t(m.o[2] + z) * gd[1] + (m.o[1] + y)) * gd[0] + (m.o[0] +
x)] =
91 segAll[off + (std::size_t(z) * m.s[1] +
y) * m.s[0] + x];
92 off += std::size_t(m.s[0]) * m.s[1] * m.s[2];
95 for (std::size_t i = 0; i < n; ++i)
96 if (segG[i] != oracle.seg[i])
99 std::printf(
"[%s] FAIL seg: %zu / %zu voxels differ\n", name, nbad, n);
104 auto op = oracle.pores;
105 std::sort(op.begin(), op.end(), poreLess);
106 std::sort(poresAll.begin(), poresAll.end(), poreLess);
107 if (op.size() != poresAll.size()) {
108 std::printf(
"[%s] FAIL pores: %zu (dist) vs %zu (oracle)\n", name, poresAll.size(),
112 for (std::size_t i = 0; i < op.size(); ++i)
113 if (!poreEq(op[i], poresAll[i], spc)) {
114 std::printf(
"[%s] FAIL pore %zu: (%g,%g,%g,r=%g) vs (%g,%g,%g,r=%g)\n", name, i,
115 poresAll[i].x, poresAll[i].y, poresAll[i].z, poresAll[i].radius, op[i].x,
116 op[i].y, op[i].z, op[i].radius);
123 if (dist.connections != oracle.connections) {
124 std::printf(
"[%s] FAIL connections: %zu (dist) vs %zu (oracle)\n", name,
125 dist.connections.size(), oracle.connections.size());
129 std::printf(
"[%s] PASS np=%d: %zu pores, %zu connections, seg exact on %zu voxels\n", name,
130 size, op.size(), oracle.connections.size(), n);
132 MPI_Bcast(&fail, 1, MPI_INT, 0, comm);
138int main(
int argc,
char** argv) {
139 MPI_Init(&argc, &argv);
142 Kokkos::ScopeGuard kokkos(argc, argv);
143 fail += runCase(
"sphere_lattice", {36, 30, 24}, {0.f, 0.f, 0.f}, {1.f, 1.f, 1.f},
145 fail += runCase(
"trig_field", {32, 32, 32}, {-1.f, 2.f, 0.5f}, {0.5f, 1.f, 2.f},
std::vector< T > allgatherv(const std::vector< T > &local, MPI_Comm comm)
Allgatherv a local vector of T (POD) — every rank returns the concatenation.
float sphereLatticeSdf(int gx, int gy, int gz, std::array< int, 3 > gd)
2x2x2 lattice of SOLID spheres in a periodic box (min-image distance); pores at the interstices.
float trigSdf(int gx, int gy, int gz, std::array< int, 3 > gd)
Smooth trigonometric field with wrap-around components (exercises the periodic images).
std::int64_t Index
Global voxel / face id (== peclet::core::Index; asserted where core is included).
MpiPoreNetwork extract_pore_network_mpi(const std::vector< float > &sdf_local, std::array< int, 3 > gdims, std::array< float, 3 > origin, std::array< float, 3 > spacing, MPI_Comm comm)
Distributed fused extraction.
void mpi_block_of(std::array< int, 3 > gdims, MPI_Comm comm, std::array< int, 3 > &offset, std::array< int, 3 > &size)
This rank's ORB block of the global grid (deterministic; same partition as flow/dem): offset = the bl...
PoreNetwork extract_pore_network_k(const std::vector< float > &sdf_h, std::array< int, 3 > resolution, std::array< float, 3 > origin, std::array< float, 3 > spacing)
int main(int argc, char **argv)