Skip to content

Commit d4d3abc

Browse files
bd713DENEL Bertrand
andauthored
fix: MeshDoctor: ensure consistent node numbering between 2D element and 3D faces (#219)
* Update mesh-doctor/src/geos/mesh_doctor/actions/generateFractures.py * Filtered mapping to 2d nodes --------- Co-authored-by: DENEL Bertrand <bertrand.denel@total.com>
1 parent bc64660 commit d4d3abc

1 file changed

Lines changed: 41 additions & 1 deletion

File tree

mesh-doctor/src/geos/mesh_doctor/actions/generateFractures.py

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -433,6 +433,46 @@ def __performSplit( oldMesh: vtkUnstructuredGrid, cellToNodeMapping: Mapping[ in
433433
collocatedNodes[ o ] = i
434434
collocatedNodes.flags.writeable = False
435435

436+
# For each 2D cell, find its adjacent 3D cell and copy the node mapping
437+
setupLogger.info( "Building 2D cell mappings from adjacent 3D cells..." )
438+
cell2dToMapping: dict[ int, dict[ int, int ] ] = {}
439+
440+
for c in tqdm( range( oldMesh.GetNumberOfCells() ), desc="Matching 2D to 3D cells" ):
441+
cell2d: vtkCell = oldMesh.GetCell( c )
442+
if cell2d.GetCellDimension() != 2:
443+
continue
444+
445+
# Get the point IDs of this 2D cell
446+
pointIds = cell2d.GetPointIds()
447+
448+
# Find a 3D cell neighbor
449+
neighborIds = vtkIdList()
450+
oldMesh.GetCellNeighbors( c, pointIds, neighborIds )
451+
452+
# Use the first 3D neighbor's mapping
453+
for i in range( neighborIds.GetNumberOfIds() ):
454+
neighborId = neighborIds.GetId( i )
455+
neighborCell = oldMesh.GetCell( neighborId )
456+
457+
if neighborCell.GetCellDimension() == 3 and neighborId in cellToNodeMapping:
458+
# This 3D cell has a mapping - use it for the 2D cell
459+
# Get the 2D cell's point IDs
460+
cell2dPointIds = set( vtkIter( pointIds ) )
461+
462+
# Only copy mappings for nodes that belong to the 2D cell
463+
neighborMapping = cellToNodeMapping[ neighborId ]
464+
cell2dToMapping[ c ] = {
465+
node: newNode
466+
for node, newNode in neighborMapping.items() if node in cell2dPointIds
467+
}
468+
break
469+
470+
setupLogger.info( f"Found mappings for {len(cell2dToMapping)} 2D cells" )
471+
472+
# Merge 2D mappings into main mapping
473+
combinedMapping = dict( cellToNodeMapping )
474+
combinedMapping.update( cell2dToMapping )
475+
436476
# We are creating a new mesh.
437477
# The cells will be the same, except that their nodes may be duplicated or renumbered nodes.
438478
# In vtk, the polyhedron and the standard cells are managed differently.
@@ -446,7 +486,7 @@ def __performSplit( oldMesh: vtkUnstructuredGrid, cellToNodeMapping: Mapping[ in
446486
newMesh.Allocate( oldMesh.GetNumberOfCells() )
447487

448488
for c in tqdm( range( oldMesh.GetNumberOfCells() ), desc="Performing the mesh split" ):
449-
cellNodeMapping: IDMapping = cellToNodeMapping.get( c, {} )
489+
cellNodeMapping: IDMapping = combinedMapping.get( c, {} )
450490
cell: vtkCell = oldMesh.GetCell( c )
451491
cellType: int = cell.GetCellType()
452492
# For polyhedron, we'll manipulate the face stream directly.

0 commit comments

Comments
 (0)