From 410a515afc178b232d0ef24650f3de80b00ad628 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Wed, 12 Jan 2022 13:18:38 +0000 Subject: [PATCH] allow flexible arguments for 1D arguments --- python/damask/__init__.py | 1 + python/damask/_colormap.py | 25 +++-- python/damask/_typehints.py | 11 +++ python/damask/grid_filters.py | 171 +++++++++++++++++----------------- python/damask/mechanics.py | 4 +- python/damask/seeds.py | 33 ++++--- 6 files changed, 130 insertions(+), 115 deletions(-) create mode 100644 python/damask/_typehints.py diff --git a/python/damask/__init__.py b/python/damask/__init__.py index 231fa8b30..584a97e87 100644 --- a/python/damask/__init__.py +++ b/python/damask/__init__.py @@ -8,6 +8,7 @@ with open(_Path(__file__).parent/_Path('VERSION')) as _f: version = _re.sub(r'^v','',_f.readline().strip()) __version__ = version +from . import _typehints # noqa from . import util # noqa from . import seeds # noqa from . import tensor # noqa diff --git a/python/damask/_colormap.py b/python/damask/_colormap.py index c2721e0fa..2da92ae3f 100644 --- a/python/damask/_colormap.py +++ b/python/damask/_colormap.py @@ -3,13 +3,9 @@ import json import functools import colorsys from pathlib import Path -from typing import Sequence, Union, TextIO +from typing import Union, TextIO 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 matplotlib as mpl if os.name == 'posix' and 'DISPLAY' not in os.environ: @@ -18,6 +14,7 @@ import matplotlib.pyplot as plt from matplotlib import cm from PIL import Image +from ._typehints import FloatSequence, FileHandle from . import util from . import Table @@ -82,8 +79,8 @@ class Colormap(mpl.colors.ListedColormap): @staticmethod - def from_range(low: ArrayLike, - high: ArrayLike, + def from_range(low: FloatSequence, + high: FloatSequence, name: str = 'DAMASK colormap', N: int = 256, model: str = 'rgb') -> 'Colormap': @@ -197,7 +194,7 @@ class Colormap(mpl.colors.ListedColormap): def at(self, - fraction : Union[float,Sequence[float]]) -> np.ndarray: + fraction : Union[float,FloatSequence]) -> np.ndarray: """ Interpolate color at fraction. @@ -229,7 +226,7 @@ class Colormap(mpl.colors.ListedColormap): def shade(self, field: np.ndarray, - bounds: ArrayLike = None, + bounds: FloatSequence = None, gap: float = None) -> Image: """ Generate PIL image of 2D field using colormap. @@ -296,7 +293,7 @@ class Colormap(mpl.colors.ListedColormap): def _get_file_handle(self, - fname: Union[TextIO, str, Path, None], + fname: Union[FileHandle, None], suffix: str = '') -> TextIO: """ Provide file handle. @@ -323,7 +320,7 @@ class Colormap(mpl.colors.ListedColormap): 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. @@ -350,7 +347,7 @@ class Colormap(mpl.colors.ListedColormap): fhandle.write('\n') - def save_ASCII(self, fname: Union[TextIO, str, Path] = None): + def save_ASCII(self, fname: FileHandle = None): """ Save as ASCII file. @@ -365,7 +362,7 @@ class Colormap(mpl.colors.ListedColormap): 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. @@ -385,7 +382,7 @@ class Colormap(mpl.colors.ListedColormap): 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. diff --git a/python/damask/_typehints.py b/python/damask/_typehints.py new file mode 100644 index 000000000..67e920957 --- /dev/null +++ b/python/damask/_typehints.py @@ -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] diff --git a/python/damask/grid_filters.py b/python/damask/grid_filters.py index 42b5a16c4..d9d658d0b 100644 --- a/python/damask/grid_filters.py +++ b/python/damask/grid_filters.py @@ -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 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. Parameters ---------- - size : numpy.ndarray of shape (3) + size : sequence of float, len (3) Physical size of the periodic field. - cells : numpy.ndarray of shape (3) + cells : sequence of int, len (3) Number of cells. first_order : bool, optional 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) -def curl(size: _np.ndarray, f: _np.ndarray) -> _np.ndarray: +def curl(size: _FloatSequence, f: _np.ndarray) -> _np.ndarray: u""" Calculate curl of a vector or tensor field in Fourier space. Parameters ---------- - size : numpy.ndarray of shape (3) + size : sequence of float, len (3) 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. Returns ------- - ∇ × f : numpy.ndarray + ∇ × f : numpy.ndarray, shape (:,:,:,3) or (:,:,:,3,3) 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]) -def divergence(size: _np.ndarray, f: _np.ndarray) -> _np.ndarray: +def divergence(size: _FloatSequence, f: _np.ndarray) -> _np.ndarray: u""" Calculate divergence of a vector or tensor field in Fourier space. Parameters ---------- - size : numpy.ndarray of shape (3) + size : sequence of float, len (3) 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. Returns ------- - ∇ · f : numpy.ndarray + ∇ · f : numpy.ndarray, shape (:,:,:,1) or (:,:,:,3) 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]) -def gradient(size: _np.ndarray, f: _np.ndarray) -> _np.ndarray: +def gradient(size: _FloatSequence, f: _np.ndarray) -> _np.ndarray: u""" - Calculate gradient of a scalar or vector fieldin Fourier space. + Calculate gradient of a scalar or vector field in Fourier space. Parameters ---------- - size : numpy.ndarray of shape (3) + size : sequence of float, len (3) 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. Returns ------- - ∇ f : numpy.ndarray + ∇ f : numpy.ndarray, shape (:,:,:,3) or (:,:,:,3,3) 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]) -def coordinates0_point(cells: Union[ _np.ndarray,Sequence[int]], - size: _np.ndarray, - origin: _np.ndarray = _np.zeros(3)) -> _np.ndarray: +def coordinates0_point(cells: _IntSequence, + size: _FloatSequence, + origin: _FloatSequence = _np.zeros(3)) -> _np.ndarray: """ Cell center positions (undeformed). Parameters ---------- - cells : numpy.ndarray of shape (3) + cells : sequence of int, len (3) Number of cells. - size : numpy.ndarray of shape (3) + size : sequence of float, len (3) 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]. Returns ------- - x_p_0 : numpy.ndarray + x_p_0 : numpy.ndarray, shape (:,:,:,3) Undeformed cell center coordinates. """ - start = origin + size/_np.array(cells)*.5 - end = origin + size - size/_np.array(cells)*.5 + size_ = _np.array(size,float) + 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]), _np.linspace(start[1],end[1],cells[1]), @@ -160,24 +163,24 @@ def coordinates0_point(cells: Union[ _np.ndarray,Sequence[int]], 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. Parameters ---------- - size : numpy.ndarray of shape (3) + size : sequence of float, len (3) Physical size of the periodic field. - F : numpy.ndarray + F : numpy.ndarray, shape (:,:,:,3,3) Deformation gradient field. Returns ------- - u_p_fluct : numpy.ndarray + u_p_fluct : numpy.ndarray, shape (:,:,:,3) 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_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]) -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. Parameters ---------- - size : numpy.ndarray of shape (3) + size : sequence of float, len (3) Physical size of the periodic field. - F : numpy.ndarray + F : numpy.ndarray, shape (:,:,:,3,3) Deformation gradient field. Returns ------- - u_p_avg : numpy.ndarray + u_p_avg : numpy.ndarray, shape (:,:,:,3) 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)) -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. Parameters ---------- - size : numpy.ndarray of shape (3) + size : sequence of float, len (3) Physical size of the periodic field. - F : numpy.ndarray + F : numpy.ndarray, shape (:,:,:,3,3) Deformation gradient field. Returns ------- - u_p : numpy.ndarray + u_p : numpy.ndarray, shape (:,:,:,3) Cell center displacements. """ 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. Parameters ---------- - size : numpy.ndarray of shape (3) + size : sequence of float, len (3) Physical size of the periodic field. - F : numpy.ndarray + F : numpy.ndarray, shape (:,:,:,3,3) 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]. Returns ------- - x_p : numpy.ndarray + x_p : numpy.ndarray, shape (:,:,:,3) 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, - 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. Parameters ---------- - coordinates0 : numpy.ndarray of shape (:,3) - Undeformed cell coordinates. + coordinates0 : numpy.ndarray, shape (:,3) + Undeformed cell center coordinates. ordered : bool, optional Expect coordinates0 data to be ordered (x fast, z slow). Defaults to True. @@ -277,7 +280,7 @@ def cellsSizeOrigin_coordinates0_point(coordinates0: _np.ndarray, coords = [_np.unique(coordinates0[:,i]) for i in range(3)] mincorner = _np.array(list(map(min,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) delta = size/cells origin = mincorner - delta*.5 @@ -305,24 +308,24 @@ def cellsSizeOrigin_coordinates0_point(coordinates0: _np.ndarray, return (cells,size,origin) -def coordinates0_node(cells: Union[_np.ndarray,Sequence[int]], - size: _np.ndarray, - origin: _np.ndarray = _np.zeros(3)) -> _np.ndarray: +def coordinates0_node(cells: _IntSequence, + size: _FloatSequence, + origin: _FloatSequence = _np.zeros(3)) -> _np.ndarray: """ Nodal positions (undeformed). Parameters ---------- - cells : numpy.ndarray of shape (3) + cells : sequence of int, len (3) Number of cells. - size : numpy.ndarray of shape (3) + size : sequence of float, len (3) 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]. Returns ------- - x_n_0 : numpy.ndarray + x_n_0 : numpy.ndarray, shape (:,:,:,3) Undeformed nodal coordinates. """ @@ -332,40 +335,40 @@ def coordinates0_node(cells: Union[_np.ndarray,Sequence[int]], 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. Parameters ---------- - size : numpy.ndarray of shape (3) + size : sequence of float, len (3) Physical size of the periodic field. - F : numpy.ndarray + F : numpy.ndarray, shape (:,:,:,3,3) Deformation gradient field. Returns ------- - u_n_fluct : numpy.ndarray + u_n_fluct : numpy.ndarray, shape (:,:,:,3) Fluctuating part of the nodal displacements. """ 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. Parameters ---------- - size : numpy.ndarray of shape (3) + size : sequence of float, len (3) Physical size of the periodic field. - F : numpy.ndarray + F : numpy.ndarray, shape (:,:,:,3,3) Deformation gradient field. Returns ------- - u_n_avg : numpy.ndarray + u_n_avg : numpy.ndarray, shape (:,:,:,3) 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)) -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. Parameters ---------- - size : numpy.ndarray of shape (3) + size : sequence of float, len (3) Physical size of the periodic field. - F : numpy.ndarray + F : numpy.ndarray, shape (:,:,:,3,3) Deformation gradient field. Returns ------- - u_p : numpy.ndarray + u_p : numpy.ndarray, shape (:,:,:,3) Nodal displacements. """ 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. Parameters ---------- - size : numpy.ndarray of shape (3) + size : sequence of float, len (3) Physical size of the periodic field. - F : numpy.ndarray + F : numpy.ndarray, shape (:,:,:,3,3) 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]. Returns ------- - x_n : numpy.ndarray + x_n : numpy.ndarray, shape (:,:,:,3) 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, - 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. Parameters ---------- - coordinates0 : numpy.ndarray of shape (:,3) + coordinates0 : numpy.ndarray, shape (:,3) Undeformed nodal coordinates. ordered : bool, optional 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)] mincorner = _np.array(list(map(min,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 origin = mincorner @@ -463,12 +466,12 @@ def point_to_node(cell_data: _np.ndarray) -> _np.ndarray: Parameters ---------- - cell_data : numpy.ndarray of shape (:,:,:,...) + cell_data : numpy.ndarray, shape (:,:,:,...) Data defined on the cell centers of a periodic grid. Returns ------- - node_data : numpy.ndarray of shape (:,:,:,...) + node_data : numpy.ndarray, shape (:,:,:,...) Data defined on the nodes of a periodic grid. """ @@ -485,12 +488,12 @@ def node_to_point(node_data: _np.ndarray) -> _np.ndarray: Parameters ---------- - node_data : numpy.ndarray of shape (:,:,:,...) + node_data : numpy.ndarray, shape (:,:,:,...) Data defined on the nodes of a periodic grid. Returns ------- - cell_data : numpy.ndarray of shape (:,:,:,...) + cell_data : numpy.ndarray, shape (:,:,:,...) Data defined on the cell centers of a periodic grid. """ @@ -507,7 +510,7 @@ def coordinates0_valid(coordinates0: _np.ndarray) -> bool: Parameters ---------- - coordinates0 : numpy.ndarray + coordinates0 : numpy.ndarray, shape (:,3) Array of undeformed cell coordinates. Returns @@ -523,17 +526,17 @@ def coordinates0_valid(coordinates0: _np.ndarray) -> bool: 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. Parameters ---------- - size : numpy.ndarray of shape (3) + size : sequence of float, len (3) Physical size. - F : numpy.ndarray of shape (:,:,:,3,3) + F : numpy.ndarray, shape (:,:,:,3,3), shape (:,:,:,3,3) Deformation gradient field. - cells : numpy.ndarray of shape (3) + cells : sequence of int, len (3) Cell count along x,y,z of remapping grid. """ diff --git a/python/damask/mechanics.py b/python/damask/mechanics.py index 22e3aeabf..7c1af6c5f 100644 --- a/python/damask/mechanics.py +++ b/python/damask/mechanics.py @@ -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 @@ -243,7 +243,7 @@ def stretch_right(T: _np.ndarray) -> _np.ndarray: 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. diff --git a/python/damask/seeds.py b/python/damask/seeds.py index 4d5a8c624..7e01a40e6 100644 --- a/python/damask/seeds.py +++ b/python/damask/seeds.py @@ -1,25 +1,27 @@ """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 import numpy as _np +from ._typehints import FloatSequence as _FloatSequence, IntSequence as _IntSequence from . import util as _util 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. Parameters ---------- - size : numpy.ndarray of shape (3) + size : sequence of float, len (3) Physical size of the seeding domain. N_seeds : int 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 tessellation is performed using the given grid resolution (i.e. size/cells). 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 ------- - coords : numpy.ndarray of shape (N_seeds,3) + coords : numpy.ndarray, shape (N_seeds,3) Seed coordinates in 3D space. """ + size_ = _np.array(size,float) rng = _np.random.default_rng(rng_seed) if cells is None: - coords = rng.random((N_seeds,3)) * size + coords = rng.random((N_seeds,3)) * size_ else: 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)] \ - + _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 -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: """ Place seeds according to a Poisson disc distribution. Parameters ---------- - size : numpy.ndarray of shape (3) + size : sequence of float, len (3) Physical size of the seeding domain. N_seeds : int Number of seeds. @@ -66,13 +69,13 @@ def from_Poisson_disc(size: _np.ndarray, N_seeds: int, N_candidates: int, distan Returns ------- - coords : numpy.ndarray of shape (N_seeds,3) + coords : numpy.ndarray, shape (N_seeds,3) Seed coordinates in 3D space. """ rng = _np.random.default_rng(rng_seed) coords = _np.empty((N_seeds,3)) - coords[0] = rng.random(3) * size + coords[0] = rng.random(3) * _np.array(size,float) s = 1 i = 0 @@ -96,8 +99,8 @@ def from_Poisson_disc(size: _np.ndarray, N_seeds: int, N_candidates: int, distan return coords -def from_grid(grid, selection: Sequence[int] = None, - invert: bool = False, average: bool = False, periodic: bool = True) -> Tuple[_np.ndarray, _np.ndarray]: +def from_grid(grid, selection: _IntSequence = None, + invert: bool = False, average: bool = False, periodic: bool = True) -> _Tuple[_np.ndarray, _np.ndarray]: """ Create seeds from grid description. @@ -105,7 +108,7 @@ def from_grid(grid, selection: Sequence[int] = None, ---------- grid : damask.Grid Grid from which the material IDs are used as seeds. - selection : iterable of integers, optional + selection : sequence of int, optional Material IDs to consider. invert : boolean, 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 ------- - 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. """