Skip to content

Commit

Permalink
Add MeshContainer.from_unstructured_grid() (#847)
Browse files Browse the repository at this point in the history
* Add `MeshContainer.from_unstructured_grid()`

* Add test to read an unstructured grid
  • Loading branch information
adtzlr authored Sep 1, 2024
1 parent a4b16f3 commit 214d99e
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ All notable changes to this project will be documented in this file. The format
- Add `LinearElasticOrthotropic`.
- Add `SolidBodyCauchyStress` in addition to `SolidBodyPressure`.
- Add `mesh.cell_types()` which returns an object-array with cell-type mappings for FElupe and PyVista.
- Add `MeshContainer.from_unstructured_grid(grid, dim=None, **kwargs)` to create a mesh-container from an unstructured grid (PyVista).

### Changed
- Change the internal initialization of `field = Field(region, values=1, dtype=None)` values from `field.values = np.ones(shape) * values` to `field = np.full(shape, fill_value=values, dtype=dtype)`. This enforces `field = Field(region, values=1)` to return the gradient array with data-type `int` which was of type `float` before.
Expand Down
52 changes: 52 additions & 0 deletions src/felupe/mesh/_container.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

import numpy as np

from ._convert import cell_types
from ._mesh import Mesh
from ._tools import merge_duplicate_points as sweep
from ._tools import stack
Expand Down Expand Up @@ -202,6 +203,57 @@ def stack(self, idx=None):
]
raise TypeError(" ".join(message))

@classmethod
def from_unstructured_grid(cls, grid, dim=None, **kwargs):
r"""Create a mesh container from an unstructured grid (PyVista).
Parameters
----------
grid : pyvista.UnstructuredGrid
PyVista dataset used for arbitrary combinations of all possible cell types.
dim : int or None, optional
Trim the dimension of the ``points``-array (default is None).
**kwargs : dict, optional
Additional keyword-arguments are passed to the mesh container.
Returns
-------
MeshContainer
A container which operates on a list of meshes with identical dimensions.
Examples
--------
.. pyvista-plot::
>>> import felupe as fem
>>> import pyvista as pv
>>>
>>> grid = pv.UnstructuredGrid(pv.examples.hexbeamfile)
>>> container = fem.MechContainer.from_unstructured_grid(grid)
>>>
>>> container
<felupe mesh container object>
Number of points: 99
Number of cells:
hexahedron: 40
See Also
--------
felupe.mesh.cell_types : Return a list with tuples of cell type mappings.
felupe.Mesh.as_unstructured_grid : Export the mesh as unstructured grid.
"""

points = grid.points
meshes = []

cell_types_felupe = dict(cell_types()[:, [1, 0]])

for cell_type, cells in grid.cells_dict.items():
meshes.append(Mesh(points[:, :dim], cells, cell_types_felupe[cell_type]))

return cls(meshes, **kwargs)

def as_meshio(self, combined=True, **kwargs):
"Export a (combined) mesh object as :class:`meshio.Mesh`."

Expand Down
7 changes: 7 additions & 0 deletions tests/test_mesh.py
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,13 @@ def test_container():
for combined in [False, True]:
print(container.as_meshio(combined=combined))

container_2 = fem.MeshContainer.from_unstructured_grid(
mesh_1.as_unstructured_grid(), dim=2
)

assert np.allclose(container_2[0].points, mesh_1.points)
assert np.allclose(container_2[0].cells, mesh_1.cells)


def test_read(filename="tests/mesh.bdf"):
mesh = fem.mesh.read(filename=filename, dim=2)[0]
Expand Down

0 comments on commit 214d99e

Please sign in to comment.