Skip to content

Commit adc25d1

Browse files
committed
Sort tetra faces and enforce exact match for GlobalElementID mapping
1 parent ec967f6 commit adc25d1

File tree

1 file changed

+32
-5
lines changed

1 file changed

+32
-5
lines changed

svv/simulation/utils/extract_faces.py

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -401,8 +401,10 @@ def compute_circularity(loop_polydata):
401401
tet_faces = []
402402
for i in tqdm.trange(global_elements.shape[0], desc="Building tetrahedral faces", leave=False):
403403
for j in range(4):
404-
idx = set(list(range(4))) - set([j])
405-
tet_faces.append(global_elements[i, list(idx)])
404+
# Build each face as a sorted triple of node IDs for exact matching
405+
face_nodes = numpy.delete(global_elements[i], j)
406+
face_nodes = numpy.sort(face_nodes)
407+
tet_faces.append(face_nodes)
406408
tet_face_tree = cKDTree(tet_faces)
407409
#for i, cap in enumerate(iscap):
408410
# if not cap == 1:
@@ -425,7 +427,16 @@ def compute_circularity(loop_polydata):
425427
wall_faces = wall_surface.point_data["GlobalNodeID"][wall_surface.faces]
426428
wall_faces = wall_faces.reshape(-1, 4)[:, 1:]
427429
wall_faces = numpy.sort(wall_faces, axis=1)
428-
_, indices = tet_face_tree.query(wall_faces)
430+
dists, indices = tet_face_tree.query(wall_faces)
431+
if not numpy.all(numpy.isclose(dists, 0.0)):
432+
# Identify a small sample of mismatches for debugging
433+
bad_idx = numpy.where(~numpy.isclose(dists, 0.0))[0]
434+
sample = bad_idx[:5]
435+
examples = wall_faces[sample]
436+
raise ValueError(
437+
f"Failed to map all wall surface faces to volume mesh faces: {bad_idx.size} mismatches. "
438+
f"Example face node triples (GlobalNodeID) that failed exact match: {examples.tolist()}"
439+
)
429440
wall_surface.cell_data["GlobalElementID"] = indices // 4
430441
wall_surface.cell_data["GlobalElementID"] = wall_surface.cell_data["GlobalElementID"].astype(numpy.int32)
431442
boundaries = wall_surface.extract_feature_edges(boundary_edges=True, manifold_edges=False,
@@ -454,7 +465,15 @@ def compute_circularity(loop_polydata):
454465
cap_faces = cap_surface.point_data["GlobalNodeID"][cap_surface.faces]
455466
cap_faces = cap_faces.reshape(-1, 4)[:, 1:]
456467
cap_faces = numpy.sort(cap_faces, axis=1)
457-
_, indices = tet_face_tree.query(cap_faces)
468+
dists, indices = tet_face_tree.query(cap_faces)
469+
if not numpy.all(numpy.isclose(dists, 0.0)):
470+
bad_idx = numpy.where(~numpy.isclose(dists, 0.0))[0]
471+
sample = bad_idx[:5]
472+
examples = cap_faces[sample]
473+
raise ValueError(
474+
f"Failed to map all cap surface faces to volume mesh faces: {bad_idx.size} mismatches. "
475+
f"Example face node triples (GlobalNodeID) that failed exact match: {examples.tolist()}"
476+
)
458477
cap_surface.cell_data["GlobalElementID"] = indices // 4
459478
cap_surface.cell_data["GlobalElementID"] = cap_surface.cell_data["GlobalElementID"].astype(numpy.int32)
460479
boundaries = cap_surface.extract_feature_edges(boundary_edges=True, manifold_edges=False,
@@ -484,7 +503,15 @@ def compute_circularity(loop_polydata):
484503
lumen_faces = lumen_surface.point_data["GlobalNodeID"][lumen_surface.faces]
485504
lumen_faces = lumen_faces.reshape(-1, 4)[:, 1:]
486505
lumen_faces = numpy.sort(lumen_faces, axis=1)
487-
_, indices = tet_face_tree.query(lumen_faces)
506+
dists, indices = tet_face_tree.query(lumen_faces)
507+
if not numpy.all(numpy.isclose(dists, 0.0)):
508+
bad_idx = numpy.where(~numpy.isclose(dists, 0.0))[0]
509+
sample = bad_idx[:5]
510+
examples = lumen_faces[sample]
511+
raise ValueError(
512+
f"Failed to map all lumen surface faces to volume mesh faces: {bad_idx.size} mismatches. "
513+
f"Example face node triples (GlobalNodeID) that failed exact match: {examples.tolist()}"
514+
)
488515
lumen_surface.cell_data["GlobalElementID"] = indices // 4
489516
lumen_surface.cell_data["GlobalElementID"] = lumen_surface.cell_data["GlobalElementID"].astype(numpy.int32)
490517
boundaries = lumen_surface.extract_feature_edges(boundary_edges=True, manifold_edges=False,

0 commit comments

Comments
 (0)