Skip to content

Commit e486b44

Browse files
ability to read unstructured data from legacy vtk format
1 parent 7c093b1 commit e486b44

File tree

3 files changed

+77
-8
lines changed

3 files changed

+77
-8
lines changed

tidy3d/components/data/unstructured/base.py

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -483,6 +483,17 @@ def _read_vtkUnstructuredGrid(fname: str):
483483

484484
return grid
485485

486+
@staticmethod
487+
@requires_vtk
488+
def _read_vtkLegacyFile(fname: str):
489+
"""Load a grid from a legacy `.vtk` file."""
490+
reader = vtk["mod"].vtkGenericDataObjectReader()
491+
reader.SetFileName(fname)
492+
reader.Update()
493+
grid = reader.GetOutput()
494+
495+
return grid
496+
486497
@classmethod
487498
@abstractmethod
488499
@requires_vtk
@@ -494,6 +505,7 @@ def _from_vtk_obj(
494505
remove_unused_points: bool = False,
495506
values_type=IndexedDataArray,
496507
expect_complex=None,
508+
ignore_invalid_cells=False,
497509
) -> UnstructuredGridDataset:
498510
"""Initialize from a vtk object."""
499511

@@ -524,6 +536,7 @@ def from_vtu(
524536
field: Optional[str] = None,
525537
remove_degenerate_cells: bool = False,
526538
remove_unused_points: bool = False,
539+
ignore_invalid_cells: bool = False,
527540
) -> UnstructuredGridDataset:
528541
"""Load unstructured data from a vtu file.
529542
@@ -549,6 +562,44 @@ def from_vtu(
549562
field=field,
550563
remove_degenerate_cells=remove_degenerate_cells,
551564
remove_unused_points=remove_unused_points,
565+
ignore_invalid_cells=ignore_invalid_cells,
566+
)
567+
568+
@classmethod
569+
@requires_vtk
570+
def from_vtk(
571+
cls,
572+
file: str,
573+
field: Optional[str] = None,
574+
remove_degenerate_cells: bool = False,
575+
remove_unused_points: bool = False,
576+
ignore_invalid_cells: bool = False,
577+
) -> UnstructuredGridDataset:
578+
"""Load unstructured data from a vtk file.
579+
580+
Parameters
581+
----------
582+
fname : str
583+
Full path to the .vtk file to load the unstructured data from.
584+
field : str = None
585+
Name of the field to load.
586+
remove_degenerate_cells : bool = False
587+
Remove explicitly degenerate cells.
588+
remove_unused_points : bool = False
589+
Remove unused points.
590+
591+
Returns
592+
-------
593+
UnstructuredGridDataset
594+
Unstructured data.
595+
"""
596+
grid = cls._read_vtkLegacyFile(file)
597+
return cls._from_vtk_obj(
598+
grid,
599+
field=field,
600+
remove_degenerate_cells=remove_degenerate_cells,
601+
remove_unused_points=remove_unused_points,
602+
ignore_invalid_cells=ignore_invalid_cells,
552603
)
553604

554605
@requires_vtk
@@ -586,7 +637,7 @@ def _get_values_from_vtk(
586637
"No point data is found in a VTK object. '.values' will be initialized to zeros."
587638
)
588639
values_numpy = np.zeros(num_points)
589-
values_coords = {"index": []}
640+
values_coords = {"index": np.arange(num_points)}
590641
values_name = None
591642

592643
else:

tidy3d/components/data/unstructured/tetrahedral.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ def _from_vtk_obj(
9797
remove_unused_points: bool = False,
9898
values_type=IndexedDataArray,
9999
expect_complex: bool = False,
100+
ignore_invalid_cells: bool = False,
100101
) -> TetrahedralGridDataset:
101102
"""Initialize from a vtkUnstructuredGrid instance."""
102103

@@ -109,8 +110,16 @@ def _from_vtk_obj(
109110

110111
# verify cell_types
111112
cells_types = vtk["vtk_to_numpy"](vtk_obj.GetCellTypesArray())
112-
if not np.all(cells_types == cls._vtk_cell_type()):
113-
raise DataError("Only tetrahedral 'vtkUnstructuredGrid' is currently supported")
113+
invalid_cells = cells_types != cls._vtk_cell_type()
114+
if any(invalid_cells):
115+
if ignore_invalid_cells:
116+
cell_offsets = vtk["vtk_to_numpy"](vtk_obj.GetCells().GetOffsetsArray())
117+
valid_cell_offsets = cell_offsets[:-1][invalid_cells == 0]
118+
cells_numpy = cells_numpy[
119+
np.ravel(valid_cell_offsets[:, None] + np.arange(4, dtype=int)[None, :])
120+
]
121+
else:
122+
raise DataError("Only tetrahedral 'vtkUnstructuredGrid' is currently supported")
114123

115124
# pack point and cell information into Tidy3D arrays
116125
num_cells = len(cells_numpy) // cls._cell_num_vertices()

tidy3d/components/data/unstructured/triangular.py

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,7 @@ def _from_vtk_obj(
132132
remove_unused_points: bool = False,
133133
values_type=IndexedDataArray,
134134
expect_complex=None,
135+
ignore_invalid_cells: bool = False,
135136
):
136137
"""Initialize from a vtkUnstructuredGrid instance."""
137138

@@ -143,12 +144,20 @@ def _from_vtk_obj(
143144

144145
cells_numpy = vtk["vtk_to_numpy"](cells_vtk.GetConnectivityArray())
145146

147+
# verify cell_types
146148
cell_offsets = vtk["vtk_to_numpy"](cells_vtk.GetOffsetsArray())
147-
if not np.all(np.diff(cell_offsets) == cls._cell_num_vertices()):
148-
raise DataError(
149-
"Only triangular 'vtkUnstructuredGrid' or 'vtkPolyData' can be converted into "
150-
"'TriangularGridDataset'."
151-
)
149+
invalid_cells = np.diff(cell_offsets) != cls._cell_num_vertices()
150+
if any(invalid_cells):
151+
if ignore_invalid_cells:
152+
valid_cell_offsets = cell_offsets[:-1][invalid_cells == 0]
153+
cells_numpy = cells_numpy[
154+
np.ravel(valid_cell_offsets[:, None] + np.arange(3, dtype=int)[None, :])
155+
]
156+
else:
157+
raise DataError(
158+
"Only triangular 'vtkUnstructuredGrid' or 'vtkPolyData' can be converted into "
159+
"'TriangularGridDataset'."
160+
)
152161

153162
points_numpy = vtk["vtk_to_numpy"](vtk_obj.GetPoints().GetData())
154163

0 commit comments

Comments
 (0)