19 nx, ny, nz = shape_xyz
20 z, y, x = np.meshgrid(
21 np.arange(nz, dtype=np.float32),
22 np.arange(ny, dtype=np.float32),
23 np.arange(nx, dtype=np.float32),
35 x, y, z =
grid((n, n, n))
36 sdf = (R - np.sqrt((x - 8) ** 2 + (y - 8) ** 2 + (z - 8) ** 2)).astype(np.float32)
37 pores, seg, conns = pnm.extract_pore_network(sdf, [0.0] * 3, [1.0] * 3)
38 assert isinstance(seg, np.ndarray)
and seg.dtype == np.int32
and seg.shape == sdf.shape
39 assert isinstance(conns, np.ndarray)
and conns.dtype == np.int32
and conns.shape == (1, 2)
40 assert len(pores) == 1, pores
42 assert p.radius == np.float32(R), p
43 assert (p.x, p.y, p.z) == (8.0, 8.0, 8.0), p
44 assert seg.max() == 1
and seg.min() == -1
and not (seg == 0).any()
45 assert conns.tolist() == [[-1, 1]], conns
46 assert len(pnm.extract_pores(sdf, [0.0] * 3, [1.0] * 3)) == 1
48 seg2 = pnm.segment_volume(sdf, [1.0] * 3)
49 assert seg2.shape == sdf.shape
and np.array_equal(seg2, seg)
50 assert np.array_equal(pnm.extract_topology(seg2), conns)
51 assert np.array_equal(pnm.extract_topology(seg2.ravel(), shape_zyx=sdf.shape), conns)
53 (p2,), _, _ = pnm.extract_pore_network(sdf, [0.5, 2.0, -1.0], [2.0, 1.0, 0.5])
54 assert abs(p2.x - (-1.0 + 8 * 0.5)) < 1e-5
and abs(p2.y - (2.0 + 8)) < 1e-5, p2
55 assert abs(p2.z - (0.5 + 8 * 2.0)) < 1e-5, p2
56 print(
"one_sphere: 1 pore, 0 throats, 1 connection ok")
61 x, y, z =
grid((24, 16, 16))
62 d1 = R - np.sqrt((x - 8) ** 2 + (y - 8) ** 2 + (z - 8) ** 2)
63 d2 = R - np.sqrt((x - 16) ** 2 + (y - 8) ** 2 + (z - 8) ** 2)
64 sdf = np.maximum(d1, d2).astype(np.float32)
65 pores, seg, conns = pnm.extract_pore_network(sdf, [0.0] * 3, [1.0] * 3)
66 assert len(pores) == 2, pores
67 assert sorted((p.x, p.y, p.z)
for p
in pores) == [(8.0, 8.0, 8.0), (16.0, 8.0, 8.0)], pores
68 assert conns.tolist() == [[-1, 1], [-1, 2], [1, 2]], conns
69 assert throats(conns) == [[1, 2]]
70 assert seg.max() == 2
and seg.min() == -1
and not (seg == 0).any()
71 assert seg.shape == sdf.shape
and seg[8, 8, 8] == 1
and seg[8, 8, 16] == 2
72 print(
"two_spheres: 2 pores, 1 throat, 3 connections ok")
78 R = np.float32(0.22 * min(gd))
80 sdf = np.full(x.shape, 1e30, np.float32)
84 cc = [gd[i] * (2 * c + 1) / 4.0
for i, c
in enumerate((cx, cy, cz))]
85 dx, dy, dz = np.abs(x - cc[0]), np.abs(y - cc[1]), np.abs(z - cc[2])
86 dx = np.minimum(dx, gd[0] - dx)
87 dy = np.minimum(dy, gd[1] - dy)
88 dz = np.minimum(dz, gd[2] - dz)
89 sdf = np.minimum(sdf, (np.sqrt(dx * dx + dy * dy + dz * dz) - R).astype(np.float32))
90 pores, seg, conns = pnm.extract_pore_network(sdf, [0.0] * 3, [1.0] * 3)
91 assert len(pores) == 8, len(pores)
92 centres = sorted((round(p.x), round(p.y), round(p.z))
for p
in pores)
93 assert centres == [(px, py, pz)
for px
in (0, 18)
for py
in (0, 15)
for pz
in (0, 12)], centres
94 assert all(abs(p.radius - sdf[0, 0, 0]) == 0
for p
in pores), pores
95 assert len(
throats(conns)) == 12
and len(conns) == 76, (len(
throats(conns)), len(conns))
96 assert seg.max() == 8
and seg.min() == -8
and not (seg == 0).any()
97 assert len(pnm.extract_pores(sdf, [0.0] * 3, [1.0] * 3)) == 8
98 print(
"sphere_lattice: 8 pores, 12 throats, 76 connections ok")