Ensuring regular spacing for grid

This commit is contained in:
Martin Diehl 2020-12-10 20:53:11 +01:00
parent 4286fc3b82
commit 32c2de6b91
2 changed files with 28 additions and 14 deletions

View File

@ -7,7 +7,8 @@ import warnings
import numpy as np import numpy as np
import pandas as pd import pandas as pd
import h5py import h5py
from scipy import ndimage,spatial from scipy import ndimage, spatial
from vtk.util.numpy_support import vtk_to_numpy as vtk_to_np
from . import environment from . import environment
from . import VTK from . import VTK
@ -50,8 +51,8 @@ class Grid:
f'cells a b c: {util.srepr(self.cells, " x ")}', f'cells a b c: {util.srepr(self.cells, " x ")}',
f'size x y z: {util.srepr(self.size, " x ")}', f'size x y z: {util.srepr(self.size, " x ")}',
f'origin x y z: {util.srepr(self.origin," ")}', f'origin x y z: {util.srepr(self.origin," ")}',
f'# materials: {mat_N}' + ('' if mat_min == 0 and mat_max+1 == mat_N else f'# materials: {mat_N}' + ('' if mat_min == 0 and mat_max+1 == mat_N else
f' (min: {mat_min}, max: {mat_max})') f' (min: {mat_min}, max: {mat_max})')
]) ])
@ -107,9 +108,9 @@ class Grid:
@material.setter @material.setter
def material(self,material): def material(self,material):
if len(material.shape) != 3: if len(material.shape) != 3:
raise ValueError(f'Invalid material shape {material.shape}.') raise ValueError(f'invalid material shape {material.shape}')
elif material.dtype not in np.sctypes['float'] + np.sctypes['int']: elif material.dtype not in np.sctypes['float'] + np.sctypes['int']:
raise TypeError(f'Invalid material data type {material.dtype}.') raise TypeError(f'invalid material data type {material.dtype}')
else: else:
self._material = np.copy(material) self._material = np.copy(material)
@ -126,7 +127,7 @@ class Grid:
@size.setter @size.setter
def size(self,size): def size(self,size):
if len(size) != 3 or any(np.array(size) <= 0): if len(size) != 3 or any(np.array(size) <= 0):
raise ValueError(f'Invalid size {size}.') raise ValueError(f'invalid size {size}')
else: else:
self._size = np.array(size) self._size = np.array(size)
@ -138,7 +139,7 @@ class Grid:
@origin.setter @origin.setter
def origin(self,origin): def origin(self,origin):
if len(origin) != 3: if len(origin) != 3:
raise ValueError(f'Invalid origin {origin}.') raise ValueError(f'invalid origin {origin}')
else: else:
self._origin = np.array(origin) self._origin = np.array(origin)
@ -181,6 +182,10 @@ class Grid:
cells = np.array(v.vtk_data.GetDimensions())-1 cells = np.array(v.vtk_data.GetDimensions())-1
bbox = np.array(v.vtk_data.GetBounds()).reshape(3,2).T bbox = np.array(v.vtk_data.GetBounds()).reshape(3,2).T
for i,c in enumerate([v.vtk_data.GetXCoordinates(),v.vtk_data.GetYCoordinates(),v.vtk_data.GetZCoordinates()]):
if not np.allclose(vtk_to_np(c),np.linspace(bbox[0][i],bbox[1][i],cells[i]+1)):
raise ValueError('regular grid spacing violated')
return Grid(material = v.get('material').reshape(cells,order='F'), return Grid(material = v.get('material').reshape(cells,order='F'),
size = bbox[1] - bbox[0], size = bbox[1] - bbox[0],
origin = bbox[0], origin = bbox[0],
@ -214,7 +219,7 @@ class Grid:
except ValueError: except ValueError:
header_length,keyword = (-1, 'invalid') header_length,keyword = (-1, 'invalid')
if not keyword.startswith('head') or header_length < 3: if not keyword.startswith('head') or header_length < 3:
raise TypeError('Header length information missing or invalid') raise TypeError('header length information missing or invalid')
comments = [] comments = []
content = f.readlines() content = f.readlines()
@ -246,7 +251,7 @@ class Grid:
i += len(items) i += len(items)
if i != cells.prod(): if i != cells.prod():
raise TypeError(f'Invalid file: expected {cells.prod()} entries, found {i}') raise TypeError(f'invalid file: expected {cells.prod()} entries, found {i}')
if not np.any(np.mod(material,1) != 0.0): # no float present if not np.any(np.mod(material,1) != 0.0): # no float present
material = material.astype('int') - (1 if material.min() > 0 else 0) material = material.astype('int') - (1 if material.min() > 0 else 0)
@ -631,7 +636,7 @@ class Grid:
""" """
valid = ['x','y','z'] valid = ['x','y','z']
if not set(directions).issubset(valid): if not set(directions).issubset(valid):
raise ValueError(f'Invalid direction {set(directions).difference(valid)} specified.') raise ValueError(f'invalid direction {set(directions).difference(valid)} specified')
limits = [None,None] if reflect else [-2,0] limits = [None,None] if reflect else [-2,0]
mat = self.material.copy() mat = self.material.copy()
@ -663,7 +668,7 @@ class Grid:
""" """
valid = ['x','y','z'] valid = ['x','y','z']
if not set(directions).issubset(valid): if not set(directions).issubset(valid):
raise ValueError(f'Invalid direction {set(directions).difference(valid)} specified.') raise ValueError(f'invalid direction {set(directions).difference(valid)} specified')
mat = np.flip(self.material, (valid.index(d) for d in directions if d in valid)) mat = np.flip(self.material, (valid.index(d) for d in directions if d in valid))
@ -916,7 +921,7 @@ class Grid:
""" """
valid = ['x','y','z'] valid = ['x','y','z']
if not set(directions).issubset(valid): if not set(directions).issubset(valid):
raise ValueError(f'Invalid direction {set(directions).difference(valid)} specified.') raise ValueError(f'invalid direction {set(directions).difference(valid)} specified')
o = [[0, self.cells[0]+1, np.prod(self.cells[:2]+1)+self.cells[0]+1, np.prod(self.cells[:2]+1)], o = [[0, self.cells[0]+1, np.prod(self.cells[:2]+1)+self.cells[0]+1, np.prod(self.cells[:2]+1)],
[0, np.prod(self.cells[:2]+1), np.prod(self.cells[:2]+1)+1, 1], [0, np.prod(self.cells[:2]+1), np.prod(self.cells[:2]+1)+1, 1],

View File

@ -1,5 +1,6 @@
import pytest import pytest
import numpy as np import numpy as np
from vtk.util.numpy_support import numpy_to_vtk as np_to_vtk
from damask import VTK from damask import VTK
from damask import Grid from damask import Grid
@ -57,13 +58,21 @@ class TestGrid:
new = Grid.load(tmp_path/'default.vtr') new = Grid.load(tmp_path/'default.vtr')
assert grid_equal(new,default) assert grid_equal(new,default)
def test_invalid_vtr(self,tmp_path): def test_invalid_no_material(self,tmp_path):
v = VTK.from_rectilinear_grid(np.random.randint(5,10,3)*2,np.random.random(3) + 1.0) v = VTK.from_rectilinear_grid(np.random.randint(5,10,3)*2,np.random.random(3) + 1.0)
v.save(tmp_path/'no_materialpoint.vtr',parallel=False) v.save(tmp_path/'no_materialpoint.vtr',parallel=False)
with pytest.raises(ValueError): with pytest.raises(ValueError):
Grid.load(tmp_path/'no_materialpoint.vtr') Grid.load(tmp_path/'no_materialpoint.vtr')
def test_invalid_material(self): def test_invalid_spacing(self,tmp_path,default):
default.save(tmp_path/'spacing_ok.vtr')
vtk = VTK.load(tmp_path/'spacing_ok.vtr')
vtk.vtk_data.SetXCoordinates(np_to_vtk(np.sort(np.random.random(default.cells[0]))))
vtk.save(tmp_path/'invalid_spacing.vtr',parallel=False)
with pytest.raises(ValueError):
Grid.load(tmp_path/'invalid_spacing.vtr')
def test_invalid_material_type(self):
with pytest.raises(TypeError): with pytest.raises(TypeError):
Grid(np.zeros((3,3,3),dtype='complex'),np.ones(3)) Grid(np.zeros((3,3,3),dtype='complex'),np.ones(3))