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