From f13a4c82dae1ab9fe1f9124fc64d7e674a67d21f Mon Sep 17 00:00:00 2001 From: Philip Eisenlohr Date: Wed, 9 Mar 2022 18:24:05 -0500 Subject: [PATCH] grid.clean/vicinity now uses ball neighborhood; lots of polishing --- python/damask/_grid.py | 122 +++++++++++------- python/damask/_orientation.py | 14 +- python/damask/seeds.py | 5 +- python/damask/util.py | 25 ++-- ...3_1_True.vti => clean_1.0_1+2+3_False.vti} | 2 +- ...2+3_False.vti => clean_1.0_1+2+3_True.vti} | 2 +- ...ean_2_1_True.vti => clean_1.0_1_False.vti} | 2 +- ...ean_3_1_False.vti => clean_1.0_1_True.vti} | 2 +- ..._2_1+2+3_True.vti => clean_1.0__False.vti} | 4 +- .../tests/reference/Grid/clean_1.0__True.vti | 19 +++ ... clean_1.7320508075688772_1+2+3_False.vti} | 2 +- .../clean_1.7320508075688772_1+2+3_True.vti | 19 +++ ...i => clean_1.7320508075688772_1_False.vti} | 2 +- ...ti => clean_1.7320508075688772_1_True.vti} | 2 +- ...ti => clean_1.7320508075688772__False.vti} | 4 +- ...vti => clean_1.7320508075688772__True.vti} | 4 +- .../reference/Grid/clean_3_1+2+3_True.vti | 19 --- .../reference/Grid/clean_3_None_False.vti | 19 --- .../reference/Grid/clean_3_None_True.vti | 19 --- .../reference/Grid/clean_4_1+2+3_False.vti | 19 --- .../reference/Grid/clean_4_1+2+3_True.vti | 19 --- .../tests/reference/Grid/clean_4_1_True.vti | 19 --- .../reference/Grid/clean_4_None_False.vti | 19 --- .../reference/Grid/clean_4_None_True.vti | 19 --- python/tests/test_Grid.py | 38 +++--- python/tests/test_util.py | 4 + 26 files changed, 173 insertions(+), 251 deletions(-) rename python/tests/reference/Grid/{clean_3_1_True.vti => clean_1.0_1+2+3_False.vti} (87%) rename python/tests/reference/Grid/{clean_2_1+2+3_False.vti => clean_1.0_1+2+3_True.vti} (87%) rename python/tests/reference/Grid/{clean_2_1_True.vti => clean_1.0_1_False.vti} (87%) rename python/tests/reference/Grid/{clean_3_1_False.vti => clean_1.0_1_True.vti} (87%) rename python/tests/reference/Grid/{clean_2_1+2+3_True.vti => clean_1.0__False.vti} (66%) create mode 100644 python/tests/reference/Grid/clean_1.0__True.vti rename python/tests/reference/Grid/{clean_3_1+2+3_False.vti => clean_1.7320508075688772_1+2+3_False.vti} (87%) create mode 100644 python/tests/reference/Grid/clean_1.7320508075688772_1+2+3_True.vti rename python/tests/reference/Grid/{clean_4_1_False.vti => clean_1.7320508075688772_1_False.vti} (87%) rename python/tests/reference/Grid/{clean_2_1_False.vti => clean_1.7320508075688772_1_True.vti} (87%) rename python/tests/reference/Grid/{clean_2_None_True.vti => clean_1.7320508075688772__False.vti} (75%) rename python/tests/reference/Grid/{clean_2_None_False.vti => clean_1.7320508075688772__True.vti} (73%) delete mode 100644 python/tests/reference/Grid/clean_3_1+2+3_True.vti delete mode 100644 python/tests/reference/Grid/clean_3_None_False.vti delete mode 100644 python/tests/reference/Grid/clean_3_None_True.vti delete mode 100644 python/tests/reference/Grid/clean_4_1+2+3_False.vti delete mode 100644 python/tests/reference/Grid/clean_4_1+2+3_True.vti delete mode 100644 python/tests/reference/Grid/clean_4_1_True.vti delete mode 100644 python/tests/reference/Grid/clean_4_None_False.vti delete mode 100644 python/tests/reference/Grid/clean_4_None_True.vti diff --git a/python/damask/_grid.py b/python/damask/_grid.py index d4dc456a2..0292cd6cc 100644 --- a/python/damask/_grid.py +++ b/python/damask/_grid.py @@ -18,7 +18,7 @@ from . import grid_filters from . import Rotation from . import Table from . import Colormap -from ._typehints import FloatSequence, IntSequence, IntCollection +from ._typehints import FloatSequence, IntSequence, IntCollection, NumpyRngSeed class Grid: """ @@ -92,10 +92,10 @@ class Grid: """ if not isinstance(other, Grid): return NotImplemented - return bool(np.allclose(other.size,self.size) - and np.allclose(other.origin,self.origin) - and np.all(other.cells == self.cells) - and np.all(other.material == self.material)) + return bool( np.allclose(other.size,self.size) + and np.allclose(other.origin,self.origin) + and np.all(other.cells == self.cells) + and np.all(other.material == self.material)) @property @@ -191,8 +191,8 @@ class Grid: ic = {label:v.get(label).reshape(cells,order='F') for label in set(v.labels['Cell Data']) - {'material'}} return Grid(material = v.get('material').reshape(cells,order='F'), - size = bbox[1] - bbox[0], - origin = bbox[0], + size = bbox[1] - bbox[0], + origin = bbox[0], comments = comments, initial_conditions = ic) @@ -247,7 +247,7 @@ class Grid: else: comments.append(line.strip()) - material = np.empty(int(cells.prod())) # initialize as flat array + material = np.empty(cells.prod()) # initialize as flat array i = 0 for line in content[header_length:]: if len(items := line.split('#')[0].split()) == 3: @@ -265,7 +265,7 @@ class Grid: raise TypeError(f'mismatch between {cells.prod()} expected entries and {i} found') if not np.any(np.mod(material,1) != 0.0): # no float present - material = material.astype('int') - (1 if material.min() > 0 else 0) + material = material.astype(int) - (1 if material.min() > 0 else 0) return Grid(material.reshape(cells,order='F'),size,origin,comments) @@ -927,7 +927,7 @@ class Grid: cells/self.cells, output=self.material.dtype, order=0, - mode=('wrap' if periodic else 'nearest'), + mode='wrap' if periodic else 'nearest', prefilter=False ), size = self.size, @@ -937,45 +937,62 @@ class Grid: def clean(self, - stencil: int = 3, + distance: float = np.sqrt(3), selection: IntCollection = None, invert_selection: bool = False, - periodic: bool = True) -> 'Grid': + periodic: bool = True, + rng_seed: NumpyRngSeed = None) -> 'Grid': """ Smooth grid by selecting most frequent material ID within given stencil at each location. Parameters ---------- - stencil : int, optional - Size of smoothing stencil. Defaults to 3. + distance : float, optional + Voxel distance checked for presence of other materials. + Defaults to sqrt(3). selection : int or collection of int, optional Material IDs to consider. invert_selection : bool, optional Consider all material IDs except those in selection. Defaults to False. periodic : bool, optional Assume grid to be periodic. Defaults to True. + rng_seed : {None, int, array_like[ints], SeedSequence, BitGenerator, Generator}, optional + A seed to initialize the BitGenerator. Defaults to None. + If None, then fresh, unpredictable entropy will be pulled from the OS. Returns ------- updated : damask.Grid Updated grid-based geometry. + Notes + ----- + If multiple material IDs are most frequent within a stencil, a random choice is taken. + """ - def mostFrequent(arr: np.ndarray, selection: List, invert: bool): - me = arr[arr.size//2] - if selection is None or np.isin(me,selection,invert=invert): - unique, inverse = np.unique(arr, return_inverse=True) - return unique[np.argmax(np.bincount(inverse))] + def most_frequent(stencil: np.ndarray, + selection: set, + rng: NumpyRngSeed): + me = stencil[stencil.size//2] + if not selection or me in selection: + unique, counts = np.unique(stencil,return_counts=True) + return rng.choice(unique[counts==np.max(counts)]) else: return me - extra_keywords = dict(selection=util.ensure_integer_list(selection),invert=invert_selection) + rng = np.random.default_rng(rng_seed) + d = np.floor(distance).astype(int) + ext = np.linspace(-d,d,1+2*d,dtype=float), + xx,yy,zz = np.meshgrid(ext,ext,ext) + footprint = xx**2+yy**2+zz**2 <= distance**2+distance*1e-8 + selection_ = set(self.material.flatten()) - set(util.aslist(selection)) if invert_selection else \ + set(util.aslist(selection)) material = ndimage.filters.generic_filter( self.material, - mostFrequent, - size=(stencil if selection is None else stencil//2*2+1,)*3, - mode=('wrap' if periodic else 'nearest'), - extra_keywords=extra_keywords, + most_frequent, + footprint=footprint, + mode='wrap' if periodic else 'nearest', + extra_keywords=dict(selection=selection_,rng=rng), ).astype(self.material.dtype) return Grid(material = material, size = self.size, @@ -1007,14 +1024,15 @@ class Grid: R: Rotation, fill: int = None) -> 'Grid': """ - Rotate grid (pad if required). + Rotate grid (and pad if required). Parameters ---------- R : damask.Rotation Rotation to apply to the grid. fill : int, optional - Material ID to fill the corners. Defaults to material.max() + 1. + Material ID to fill enlarged bounding box. + Defaults to material.max() + 1. Returns ------- @@ -1054,9 +1072,11 @@ class Grid: cells : sequence of int, len (3), optional Number of cells x,y,z direction. offset : sequence of int, len (3), optional - Offset (measured in cells) from old to new grid [0,0,0]. + Offset (measured in cells) from old to new grid. + Defaults to [0,0,0]. fill : int, optional - Material ID to fill the background. Defaults to material.max() + 1. + Material ID to fill the background. + Defaults to material.max() + 1. Returns ------- @@ -1065,15 +1085,15 @@ class Grid: Examples -------- - Remove 1/2 of the microstructure in z-direction. + Remove lower 1/2 of the microstructure in z-direction. >>> import numpy as np >>> import damask >>> g = damask.Grid(np.zeros([32]*3,int),np.ones(3)*1e-4) - >>> g.canvas([32,32,16]) + >>> g.canvas([32,32,16],[0,0,16]) cells : 33 x 32 x 16 size : 0.0001 x 0.0001 x 5e-05 m³ - origin: 0.0 0.0 0.0 m + origin: 0.0 0.0 5e-05 m # materials: 1 """ @@ -1150,29 +1170,31 @@ class Grid: def vicinity_offset(self, - vicinity: int = 1, + distance: float = np.sqrt(3), offset: int = None, selection: IntCollection = None, invert_selection: bool = False, periodic: bool = True) -> 'Grid': """ - Offset material ID of points in the vicinity of a trigger point. + Offset material ID of points in the vicinity of selected (or just other) material IDs. Trigger points are variations in material ID, i.e. grain/phase boundaries or explicitly given material IDs. Parameters ---------- - vicinity : int, optional + distance : float, optional Voxel distance checked for presence of other materials. - Defaults to 1. + Defaults to sqrt(3). offset : int, optional - Offset (positive or negative) to tag material indices, - defaults to material.max()+1. + Offset (positive or negative) to tag material IDs. + Defaults to material.max()+1. selection : int or collection of int, optional - Material IDs that triger the offset. + Material IDs that trigger an offset. + Defaults to any other than own material ID. invert_selection : bool, optional - Consider all material IDs except those in selection. Defaults to False. + Consider all material IDs except those in selection. + Defaults to False. periodic : bool, optional Assume grid to be periodic. Defaults to True. @@ -1182,20 +1204,24 @@ class Grid: Updated grid-based geometry. """ - def tainted_neighborhood(stencil: np.ndarray, selection): - me = stencil[stencil.shape[0]//2] - return np.any(stencil != me if selection is None else - np.in1d(stencil,np.array(list(set(selection) - {me})))) + def tainted_neighborhood(stencil: np.ndarray, selection: set): + me = stencil[stencil.size//2] + return np.any(stencil != me if not selection else + np.in1d(stencil,np.array(list(selection - {me})))) + d = np.floor(distance).astype(int) + ext = np.linspace(-d,d,1+2*d,dtype=float), + xx,yy,zz = np.meshgrid(ext,ext,ext) + footprint = xx**2+yy**2+zz**2 <= distance**2+distance*1e-8 offset_ = np.nanmax(self.material)+1 if offset is None else offset - selection_ = util.ensure_integer_list(selection) - if selection_ is not None and invert_selection: - selection_ = list(set(self.material.flatten()) - set(selection_)) + selection_ = set(self.material.flatten()) - set(util.aslist(selection)) if invert_selection else \ + set(util.aslist(selection)) mask = ndimage.filters.generic_filter(self.material, tainted_neighborhood, - size=1+2*vicinity, + footprint=footprint, mode='wrap' if periodic else 'nearest', - extra_keywords=dict(selection=selection_)) + extra_keywords=dict(selection=selection_), + ) return Grid(material = np.where(mask, self.material + offset_,self.material), size = self.size, diff --git a/python/damask/_orientation.py b/python/damask/_orientation.py index 195394449..534a9548d 100644 --- a/python/damask/_orientation.py +++ b/python/damask/_orientation.py @@ -870,23 +870,23 @@ class Orientation(Rotation,Crystal): def related(self: MyType, model: str) -> MyType: """ - Orientations derived from the given relationship. + All orientations related to self by given relationship model. Parameters ---------- model : str - Model for orientation relationship. - Must be out of self.orientation_relationships. + Orientation relationship model selected from self.orientation_relationships. Returns ------- - Orientations with crystal structure according to - the selected model for the orienation relationship. + Orientations related to self following the selected + model for the orientation relationship. Examples -------- - Rotations of the Bain orientation relationship (cI -> cF) - of a crystal in "Cube" orientation. + Face-centered cubic orientations following from a + body-centered cubic crystal in "Cube" orientation according + to the Bain orientation relationship (cI -> cF). >>> import numpy as np >>> import damask diff --git a/python/damask/seeds.py b/python/damask/seeds.py index 9f4df1ed1..a4ddfb418 100644 --- a/python/damask/seeds.py +++ b/python/damask/seeds.py @@ -134,9 +134,8 @@ def from_grid(grid, """ material = grid.material.reshape((-1,1),order='F') - selection_ = _util.ensure_integer_list(selection) - mask = _np.full(grid.cells.prod(),True,dtype=bool) if selection_ is None else \ - _np.isin(material,selection_,invert=invert_selection).flatten() + mask = _np.full(grid.cells.prod(),True,dtype=bool) if selection is None else \ + _np.isin(material,_util.aslist(selection),invert=invert_selection).flatten() coords = _grid_filters.coordinates0_point(grid.cells,grid.size).reshape(-1,3,order='F') if not average: diff --git a/python/damask/util.py b/python/damask/util.py index 1ad17443d..285c5f682 100644 --- a/python/damask/util.py +++ b/python/damask/util.py @@ -767,14 +767,23 @@ def tail_repack(extended: Union[str, Sequence[str]], list(extended[len(existing):])) -def ensure_integer_list(arg: Union[IntCollection,int,None]) -> Union[List,None]: - """Convert to list of Integers.""" - if arg is None: - return None - elif isinstance(arg,(np.ndarray,Collection)): - return list(arg) - else: - return [arg] +def aslist(arg: Union[IntCollection,int,None]) -> List: + """ + Transform argument to list. + + Parameters + ---------- + arg : int or collection of int or None + Entity to transform into list. + + Returns + ------- + transformed : list + Entity transformed into list. + + """ + return [] if arg is None else list(arg) if isinstance(arg,(np.ndarray,Collection)) else [arg] + #################################################################################################### # Classes diff --git a/python/tests/reference/Grid/clean_3_1_True.vti b/python/tests/reference/Grid/clean_1.0_1+2+3_False.vti similarity index 87% rename from python/tests/reference/Grid/clean_3_1_True.vti rename to python/tests/reference/Grid/clean_1.0_1+2+3_False.vti index be670913c..e2a97c1af 100644 --- a/python/tests/reference/Grid/clean_3_1_True.vti +++ b/python/tests/reference/Grid/clean_1.0_1+2+3_False.vti @@ -3,7 +3,7 @@ - AQAAAACAAAA+AAAAQQAAAA==eF5LScxNLM7Wc0/Nz9VLzklNzFMos7TUAyNdSyDQLagsSS0uUdAwMjC01DU01DUwUjA0tDK1sDIw0GQAAFT8EKY= + AQAAAACAAAA+AAAAQQAAAA==eF5LScxNLM7Wcy/KTNFLzklNzFMos7TUAyNdSyDQLagsSS0uUdAwMjC01DU01DUwUjA0tDK1sDIw0GQAAFSoEKQ= diff --git a/python/tests/reference/Grid/clean_2_1+2+3_False.vti b/python/tests/reference/Grid/clean_1.0_1+2+3_True.vti similarity index 87% rename from python/tests/reference/Grid/clean_2_1+2+3_False.vti rename to python/tests/reference/Grid/clean_1.0_1+2+3_True.vti index 33dc58cae..7cac33a2a 100644 --- a/python/tests/reference/Grid/clean_2_1+2+3_False.vti +++ b/python/tests/reference/Grid/clean_1.0_1+2+3_True.vti @@ -3,7 +3,7 @@ - AQAAAACAAAA+AAAAQQAAAA==eF5LScxNLM7Wc0/Nz9VLzklNzFMos7TUAyNdSyDQLagsSS0uUdAwMjC01DU01DUwUjA0tDK1sDIw0GQAAFT8EKY= + AQAAAACAAAA+AAAAQQAAAA==eF5LScxNLM7Wcy/KTNFLzklNzFMos7TUAyNdSyDQLagsSS0uUdAwMjC01DU01DUwUjA0tDK1sDIw0GQAAFSoEKQ= diff --git a/python/tests/reference/Grid/clean_2_1_True.vti b/python/tests/reference/Grid/clean_1.0_1_False.vti similarity index 87% rename from python/tests/reference/Grid/clean_2_1_True.vti rename to python/tests/reference/Grid/clean_1.0_1_False.vti index be670913c..e2a97c1af 100644 --- a/python/tests/reference/Grid/clean_2_1_True.vti +++ b/python/tests/reference/Grid/clean_1.0_1_False.vti @@ -3,7 +3,7 @@ - AQAAAACAAAA+AAAAQQAAAA==eF5LScxNLM7Wc0/Nz9VLzklNzFMos7TUAyNdSyDQLagsSS0uUdAwMjC01DU01DUwUjA0tDK1sDIw0GQAAFT8EKY= + AQAAAACAAAA+AAAAQQAAAA==eF5LScxNLM7Wcy/KTNFLzklNzFMos7TUAyNdSyDQLagsSS0uUdAwMjC01DU01DUwUjA0tDK1sDIw0GQAAFSoEKQ= diff --git a/python/tests/reference/Grid/clean_3_1_False.vti b/python/tests/reference/Grid/clean_1.0_1_True.vti similarity index 87% rename from python/tests/reference/Grid/clean_3_1_False.vti rename to python/tests/reference/Grid/clean_1.0_1_True.vti index d8ee724cc..561cb3245 100644 --- a/python/tests/reference/Grid/clean_3_1_False.vti +++ b/python/tests/reference/Grid/clean_1.0_1_True.vti @@ -3,7 +3,7 @@ - AQAAAACAAAA+AAAAQQAAAA==eF5LScxNLM7Wc0/Nz9VLzklNzFMos7TUAyNdSyDQLagsSS0uUdAwMjC01DU01DUwUjA0tDK1sDIw0GQAAFT8EKY= + AQAAAACAAAA+AAAAQQAAAA==eF5LScxNLM7Wcy/KTNFLzklNzFMos7TUAyNdSyDQLagsSS0uUdAwMjC01DU01DUwUjA0tDK1sDIw0GQAAFSoEKQ= diff --git a/python/tests/reference/Grid/clean_2_1+2+3_True.vti b/python/tests/reference/Grid/clean_1.0__False.vti similarity index 66% rename from python/tests/reference/Grid/clean_2_1+2+3_True.vti rename to python/tests/reference/Grid/clean_1.0__False.vti index e73ebc444..70dbb7542 100644 --- a/python/tests/reference/Grid/clean_2_1+2+3_True.vti +++ b/python/tests/reference/Grid/clean_1.0__False.vti @@ -3,7 +3,7 @@ - AQAAAACAAAA+AAAAQQAAAA==eF5LScxNLM7Wc0/Nz9VLzklNzFMos7TUAyNdSyDQLagsSS0uUdAwMjC01DU01DUwUjA0tDK1sDIw0GQAAFT8EKY= + AQAAAACAAAA+AAAAQQAAAA==eF5LScxNLM7Wcy/KTNFLzklNzFMos7TUAyNdSyDQLagsSS0uUdAwMjC01DU01DUwUjA0tDK1sDIw0GQAAFSoEKQ= @@ -11,7 +11,7 @@ - AQAAAACAAAAABQAAagAAAA==eF7t0rkOglAARFExLrgCKuKuqLj8/w9acCoSY7B+05x+cqNOvSj4l92GPfY54JAxRxxzwilnnDNhyowLLrlizjULbrjljnseeOSJZ15Y8sob76z44JMvvtn8L9jObz2GDuv96vADk5QHBg== + AQAAAACAAAAABQAAhAAAAA==eF7t0jcOAjEURVGGnHOOQ4b9b5CC8xtLNAwlbk5hPUuWblZ6n+zvV5ZZYZU11tlgky22E+PdPnsccsARx+ww9jPOuWDOFddM/3Pljfvk/sgTz7ww3d/54JPlv4X8VYexj466jP6ix+gvekw7nHDKTx0umXa44ZY7Rn8H5iza4QtoVQaf diff --git a/python/tests/reference/Grid/clean_1.0__True.vti b/python/tests/reference/Grid/clean_1.0__True.vti new file mode 100644 index 000000000..654968e1f --- /dev/null +++ b/python/tests/reference/Grid/clean_1.0__True.vti @@ -0,0 +1,19 @@ + + + + + + AQAAAACAAAA+AAAAQQAAAA==eF5LScxNLM7Wcy/KTNFLzklNzFMos7TUAyNdSyDQLagsSS0uUdAwMjC01DU01DUwUjA0tDK1sDIw0GQAAFSoEKQ= + + + + + + + + AQAAAACAAAAABQAAkAAAAA==eF7t070OgkAQRWExKo0GDREMaNjCv/d/QgvPbU5CQw3Nl5nZZZPlUm3+T7W6yK3c4Un9rK/V9/youlN9wzO2ml/xobrHghfM+Xcc0edPWDTP/ie+5AHf+MEv+h5Wl+nvsVff+ZvLcfKUHHtdctegc9RK5zL7Cmb/IJPf5DLvT36Sx7n/MHnMPTh/8QfFJwU8 + + + + + diff --git a/python/tests/reference/Grid/clean_3_1+2+3_False.vti b/python/tests/reference/Grid/clean_1.7320508075688772_1+2+3_False.vti similarity index 87% rename from python/tests/reference/Grid/clean_3_1+2+3_False.vti rename to python/tests/reference/Grid/clean_1.7320508075688772_1+2+3_False.vti index 33dc58cae..7cac33a2a 100644 --- a/python/tests/reference/Grid/clean_3_1+2+3_False.vti +++ b/python/tests/reference/Grid/clean_1.7320508075688772_1+2+3_False.vti @@ -3,7 +3,7 @@ - AQAAAACAAAA+AAAAQQAAAA==eF5LScxNLM7Wc0/Nz9VLzklNzFMos7TUAyNdSyDQLagsSS0uUdAwMjC01DU01DUwUjA0tDK1sDIw0GQAAFT8EKY= + AQAAAACAAAA+AAAAQQAAAA==eF5LScxNLM7Wcy/KTNFLzklNzFMos7TUAyNdSyDQLagsSS0uUdAwMjC01DU01DUwUjA0tDK1sDIw0GQAAFSoEKQ= diff --git a/python/tests/reference/Grid/clean_1.7320508075688772_1+2+3_True.vti b/python/tests/reference/Grid/clean_1.7320508075688772_1+2+3_True.vti new file mode 100644 index 000000000..7cac33a2a --- /dev/null +++ b/python/tests/reference/Grid/clean_1.7320508075688772_1+2+3_True.vti @@ -0,0 +1,19 @@ + + + + + + AQAAAACAAAA+AAAAQQAAAA==eF5LScxNLM7Wcy/KTNFLzklNzFMos7TUAyNdSyDQLagsSS0uUdAwMjC01DU01DUwUjA0tDK1sDIw0GQAAFSoEKQ= + + + + + + + + AQAAAACAAAAABQAAZwAAAA==eF7t0rcOgmAAhVEgNmyo2AuoWN//BR04EwsJcfzvcvabL47qxcFOJg177HPAIUdMOeaEU844Z8YFl1wx55obbrnjngceeeKZFxYseeWNd1Z88MkX3/zwy+Z/wf8YOqzX1uEPlgwHCA== + + + + + diff --git a/python/tests/reference/Grid/clean_4_1_False.vti b/python/tests/reference/Grid/clean_1.7320508075688772_1_False.vti similarity index 87% rename from python/tests/reference/Grid/clean_4_1_False.vti rename to python/tests/reference/Grid/clean_1.7320508075688772_1_False.vti index d8ee724cc..561cb3245 100644 --- a/python/tests/reference/Grid/clean_4_1_False.vti +++ b/python/tests/reference/Grid/clean_1.7320508075688772_1_False.vti @@ -3,7 +3,7 @@ - AQAAAACAAAA+AAAAQQAAAA==eF5LScxNLM7Wc0/Nz9VLzklNzFMos7TUAyNdSyDQLagsSS0uUdAwMjC01DU01DUwUjA0tDK1sDIw0GQAAFT8EKY= + AQAAAACAAAA+AAAAQQAAAA==eF5LScxNLM7Wcy/KTNFLzklNzFMos7TUAyNdSyDQLagsSS0uUdAwMjC01DU01DUwUjA0tDK1sDIw0GQAAFSoEKQ= diff --git a/python/tests/reference/Grid/clean_2_1_False.vti b/python/tests/reference/Grid/clean_1.7320508075688772_1_True.vti similarity index 87% rename from python/tests/reference/Grid/clean_2_1_False.vti rename to python/tests/reference/Grid/clean_1.7320508075688772_1_True.vti index d8ee724cc..561cb3245 100644 --- a/python/tests/reference/Grid/clean_2_1_False.vti +++ b/python/tests/reference/Grid/clean_1.7320508075688772_1_True.vti @@ -3,7 +3,7 @@ - AQAAAACAAAA+AAAAQQAAAA==eF5LScxNLM7Wc0/Nz9VLzklNzFMos7TUAyNdSyDQLagsSS0uUdAwMjC01DU01DUwUjA0tDK1sDIw0GQAAFT8EKY= + AQAAAACAAAA+AAAAQQAAAA==eF5LScxNLM7Wcy/KTNFLzklNzFMos7TUAyNdSyDQLagsSS0uUdAwMjC01DU01DUwUjA0tDK1sDIw0GQAAFSoEKQ= diff --git a/python/tests/reference/Grid/clean_2_None_True.vti b/python/tests/reference/Grid/clean_1.7320508075688772__False.vti similarity index 75% rename from python/tests/reference/Grid/clean_2_None_True.vti rename to python/tests/reference/Grid/clean_1.7320508075688772__False.vti index cf91a6700..21cbfbb4a 100644 --- a/python/tests/reference/Grid/clean_2_None_True.vti +++ b/python/tests/reference/Grid/clean_1.7320508075688772__False.vti @@ -3,7 +3,7 @@ - AQAAAACAAAA+AAAAQQAAAA==eF5LScxNLM7Wc0/Nz9VLzklNzFMos7TUAyNdSyDQLagsSS0uUdAwMjC01DU01DUwUjA0tDK1sDIw0GQAAFT8EKY= + AQAAAACAAAA+AAAAQQAAAA==eF5LScxNLM7Wcy/KTNFLzklNzFMos7TUAyNdSyDQLagsSS0uUdAwMjC01DU01DUwUjA0tDK1sDIw0GQAAFSoEKQ= @@ -11,7 +11,7 @@ - AQAAAACAAAAABQAAGQAAAA==eF5jZIAAxlF6lB4AmmmUHqUHkAYA/M8A8Q== + AQAAAACAAAAABQAAKwAAAA==eF5jZIAAxlGaLJoJjcYlTqw6Qvpx2U+pu0iVJ8QnJD5Kj9KDgQYAUc4BDA== diff --git a/python/tests/reference/Grid/clean_2_None_False.vti b/python/tests/reference/Grid/clean_1.7320508075688772__True.vti similarity index 73% rename from python/tests/reference/Grid/clean_2_None_False.vti rename to python/tests/reference/Grid/clean_1.7320508075688772__True.vti index 9d0302a10..272f0ecf7 100644 --- a/python/tests/reference/Grid/clean_2_None_False.vti +++ b/python/tests/reference/Grid/clean_1.7320508075688772__True.vti @@ -3,7 +3,7 @@ - AQAAAACAAAA+AAAAQQAAAA==eF5LScxNLM7Wc0/Nz9VLzklNzFMos7TUAyNdSyDQLagsSS0uUdAwMjC01DU01DUwUjA0tDK1sDIw0GQAAFT8EKY= + AQAAAACAAAA+AAAAQQAAAA==eF5LScxNLM7Wcy/KTNFLzklNzFMos7TUAyNdSyDQLagsSS0uUdAwMjC01DU01DUwUjA0tDK1sDIw0GQAAFSoEKQ= @@ -11,7 +11,7 @@ - AQAAAACAAAAABQAAGwAAAA==eF5jZIAAxlF6lB4AmmmUpogeDUfKaAD7jwDw + AQAAAACAAAAABQAAPwAAAA==eF5jZIAAxlGaLJqJAE2pPlx8atG4zCXkXmLFaeXuURqVJhQfhNIhLj4h9YTil1h7COkn5D9C+nGJAwBKngD7 diff --git a/python/tests/reference/Grid/clean_3_1+2+3_True.vti b/python/tests/reference/Grid/clean_3_1+2+3_True.vti deleted file mode 100644 index e73ebc444..000000000 --- a/python/tests/reference/Grid/clean_3_1+2+3_True.vti +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - AQAAAACAAAA+AAAAQQAAAA==eF5LScxNLM7Wc0/Nz9VLzklNzFMos7TUAyNdSyDQLagsSS0uUdAwMjC01DU01DUwUjA0tDK1sDIw0GQAAFT8EKY= - - - - - - - - AQAAAACAAAAABQAAagAAAA==eF7t0rkOglAARFExLrgCKuKuqLj8/w9acCoSY7B+05x+cqNOvSj4l92GPfY54JAxRxxzwilnnDNhyowLLrlizjULbrjljnseeOSJZ15Y8sob76z44JMvvtn8L9jObz2GDuv96vADk5QHBg== - - - - - diff --git a/python/tests/reference/Grid/clean_3_None_False.vti b/python/tests/reference/Grid/clean_3_None_False.vti deleted file mode 100644 index 80a3ce9d2..000000000 --- a/python/tests/reference/Grid/clean_3_None_False.vti +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - AQAAAACAAAA+AAAAQQAAAA==eF5LScxNLM7Wc0/Nz9VLzklNzFMos7TUAyNdSyDQLagsSS0uUdAwMjC01DU01DUwUjA0tDK1sDIw0GQAAFT8EKY= - - - - - - - - AQAAAACAAAAABQAAIgAAAA==eF5jZIAAxlGaLJoJjSakntr6hzqN7v9RepSmJw0AC04A9Q== - - - - - diff --git a/python/tests/reference/Grid/clean_3_None_True.vti b/python/tests/reference/Grid/clean_3_None_True.vti deleted file mode 100644 index b1ffa6b5d..000000000 --- a/python/tests/reference/Grid/clean_3_None_True.vti +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - AQAAAACAAAA+AAAAQQAAAA==eF5LScxNLM7Wc0/Nz9VLzklNzFMos7TUAyNdSyDQLagsSS0uUdAwMjC01DU01DUwUjA0tDK1sDIw0GQAAFT8EKY= - - - - - - - - AQAAAACAAAAABQAALwAAAA==eF5jZIAAxlGaLJoJjSakHpc+cvUTUkdrmlL3j9KU0dROF5TqH2iaVPcDAALOANU= - - - - - diff --git a/python/tests/reference/Grid/clean_4_1+2+3_False.vti b/python/tests/reference/Grid/clean_4_1+2+3_False.vti deleted file mode 100644 index c02459176..000000000 --- a/python/tests/reference/Grid/clean_4_1+2+3_False.vti +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - AQAAAACAAAA+AAAAQQAAAA==eF5LScxNLM7Wc0/Nz9VLzklNzFMos7TUAyNdSyDQLagsSS0uUdAwMjC01DU01DUwUjA0tDK1sDIw0GQAAFT8EKY= - - - - - - - - AQAAAACAAAAABQAAcQAAAA==eF7t0rkOglAUBFAxKu6igvsKrv//gxYcm9fQGEPBNKe6yc1kolaZqPEndthljzH7HHDIEceccMoZE8654JIpM6645oZb7rjngUeeeOaFV+YseOOdDz754pthf+3Aqr7rdv9vw3+/NjssU7XDD0/8BuQ= - - - - - diff --git a/python/tests/reference/Grid/clean_4_1+2+3_True.vti b/python/tests/reference/Grid/clean_4_1+2+3_True.vti deleted file mode 100644 index 37e026a0a..000000000 --- a/python/tests/reference/Grid/clean_4_1+2+3_True.vti +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - AQAAAACAAAA+AAAAQQAAAA==eF5LScxNLM7Wc0/Nz9VLzklNzFMos7TUAyNdSyDQLagsSS0uUdAwMjC01DU01DUwUjA0tDK1sDIw0GQAAFT8EKY= - - - - - - - - AQAAAACAAAAABQAAYQAAAA==eF7t0scVglAAAEHgqZgBA2ZExdR/gx6YCpDj38s0sEnUlgR7ccAhR0w55oRTzjjngktmzFlwxTU33LLkjnseeOSJZ15Y8cqaN975YMMnX3zzwy/j4F+GD9u6fvgD+gwHCA== - - - - - diff --git a/python/tests/reference/Grid/clean_4_1_True.vti b/python/tests/reference/Grid/clean_4_1_True.vti deleted file mode 100644 index fb9aa04f7..000000000 --- a/python/tests/reference/Grid/clean_4_1_True.vti +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - AQAAAACAAAA+AAAAQQAAAA==eF5LScxNLM7Wc0/Nz9VLzklNzFMos7TUAyNdSyDQLagsSS0uUdAwMjC01DU01DUwUjA0tDK1sDIw0GQAAFT8EKY= - - - - - - - - AQAAAACAAAAABQAAZAAAAA==eF7t0rcSglAARFEHE0bAgBkE8///oAWnF8b2bXP6nRv1mkXBv+xzwCFHHDPmhFPOOOeCSyZMmXHFNTfcMueOex545IlnXliw5JUVa95454NPvvjmh79+DXYzdNisbYdfSqMHMg== - - - - - diff --git a/python/tests/reference/Grid/clean_4_None_False.vti b/python/tests/reference/Grid/clean_4_None_False.vti deleted file mode 100644 index 121c43671..000000000 --- a/python/tests/reference/Grid/clean_4_None_False.vti +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - AQAAAACAAAA+AAAAQQAAAA==eF5LScxNLM7Wc0/Nz9VLzklNzFMos7TUAyNdSyDQLagsSS0uUdAwMjC01DU01DUwUjA0tDK1sDIw0GQAAFT8EKY= - - - - - - - - AQAAAACAAAAABQAAIAAAAA==eF5jZIAAxlF6lB4AmokAPdj1DzRNyP2jNH4aAMufANU= - - - - - diff --git a/python/tests/reference/Grid/clean_4_None_True.vti b/python/tests/reference/Grid/clean_4_None_True.vti deleted file mode 100644 index 54fa77562..000000000 --- a/python/tests/reference/Grid/clean_4_None_True.vti +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - AQAAAACAAAA+AAAAQQAAAA==eF5LScxNLM7Wc0/Nz9VLzklNzFMos7TUAyNdSyDQLagsSS0uUdAwMjC01DU01DUwUjA0tDK1sDIw0GQAAFT8EKY= - - - - - - - - AQAAAACAAAAABQAAMAAAAA==eF5jYoAAJhw0IwEalz566aeUptT+oa6fUppS+4e6fkppSu0f6voppSm1HwBAngDh - - - - - diff --git a/python/tests/test_Grid.py b/python/tests/test_Grid.py index 6e5953ff0..416559572 100644 --- a/python/tests/test_Grid.py +++ b/python/tests/test_Grid.py @@ -165,28 +165,26 @@ class TestGrid: default.flip(directions) - @pytest.mark.parametrize('stencil',[1,2,3,4]) - @pytest.mark.parametrize('selection',[None,[1],[1,2,3]]) + @pytest.mark.parametrize('distance',[1.,np.sqrt(3)]) + @pytest.mark.parametrize('selection',[None,1,[1],[1,2,3]]) @pytest.mark.parametrize('periodic',[True,False]) - def test_clean_reference(self,default,update,ref_path,stencil,selection,periodic): - current = default.clean(stencil,selection,periodic=periodic) - reference = ref_path/f'clean_{stencil}_{"+".join(map(str,[None] if selection is None else selection))}_{periodic}.vti' - if update and stencil > 1: + def test_clean_reference(self,default,update,ref_path,distance,selection,periodic): + current = default.clean(distance,selection,periodic=periodic,rng_seed=0) + reference = ref_path/f'clean_{distance}_{"+".join(map(str,util.aslist(selection)))}_{periodic}.vti' + if update: current.save(reference) - assert grid_equal(Grid.load(reference) if stencil > 1 else default, - current - ) + assert grid_equal(Grid.load(reference),current) @pytest.mark.parametrize('selection',[list(np.random.randint(1,20,6)),set(np.random.randint(1,20,6)),np.random.randint(1,20,6)]) @pytest.mark.parametrize('invert',[True,False]) - def test_clean_invert(self,random,selection,invert): - selection_inverse = set(random.material.flatten()) - set(selection) - assert random.clean(selection=selection,invert_selection=invert) == \ - random.clean(selection=selection_inverse,invert_selection=not invert) + def test_clean_invert(self,default,selection,invert): + selection_inverse = set(default.material.flatten()) - set(selection) + assert default.clean(selection=selection,invert_selection=invert,rng_seed=0) == \ + default.clean(selection=selection_inverse,invert_selection=not invert,rng_seed=0) def test_clean_selection_empty(self,random): - assert random.clean(selection=[],invert_selection=False) == random and \ - random.clean(selection=[],invert_selection=True) == random.clean() + assert random.clean(selection=None,invert_selection=True,rng_seed=0) == random.clean(rng_seed=0) and \ + random.clean(selection=None,invert_selection=False,rng_seed=0) == random.clean(rng_seed=0) @pytest.mark.parametrize('cells',[ @@ -329,20 +327,20 @@ class TestGrid: @pytest.mark.parametrize('selection',[1,None]) def test_vicinity_offset(self,selection): offset = np.random.randint(2,4) - vicinity = np.random.randint(2,4) + distance = np.random.randint(2,4) g = np.random.randint(28,40,(3)) m = np.ones(g,'i') - x = (g*np.random.permutation(np.array([.5,1,1]))).astype('i') + x = (g*np.random.permutation(np.array([.5,1,1]))).astype(int) m[slice(0,x[0]),slice(0,x[1]),slice(0,x[2])] = 2 m2 = m.copy() for i in [0,1,2]: - m2[(np.roll(m,+vicinity,i)-m)!=0] += offset - m2[(np.roll(m,-vicinity,i)-m)!=0] += offset + m2[(np.roll(m,+distance,i)-m)!=0] += offset + m2[(np.roll(m,-distance,i)-m)!=0] += offset if selection == 1: m2[m==1] = 1 - grid = Grid(m,np.random.rand(3)).vicinity_offset(vicinity,offset,selection=selection) + grid = Grid(m,np.random.rand(3)).vicinity_offset(distance,offset,selection=selection) assert np.all(m2==grid.material) diff --git a/python/tests/test_util.py b/python/tests/test_util.py index ee345605f..671654ee0 100644 --- a/python/tests/test_util.py +++ b/python/tests/test_util.py @@ -117,6 +117,10 @@ class TestUtil: def test_decorate(self,style): assert 'DAMASK' in style('DAMASK') + @pytest.mark.parametrize('lst',[1,[1,2],set([1,2,3]),np.arange(4)]) + def test_aslist(self,lst): + assert len(util.aslist(lst)) > 0 + @pytest.mark.parametrize('complete',[True,False]) def test_D3D_base_group(self,tmp_path,complete): base_group = ''.join(random.choices('DAMASK', k=10))