flow
Kokkos cut-cell IBM incompressible Navier-Stokes solver + pnm pore extraction
Loading...
Searching...
No Matches
test_extraction.py
Go to the documentation of this file.
1"""Smoke test for pore-network extraction from an SDF."""
2import sys
3import os
4
5sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../build')))
6from peclet.flow import pnm
7
8def test_extraction(filename):
9 print(f"Reading {filename}...")
10 sdf_3d, origin_zyx, spacing_zyx = pnm.SDFReader.read_vti(filename)
11 print(f"Loaded SDF. Shape: {sdf_3d.shape}")
12
13 print("Extracting pores on GPU...")
14 pores = pnm.extract_pores(sdf_3d, origin_zyx, spacing_zyx)
15
16 print(f"Found {len(pores)} pores.")
17 if len(pores) > 0:
18 print("First 5 pores:")
19 for i in range(min(5, len(pores))):
20 print(pores[i])
21
22 # Simple validation: Check if duplicate locations?
23 import numpy as np
24 coords = np.array([[p.x, p.y, p.z] for p in pores])
25 if len(coords) > 0:
26 print(f"Bounds: Min {coords.min(axis=0)}, Max {coords.max(axis=0)}")
27
28 return pores
29
30def save_vtp(filename, pores):
31 import struct
32 with open(filename, 'w') as f:
33 f.write('<?xml version="1.0"?>\n')
34 f.write('<VTKFile type="PolyData" version="0.1" byte_order="LittleEndian">\n')
35 f.write(' <PolyData>\n')
36 f.write(f' <Piece NumberOfPoints="{len(pores)}" NumberOfVerts="0" NumberOfLines="0" NumberOfStrips="0" NumberOfPolys="0">\n')
37
38 f.write(' <Points>\n')
39 f.write(' <DataArray type="Float32" NumberOfComponents="3" format="ascii">\n')
40 for p in pores:
41 f.write(f'{p.x} {p.y} {p.z}\n')
42 f.write(' </DataArray>\n')
43 f.write(' </Points>\n')
44
45 f.write(' <PointData Scalars="Radius">\n')
46 f.write(' <DataArray type="Float32" Name="Radius" format="ascii">\n')
47 for p in pores:
48 f.write(f'{p.radius}\n')
49 f.write(' </DataArray>\n')
50 f.write(' </PointData>\n')
51
52 f.write(' </Piece>\n')
53 f.write(' </PolyData>\n')
54 f.write('</VTKFile>\n')
55 print(f"Saved pores to {filename}")
56
57if __name__ == "__main__":
58 if len(sys.argv) > 1:
59 pores = test_extraction(sys.argv[1])
60 outfile = "pores.vtp"
61 save_vtp(outfile, pores)
62 else:
63 # Default to a file in data/ if exists
64 default_file = "data/packing_ring.vti"
65 if os.path.exists(default_file):
66 pores = test_extraction(default_file)
67 save_vtp("pores.vtp", pores)
68 else:
69 print(f"Usage: {sys.argv[0]} <vti_file>")
save_vtp(filename, pores)