Merge remote-tracking branch 'origin/geom-attributes-as-checked-properties' into development
This commit is contained in:
commit
e90c20ccd6
|
@ -20,7 +20,7 @@ class Geom:
|
||||||
|
|
||||||
def __init__(self,material,size,origin=[0.0,0.0,0.0],comments=[]):
|
def __init__(self,material,size,origin=[0.0,0.0,0.0],comments=[]):
|
||||||
"""
|
"""
|
||||||
New geometry definition from array of material, size, and origin.
|
New geometry definition from array of materials, size, and origin.
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
----------
|
----------
|
||||||
|
@ -34,28 +34,10 @@ class Geom:
|
||||||
Comment lines.
|
Comment lines.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
if len(material.shape) != 3:
|
self.material = material
|
||||||
raise ValueError(f'Invalid material shape {material.shape}.')
|
self.size = size
|
||||||
elif material.dtype not in np.sctypes['float'] + np.sctypes['int']:
|
self.origin = origin
|
||||||
raise TypeError(f'Invalid material data type {material.dtype}.')
|
self.comments = comments
|
||||||
else:
|
|
||||||
self.material = np.copy(material)
|
|
||||||
|
|
||||||
if self.material.dtype in np.sctypes['float'] and \
|
|
||||||
np.all(self.material == self.material.astype(int).astype(float)):
|
|
||||||
self.material = self.material.astype(int)
|
|
||||||
|
|
||||||
if len(size) != 3 or any(np.array(size) <= 0):
|
|
||||||
raise ValueError(f'Invalid size {size}.')
|
|
||||||
else:
|
|
||||||
self.size = np.array(size)
|
|
||||||
|
|
||||||
if len(origin) != 3:
|
|
||||||
raise ValueError(f'Invalid origin {origin}.')
|
|
||||||
else:
|
|
||||||
self.origin = np.array(origin)
|
|
||||||
|
|
||||||
self.comments = [str(c) for c in comments] if isinstance(comments,list) else [str(comments)]
|
|
||||||
|
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
|
@ -113,13 +95,68 @@ class Geom:
|
||||||
return util.return_message(message)
|
return util.return_message(message)
|
||||||
|
|
||||||
|
|
||||||
|
@property
|
||||||
|
def material(self):
|
||||||
|
"""Material indices."""
|
||||||
|
return self._material
|
||||||
|
|
||||||
|
@material.setter
|
||||||
|
def material(self,material):
|
||||||
|
if len(material.shape) != 3:
|
||||||
|
raise ValueError(f'Invalid material shape {material.shape}.')
|
||||||
|
elif material.dtype not in np.sctypes['float'] + np.sctypes['int']:
|
||||||
|
raise TypeError(f'Invalid material data type {material.dtype}.')
|
||||||
|
else:
|
||||||
|
self._material = np.copy(material)
|
||||||
|
|
||||||
|
if self.material.dtype in np.sctypes['float'] and \
|
||||||
|
np.all(self.material == self.material.astype(int).astype(float)):
|
||||||
|
self._material = self.material.astype(int)
|
||||||
|
|
||||||
|
|
||||||
|
@property
|
||||||
|
def size(self):
|
||||||
|
"""Physical size of geometry in meter."""
|
||||||
|
return self._size
|
||||||
|
|
||||||
|
@size.setter
|
||||||
|
def size(self,size):
|
||||||
|
if len(size) != 3 or any(np.array(size) <= 0):
|
||||||
|
raise ValueError(f'Invalid size {size}.')
|
||||||
|
else:
|
||||||
|
self._size = np.array(size)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def origin(self):
|
||||||
|
"""Coordinates of geometry origin in meter."""
|
||||||
|
return self._origin
|
||||||
|
|
||||||
|
@origin.setter
|
||||||
|
def origin(self,origin):
|
||||||
|
if len(origin) != 3:
|
||||||
|
raise ValueError(f'Invalid origin {origin}.')
|
||||||
|
else:
|
||||||
|
self._origin = np.array(origin)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def comments(self):
|
||||||
|
"""Comments/history of geometry."""
|
||||||
|
return self._comments
|
||||||
|
|
||||||
|
@comments.setter
|
||||||
|
def comments(self,comments):
|
||||||
|
self._comments = [str(c) for c in comments] if isinstance(comments,list) else [str(comments)]
|
||||||
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def grid(self):
|
def grid(self):
|
||||||
|
"""Grid dimension of geometry."""
|
||||||
return np.asarray(self.material.shape)
|
return np.asarray(self.material.shape)
|
||||||
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def N_materials(self):
|
def N_materials(self):
|
||||||
|
"""Number of (unique) material indices within geometry."""
|
||||||
return np.unique(self.material).size
|
return np.unique(self.material).size
|
||||||
|
|
||||||
|
|
||||||
|
@ -132,7 +169,7 @@ class Geom:
|
||||||
----------
|
----------
|
||||||
fname : str or or pathlib.Path
|
fname : str or or pathlib.Path
|
||||||
Geometry file to read.
|
Geometry file to read.
|
||||||
Valid extension is .vtr, it will be appended if not given.
|
Valid extension is .vtr, which will be appended if not given.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
v = VTK.load(fname if str(fname).endswith('.vtr') else str(fname)+'.vtr')
|
v = VTK.load(fname if str(fname).endswith('.vtr') else str(fname)+'.vtr')
|
||||||
|
@ -153,7 +190,7 @@ class Geom:
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
----------
|
----------
|
||||||
fname : str or file handle
|
fname : str, pathlib.Path, or file handle
|
||||||
Geometry file to read.
|
Geometry file to read.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
@ -221,26 +258,26 @@ class Geom:
|
||||||
fname : str
|
fname : str
|
||||||
Filename of the DREAM.3D file
|
Filename of the DREAM.3D file
|
||||||
base_group : str
|
base_group : str
|
||||||
Name of the group (folder) below 'DataContainers'. For example
|
Name of the group (folder) below 'DataContainers',
|
||||||
'SyntheticVolumeDataContainer'.
|
for example 'SyntheticVolumeDataContainer'.
|
||||||
point_data : str, optional
|
point_data : str, optional
|
||||||
Name of the group (folder) containing the pointwise material data,
|
Name of the group (folder) containing the pointwise material data,
|
||||||
for example 'CellData'. Defaults to None, in which case points consecutively numbered.
|
for example 'CellData'. Defaults to None, in which case points are consecutively numbered.
|
||||||
material : str, optional
|
material : str, optional
|
||||||
Name of the dataset containing the material ID. Defaults to
|
Name of the dataset containing the material ID.
|
||||||
'FeatureIds'.
|
Defaults to 'FeatureIds'.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
root_dir ='DataContainers'
|
root_dir ='DataContainers'
|
||||||
f = h5py.File(fname, 'r')
|
f = h5py.File(fname, 'r')
|
||||||
g = path.join(root_dir,base_group,'_SIMPL_GEOMETRY')
|
g = path.join(root_dir,base_group,'_SIMPL_GEOMETRY')
|
||||||
size = f[path.join(g,'DIMENSIONS')][()] * f[path.join(g,'SPACING')][()]
|
|
||||||
grid = f[path.join(g,'DIMENSIONS')][()]
|
grid = f[path.join(g,'DIMENSIONS')][()]
|
||||||
|
size = f[path.join(g,'SPACING')][()] * grid
|
||||||
origin = f[path.join(g,'ORIGIN')][()]
|
origin = f[path.join(g,'ORIGIN')][()]
|
||||||
group_pointwise = path.join(root_dir,base_group,point_data)
|
|
||||||
|
|
||||||
ma = np.arange(1,np.product(grid)+1,dtype=int) if point_data is None else \
|
ma = np.arange(grid.prod(),dtype=int) \
|
||||||
np.reshape(f[path.join(group_pointwise,material)],grid.prod())
|
if point_data is None else \
|
||||||
|
np.reshape(f[path.join(root_dir,base_group,point_data,material)],grid.prod())
|
||||||
|
|
||||||
return Geom(ma.reshape(grid,order='F'),size,origin,util.execution_stamp('Geom','load_DREAM3D'))
|
return Geom(ma.reshape(grid,order='F'),size,origin,util.execution_stamp('Geom','load_DREAM3D'))
|
||||||
|
|
||||||
|
@ -248,18 +285,18 @@ class Geom:
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def from_table(table,coordinates,labels):
|
def from_table(table,coordinates,labels):
|
||||||
"""
|
"""
|
||||||
Load an ASCII table.
|
Derive geometry from an ASCII table.
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
----------
|
----------
|
||||||
table : damask.Table
|
table : damask.Table
|
||||||
Table that contains material information.
|
Table that contains material information.
|
||||||
coordinates : str
|
coordinates : str
|
||||||
Label of the column containing the vector of spatial coordinates.
|
Label of the vector column containing the spatial coordinates.
|
||||||
Need to be ordered (1./x fast, 3./z slow).
|
Need to be ordered (1./x fast, 3./z slow).
|
||||||
labels : str or list of str
|
labels : str or list of str
|
||||||
Label(s) of the columns containing the material definition.
|
Label(s) of the columns containing the material definition.
|
||||||
Each unique combintation of values results in a material.
|
Each unique combintation of values results in one material ID.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
grid,size,origin = grid_filters.cell_coord0_gridSizeOrigin(table.get(coordinates))
|
grid,size,origin = grid_filters.cell_coord0_gridSizeOrigin(table.get(coordinates))
|
||||||
|
@ -293,8 +330,8 @@ class Geom:
|
||||||
weights : numpy.ndarray of shape (seeds.shape[0])
|
weights : numpy.ndarray of shape (seeds.shape[0])
|
||||||
Weights of the seeds. Setting all weights to 1.0 gives a standard Voronoi tessellation.
|
Weights of the seeds. Setting all weights to 1.0 gives a standard Voronoi tessellation.
|
||||||
material : numpy.ndarray of shape (seeds.shape[0]), optional
|
material : numpy.ndarray of shape (seeds.shape[0]), optional
|
||||||
Material ID of the seeds. Defaults to None, in which case materials are
|
Material ID of the seeds.
|
||||||
consecutively numbered.
|
Defaults to None, in which case materials are consecutively numbered.
|
||||||
periodic : Boolean, optional
|
periodic : Boolean, optional
|
||||||
Perform a periodic tessellation. Defaults to True.
|
Perform a periodic tessellation. Defaults to True.
|
||||||
|
|
||||||
|
@ -342,8 +379,8 @@ class Geom:
|
||||||
seeds : numpy.ndarray of shape (:,3)
|
seeds : numpy.ndarray of shape (:,3)
|
||||||
Position of the seed points in meter. All points need to lay within the box.
|
Position of the seed points in meter. All points need to lay within the box.
|
||||||
material : numpy.ndarray of shape (seeds.shape[0]), optional
|
material : numpy.ndarray of shape (seeds.shape[0]), optional
|
||||||
Material ID of the seeds. Defaults to None, in which case materials are
|
Material ID of the seeds.
|
||||||
consecutively numbered.
|
Defaults to None, in which case materials are consecutively numbered.
|
||||||
periodic : Boolean, optional
|
periodic : Boolean, optional
|
||||||
Perform a periodic tessellation. Defaults to True.
|
Perform a periodic tessellation. Defaults to True.
|
||||||
|
|
||||||
|
@ -438,19 +475,19 @@ class Geom:
|
||||||
|
|
||||||
References
|
References
|
||||||
----------
|
----------
|
||||||
Surface curvature in triply-periodic minimal surface architectures as
|
|
||||||
a distinct design parameter in preparing advanced tissue engineering scaffolds
|
|
||||||
Sébastien B G Blanquer, Maike Werner, Markus Hannula, Shahriar Sharifi,
|
Sébastien B G Blanquer, Maike Werner, Markus Hannula, Shahriar Sharifi,
|
||||||
Guillaume P R Lajoinie, David Eglin, Jari Hyttinen, André A Poot, and Dirk W Grijpma
|
Guillaume P R Lajoinie, David Eglin, Jari Hyttinen, André A Poot, and Dirk W Grijpma
|
||||||
10.1088/1758-5090/aa6553
|
Surface curvature in triply-periodic minimal surface architectures as
|
||||||
|
a distinct design parameter in preparing advanced tissue engineering scaffolds
|
||||||
|
https://doi.org/10.1088/1758-5090/aa6553
|
||||||
|
|
||||||
Triply Periodic Bicontinuous Cubic Microdomain Morphologies by Symmetries
|
|
||||||
Meinhard Wohlgemuth, Nataliya Yufa, James Hoffman, and Edwin L. Thomas
|
Meinhard Wohlgemuth, Nataliya Yufa, James Hoffman, and Edwin L. Thomas
|
||||||
10.1021/ma0019499
|
Triply Periodic Bicontinuous Cubic Microdomain Morphologies by Symmetries
|
||||||
|
https://doi.org/10.1021/ma0019499
|
||||||
|
|
||||||
Minisurf – A minimal surface generator for finite element modeling and additive manufacturing
|
|
||||||
Meng-Ting Hsieh, Lorenzo Valdevit
|
Meng-Ting Hsieh, Lorenzo Valdevit
|
||||||
10.1016/j.simpa.2020.100026
|
Minisurf – A minimal surface generator for finite element modeling and additive manufacturing
|
||||||
|
https://doi.org/10.1016/j.simpa.2020.100026
|
||||||
|
|
||||||
"""
|
"""
|
||||||
x,y,z = np.meshgrid(periods*2.0*np.pi*(np.arange(grid[0])+0.5)/grid[0],
|
x,y,z = np.meshgrid(periods*2.0*np.pi*(np.arange(grid[0])+0.5)/grid[0],
|
||||||
|
@ -465,7 +502,7 @@ class Geom:
|
||||||
|
|
||||||
def save(self,fname,compress=True):
|
def save(self,fname,compress=True):
|
||||||
"""
|
"""
|
||||||
Store as vtk rectilinear grid.
|
Store as VTK rectilinear grid.
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
----------
|
----------
|
||||||
|
@ -689,7 +726,7 @@ class Geom:
|
||||||
|
|
||||||
|
|
||||||
def renumber(self):
|
def renumber(self):
|
||||||
"""Renumber sorted material indices to 0,...,N-1."""
|
"""Renumber sorted material indices as 0,...,N-1."""
|
||||||
_,renumbered = np.unique(self.material,return_inverse=True)
|
_,renumbered = np.unique(self.material,return_inverse=True)
|
||||||
|
|
||||||
return Geom(material = renumbered.reshape(self.grid),
|
return Geom(material = renumbered.reshape(self.grid),
|
||||||
|
|
Loading…
Reference in New Issue