Skip to content

ability to read unstructured data from legacy vtk format #2569

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from

Conversation

dbochkov-flexcompute
Copy link
Contributor

@dbochkov-flexcompute dbochkov-flexcompute commented Jun 12, 2025

  • adds the ability to read from legacy VTK format .vtk in addition to existing .vtu
  • adds an option to not error when loading unstructured grid with non-triangle/-tetrahedral cells (for example, to skip triangle elements that are not relevant)
  • fixes a bug when loading from vtk file without any point data

todo:

  • unit tests
  • changelog entry
  • missing docstrings

Greptile Summary

Enhances VTK file support by adding legacy .vtk format compatibility and flexible cell type handling in unstructured grids.

  • Added support for reading legacy VTK format (.vtk) files in addition to existing .vtu format
  • Introduced ignore_invalid_cells parameter to gracefully handle non-triangular/-tetrahedral cells instead of erroring
  • Fixed bug when loading VTK files without point data by properly handling empty coordinate lists
  • Modified cell type validation in _from_vtk_obj to support mixed cell types when ignore_invalid_cells=True
  • Missing unit tests, changelog entry, and docstrings need to be addressed

Copy link
Contributor

github-actions bot commented Jun 12, 2025

Diff Coverage

Diff: origin/develop...HEAD, staged and unstaged changes

  • tidy3d/components/data/unstructured/base.py (42.9%): Missing lines 490-493,495,596-597,640
  • tidy3d/components/data/unstructured/tetrahedral.py (28.6%): Missing lines 115-118,122
  • tidy3d/components/data/unstructured/triangular.py (33.3%): Missing lines 151-153,157

Summary

  • Total: 27 lines
  • Missing: 17 lines
  • Coverage: 37%

tidy3d/components/data/unstructured/base.py

Lines 486-499

  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 
  497     @classmethod
  498     @abstractmethod
  499     @requires_vtk

Lines 592-601

  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,

Lines 636-644

  636             log.warning(
  637                 "No point data is found in a VTK object. '.values' will be initialized to zeros."
  638             )
  639             values_numpy = np.zeros(num_points)
! 640             values_coords = {"index": np.arange(num_points)}
  641             values_name = None
  642 
  643         else:
  644             field_ind = field if isinstance(field, str) else 0

tidy3d/components/data/unstructured/tetrahedral.py

Lines 111-126

  111         # verify cell_types
  112         cells_types = vtk["vtk_to_numpy"](vtk_obj.GetCellTypesArray())
  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")
  123 
  124         # pack point and cell information into Tidy3D arrays
  125         num_cells = len(cells_numpy) // cls._cell_num_vertices()
  126         cells_numpy = np.reshape(cells_numpy, (num_cells, cls._cell_num_vertices()))

tidy3d/components/data/unstructured/triangular.py

Lines 147-161

  147         # verify cell_types
  148         cell_offsets = vtk["vtk_to_numpy"](cells_vtk.GetOffsetsArray())
  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                 )

Copy link

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

3 files reviewed, 1 comment
Edit PR Review Bot Settings | Greptile

np.ravel(valid_cell_offsets[:, None] + np.arange(4, dtype=int)[None, :])
]
else:
raise DataError("Only tetrahedral 'vtkUnstructuredGrid' is currently supported")
Copy link

Choose a reason for hiding this comment

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

style: Error message should specify which invalid cell types were found to help debugging

Copy link
Collaborator

@momchil-flex momchil-flex left a comment

Choose a reason for hiding this comment

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

Looks good to me and seems to work in my separate meshing pipeline PR for both 3D and 2D meshes. Just needs some tests yeah.

Copy link
Contributor

@marc-flex marc-flex left a comment

Choose a reason for hiding this comment

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

Thanks Daniil. This looks good.

In terms of testing, how do you plan on doing this? I'm should probably test a function in a different PR and I didn't really know how to do it.

@momchil-flex
Copy link
Collaborator

Closing in favor of #2493

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants