Merge branch 'grid_filter-flexible-typehints' into 'development'
allow flexible arguments for 1D arguments See merge request damask/DAMASK!494
This commit is contained in:
commit
731222d099
|
@ -8,6 +8,7 @@ with open(_Path(__file__).parent/_Path('VERSION')) as _f:
|
||||||
version = _re.sub(r'^v','',_f.readline().strip())
|
version = _re.sub(r'^v','',_f.readline().strip())
|
||||||
__version__ = version
|
__version__ = version
|
||||||
|
|
||||||
|
from . import _typehints # noqa
|
||||||
from . import util # noqa
|
from . import util # noqa
|
||||||
from . import seeds # noqa
|
from . import seeds # noqa
|
||||||
from . import tensor # noqa
|
from . import tensor # noqa
|
||||||
|
|
|
@ -3,13 +3,9 @@ import json
|
||||||
import functools
|
import functools
|
||||||
import colorsys
|
import colorsys
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Sequence, Union, TextIO
|
from typing import Union, TextIO
|
||||||
|
|
||||||
import numpy as np
|
import numpy as np
|
||||||
try:
|
|
||||||
from numpy.typing import ArrayLike
|
|
||||||
except ImportError:
|
|
||||||
ArrayLike = Union[np.ndarray,Sequence[float]] # type: ignore
|
|
||||||
import scipy.interpolate as interp
|
import scipy.interpolate as interp
|
||||||
import matplotlib as mpl
|
import matplotlib as mpl
|
||||||
if os.name == 'posix' and 'DISPLAY' not in os.environ:
|
if os.name == 'posix' and 'DISPLAY' not in os.environ:
|
||||||
|
@ -18,6 +14,7 @@ import matplotlib.pyplot as plt
|
||||||
from matplotlib import cm
|
from matplotlib import cm
|
||||||
from PIL import Image
|
from PIL import Image
|
||||||
|
|
||||||
|
from ._typehints import FloatSequence, FileHandle
|
||||||
from . import util
|
from . import util
|
||||||
from . import Table
|
from . import Table
|
||||||
|
|
||||||
|
@ -82,8 +79,8 @@ class Colormap(mpl.colors.ListedColormap):
|
||||||
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def from_range(low: ArrayLike,
|
def from_range(low: FloatSequence,
|
||||||
high: ArrayLike,
|
high: FloatSequence,
|
||||||
name: str = 'DAMASK colormap',
|
name: str = 'DAMASK colormap',
|
||||||
N: int = 256,
|
N: int = 256,
|
||||||
model: str = 'rgb') -> 'Colormap':
|
model: str = 'rgb') -> 'Colormap':
|
||||||
|
@ -197,7 +194,7 @@ class Colormap(mpl.colors.ListedColormap):
|
||||||
|
|
||||||
|
|
||||||
def at(self,
|
def at(self,
|
||||||
fraction : Union[float,Sequence[float]]) -> np.ndarray:
|
fraction : Union[float,FloatSequence]) -> np.ndarray:
|
||||||
"""
|
"""
|
||||||
Interpolate color at fraction.
|
Interpolate color at fraction.
|
||||||
|
|
||||||
|
@ -229,7 +226,7 @@ class Colormap(mpl.colors.ListedColormap):
|
||||||
|
|
||||||
def shade(self,
|
def shade(self,
|
||||||
field: np.ndarray,
|
field: np.ndarray,
|
||||||
bounds: ArrayLike = None,
|
bounds: FloatSequence = None,
|
||||||
gap: float = None) -> Image:
|
gap: float = None) -> Image:
|
||||||
"""
|
"""
|
||||||
Generate PIL image of 2D field using colormap.
|
Generate PIL image of 2D field using colormap.
|
||||||
|
@ -296,7 +293,7 @@ class Colormap(mpl.colors.ListedColormap):
|
||||||
|
|
||||||
|
|
||||||
def _get_file_handle(self,
|
def _get_file_handle(self,
|
||||||
fname: Union[TextIO, str, Path, None],
|
fname: Union[FileHandle, None],
|
||||||
suffix: str = '') -> TextIO:
|
suffix: str = '') -> TextIO:
|
||||||
"""
|
"""
|
||||||
Provide file handle.
|
Provide file handle.
|
||||||
|
@ -323,7 +320,7 @@ class Colormap(mpl.colors.ListedColormap):
|
||||||
return fname
|
return fname
|
||||||
|
|
||||||
|
|
||||||
def save_paraview(self, fname: Union[TextIO, str, Path] = None):
|
def save_paraview(self, fname: FileHandle = None):
|
||||||
"""
|
"""
|
||||||
Save as JSON file for use in Paraview.
|
Save as JSON file for use in Paraview.
|
||||||
|
|
||||||
|
@ -350,7 +347,7 @@ class Colormap(mpl.colors.ListedColormap):
|
||||||
fhandle.write('\n')
|
fhandle.write('\n')
|
||||||
|
|
||||||
|
|
||||||
def save_ASCII(self, fname: Union[TextIO, str, Path] = None):
|
def save_ASCII(self, fname: FileHandle = None):
|
||||||
"""
|
"""
|
||||||
Save as ASCII file.
|
Save as ASCII file.
|
||||||
|
|
||||||
|
@ -365,7 +362,7 @@ class Colormap(mpl.colors.ListedColormap):
|
||||||
t.save(self._get_file_handle(fname,'.txt'))
|
t.save(self._get_file_handle(fname,'.txt'))
|
||||||
|
|
||||||
|
|
||||||
def save_GOM(self, fname: Union[TextIO, str, Path] = None):
|
def save_GOM(self, fname: FileHandle = None):
|
||||||
"""
|
"""
|
||||||
Save as ASCII file for use in GOM Aramis.
|
Save as ASCII file for use in GOM Aramis.
|
||||||
|
|
||||||
|
@ -385,7 +382,7 @@ class Colormap(mpl.colors.ListedColormap):
|
||||||
self._get_file_handle(fname,'.legend').write(GOM_str)
|
self._get_file_handle(fname,'.legend').write(GOM_str)
|
||||||
|
|
||||||
|
|
||||||
def save_gmsh(self, fname: Union[TextIO, str, Path] = None):
|
def save_gmsh(self, fname: FileHandle = None):
|
||||||
"""
|
"""
|
||||||
Save as ASCII file for use in gmsh.
|
Save as ASCII file for use in gmsh.
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
"""Functionality for typehints."""
|
||||||
|
|
||||||
|
from typing import Sequence, Union, TextIO
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
|
||||||
|
FloatSequence = Union[np.ndarray,Sequence[float]]
|
||||||
|
IntSequence = Union[np.ndarray,Sequence[int]]
|
||||||
|
FileHandle = Union[TextIO, str, Path]
|
|
@ -12,21 +12,23 @@ the following operations are required for tensorial data:
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from typing import Sequence, Tuple, Union
|
from typing import Tuple as _Tuple
|
||||||
|
|
||||||
from scipy import spatial as _spatial
|
from scipy import spatial as _spatial
|
||||||
import numpy as _np
|
import numpy as _np
|
||||||
|
|
||||||
|
from ._typehints import FloatSequence as _FloatSequence, IntSequence as _IntSequence
|
||||||
|
|
||||||
def _ks(size: _np.ndarray, cells: Union[_np.ndarray,Sequence[int]], first_order: bool = False) -> _np.ndarray:
|
|
||||||
|
def _ks(size: _FloatSequence, cells: _IntSequence, first_order: bool = False) -> _np.ndarray:
|
||||||
"""
|
"""
|
||||||
Get wave numbers operator.
|
Get wave numbers operator.
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
----------
|
----------
|
||||||
size : numpy.ndarray of shape (3)
|
size : sequence of float, len (3)
|
||||||
Physical size of the periodic field.
|
Physical size of the periodic field.
|
||||||
cells : numpy.ndarray of shape (3)
|
cells : sequence of int, len (3)
|
||||||
Number of cells.
|
Number of cells.
|
||||||
first_order : bool, optional
|
first_order : bool, optional
|
||||||
Correction for first order derivatives, defaults to False.
|
Correction for first order derivatives, defaults to False.
|
||||||
|
@ -45,20 +47,20 @@ def _ks(size: _np.ndarray, cells: Union[_np.ndarray,Sequence[int]], first_order:
|
||||||
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: _np.ndarray, f: _np.ndarray) -> _np.ndarray:
|
def curl(size: _FloatSequence, f: _np.ndarray) -> _np.ndarray:
|
||||||
u"""
|
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 : sequence of float, len (3)
|
||||||
Physical size of the periodic field.
|
Physical size of the periodic field.
|
||||||
f : numpy.ndarray of shape (:,:,:,3) or (:,:,:,3,3)
|
f : numpy.ndarray, shape (:,:,:,3) or (:,:,:,3,3)
|
||||||
Periodic field of which the curl is calculated.
|
Periodic field of which the curl is calculated.
|
||||||
|
|
||||||
Returns
|
Returns
|
||||||
-------
|
-------
|
||||||
∇ × f : numpy.ndarray
|
∇ × f : numpy.ndarray, shape (:,:,:,3) or (:,:,:,3,3)
|
||||||
Curl of f.
|
Curl of f.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
@ -76,20 +78,20 @@ def curl(size: _np.ndarray, f: _np.ndarray) -> _np.ndarray:
|
||||||
return _np.fft.irfftn(curl_,axes=(0,1,2),s=f.shape[:3])
|
return _np.fft.irfftn(curl_,axes=(0,1,2),s=f.shape[:3])
|
||||||
|
|
||||||
|
|
||||||
def divergence(size: _np.ndarray, f: _np.ndarray) -> _np.ndarray:
|
def divergence(size: _FloatSequence, f: _np.ndarray) -> _np.ndarray:
|
||||||
u"""
|
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 : sequence of float, len (3)
|
||||||
Physical size of the periodic field.
|
Physical size of the periodic field.
|
||||||
f : numpy.ndarray of shape (:,:,:,3) or (:,:,:,3,3)
|
f : numpy.ndarray, shape (:,:,:,3) or (:,:,:,3,3)
|
||||||
Periodic field of which the divergence is calculated.
|
Periodic field of which the divergence is calculated.
|
||||||
|
|
||||||
Returns
|
Returns
|
||||||
-------
|
-------
|
||||||
∇ · f : numpy.ndarray
|
∇ · f : numpy.ndarray, shape (:,:,:,1) or (:,:,:,3)
|
||||||
Divergence of f.
|
Divergence of f.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
@ -103,20 +105,20 @@ def divergence(size: _np.ndarray, f: _np.ndarray) -> _np.ndarray:
|
||||||
return _np.fft.irfftn(div_,axes=(0,1,2),s=f.shape[:3])
|
return _np.fft.irfftn(div_,axes=(0,1,2),s=f.shape[:3])
|
||||||
|
|
||||||
|
|
||||||
def gradient(size: _np.ndarray, f: _np.ndarray) -> _np.ndarray:
|
def gradient(size: _FloatSequence, f: _np.ndarray) -> _np.ndarray:
|
||||||
u"""
|
u"""
|
||||||
Calculate gradient of a scalar or vector field in Fourier space.
|
Calculate gradient of a scalar or vector field in Fourier space.
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
----------
|
----------
|
||||||
size : numpy.ndarray of shape (3)
|
size : sequence of float, len (3)
|
||||||
Physical size of the periodic field.
|
Physical size of the periodic field.
|
||||||
f : numpy.ndarray of shape (:,:,:,1) or (:,:,:,3)
|
f : numpy.ndarray, shape (:,:,:,1) or (:,:,:,3)
|
||||||
Periodic field of which the gradient is calculated.
|
Periodic field of which the gradient is calculated.
|
||||||
|
|
||||||
Returns
|
Returns
|
||||||
-------
|
-------
|
||||||
∇ f : numpy.ndarray
|
∇ f : numpy.ndarray, shape (:,:,:,3) or (:,:,:,3,3)
|
||||||
Divergence of f.
|
Divergence of f.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
@ -130,29 +132,30 @@ def gradient(size: _np.ndarray, f: _np.ndarray) -> _np.ndarray:
|
||||||
return _np.fft.irfftn(grad_,axes=(0,1,2),s=f.shape[:3])
|
return _np.fft.irfftn(grad_,axes=(0,1,2),s=f.shape[:3])
|
||||||
|
|
||||||
|
|
||||||
def coordinates0_point(cells: Union[ _np.ndarray,Sequence[int]],
|
def coordinates0_point(cells: _IntSequence,
|
||||||
size: _np.ndarray,
|
size: _FloatSequence,
|
||||||
origin: _np.ndarray = _np.zeros(3)) -> _np.ndarray:
|
origin: _FloatSequence = _np.zeros(3)) -> _np.ndarray:
|
||||||
"""
|
"""
|
||||||
Cell center positions (undeformed).
|
Cell center positions (undeformed).
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
----------
|
----------
|
||||||
cells : numpy.ndarray of shape (3)
|
cells : sequence of int, len (3)
|
||||||
Number of cells.
|
Number of cells.
|
||||||
size : numpy.ndarray of shape (3)
|
size : sequence of float, len (3)
|
||||||
Physical size of the periodic field.
|
Physical size of the periodic field.
|
||||||
origin : numpy.ndarray, optional
|
origin : sequence of float, len(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
|
Returns
|
||||||
-------
|
-------
|
||||||
x_p_0 : numpy.ndarray
|
x_p_0 : numpy.ndarray, shape (:,:,:,3)
|
||||||
Undeformed cell center coordinates.
|
Undeformed cell center coordinates.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
start = origin + size/_np.array(cells)*.5
|
size_ = _np.array(size,float)
|
||||||
end = origin + size - size/_np.array(cells)*.5
|
start = origin + size_/_np.array(cells,int)*.5
|
||||||
|
end = origin + size_ - size_/_np.array(cells,int)*.5
|
||||||
|
|
||||||
return _np.stack(_np.meshgrid(_np.linspace(start[0],end[0],cells[0]),
|
return _np.stack(_np.meshgrid(_np.linspace(start[0],end[0],cells[0]),
|
||||||
_np.linspace(start[1],end[1],cells[1]),
|
_np.linspace(start[1],end[1],cells[1]),
|
||||||
|
@ -160,24 +163,24 @@ def coordinates0_point(cells: Union[ _np.ndarray,Sequence[int]],
|
||||||
axis = -1)
|
axis = -1)
|
||||||
|
|
||||||
|
|
||||||
def displacement_fluct_point(size: _np.ndarray, F: _np.ndarray) -> _np.ndarray:
|
def displacement_fluct_point(size: _FloatSequence, F: _np.ndarray) -> _np.ndarray:
|
||||||
"""
|
"""
|
||||||
Cell center displacement field from fluctuation part of the deformation gradient field.
|
Cell center displacement field from fluctuation part of the deformation gradient field.
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
----------
|
----------
|
||||||
size : numpy.ndarray of shape (3)
|
size : sequence of float, len (3)
|
||||||
Physical size of the periodic field.
|
Physical size of the periodic field.
|
||||||
F : numpy.ndarray
|
F : numpy.ndarray, shape (:,:,:,3,3)
|
||||||
Deformation gradient field.
|
Deformation gradient field.
|
||||||
|
|
||||||
Returns
|
Returns
|
||||||
-------
|
-------
|
||||||
u_p_fluct : numpy.ndarray
|
u_p_fluct : numpy.ndarray, shape (:,:,:,3)
|
||||||
Fluctuating part of the cell center displacements.
|
Fluctuating part of the cell center displacements.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
integrator = 0.5j*size/_np.pi
|
integrator = 0.5j*_np.array(size,float)/_np.pi
|
||||||
|
|
||||||
k_s = _ks(size,F.shape[:3],False)
|
k_s = _ks(size,F.shape[:3],False)
|
||||||
k_s_squared = _np.einsum('...l,...l',k_s,k_s)
|
k_s_squared = _np.einsum('...l,...l',k_s,k_s)
|
||||||
|
@ -192,20 +195,20 @@ def displacement_fluct_point(size: _np.ndarray, F: _np.ndarray) -> _np.ndarray:
|
||||||
return _np.fft.irfftn(displacement,axes=(0,1,2),s=F.shape[:3])
|
return _np.fft.irfftn(displacement,axes=(0,1,2),s=F.shape[:3])
|
||||||
|
|
||||||
|
|
||||||
def displacement_avg_point(size: _np.ndarray, F: _np.ndarray) -> _np.ndarray:
|
def displacement_avg_point(size: _FloatSequence, F: _np.ndarray) -> _np.ndarray:
|
||||||
"""
|
"""
|
||||||
Cell center displacement field from average part of the deformation gradient field.
|
Cell center displacement field from average part of the deformation gradient field.
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
----------
|
----------
|
||||||
size : numpy.ndarray of shape (3)
|
size : sequence of float, len (3)
|
||||||
Physical size of the periodic field.
|
Physical size of the periodic field.
|
||||||
F : numpy.ndarray
|
F : numpy.ndarray, shape (:,:,:,3,3)
|
||||||
Deformation gradient field.
|
Deformation gradient field.
|
||||||
|
|
||||||
Returns
|
Returns
|
||||||
-------
|
-------
|
||||||
u_p_avg : numpy.ndarray
|
u_p_avg : numpy.ndarray, shape (:,:,:,3)
|
||||||
Average part of the cell center displacements.
|
Average part of the cell center displacements.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
@ -213,42 +216,42 @@ def displacement_avg_point(size: _np.ndarray, F: _np.ndarray) -> _np.ndarray:
|
||||||
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))
|
||||||
|
|
||||||
|
|
||||||
def displacement_point(size: _np.ndarray, F: _np.ndarray) -> _np.ndarray:
|
def displacement_point(size: _FloatSequence, F: _np.ndarray) -> _np.ndarray:
|
||||||
"""
|
"""
|
||||||
Cell center displacement field from deformation gradient field.
|
Cell center displacement field from deformation gradient field.
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
----------
|
----------
|
||||||
size : numpy.ndarray of shape (3)
|
size : sequence of float, len (3)
|
||||||
Physical size of the periodic field.
|
Physical size of the periodic field.
|
||||||
F : numpy.ndarray
|
F : numpy.ndarray, shape (:,:,:,3,3)
|
||||||
Deformation gradient field.
|
Deformation gradient field.
|
||||||
|
|
||||||
Returns
|
Returns
|
||||||
-------
|
-------
|
||||||
u_p : numpy.ndarray
|
u_p : numpy.ndarray, shape (:,:,:,3)
|
||||||
Cell center displacements.
|
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)
|
||||||
|
|
||||||
|
|
||||||
def coordinates_point(size: _np.ndarray, F: _np.ndarray, origin: _np.ndarray = _np.zeros(3)) -> _np.ndarray:
|
def coordinates_point(size: _FloatSequence, F: _np.ndarray, origin: _FloatSequence = _np.zeros(3)) -> _np.ndarray:
|
||||||
"""
|
"""
|
||||||
Cell center positions.
|
Cell center positions.
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
----------
|
----------
|
||||||
size : numpy.ndarray of shape (3)
|
size : sequence of float, len (3)
|
||||||
Physical size of the periodic field.
|
Physical size of the periodic field.
|
||||||
F : numpy.ndarray
|
F : numpy.ndarray, shape (:,:,:,3,3)
|
||||||
Deformation gradient field.
|
Deformation gradient field.
|
||||||
origin : numpy.ndarray of shape (3), optional
|
origin : sequence of float, len(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
|
Returns
|
||||||
-------
|
-------
|
||||||
x_p : numpy.ndarray
|
x_p : numpy.ndarray, shape (:,:,:,3)
|
||||||
Cell center coordinates.
|
Cell center coordinates.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
@ -256,14 +259,14 @@ def coordinates_point(size: _np.ndarray, F: _np.ndarray, origin: _np.ndarray = _
|
||||||
|
|
||||||
|
|
||||||
def cellsSizeOrigin_coordinates0_point(coordinates0: _np.ndarray,
|
def cellsSizeOrigin_coordinates0_point(coordinates0: _np.ndarray,
|
||||||
ordered: bool = True) -> Tuple[_np.ndarray,_np.ndarray,_np.ndarray]:
|
ordered: bool = True) -> _Tuple[_np.ndarray,_np.ndarray,_np.ndarray]:
|
||||||
"""
|
"""
|
||||||
Return grid 'DNA', i.e. cells, size, and origin from 1D array of point positions.
|
Return grid 'DNA', i.e. cells, size, and origin from 1D array of point positions.
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
----------
|
----------
|
||||||
coordinates0 : numpy.ndarray of shape (:,3)
|
coordinates0 : numpy.ndarray, shape (:,3)
|
||||||
Undeformed cell coordinates.
|
Undeformed cell center coordinates.
|
||||||
ordered : bool, optional
|
ordered : bool, optional
|
||||||
Expect coordinates0 data to be ordered (x fast, z slow).
|
Expect coordinates0 data to be ordered (x fast, z slow).
|
||||||
Defaults to True.
|
Defaults to True.
|
||||||
|
@ -277,7 +280,7 @@ def cellsSizeOrigin_coordinates0_point(coordinates0: _np.ndarray,
|
||||||
coords = [_np.unique(coordinates0[:,i]) for i in range(3)]
|
coords = [_np.unique(coordinates0[:,i]) for i in range(3)]
|
||||||
mincorner = _np.array(list(map(min,coords)))
|
mincorner = _np.array(list(map(min,coords)))
|
||||||
maxcorner = _np.array(list(map(max,coords)))
|
maxcorner = _np.array(list(map(max,coords)))
|
||||||
cells = _np.array(list(map(len,coords)),'i')
|
cells = _np.array(list(map(len,coords)),int)
|
||||||
size = cells/_np.maximum(cells-1,1) * (maxcorner-mincorner)
|
size = cells/_np.maximum(cells-1,1) * (maxcorner-mincorner)
|
||||||
delta = size/cells
|
delta = size/cells
|
||||||
origin = mincorner - delta*.5
|
origin = mincorner - delta*.5
|
||||||
|
@ -305,24 +308,24 @@ def cellsSizeOrigin_coordinates0_point(coordinates0: _np.ndarray,
|
||||||
return (cells,size,origin)
|
return (cells,size,origin)
|
||||||
|
|
||||||
|
|
||||||
def coordinates0_node(cells: Union[_np.ndarray,Sequence[int]],
|
def coordinates0_node(cells: _IntSequence,
|
||||||
size: _np.ndarray,
|
size: _FloatSequence,
|
||||||
origin: _np.ndarray = _np.zeros(3)) -> _np.ndarray:
|
origin: _FloatSequence = _np.zeros(3)) -> _np.ndarray:
|
||||||
"""
|
"""
|
||||||
Nodal positions (undeformed).
|
Nodal positions (undeformed).
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
----------
|
----------
|
||||||
cells : numpy.ndarray of shape (3)
|
cells : sequence of int, len (3)
|
||||||
Number of cells.
|
Number of cells.
|
||||||
size : numpy.ndarray of shape (3)
|
size : sequence of float, len (3)
|
||||||
Physical size of the periodic field.
|
Physical size of the periodic field.
|
||||||
origin : numpy.ndarray of shape (3), optional
|
origin : sequence of float, len(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
|
Returns
|
||||||
-------
|
-------
|
||||||
x_n_0 : numpy.ndarray
|
x_n_0 : numpy.ndarray, shape (:,:,:,3)
|
||||||
Undeformed nodal coordinates.
|
Undeformed nodal coordinates.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
@ -332,40 +335,40 @@ def coordinates0_node(cells: Union[_np.ndarray,Sequence[int]],
|
||||||
axis = -1)
|
axis = -1)
|
||||||
|
|
||||||
|
|
||||||
def displacement_fluct_node(size: _np.ndarray, F: _np.ndarray) -> _np.ndarray:
|
def displacement_fluct_node(size: _FloatSequence, F: _np.ndarray) -> _np.ndarray:
|
||||||
"""
|
"""
|
||||||
Nodal displacement field from fluctuation part of the deformation gradient field.
|
Nodal displacement field from fluctuation part of the deformation gradient field.
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
----------
|
----------
|
||||||
size : numpy.ndarray of shape (3)
|
size : sequence of float, len (3)
|
||||||
Physical size of the periodic field.
|
Physical size of the periodic field.
|
||||||
F : numpy.ndarray
|
F : numpy.ndarray, shape (:,:,:,3,3)
|
||||||
Deformation gradient field.
|
Deformation gradient field.
|
||||||
|
|
||||||
Returns
|
Returns
|
||||||
-------
|
-------
|
||||||
u_n_fluct : numpy.ndarray
|
u_n_fluct : numpy.ndarray, shape (:,:,:,3)
|
||||||
Fluctuating part of the nodal displacements.
|
Fluctuating part of the nodal displacements.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return point_to_node(displacement_fluct_point(size,F))
|
return point_to_node(displacement_fluct_point(size,F))
|
||||||
|
|
||||||
|
|
||||||
def displacement_avg_node(size: _np.ndarray, F: _np.ndarray) -> _np.ndarray:
|
def displacement_avg_node(size: _FloatSequence, F: _np.ndarray) -> _np.ndarray:
|
||||||
"""
|
"""
|
||||||
Nodal displacement field from average part of the deformation gradient field.
|
Nodal displacement field from average part of the deformation gradient field.
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
----------
|
----------
|
||||||
size : numpy.ndarray of shape (3)
|
size : sequence of float, len (3)
|
||||||
Physical size of the periodic field.
|
Physical size of the periodic field.
|
||||||
F : numpy.ndarray
|
F : numpy.ndarray, shape (:,:,:,3,3)
|
||||||
Deformation gradient field.
|
Deformation gradient field.
|
||||||
|
|
||||||
Returns
|
Returns
|
||||||
-------
|
-------
|
||||||
u_n_avg : numpy.ndarray
|
u_n_avg : numpy.ndarray, shape (:,:,:,3)
|
||||||
Average part of the nodal displacements.
|
Average part of the nodal displacements.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
@ -373,42 +376,42 @@ def displacement_avg_node(size: _np.ndarray, F: _np.ndarray) -> _np.ndarray:
|
||||||
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))
|
||||||
|
|
||||||
|
|
||||||
def displacement_node(size: _np.ndarray, F: _np.ndarray) -> _np.ndarray:
|
def displacement_node(size: _FloatSequence, F: _np.ndarray) -> _np.ndarray:
|
||||||
"""
|
"""
|
||||||
Nodal displacement field from deformation gradient field.
|
Nodal displacement field from deformation gradient field.
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
----------
|
----------
|
||||||
size : numpy.ndarray of shape (3)
|
size : sequence of float, len (3)
|
||||||
Physical size of the periodic field.
|
Physical size of the periodic field.
|
||||||
F : numpy.ndarray
|
F : numpy.ndarray, shape (:,:,:,3,3)
|
||||||
Deformation gradient field.
|
Deformation gradient field.
|
||||||
|
|
||||||
Returns
|
Returns
|
||||||
-------
|
-------
|
||||||
u_p : numpy.ndarray
|
u_p : numpy.ndarray, shape (:,:,:,3)
|
||||||
Nodal displacements.
|
Nodal displacements.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return displacement_avg_node(size,F) + displacement_fluct_node(size,F)
|
return displacement_avg_node(size,F) + displacement_fluct_node(size,F)
|
||||||
|
|
||||||
|
|
||||||
def coordinates_node(size: _np.ndarray, F: _np.ndarray, origin: _np.ndarray = _np.zeros(3)) -> _np.ndarray:
|
def coordinates_node(size: _FloatSequence, F: _np.ndarray, origin: _FloatSequence = _np.zeros(3)) -> _np.ndarray:
|
||||||
"""
|
"""
|
||||||
Nodal positions.
|
Nodal positions.
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
----------
|
----------
|
||||||
size : numpy.ndarray of shape (3)
|
size : sequence of float, len (3)
|
||||||
Physical size of the periodic field.
|
Physical size of the periodic field.
|
||||||
F : numpy.ndarray
|
F : numpy.ndarray, shape (:,:,:,3,3)
|
||||||
Deformation gradient field.
|
Deformation gradient field.
|
||||||
origin : numpy.ndarray of shape (3), optional
|
origin : sequence of float, len(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
|
Returns
|
||||||
-------
|
-------
|
||||||
x_n : numpy.ndarray
|
x_n : numpy.ndarray, shape (:,:,:,3)
|
||||||
Nodal coordinates.
|
Nodal coordinates.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
@ -416,13 +419,13 @@ def coordinates_node(size: _np.ndarray, F: _np.ndarray, origin: _np.ndarray = _n
|
||||||
|
|
||||||
|
|
||||||
def cellsSizeOrigin_coordinates0_node(coordinates0: _np.ndarray,
|
def cellsSizeOrigin_coordinates0_node(coordinates0: _np.ndarray,
|
||||||
ordered: bool = True) -> Tuple[_np.ndarray,_np.ndarray,_np.ndarray]:
|
ordered: bool = True) -> _Tuple[_np.ndarray,_np.ndarray,_np.ndarray]:
|
||||||
"""
|
"""
|
||||||
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.
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
----------
|
----------
|
||||||
coordinates0 : numpy.ndarray of shape (:,3)
|
coordinates0 : numpy.ndarray, shape (:,3)
|
||||||
Undeformed nodal coordinates.
|
Undeformed nodal coordinates.
|
||||||
ordered : bool, optional
|
ordered : bool, optional
|
||||||
Expect coordinates0 data to be ordered (x fast, z slow).
|
Expect coordinates0 data to be ordered (x fast, z slow).
|
||||||
|
@ -437,7 +440,7 @@ def cellsSizeOrigin_coordinates0_node(coordinates0: _np.ndarray,
|
||||||
coords = [_np.unique(coordinates0[:,i]) for i in range(3)]
|
coords = [_np.unique(coordinates0[:,i]) for i in range(3)]
|
||||||
mincorner = _np.array(list(map(min,coords)))
|
mincorner = _np.array(list(map(min,coords)))
|
||||||
maxcorner = _np.array(list(map(max,coords)))
|
maxcorner = _np.array(list(map(max,coords)))
|
||||||
cells = _np.array(list(map(len,coords)),'i') - 1
|
cells = _np.array(list(map(len,coords)),int) - 1
|
||||||
size = maxcorner-mincorner
|
size = maxcorner-mincorner
|
||||||
origin = mincorner
|
origin = mincorner
|
||||||
|
|
||||||
|
@ -463,12 +466,12 @@ def point_to_node(cell_data: _np.ndarray) -> _np.ndarray:
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
----------
|
----------
|
||||||
cell_data : numpy.ndarray of shape (:,:,:,...)
|
cell_data : numpy.ndarray, shape (:,:,:,...)
|
||||||
Data defined on the cell centers of a periodic grid.
|
Data defined on the cell centers of a periodic grid.
|
||||||
|
|
||||||
Returns
|
Returns
|
||||||
-------
|
-------
|
||||||
node_data : numpy.ndarray of shape (:,:,:,...)
|
node_data : numpy.ndarray, shape (:,:,:,...)
|
||||||
Data defined on the nodes of a periodic grid.
|
Data defined on the nodes of a periodic grid.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
@ -485,12 +488,12 @@ def node_to_point(node_data: _np.ndarray) -> _np.ndarray:
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
----------
|
----------
|
||||||
node_data : numpy.ndarray of shape (:,:,:,...)
|
node_data : numpy.ndarray, shape (:,:,:,...)
|
||||||
Data defined on the nodes of a periodic grid.
|
Data defined on the nodes of a periodic grid.
|
||||||
|
|
||||||
Returns
|
Returns
|
||||||
-------
|
-------
|
||||||
cell_data : numpy.ndarray of shape (:,:,:,...)
|
cell_data : numpy.ndarray, shape (:,:,:,...)
|
||||||
Data defined on the cell centers of a periodic grid.
|
Data defined on the cell centers of a periodic grid.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
@ -507,7 +510,7 @@ def coordinates0_valid(coordinates0: _np.ndarray) -> bool:
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
----------
|
----------
|
||||||
coordinates0 : numpy.ndarray
|
coordinates0 : numpy.ndarray, shape (:,3)
|
||||||
Array of undeformed cell coordinates.
|
Array of undeformed cell coordinates.
|
||||||
|
|
||||||
Returns
|
Returns
|
||||||
|
@ -523,17 +526,17 @@ def coordinates0_valid(coordinates0: _np.ndarray) -> bool:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def regrid(size: _np.ndarray, F: _np.ndarray, cells: Union[_np.ndarray,Sequence[int]]) -> _np.ndarray:
|
def regrid(size: _FloatSequence, F: _np.ndarray, cells: _IntSequence) -> _np.ndarray:
|
||||||
"""
|
"""
|
||||||
Return mapping from coordinates in deformed configuration to a regular grid.
|
Return mapping from coordinates in deformed configuration to a regular grid.
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
----------
|
----------
|
||||||
size : numpy.ndarray of shape (3)
|
size : sequence of float, len (3)
|
||||||
Physical size.
|
Physical size.
|
||||||
F : numpy.ndarray of shape (:,:,:,3,3)
|
F : numpy.ndarray, shape (:,:,:,3,3), shape (:,:,:,3,3)
|
||||||
Deformation gradient field.
|
Deformation gradient field.
|
||||||
cells : numpy.ndarray of shape (3)
|
cells : sequence of int, len (3)
|
||||||
Cell count along x,y,z of remapping grid.
|
Cell count along x,y,z of remapping grid.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -5,7 +5,7 @@ All routines operate on numpy.ndarrays of shape (...,3,3).
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from typing import Sequence
|
from typing import Sequence as _Sequence
|
||||||
|
|
||||||
import numpy as _np
|
import numpy as _np
|
||||||
|
|
||||||
|
@ -243,7 +243,7 @@ def stretch_right(T: _np.ndarray) -> _np.ndarray:
|
||||||
return _polar_decomposition(T,'U')[0]
|
return _polar_decomposition(T,'U')[0]
|
||||||
|
|
||||||
|
|
||||||
def _polar_decomposition(T: _np.ndarray, requested: Sequence[str]) -> tuple:
|
def _polar_decomposition(T: _np.ndarray, requested: _Sequence[str]) -> tuple:
|
||||||
"""
|
"""
|
||||||
Perform singular value decomposition.
|
Perform singular value decomposition.
|
||||||
|
|
||||||
|
|
|
@ -1,25 +1,27 @@
|
||||||
"""Functionality for generation of seed points for Voronoi or Laguerre tessellation."""
|
"""Functionality for generation of seed points for Voronoi or Laguerre tessellation."""
|
||||||
|
|
||||||
from typing import Sequence,Tuple
|
from typing import Tuple as _Tuple
|
||||||
|
|
||||||
from scipy import spatial as _spatial
|
from scipy import spatial as _spatial
|
||||||
import numpy as _np
|
import numpy as _np
|
||||||
|
|
||||||
|
from ._typehints import FloatSequence as _FloatSequence, IntSequence as _IntSequence
|
||||||
from . import util as _util
|
from . import util as _util
|
||||||
from . import grid_filters as _grid_filters
|
from . import grid_filters as _grid_filters
|
||||||
|
|
||||||
|
|
||||||
def from_random(size: _np.ndarray, N_seeds: int, cells: _np.ndarray = None, rng_seed=None) -> _np.ndarray:
|
def from_random(size: _FloatSequence, N_seeds: int, cells: _IntSequence = None,
|
||||||
|
rng_seed=None) -> _np.ndarray:
|
||||||
"""
|
"""
|
||||||
Place seeds randomly in space.
|
Place seeds randomly in space.
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
----------
|
----------
|
||||||
size : numpy.ndarray of shape (3)
|
size : sequence of float, len (3)
|
||||||
Physical size of the seeding domain.
|
Physical size of the seeding domain.
|
||||||
N_seeds : int
|
N_seeds : int
|
||||||
Number of seeds.
|
Number of seeds.
|
||||||
cells : numpy.ndarray of shape (3), optional.
|
cells : sequence of int, len (3), optional.
|
||||||
If given, ensures that each seed results in a grain when a standard Voronoi
|
If given, ensures that each seed results in a grain when a standard Voronoi
|
||||||
tessellation is performed using the given grid resolution (i.e. size/cells).
|
tessellation is performed using the given grid resolution (i.e. size/cells).
|
||||||
rng_seed : {None, int, array_like[ints], SeedSequence, BitGenerator, Generator}, optional
|
rng_seed : {None, int, array_like[ints], SeedSequence, BitGenerator, Generator}, optional
|
||||||
|
@ -28,29 +30,30 @@ def from_random(size: _np.ndarray, N_seeds: int, cells: _np.ndarray = None, rng_
|
||||||
|
|
||||||
Returns
|
Returns
|
||||||
-------
|
-------
|
||||||
coords : numpy.ndarray of shape (N_seeds,3)
|
coords : numpy.ndarray, shape (N_seeds,3)
|
||||||
Seed coordinates in 3D space.
|
Seed coordinates in 3D space.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
size_ = _np.array(size,float)
|
||||||
rng = _np.random.default_rng(rng_seed)
|
rng = _np.random.default_rng(rng_seed)
|
||||||
if cells is None:
|
if cells is None:
|
||||||
coords = rng.random((N_seeds,3)) * size
|
coords = rng.random((N_seeds,3)) * size_
|
||||||
else:
|
else:
|
||||||
grid_coords = _grid_filters.coordinates0_point(cells,size).reshape(-1,3,order='F')
|
grid_coords = _grid_filters.coordinates0_point(cells,size).reshape(-1,3,order='F')
|
||||||
coords = grid_coords[rng.choice(_np.prod(cells),N_seeds, replace=False)] \
|
coords = grid_coords[rng.choice(_np.prod(cells),N_seeds, replace=False)] \
|
||||||
+ _np.broadcast_to(size/cells,(N_seeds,3))*(rng.random((N_seeds,3))*.5-.25) # wobble without leaving cells
|
+ _np.broadcast_to(size_/_np.array(cells,int),(N_seeds,3))*(rng.random((N_seeds,3))*.5-.25) # wobble w/o leaving grid
|
||||||
|
|
||||||
return coords
|
return coords
|
||||||
|
|
||||||
|
|
||||||
def from_Poisson_disc(size: _np.ndarray, N_seeds: int, N_candidates: int, distance: float,
|
def from_Poisson_disc(size: _FloatSequence, N_seeds: int, N_candidates: int, distance: float,
|
||||||
periodic: bool = True, rng_seed=None) -> _np.ndarray:
|
periodic: bool = True, rng_seed=None) -> _np.ndarray:
|
||||||
"""
|
"""
|
||||||
Place seeds according to a Poisson disc distribution.
|
Place seeds according to a Poisson disc distribution.
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
----------
|
----------
|
||||||
size : numpy.ndarray of shape (3)
|
size : sequence of float, len (3)
|
||||||
Physical size of the seeding domain.
|
Physical size of the seeding domain.
|
||||||
N_seeds : int
|
N_seeds : int
|
||||||
Number of seeds.
|
Number of seeds.
|
||||||
|
@ -66,13 +69,13 @@ def from_Poisson_disc(size: _np.ndarray, N_seeds: int, N_candidates: int, distan
|
||||||
|
|
||||||
Returns
|
Returns
|
||||||
-------
|
-------
|
||||||
coords : numpy.ndarray of shape (N_seeds,3)
|
coords : numpy.ndarray, shape (N_seeds,3)
|
||||||
Seed coordinates in 3D space.
|
Seed 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))
|
||||||
coords[0] = rng.random(3) * size
|
coords[0] = rng.random(3) * _np.array(size,float)
|
||||||
|
|
||||||
s = 1
|
s = 1
|
||||||
i = 0
|
i = 0
|
||||||
|
@ -96,8 +99,8 @@ def from_Poisson_disc(size: _np.ndarray, N_seeds: int, N_candidates: int, distan
|
||||||
return coords
|
return coords
|
||||||
|
|
||||||
|
|
||||||
def from_grid(grid, selection: Sequence[int] = None,
|
def from_grid(grid, selection: _IntSequence = None,
|
||||||
invert: bool = False, average: bool = False, periodic: bool = True) -> Tuple[_np.ndarray, _np.ndarray]:
|
invert: bool = False, average: bool = False, periodic: bool = True) -> _Tuple[_np.ndarray, _np.ndarray]:
|
||||||
"""
|
"""
|
||||||
Create seeds from grid description.
|
Create seeds from grid description.
|
||||||
|
|
||||||
|
@ -105,7 +108,7 @@ def from_grid(grid, selection: Sequence[int] = None,
|
||||||
----------
|
----------
|
||||||
grid : damask.Grid
|
grid : damask.Grid
|
||||||
Grid from which the material IDs are used as seeds.
|
Grid from which the material IDs are used as seeds.
|
||||||
selection : iterable of integers, optional
|
selection : sequence of int, optional
|
||||||
Material IDs to consider.
|
Material IDs to consider.
|
||||||
invert : boolean, false
|
invert : boolean, false
|
||||||
Consider all material IDs except those in selection. Defaults to False.
|
Consider all material IDs except those in selection. Defaults to False.
|
||||||
|
@ -116,7 +119,7 @@ def from_grid(grid, selection: Sequence[int] = None,
|
||||||
|
|
||||||
Returns
|
Returns
|
||||||
-------
|
-------
|
||||||
coords, materials : numpy.ndarray of shape (:,3), numpy.ndarray of shape (:)
|
coords, materials : numpy.ndarray, shape (:,3); numpy.ndarray, shape (:)
|
||||||
Seed coordinates in 3D space, material IDs.
|
Seed coordinates in 3D space, material IDs.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
Loading…
Reference in New Issue