implemented VTK.add(damask.Table)

This commit is contained in:
Philip Eisenlohr 2022-02-15 16:38:02 -05:00
parent 18f9ac7d44
commit 6916160ed1
3 changed files with 55 additions and 18 deletions

View File

@ -326,7 +326,7 @@ class Table:
@property
def labels(self) -> List[Tuple[int, ...]]:
def labels(self) -> List[str]:
return list(self.shapes)

View File

@ -38,6 +38,18 @@ class VTK:
self.vtk_data = vtk_data
@property
def N_points(self) -> int:
"""Number of points in vtkdata."""
return self.vtk_data.GetNumberOfPoints()
@property
def N_cells(self) -> int:
"""Number of cells in vtkdata."""
return self.vtk_data.GetNumberOfCells()
@staticmethod
def from_image_data(cells: IntSequence,
size: FloatSequence,
@ -295,7 +307,7 @@ class VTK:
# Check https://blog.kitware.com/ghost-and-blanking-visibility-changes/ for missing data
# Needs support for damask.Table
def add(self,
data: Union[np.ndarray, np.ma.MaskedArray],
data: Union[np.ndarray, np.ma.MaskedArray, 'Table'],
label: str = None):
"""
Add data to either cells or points.
@ -309,20 +321,17 @@ class VTK:
Data label.
"""
N_points = self.vtk_data.GetNumberOfPoints()
N_cells = self.vtk_data.GetNumberOfCells()
if isinstance(data,np.ndarray):
if label is None:
raise ValueError('No label defined for numpy.ndarray')
def _add_array(self,
data: np.ndarray,
label: str):
N_data = data.shape[0]
data_ = (data if not isinstance(data,np.ma.MaskedArray) else
np.where(data.mask,data.fill_value,data)).reshape(N_data,-1)
N_data = data.shape[0]
if data_.dtype in [np.double,np.longdouble]:
d = np_to_vtk(data_.astype(np.single),deep=True) # avoid large files
elif data_.dtype.type is np.str_:
data_ = data.reshape(N_data,-1)\
.astype(np.single if data.dtype in [np.double,np.longdouble] else data.dtype)
if data.dtype.type is np.str_:
d = vtk.vtkStringArray()
for s in np.squeeze(data_):
d.InsertNextValue(s)
@ -331,14 +340,24 @@ class VTK:
d.SetName(label)
if N_data == N_points:
if N_data == self.N_points:
self.vtk_data.GetPointData().AddArray(d)
elif N_data == N_cells:
elif N_data == self.N_cells:
self.vtk_data.GetCellData().AddArray(d)
else:
raise ValueError(f'Cell / point count ({N_cells} / {N_points}) differs from data ({N_data}).')
raise ValueError(f'Data count mismatch ({N_data}{self.N_points} & {self.N_cells})')
if isinstance(data,np.ndarray):
if label is not None:
_add_array(self,
np.where(data.mask,data.fill_value,data) if isinstance(data,np.ma.MaskedArray) else data,
label)
else:
raise ValueError('No label defined for numpy.ndarray')
elif isinstance(data,Table):
raise NotImplementedError('damask.Table')
for l in data.labels:
_add_array(self,data.get(l),l)
else:
raise TypeError
@ -383,7 +402,7 @@ class VTK:
# string array
return np.array([vtk_array.GetValue(i) for i in range(vtk_array.GetNumberOfValues())]).astype(str)
except UnboundLocalError:
raise ValueError(f'Array "{label}" not found.')
raise ValueError(f'Array "{label}" not found')
@property

View File

@ -7,7 +7,9 @@ import numpy as np
import numpy.ma as ma
import vtk
from collections import defaultdict
from damask import VTK
from damask import Table
from damask import grid_filters
@pytest.fixture
@ -152,6 +154,22 @@ class TestVTK:
assert (np.squeeze(data.reshape(N_values,-1)) == default.get('data')).all()
@pytest.mark.parametrize('shapes',[{'scalar':(1,),'vector':(3,),'tensor':(3,3)},
{'vector':(6,),'tensor':(3,3)},
{'tensor':(3,3),'scalar':(1,)}])
def test_add_table(self,default,shapes):
N = np.random.choice([default.N_points,default.N_cells])
d = defaultdict(dict)
for k,s in shapes.items():
d[k]['shape'] = s
d[k]['data'] = np.random.random(N*np.prod(s)).reshape((N,-1))
t = Table(np.column_stack([d[k]['data'] for k in shapes.keys()]),shapes)
default.add(t)
for k,s in shapes.items():
assert np.allclose(default.get(k).reshape((N,-1)),d[k]['data'],
rtol=1e-7)
def test_add_masked(self,default):
data = np.random.rand(5*6*7,3)
masked = ma.MaskedArray(data,mask=data<.4,fill_value=42.)