Skip to content
35 changes: 33 additions & 2 deletions mesh-doctor/src/geos/mesh_doctor/actions/generateFractures.py
Original file line number Diff line number Diff line change
Expand Up @@ -433,6 +433,38 @@ def __performSplit( oldMesh: vtkUnstructuredGrid, cellToNodeMapping: Mapping[ in
collocatedNodes[ o ] = i
collocatedNodes.flags.writeable = False

# For each 2D cell, find its adjacent 3D cell and copy the node mapping
setupLogger.info("Building 2D cell mappings from adjacent 3D cells...")
cell_2d_to_mapping: dict[ int, dict[ int, int ] ] = {}
Comment thread
bd713 marked this conversation as resolved.
Outdated

for c in tqdm( range( oldMesh.GetNumberOfCells() ), desc="Matching 2D to 3D cells" ):
cell2d: vtkCell = oldMesh.GetCell( c )
if cell2d.GetCellDimension() != 2:
continue

# Get the point IDs of this 2D cell
pointIds = cell2d.GetPointIds()

# Find a 3D cell neighbor
neighborIds = vtkIdList()
oldMesh.GetCellNeighbors( c, pointIds, neighborIds )

# Use the first 3D neighbor's mapping
for i in range( neighborIds.GetNumberOfIds() ):
neighborId = neighborIds.GetId( i )
neighborCell = oldMesh.GetCell( neighborId )
if neighborCell.GetCellDimension() == 3:
# This 3D cell has a mapping - use it for the 2D cell
if neighborId in cellToNodeMapping:
cell_2d_to_mapping[ c ] = dict( cellToNodeMapping[ neighborId ] )
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wouldn't this add the full neighbor cell's mapping and not only the partial mapping for the 2d cell ?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jafranc you are absolutely correct, this was a bit lazy on my part.
I removed these extra mappings for code clarity and memory efficiency.
Thanks for catching this!

Comment thread
bd713 marked this conversation as resolved.
Outdated
break

setupLogger.info(f"Found mappings for {len(cell_2d_to_mapping)} 2D cells")

# Merge 2D mappings into main mapping
combined_mapping = dict( cellToNodeMapping )
Comment thread
bd713 marked this conversation as resolved.
Outdated
combined_mapping.update( cell_2d_to_mapping )
Comment thread
bd713 marked this conversation as resolved.
Outdated

# We are creating a new mesh.
# The cells will be the same, except that their nodes may be duplicated or renumbered nodes.
# In vtk, the polyhedron and the standard cells are managed differently.
Expand All @@ -446,7 +478,7 @@ def __performSplit( oldMesh: vtkUnstructuredGrid, cellToNodeMapping: Mapping[ in
newMesh.Allocate( oldMesh.GetNumberOfCells() )

for c in tqdm( range( oldMesh.GetNumberOfCells() ), desc="Performing the mesh split" ):
cellNodeMapping: IDMapping = cellToNodeMapping.get( c, {} )
cellNodeMapping: IDMapping = combined_mapping.get( c, {} )
cell: vtkCell = oldMesh.GetCell( c )
cellType: int = cell.GetCellType()
# For polyhedron, we'll manipulate the face stream directly.
Expand Down Expand Up @@ -475,7 +507,6 @@ def __performSplit( oldMesh: vtkUnstructuredGrid, cellToNodeMapping: Mapping[ in

return newMesh


def __generateFractureMesh( oldMesh: vtkUnstructuredGrid, fractureInfo: FractureInfo,
cellToNodeMapping: Mapping[ int, IDMapping ] ) -> vtkUnstructuredGrid:
"""Generates the mesh of the fracture.
Expand Down
Loading