clarify out-of-place behavior and document return values
This commit is contained in:
parent
26f37d822d
commit
4d67c85a33
2
PRIVATE
2
PRIVATE
|
@ -1 +1 @@
|
||||||
Subproject commit 23eac08c9f9638f8dae76710095222d00f948eec
|
Subproject commit d58a002b0a43d240f143aee1396fdc766d87a886
|
|
@ -60,54 +60,6 @@ class ConfigMaterial(Config):
|
||||||
return super(ConfigMaterial,cls).load(fname)
|
return super(ConfigMaterial,cls).load(fname)
|
||||||
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def from_table(table,**kwargs):
|
|
||||||
"""
|
|
||||||
Generate from an ASCII table.
|
|
||||||
|
|
||||||
Parameters
|
|
||||||
----------
|
|
||||||
table : damask.Table
|
|
||||||
Table that contains material information.
|
|
||||||
**kwargs
|
|
||||||
Keyword arguments where the key is the name and the value specifies
|
|
||||||
the label of the data column in the table.
|
|
||||||
|
|
||||||
Examples
|
|
||||||
--------
|
|
||||||
>>> import damask
|
|
||||||
>>> import damask.ConfigMaterial as cm
|
|
||||||
>>> t = damask.Table.load('small.txt')
|
|
||||||
>>> t
|
|
||||||
pos pos pos qu qu qu qu phase homog
|
|
||||||
0 0 0 0 0.19 0.8 0.24 -0.51 Aluminum SX
|
|
||||||
1 1 0 0 0.8 0.19 0.24 -0.51 Steel SX
|
|
||||||
1 1 1 0 0.8 0.19 0.24 -0.51 Steel SX
|
|
||||||
>>> cm.from_table(t,O='qu',phase='phase',homogenization='homog')
|
|
||||||
material:
|
|
||||||
- constituents:
|
|
||||||
- O: [0.19, 0.8, 0.24, -0.51]
|
|
||||||
v: 1.0
|
|
||||||
phase: Aluminum
|
|
||||||
homogenization: SX
|
|
||||||
- constituents:
|
|
||||||
- O: [0.8, 0.19, 0.24, -0.51]
|
|
||||||
v: 1.0
|
|
||||||
phase: Steel
|
|
||||||
homogenization: SX
|
|
||||||
homogenization: {}
|
|
||||||
phase: {}
|
|
||||||
|
|
||||||
"""
|
|
||||||
kwargs_ = {k:table.get(v) for k,v in kwargs.items()}
|
|
||||||
|
|
||||||
_,idx = np.unique(np.hstack(list(kwargs_.values())),return_index=True,axis=0)
|
|
||||||
idx = np.sort(idx)
|
|
||||||
kwargs_ = {k:np.atleast_1d(v[idx].squeeze()) for k,v in kwargs_.items()}
|
|
||||||
|
|
||||||
return ConfigMaterial().material_add(**kwargs_)
|
|
||||||
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def load_DREAM3D(fname,
|
def load_DREAM3D(fname,
|
||||||
grain_data=None,cell_data=None,cell_ensemble_data='CellEnsembleData',
|
grain_data=None,cell_data=None,cell_ensemble_data='CellEnsembleData',
|
||||||
|
@ -181,9 +133,69 @@ class ConfigMaterial(Config):
|
||||||
return base_config.material_add(**constituent,homogenization='direct')
|
return base_config.material_add(**constituent,homogenization='direct')
|
||||||
|
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def from_table(table,**kwargs):
|
||||||
|
"""
|
||||||
|
Generate from an ASCII table.
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
table : damask.Table
|
||||||
|
Table that contains material information.
|
||||||
|
**kwargs
|
||||||
|
Keyword arguments where the key is the name and the value specifies
|
||||||
|
the label of the data column in the table.
|
||||||
|
|
||||||
|
Examples
|
||||||
|
--------
|
||||||
|
>>> import damask
|
||||||
|
>>> import damask.ConfigMaterial as cm
|
||||||
|
>>> t = damask.Table.load('small.txt')
|
||||||
|
>>> t
|
||||||
|
pos pos pos qu qu qu qu phase homog
|
||||||
|
0 0 0 0 0.19 0.8 0.24 -0.51 Aluminum SX
|
||||||
|
1 1 0 0 0.8 0.19 0.24 -0.51 Steel SX
|
||||||
|
1 1 1 0 0.8 0.19 0.24 -0.51 Steel SX
|
||||||
|
>>> cm.from_table(t,O='qu',phase='phase',homogenization='homog')
|
||||||
|
material:
|
||||||
|
- constituents:
|
||||||
|
- O: [0.19, 0.8, 0.24, -0.51]
|
||||||
|
v: 1.0
|
||||||
|
phase: Aluminum
|
||||||
|
homogenization: SX
|
||||||
|
- constituents:
|
||||||
|
- O: [0.8, 0.19, 0.24, -0.51]
|
||||||
|
v: 1.0
|
||||||
|
phase: Steel
|
||||||
|
homogenization: SX
|
||||||
|
homogenization: {}
|
||||||
|
phase: {}
|
||||||
|
|
||||||
|
"""
|
||||||
|
kwargs_ = {k:table.get(v) for k,v in kwargs.items()}
|
||||||
|
|
||||||
|
_,idx = np.unique(np.hstack(list(kwargs_.values())),return_index=True,axis=0)
|
||||||
|
idx = np.sort(idx)
|
||||||
|
kwargs_ = {k:np.atleast_1d(v[idx].squeeze()) for k,v in kwargs_.items()}
|
||||||
|
|
||||||
|
return ConfigMaterial().material_add(**kwargs_)
|
||||||
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def is_complete(self):
|
def is_complete(self):
|
||||||
"""Check for completeness."""
|
"""
|
||||||
|
Check for completeness.
|
||||||
|
|
||||||
|
Only the general file layout is considered.
|
||||||
|
This check does not consider whether parameters for
|
||||||
|
a particular phase/homogenization model are missing.
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
complete : bool
|
||||||
|
Whether the material.yaml definition is complete.
|
||||||
|
|
||||||
|
"""
|
||||||
ok = True
|
ok = True
|
||||||
for top_level in ['homogenization','phase','material']:
|
for top_level in ['homogenization','phase','material']:
|
||||||
ok &= top_level in self
|
ok &= top_level in self
|
||||||
|
@ -236,7 +248,19 @@ class ConfigMaterial(Config):
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def is_valid(self):
|
def is_valid(self):
|
||||||
"""Check for valid content."""
|
"""
|
||||||
|
Check for valid content.
|
||||||
|
|
||||||
|
Only the generic file content is considered.
|
||||||
|
This check does not consider whether parameters for a
|
||||||
|
particular phase/homogenization mode are out of bounds.
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
valid : bool
|
||||||
|
Whether the material.yaml definition is valid.
|
||||||
|
|
||||||
|
"""
|
||||||
ok = True
|
ok = True
|
||||||
|
|
||||||
if 'phase' in self:
|
if 'phase' in self:
|
||||||
|
@ -282,7 +306,7 @@ class ConfigMaterial(Config):
|
||||||
|
|
||||||
Returns
|
Returns
|
||||||
-------
|
-------
|
||||||
cfg : damask.ConfigMaterial
|
updated : damask.ConfigMaterial
|
||||||
Updated material configuration.
|
Updated material configuration.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
@ -311,7 +335,7 @@ class ConfigMaterial(Config):
|
||||||
|
|
||||||
Returns
|
Returns
|
||||||
-------
|
-------
|
||||||
cfg : damask.ConfigMaterial
|
updated : damask.ConfigMaterial
|
||||||
Updated material configuration.
|
Updated material configuration.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
@ -336,7 +360,7 @@ class ConfigMaterial(Config):
|
||||||
|
|
||||||
Returns
|
Returns
|
||||||
-------
|
-------
|
||||||
cfg : damask.ConfigMaterial
|
updated : damask.ConfigMaterial
|
||||||
Updated material configuration.
|
Updated material configuration.
|
||||||
|
|
||||||
Examples
|
Examples
|
||||||
|
|
|
@ -57,11 +57,15 @@ def _empty_like(dataset,N_materialpoints,fill_float,fill_int):
|
||||||
|
|
||||||
class Result:
|
class Result:
|
||||||
"""
|
"""
|
||||||
Manipulate and read DADF5 files.
|
Add data to and export from DADF5 files.
|
||||||
|
|
||||||
DADF5 (DAMASK HDF5) files contain DAMASK results.
|
DADF5 (DAMASK HDF5) files contain DAMASK results.
|
||||||
The group/folder structure reflects the input data
|
Their group/folder structure reflects the input data in material.yaml.
|
||||||
in material.yaml.
|
|
||||||
|
This class provides a custom view on the DADF5 file.
|
||||||
|
Upon initialization, all attributes are visible.
|
||||||
|
Derived quantities can be added to the file and existing data can be exported based on the current view.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self,fname):
|
def __init__(self,fname):
|
||||||
|
@ -274,6 +278,11 @@ class Result:
|
||||||
Name of datasets; supports '?' and '*' wildcards.
|
Name of datasets; supports '?' and '*' wildcards.
|
||||||
True is equivalent to '*', False is equivalent to [].
|
True is equivalent to '*', False is equivalent to [].
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
view : damask.Result
|
||||||
|
View with where selected attributes are visible.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return self._manage_view('set',what,datasets)
|
return self._manage_view('set',what,datasets)
|
||||||
|
|
||||||
|
@ -290,6 +299,11 @@ class Result:
|
||||||
Name of datasets; supports '?' and '*' wildcards.
|
Name of datasets; supports '?' and '*' wildcards.
|
||||||
True is equivalent to '*', False is equivalent to [].
|
True is equivalent to '*', False is equivalent to [].
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
modified_view : damask.Result
|
||||||
|
View with more visible attributes.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return self._manage_view('add',what,datasets)
|
return self._manage_view('add',what,datasets)
|
||||||
|
|
||||||
|
@ -306,6 +320,11 @@ class Result:
|
||||||
Name of datasets; supports '?' and '*' wildcards.
|
Name of datasets; supports '?' and '*' wildcards.
|
||||||
True is equivalent to '*', False is equivalent to [].
|
True is equivalent to '*', False is equivalent to [].
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
modified_view : damask.Result
|
||||||
|
View with less visible attributes.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return self._manage_view('del',what,datasets)
|
return self._manage_view('del',what,datasets)
|
||||||
|
|
||||||
|
@ -372,7 +391,7 @@ class Result:
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def coordinates0_point(self):
|
def coordinates0_point(self):
|
||||||
"""Return initial coordinates of the cell centers."""
|
"""Initial/undeformed cell center coordinates."""
|
||||||
if self.structured:
|
if self.structured:
|
||||||
return grid_filters.coordinates0_point(self.cells,self.size,self.origin).reshape(-1,3,order='F')
|
return grid_filters.coordinates0_point(self.cells,self.size,self.origin).reshape(-1,3,order='F')
|
||||||
else:
|
else:
|
||||||
|
@ -381,7 +400,7 @@ class Result:
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def coordinates0_node(self):
|
def coordinates0_node(self):
|
||||||
"""Return initial coordinates of the cell centers."""
|
"""Initial/undeformed nodal coordinates."""
|
||||||
if self.structured:
|
if self.structured:
|
||||||
return grid_filters.coordinates0_node(self.cells,self.size,self.origin).reshape(-1,3,order='F')
|
return grid_filters.coordinates0_node(self.cells,self.size,self.origin).reshape(-1,3,order='F')
|
||||||
else:
|
else:
|
||||||
|
@ -390,6 +409,7 @@ class Result:
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def geometry0(self):
|
def geometry0(self):
|
||||||
|
"""Initial/undeformed geometry."""
|
||||||
if self.structured:
|
if self.structured:
|
||||||
return VTK.from_rectilinear_grid(self.cells,self.size,self.origin)
|
return VTK.from_rectilinear_grid(self.cells,self.size,self.origin)
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -223,6 +223,11 @@ class Table:
|
||||||
fname : file, str, or pathlib.Path
|
fname : file, str, or pathlib.Path
|
||||||
Filename or file for reading.
|
Filename or file for reading.
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
loaded : damask.Table
|
||||||
|
Table data from file.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
f = open(fname)
|
f = open(fname)
|
||||||
|
@ -275,6 +280,11 @@ class Table:
|
||||||
fname : file, str, or pathlib.Path
|
fname : file, str, or pathlib.Path
|
||||||
Filename or file for reading.
|
Filename or file for reading.
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
loaded : damask.Table
|
||||||
|
Table data from file.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
f = open(fname)
|
f = open(fname)
|
||||||
|
@ -334,14 +344,14 @@ class Table:
|
||||||
----------
|
----------
|
||||||
label : str
|
label : str
|
||||||
Column label.
|
Column label.
|
||||||
data : np.ndarray
|
data : numpy.ndarray
|
||||||
New data.
|
New data.
|
||||||
info : str, optional
|
info : str, optional
|
||||||
Human-readable information about the new data.
|
Human-readable information about the new data.
|
||||||
|
|
||||||
Returns
|
Returns
|
||||||
-------
|
-------
|
||||||
table : Table
|
updated : damask.Table
|
||||||
Updated table.
|
Updated table.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
@ -367,14 +377,14 @@ class Table:
|
||||||
----------
|
----------
|
||||||
label : str
|
label : str
|
||||||
Column label.
|
Column label.
|
||||||
data : np.ndarray
|
data : numpy.ndarray
|
||||||
Modified data.
|
Modified data.
|
||||||
info : str, optional
|
info : str, optional
|
||||||
Human-readable information about the modified data.
|
Human-readable information about the modified data.
|
||||||
|
|
||||||
Returns
|
Returns
|
||||||
-------
|
-------
|
||||||
table : Table
|
udated : damask.Table
|
||||||
Updated table.
|
Updated table.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
@ -402,7 +412,7 @@ class Table:
|
||||||
|
|
||||||
Returns
|
Returns
|
||||||
-------
|
-------
|
||||||
table : Table
|
udated : damask.Table
|
||||||
Updated table.
|
Updated table.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
@ -425,7 +435,7 @@ class Table:
|
||||||
|
|
||||||
Returns
|
Returns
|
||||||
-------
|
-------
|
||||||
table : Table
|
udated : damask.Table
|
||||||
Updated table.
|
Updated table.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
@ -451,7 +461,7 @@ class Table:
|
||||||
|
|
||||||
Returns
|
Returns
|
||||||
-------
|
-------
|
||||||
table : Table
|
udated : damask.Table
|
||||||
Updated table.
|
Updated table.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
@ -479,13 +489,13 @@ class Table:
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
----------
|
----------
|
||||||
other : Table
|
other : damask.Table
|
||||||
Table to append.
|
Table to append.
|
||||||
|
|
||||||
Returns
|
Returns
|
||||||
-------
|
-------
|
||||||
table : Table
|
udated : damask.Table
|
||||||
Concatenated table.
|
Updated table.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
if self.shapes != other.shapes or not self.data.columns.equals(other.data.columns):
|
if self.shapes != other.shapes or not self.data.columns.equals(other.data.columns):
|
||||||
|
@ -504,13 +514,13 @@ class Table:
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
----------
|
----------
|
||||||
other : Table
|
other : damask.Table
|
||||||
Table to join.
|
Table to join.
|
||||||
|
|
||||||
Returns
|
Returns
|
||||||
-------
|
-------
|
||||||
table : Table
|
udated : damask.Table
|
||||||
Joined table.
|
Updated table.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
if set(self.shapes) & set(other.shapes) or self.data.shape[0] != other.data.shape[0]:
|
if set(self.shapes) & set(other.shapes) or self.data.shape[0] != other.data.shape[0]:
|
||||||
|
|
|
@ -5,11 +5,12 @@ Notes
|
||||||
-----
|
-----
|
||||||
The grids are defined as (x,y,z,...) where x is fastest and z is slowest.
|
The grids are defined as (x,y,z,...) where x is fastest and z is slowest.
|
||||||
This convention is consistent with the layout in grid vtr files.
|
This convention is consistent with the layout in grid vtr files.
|
||||||
|
|
||||||
When converting to/from a plain list (e.g. storage in ASCII table),
|
When converting to/from a plain list (e.g. storage in ASCII table),
|
||||||
the following operations are required for tensorial data:
|
the following operations are required for tensorial data:
|
||||||
|
|
||||||
D3 = D1.reshape(cells+(-1,),order='F').reshape(cells+(3,3))
|
- D3 = D1.reshape(cells+(-1,),order='F').reshape(cells+(3,3))
|
||||||
D1 = D3.reshape(cells+(-1,)).reshape(-1,9,order='F')
|
- D1 = D3.reshape(cells+(-1,)).reshape(-1,9,order='F')
|
||||||
|
|
||||||
"""
|
"""
|
||||||
from scipy import spatial as _spatial
|
from scipy import spatial as _spatial
|
||||||
|
@ -29,10 +30,12 @@ def _ks(size,cells,first_order=False):
|
||||||
Correction for first order derivatives, defaults to False.
|
Correction for first order derivatives, defaults to False.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
k_sk = _np.where(_np.arange(cells[0])>cells[0]//2,_np.arange(cells[0])-cells[0],_np.arange(cells[0]))/size[0]
|
k_sk = _np.where(_np.arange(cells[0])>cells[0]//2,
|
||||||
|
_np.arange(cells[0])-cells[0],_np.arange(cells[0]))/size[0]
|
||||||
if cells[0]%2 == 0 and first_order: k_sk[cells[0]//2] = 0 # Nyquist freq=0 for even cells (Johnson, MIT, 2011)
|
if cells[0]%2 == 0 and first_order: k_sk[cells[0]//2] = 0 # Nyquist freq=0 for even cells (Johnson, MIT, 2011)
|
||||||
|
|
||||||
k_sj = _np.where(_np.arange(cells[1])>cells[1]//2,_np.arange(cells[1])-cells[1],_np.arange(cells[1]))/size[1]
|
k_sj = _np.where(_np.arange(cells[1])>cells[1]//2,
|
||||||
|
_np.arange(cells[1])-cells[1],_np.arange(cells[1]))/size[1]
|
||||||
if cells[1]%2 == 0 and first_order: k_sj[cells[1]//2] = 0 # Nyquist freq=0 for even cells (Johnson, MIT, 2011)
|
if cells[1]%2 == 0 and first_order: k_sj[cells[1]//2] = 0 # Nyquist freq=0 for even cells (Johnson, MIT, 2011)
|
||||||
|
|
||||||
k_si = _np.arange(cells[2]//2+1)/size[2]
|
k_si = _np.arange(cells[2]//2+1)/size[2]
|
||||||
|
@ -40,74 +43,89 @@ def _ks(size,cells,first_order=False):
|
||||||
return _np.stack(_np.meshgrid(k_sk,k_sj,k_si,indexing = 'ij'), axis=-1)
|
return _np.stack(_np.meshgrid(k_sk,k_sj,k_si,indexing = 'ij'), axis=-1)
|
||||||
|
|
||||||
|
|
||||||
def curl(size,field):
|
def curl(size,f):
|
||||||
"""
|
u"""
|
||||||
Calculate curl of a vector or tensor field in Fourier space.
|
Calculate curl of a vector or tensor field in Fourier space.
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
----------
|
----------
|
||||||
size : numpy.ndarray of shape (3)
|
size : numpy.ndarray of shape (3)
|
||||||
Physical size of the periodic field.
|
Physical size of the periodic field.
|
||||||
field : numpy.ndarray of shape (:,:,:,3) or (:,:,:,3,3)
|
f : numpy.ndarray of shape (:,:,:,3) or (:,:,:,3,3)
|
||||||
Periodic field of which the curl is calculated.
|
Periodic field of which the curl is calculated.
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
∇ × f : numpy.ndarray
|
||||||
|
Curl of f.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
n = _np.prod(field.shape[3:])
|
n = _np.prod(f.shape[3:])
|
||||||
k_s = _ks(size,field.shape[:3],True)
|
k_s = _ks(size,f.shape[:3],True)
|
||||||
|
|
||||||
e = _np.zeros((3, 3, 3))
|
e = _np.zeros((3, 3, 3))
|
||||||
e[0, 1, 2] = e[1, 2, 0] = e[2, 0, 1] = +1.0 # Levi-Civita symbol
|
e[0, 1, 2] = e[1, 2, 0] = e[2, 0, 1] = +1.0 # Levi-Civita symbol
|
||||||
e[0, 2, 1] = e[2, 1, 0] = e[1, 0, 2] = -1.0
|
e[0, 2, 1] = e[2, 1, 0] = e[1, 0, 2] = -1.0
|
||||||
|
|
||||||
field_fourier = _np.fft.rfftn(field,axes=(0,1,2))
|
f_fourier = _np.fft.rfftn(f,axes=(0,1,2))
|
||||||
curl_ = (_np.einsum('slm,ijkl,ijkm ->ijks', e,k_s,field_fourier)*2.0j*_np.pi if n == 3 else # vector, 3 -> 3
|
curl_ = (_np.einsum('slm,ijkl,ijkm ->ijks', e,k_s,f_fourier)*2.0j*_np.pi if n == 3 else # vector, 3 -> 3
|
||||||
_np.einsum('slm,ijkl,ijknm->ijksn',e,k_s,field_fourier)*2.0j*_np.pi) # tensor, 3x3 -> 3x3
|
_np.einsum('slm,ijkl,ijknm->ijksn',e,k_s,f_fourier)*2.0j*_np.pi) # tensor, 3x3 -> 3x3
|
||||||
|
|
||||||
return _np.fft.irfftn(curl_,axes=(0,1,2),s=field.shape[:3])
|
return _np.fft.irfftn(curl_,axes=(0,1,2),s=f.shape[:3])
|
||||||
|
|
||||||
|
|
||||||
def divergence(size,field):
|
def divergence(size,f):
|
||||||
"""
|
u"""
|
||||||
Calculate divergence of a vector or tensor field in Fourier space.
|
Calculate divergence of a vector or tensor field in Fourier space.
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
----------
|
----------
|
||||||
size : numpy.ndarray of shape (3)
|
size : numpy.ndarray of shape (3)
|
||||||
Physical size of the periodic field.
|
Physical size of the periodic field.
|
||||||
field : numpy.ndarray of shape (:,:,:,3) or (:,:,:,3,3)
|
f : numpy.ndarray of shape (:,:,:,3) or (:,:,:,3,3)
|
||||||
Periodic field of which the divergence is calculated.
|
Periodic field of which the divergence is calculated.
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
∇ · f : numpy.ndarray
|
||||||
|
Divergence of f.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
n = _np.prod(field.shape[3:])
|
n = _np.prod(f.shape[3:])
|
||||||
k_s = _ks(size,field.shape[:3],True)
|
k_s = _ks(size,f.shape[:3],True)
|
||||||
|
|
||||||
field_fourier = _np.fft.rfftn(field,axes=(0,1,2))
|
f_fourier = _np.fft.rfftn(f,axes=(0,1,2))
|
||||||
div_ = (_np.einsum('ijkl,ijkl ->ijk', k_s,field_fourier)*2.0j*_np.pi if n == 3 else # vector, 3 -> 1
|
div_ = (_np.einsum('ijkl,ijkl ->ijk', k_s,f_fourier)*2.0j*_np.pi if n == 3 else # vector, 3 -> 1
|
||||||
_np.einsum('ijkm,ijklm->ijkl',k_s,field_fourier)*2.0j*_np.pi) # tensor, 3x3 -> 3
|
_np.einsum('ijkm,ijklm->ijkl',k_s,f_fourier)*2.0j*_np.pi) # tensor, 3x3 -> 3
|
||||||
|
|
||||||
return _np.fft.irfftn(div_,axes=(0,1,2),s=field.shape[:3])
|
return _np.fft.irfftn(div_,axes=(0,1,2),s=f.shape[:3])
|
||||||
|
|
||||||
|
|
||||||
def gradient(size,field):
|
def gradient(size,f):
|
||||||
"""
|
u"""
|
||||||
Calculate gradient of a scalar or vector field in Fourier space.
|
Calculate gradient of a scalar or vector fieldin Fourier space.
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
----------
|
----------
|
||||||
size : numpy.ndarray of shape (3)
|
size : numpy.ndarray of shape (3)
|
||||||
Physical size of the periodic field.
|
Physical size of the periodic field.
|
||||||
field : numpy.ndarray of shape (:,:,:,1) or (:,:,:,3)
|
f : numpy.ndarray of shape (:,:,:,1) or (:,:,:,3)
|
||||||
Periodic field of which the gradient is calculated.
|
Periodic field of which the gradient is calculated.
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
∇ f : numpy.ndarray
|
||||||
|
Divergence of f.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
n = _np.prod(field.shape[3:])
|
n = _np.prod(f.shape[3:])
|
||||||
k_s = _ks(size,field.shape[:3],True)
|
k_s = _ks(size,f.shape[:3],True)
|
||||||
|
|
||||||
field_fourier = _np.fft.rfftn(field,axes=(0,1,2))
|
f_fourier = _np.fft.rfftn(f,axes=(0,1,2))
|
||||||
grad_ = (_np.einsum('ijkl,ijkm->ijkm', field_fourier,k_s)*2.0j*_np.pi if n == 1 else # scalar, 1 -> 3
|
grad_ = (_np.einsum('ijkl,ijkm->ijkm', f_fourier,k_s)*2.0j*_np.pi if n == 1 else # scalar, 1 -> 3
|
||||||
_np.einsum('ijkl,ijkm->ijklm',field_fourier,k_s)*2.0j*_np.pi) # vector, 3 -> 3x3
|
_np.einsum('ijkl,ijkm->ijklm',f_fourier,k_s)*2.0j*_np.pi) # vector, 3 -> 3x3
|
||||||
|
|
||||||
return _np.fft.irfftn(grad_,axes=(0,1,2),s=field.shape[:3])
|
return _np.fft.irfftn(grad_,axes=(0,1,2),s=f.shape[:3])
|
||||||
|
|
||||||
|
|
||||||
def coordinates0_point(cells,size,origin=_np.zeros(3)):
|
def coordinates0_point(cells,size,origin=_np.zeros(3)):
|
||||||
|
@ -123,6 +141,11 @@ def coordinates0_point(cells,size,origin=_np.zeros(3)):
|
||||||
origin : numpy.ndarray, optional
|
origin : numpy.ndarray, optional
|
||||||
Physical origin of the periodic field. Defaults to [0.0,0.0,0.0].
|
Physical origin of the periodic field. Defaults to [0.0,0.0,0.0].
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
x_p_0 : numpy.ndarray
|
||||||
|
Undeformed cell center coordinates.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
start = origin + size/cells*.5
|
start = origin + size/cells*.5
|
||||||
end = origin + size - size/cells*.5
|
end = origin + size - size/cells*.5
|
||||||
|
@ -144,6 +167,11 @@ def displacement_fluct_point(size,F):
|
||||||
F : numpy.ndarray
|
F : numpy.ndarray
|
||||||
Deformation gradient field.
|
Deformation gradient field.
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
u_p_fluct : numpy.ndarray
|
||||||
|
Fluctuating part of the cell center displacements.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
integrator = 0.5j*size/_np.pi
|
integrator = 0.5j*size/_np.pi
|
||||||
|
|
||||||
|
@ -171,6 +199,11 @@ def displacement_avg_point(size,F):
|
||||||
F : numpy.ndarray
|
F : numpy.ndarray
|
||||||
Deformation gradient field.
|
Deformation gradient field.
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
u_p_avg : numpy.ndarray
|
||||||
|
Average part of the cell center displacements.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
F_avg = _np.average(F,axis=(0,1,2))
|
F_avg = _np.average(F,axis=(0,1,2))
|
||||||
return _np.einsum('ml,ijkl->ijkm',F_avg - _np.eye(3),coordinates0_point(F.shape[:3],size))
|
return _np.einsum('ml,ijkl->ijkm',F_avg - _np.eye(3),coordinates0_point(F.shape[:3],size))
|
||||||
|
@ -187,6 +220,11 @@ def displacement_point(size,F):
|
||||||
F : numpy.ndarray
|
F : numpy.ndarray
|
||||||
Deformation gradient field.
|
Deformation gradient field.
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
u_p : numpy.ndarray
|
||||||
|
Cell center displacements.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return displacement_avg_point(size,F) + displacement_fluct_point(size,F)
|
return displacement_avg_point(size,F) + displacement_fluct_point(size,F)
|
||||||
|
|
||||||
|
@ -204,6 +242,11 @@ def coordinates_point(size,F,origin=_np.zeros(3)):
|
||||||
origin : numpy.ndarray of shape (3), optional
|
origin : numpy.ndarray of shape (3), optional
|
||||||
Physical origin of the periodic field. Defaults to [0.0,0.0,0.0].
|
Physical origin of the periodic field. Defaults to [0.0,0.0,0.0].
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
x_p : numpy.ndarray
|
||||||
|
Cell center coordinates.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return coordinates0_point(F.shape[:3],size,origin) + displacement_point(size,F)
|
return coordinates0_point(F.shape[:3],size,origin) + displacement_point(size,F)
|
||||||
|
|
||||||
|
@ -252,19 +295,6 @@ def cellsSizeOrigin_coordinates0_point(coordinates0,ordered=True):
|
||||||
return (cells,size,origin)
|
return (cells,size,origin)
|
||||||
|
|
||||||
|
|
||||||
def coordinates0_check(coordinates0):
|
|
||||||
"""
|
|
||||||
Check whether coordinates lie on a regular grid.
|
|
||||||
|
|
||||||
Parameters
|
|
||||||
----------
|
|
||||||
coordinates0 : numpy.ndarray
|
|
||||||
Array of undeformed cell coordinates.
|
|
||||||
|
|
||||||
"""
|
|
||||||
cellsSizeOrigin_coordinates0_point(coordinates0,ordered=True)
|
|
||||||
|
|
||||||
|
|
||||||
def coordinates0_node(cells,size,origin=_np.zeros(3)):
|
def coordinates0_node(cells,size,origin=_np.zeros(3)):
|
||||||
"""
|
"""
|
||||||
Nodal positions (undeformed).
|
Nodal positions (undeformed).
|
||||||
|
@ -278,6 +308,11 @@ def coordinates0_node(cells,size,origin=_np.zeros(3)):
|
||||||
origin : numpy.ndarray of shape (3), optional
|
origin : numpy.ndarray of shape (3), optional
|
||||||
Physical origin of the periodic field. Defaults to [0.0,0.0,0.0].
|
Physical origin of the periodic field. Defaults to [0.0,0.0,0.0].
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
x_n_0 : numpy.ndarray
|
||||||
|
Undeformed nodal coordinates.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return _np.stack(_np.meshgrid(_np.linspace(origin[0],size[0]+origin[0],cells[0]+1),
|
return _np.stack(_np.meshgrid(_np.linspace(origin[0],size[0]+origin[0],cells[0]+1),
|
||||||
_np.linspace(origin[1],size[1]+origin[1],cells[1]+1),
|
_np.linspace(origin[1],size[1]+origin[1],cells[1]+1),
|
||||||
|
@ -296,6 +331,11 @@ def displacement_fluct_node(size,F):
|
||||||
F : numpy.ndarray
|
F : numpy.ndarray
|
||||||
Deformation gradient field.
|
Deformation gradient field.
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
u_n_fluct : numpy.ndarray
|
||||||
|
Fluctuating part of the nodal displacements.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return point_to_node(displacement_fluct_point(size,F))
|
return point_to_node(displacement_fluct_point(size,F))
|
||||||
|
|
||||||
|
@ -311,6 +351,11 @@ def displacement_avg_node(size,F):
|
||||||
F : numpy.ndarray
|
F : numpy.ndarray
|
||||||
Deformation gradient field.
|
Deformation gradient field.
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
u_n_avg : numpy.ndarray
|
||||||
|
Average part of the nodal displacements.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
F_avg = _np.average(F,axis=(0,1,2))
|
F_avg = _np.average(F,axis=(0,1,2))
|
||||||
return _np.einsum('ml,ijkl->ijkm',F_avg - _np.eye(3),coordinates0_node(F.shape[:3],size))
|
return _np.einsum('ml,ijkl->ijkm',F_avg - _np.eye(3),coordinates0_node(F.shape[:3],size))
|
||||||
|
@ -327,6 +372,11 @@ def displacement_node(size,F):
|
||||||
F : numpy.ndarray
|
F : numpy.ndarray
|
||||||
Deformation gradient field.
|
Deformation gradient field.
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
u_p : numpy.ndarray
|
||||||
|
Nodal displacements.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return displacement_avg_node(size,F) + displacement_fluct_node(size,F)
|
return displacement_avg_node(size,F) + displacement_fluct_node(size,F)
|
||||||
|
|
||||||
|
@ -344,28 +394,15 @@ def coordinates_node(size,F,origin=_np.zeros(3)):
|
||||||
origin : numpy.ndarray of shape (3), optional
|
origin : numpy.ndarray of shape (3), optional
|
||||||
Physical origin of the periodic field. Defaults to [0.0,0.0,0.0].
|
Physical origin of the periodic field. Defaults to [0.0,0.0,0.0].
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
x_n : numpy.ndarray
|
||||||
|
Nodal coordinates.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return coordinates0_node(F.shape[:3],size,origin) + displacement_node(size,F)
|
return coordinates0_node(F.shape[:3],size,origin) + displacement_node(size,F)
|
||||||
|
|
||||||
|
|
||||||
def point_to_node(cell_data):
|
|
||||||
"""Interpolate periodic point data to nodal data."""
|
|
||||||
n = ( cell_data + _np.roll(cell_data,1,(0,1,2))
|
|
||||||
+ _np.roll(cell_data,1,(0,)) + _np.roll(cell_data,1,(1,)) + _np.roll(cell_data,1,(2,))
|
|
||||||
+ _np.roll(cell_data,1,(0,1)) + _np.roll(cell_data,1,(1,2)) + _np.roll(cell_data,1,(2,0)))*0.125
|
|
||||||
|
|
||||||
return _np.pad(n,((0,1),(0,1),(0,1))+((0,0),)*len(cell_data.shape[3:]),mode='wrap')
|
|
||||||
|
|
||||||
|
|
||||||
def node_2_point(node_data):
|
|
||||||
"""Interpolate periodic nodal data to point data."""
|
|
||||||
c = ( node_data + _np.roll(node_data,1,(0,1,2))
|
|
||||||
+ _np.roll(node_data,1,(0,)) + _np.roll(node_data,1,(1,)) + _np.roll(node_data,1,(2,))
|
|
||||||
+ _np.roll(node_data,1,(0,1)) + _np.roll(node_data,1,(1,2)) + _np.roll(node_data,1,(2,0)))*0.125
|
|
||||||
|
|
||||||
return c[1:,1:,1:]
|
|
||||||
|
|
||||||
|
|
||||||
def cellsSizeOrigin_coordinates0_node(coordinates0,ordered=True):
|
def cellsSizeOrigin_coordinates0_node(coordinates0,ordered=True):
|
||||||
"""
|
"""
|
||||||
Return grid 'DNA', i.e. cells, size, and origin from 1D array of nodal positions.
|
Return grid 'DNA', i.e. cells, size, and origin from 1D array of nodal positions.
|
||||||
|
@ -402,6 +439,66 @@ def cellsSizeOrigin_coordinates0_node(coordinates0,ordered=True):
|
||||||
return (cells,size,origin)
|
return (cells,size,origin)
|
||||||
|
|
||||||
|
|
||||||
|
def point_to_node(cell_data):
|
||||||
|
"""
|
||||||
|
Interpolate periodic point data to nodal data.
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
cell_data : numpy.ndarray of shape (:,:,:,...)
|
||||||
|
Data defined on the cell centers of a periodic grid.
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
node_data : numpy.ndarray of shape (:,:,:,...)
|
||||||
|
Data defined on the nodes of a periodic grid.
|
||||||
|
"""
|
||||||
|
n = ( cell_data + _np.roll(cell_data,1,(0,1,2))
|
||||||
|
+ _np.roll(cell_data,1,(0,)) + _np.roll(cell_data,1,(1,)) + _np.roll(cell_data,1,(2,))
|
||||||
|
+ _np.roll(cell_data,1,(0,1)) + _np.roll(cell_data,1,(1,2)) + _np.roll(cell_data,1,(2,0)))*0.125
|
||||||
|
|
||||||
|
return _np.pad(n,((0,1),(0,1),(0,1))+((0,0),)*len(cell_data.shape[3:]),mode='wrap')
|
||||||
|
|
||||||
|
|
||||||
|
def node_to_point(node_data):
|
||||||
|
"""
|
||||||
|
Interpolate periodic nodal data to point data.
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
node_data : numpy.ndarray of shape (:,:,:,...)
|
||||||
|
Data defined on the nodes of a periodic grid.
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
cell_data : numpy.ndarray of shape (:,:,:,...)
|
||||||
|
Data defined on the cell centers of a periodic grid.
|
||||||
|
|
||||||
|
"""
|
||||||
|
c = ( node_data + _np.roll(node_data,1,(0,1,2))
|
||||||
|
+ _np.roll(node_data,1,(0,)) + _np.roll(node_data,1,(1,)) + _np.roll(node_data,1,(2,))
|
||||||
|
+ _np.roll(node_data,1,(0,1)) + _np.roll(node_data,1,(1,2)) + _np.roll(node_data,1,(2,0)))*0.125
|
||||||
|
|
||||||
|
return c[1:,1:,1:]
|
||||||
|
|
||||||
|
|
||||||
|
def coordinates0_valid(coordinates0):
|
||||||
|
"""
|
||||||
|
Check whether coordinates lie on a regular grid.
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
coordinates0 : numpy.ndarray
|
||||||
|
Array of undeformed cell coordinates.
|
||||||
|
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
cellsSizeOrigin_coordinates0_point(coordinates0,ordered=True)
|
||||||
|
return True
|
||||||
|
except ValueError:
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
def regrid(size,F,cells):
|
def regrid(size,F,cells):
|
||||||
"""
|
"""
|
||||||
Return mapping from coordinates in deformed configuration to a regular grid.
|
Return mapping from coordinates in deformed configuration to a regular grid.
|
||||||
|
|
|
@ -1,4 +1,11 @@
|
||||||
"""Finite-strain continuum mechanics."""
|
"""
|
||||||
|
Finite-strain continuum mechanics.
|
||||||
|
|
||||||
|
Notes
|
||||||
|
-----
|
||||||
|
Collection of routines to operate on numpy.ndarrays of shape (...,3,3).
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
from . import tensor as _tensor
|
from . import tensor as _tensor
|
||||||
from . import _rotation
|
from . import _rotation
|
||||||
|
@ -154,7 +161,6 @@ def strain(F,t,m):
|
||||||
return eps
|
return eps
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def stress_Cauchy(P,F):
|
def stress_Cauchy(P,F):
|
||||||
"""
|
"""
|
||||||
Calculate the Cauchy stress (true stress).
|
Calculate the Cauchy stress (true stress).
|
||||||
|
|
|
@ -24,6 +24,11 @@ def from_random(size,N_seeds,cells=None,rng_seed=None):
|
||||||
A seed to initialize the BitGenerator. Defaults to None.
|
A seed to initialize the BitGenerator. Defaults to None.
|
||||||
If None, then fresh, unpredictable entropy will be pulled from the OS.
|
If None, then fresh, unpredictable entropy will be pulled from the OS.
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
new : numpy.ndarray of shape (N_seeds,3)
|
||||||
|
Coordinates in 3D space.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
rng = _np.random.default_rng(rng_seed)
|
rng = _np.random.default_rng(rng_seed)
|
||||||
if cells is None:
|
if cells is None:
|
||||||
|
@ -56,6 +61,11 @@ def from_Poisson_disc(size,N_seeds,N_candidates,distance,periodic=True,rng_seed=
|
||||||
A seed to initialize the BitGenerator. Defaults to None.
|
A seed to initialize the BitGenerator. Defaults to None.
|
||||||
If None, then fresh, unpredictable entropy will be pulled from the OS.
|
If None, then fresh, unpredictable entropy will be pulled from the OS.
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
new : numpy.ndarray of shape (N_seeds,3)
|
||||||
|
Coordinates in 3D space.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
rng = _np.random.default_rng(rng_seed)
|
rng = _np.random.default_rng(rng_seed)
|
||||||
coords = _np.empty((N_seeds,3))
|
coords = _np.empty((N_seeds,3))
|
||||||
|
@ -94,6 +104,11 @@ def from_grid(grid,selection=None,invert=False,average=False,periodic=True):
|
||||||
periodic : boolean, optional
|
periodic : boolean, optional
|
||||||
Center of gravity with periodic boundaries.
|
Center of gravity with periodic boundaries.
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
new : numpy.ndarray of shape (...,3)
|
||||||
|
Coordinates in 3D space.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
material = grid.material.reshape((-1,1),order='F')
|
material = grid.material.reshape((-1,1),order='F')
|
||||||
mask = _np.full(grid.cells.prod(),True,dtype=bool) if selection is None else \
|
mask = _np.full(grid.cells.prod(),True,dtype=bool) if selection is None else \
|
||||||
|
|
|
@ -60,7 +60,7 @@ class TestGridFilters:
|
||||||
cell_field_x = np.interp(coordinates0_point_x,coordinates_node_x,node_field_x,period=np.pi*2.)
|
cell_field_x = np.interp(coordinates0_point_x,coordinates_node_x,node_field_x,period=np.pi*2.)
|
||||||
cell_field = np.broadcast_to(cell_field_x.reshape(-1,1,1),cells)
|
cell_field = np.broadcast_to(cell_field_x.reshape(-1,1,1),cells)
|
||||||
|
|
||||||
assert np.allclose(cell_field,grid_filters.node_2_point(node_field))
|
assert np.allclose(cell_field,grid_filters.node_to_point(node_field))
|
||||||
|
|
||||||
@pytest.mark.parametrize('mode',['point','node'])
|
@pytest.mark.parametrize('mode',['point','node'])
|
||||||
def test_coordinates0_origin(self,mode):
|
def test_coordinates0_origin(self,mode):
|
||||||
|
@ -93,14 +93,24 @@ class TestGridFilters:
|
||||||
F = np.broadcast_to(np.random.random((3,3)), tuple(cells)+(3,3))
|
F = np.broadcast_to(np.random.random((3,3)), tuple(cells)+(3,3))
|
||||||
assert np.allclose(function(size,F),0.0)
|
assert np.allclose(function(size,F),0.0)
|
||||||
|
|
||||||
@pytest.mark.parametrize('function',[grid_filters.coordinates0_check,
|
@pytest.mark.parametrize('function',[grid_filters.cellsSizeOrigin_coordinates0_point,
|
||||||
grid_filters.cellsSizeOrigin_coordinates0_node,
|
grid_filters.cellsSizeOrigin_coordinates0_node])
|
||||||
grid_filters.cellsSizeOrigin_coordinates0_point])
|
|
||||||
def test_invalid_coordinates(self,function):
|
def test_invalid_coordinates(self,function):
|
||||||
invalid_coordinates = np.random.random((np.random.randint(12,52),3))
|
invalid_coordinates = np.random.random((np.random.randint(12,52),3))
|
||||||
with pytest.raises(ValueError):
|
with pytest.raises(ValueError):
|
||||||
function(invalid_coordinates)
|
function(invalid_coordinates)
|
||||||
|
|
||||||
|
@pytest.mark.parametrize('function',[grid_filters.coordinates0_point,
|
||||||
|
grid_filters.coordinates0_node])
|
||||||
|
def test_valid_coordinates_check(self,function):
|
||||||
|
valid_coordinates = function(np.random.randint(4,10,(3)),np.random.rand(3))
|
||||||
|
assert grid_filters.coordinates0_valid(valid_coordinates.reshape(-1,3,order='F'))
|
||||||
|
|
||||||
|
def test_invalid_coordinates_check(self):
|
||||||
|
invalid_coordinates = np.random.random((np.random.randint(12,52),3))
|
||||||
|
assert not grid_filters.coordinates0_valid(invalid_coordinates)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize('function',[grid_filters.cellsSizeOrigin_coordinates0_node,
|
@pytest.mark.parametrize('function',[grid_filters.cellsSizeOrigin_coordinates0_node,
|
||||||
grid_filters.cellsSizeOrigin_coordinates0_point])
|
grid_filters.cellsSizeOrigin_coordinates0_point])
|
||||||
def test_uneven_spaced_coordinates(self,function):
|
def test_uneven_spaced_coordinates(self,function):
|
||||||
|
|
Loading…
Reference in New Issue