2022-03-27 02:38:09 +05:30
|
|
|
import sys
|
|
|
|
|
2019-11-23 17:29:41 +05:30
|
|
|
import pytest
|
|
|
|
import numpy as np
|
2023-03-08 23:33:22 +05:30
|
|
|
from vtkmodules.vtkCommonCore import vtkVersion
|
2019-11-23 17:29:41 +05:30
|
|
|
|
2020-08-23 12:47:08 +05:30
|
|
|
from damask import VTK
|
2020-12-04 11:42:18 +05:30
|
|
|
from damask import Grid
|
2020-10-29 12:12:41 +05:30
|
|
|
from damask import Table
|
2020-05-25 00:22:19 +05:30
|
|
|
from damask import Rotation
|
2022-03-08 20:01:08 +05:30
|
|
|
from damask import Colormap
|
2020-06-25 01:04:51 +05:30
|
|
|
from damask import util
|
2020-11-01 01:16:21 +05:30
|
|
|
from damask import seeds
|
2020-10-29 12:12:41 +05:30
|
|
|
from damask import grid_filters
|
2019-11-23 17:29:41 +05:30
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture
|
|
|
|
def default():
|
|
|
|
"""Simple geometry."""
|
2022-12-14 00:02:19 +05:30
|
|
|
g = np.array([8,5,4])
|
|
|
|
l = np.prod(g[:2])
|
|
|
|
return Grid(np.concatenate((np.ones (l,dtype=int),
|
|
|
|
np.arange(l,dtype=int)+2,
|
|
|
|
np.ones (l,dtype=int)*2,
|
|
|
|
np.arange(l,dtype=int)+1)).reshape(g,order='F'),
|
|
|
|
g*1e-6)
|
2019-11-23 17:29:41 +05:30
|
|
|
|
2022-03-04 15:09:02 +05:30
|
|
|
@pytest.fixture
|
|
|
|
def random():
|
|
|
|
"""Simple geometry."""
|
|
|
|
size = (1+np.random.rand(3))*1e-5
|
|
|
|
cells = np.random.randint(10,20,3)
|
|
|
|
s = seeds.from_random(size,np.random.randint(5,25),cells)
|
|
|
|
return Grid.from_Voronoi_tessellation(cells,size,s)
|
|
|
|
|
2019-11-23 17:29:41 +05:30
|
|
|
@pytest.fixture
|
2023-04-24 10:41:14 +05:30
|
|
|
def res_path(res_path_base):
|
|
|
|
"""Directory containing testing resources."""
|
|
|
|
return res_path_base/'Grid'
|
2019-11-23 17:29:41 +05:30
|
|
|
|
|
|
|
|
2020-12-04 11:42:18 +05:30
|
|
|
class TestGrid:
|
2020-03-29 23:37:09 +05:30
|
|
|
|
2020-10-10 13:11:11 +05:30
|
|
|
@pytest.fixture(autouse=True)
|
2020-11-15 16:19:52 +05:30
|
|
|
def _patch_execution_stamp(self, patch_execution_stamp):
|
2020-10-10 13:11:11 +05:30
|
|
|
print('patched damask.util.execution_stamp')
|
|
|
|
|
2020-11-30 01:20:41 +05:30
|
|
|
@pytest.fixture(autouse=True)
|
|
|
|
def _patch_datetime_now(self, patch_datetime_now):
|
|
|
|
print('patched datetime.datetime.now')
|
|
|
|
|
2020-08-25 04:29:41 +05:30
|
|
|
|
2022-03-09 03:13:54 +05:30
|
|
|
@pytest.mark.parametrize('cmap',[Colormap.from_predefined('stress'),'viridis'])
|
2022-03-27 02:38:09 +05:30
|
|
|
@pytest.mark.skipif(sys.platform == 'win32', reason='DISPLAY has no effect on windows')
|
2022-03-08 20:01:08 +05:30
|
|
|
def test_show(sef,default,cmap,monkeypatch):
|
2022-02-22 18:30:36 +05:30
|
|
|
monkeypatch.delenv('DISPLAY',raising=False)
|
2022-03-08 20:01:08 +05:30
|
|
|
default.show(cmap)
|
2022-02-22 18:30:36 +05:30
|
|
|
|
2021-04-06 21:40:35 +05:30
|
|
|
def test_equal(self,default):
|
|
|
|
assert default == default
|
2022-01-15 17:52:15 +05:30
|
|
|
assert not default == 42
|
2020-08-25 04:29:41 +05:30
|
|
|
|
2020-11-14 22:24:47 +05:30
|
|
|
def test_repr(self,default):
|
|
|
|
print(default)
|
2019-11-23 17:29:41 +05:30
|
|
|
|
2022-03-12 06:37:18 +05:30
|
|
|
def test_read_write_vti(self,default,tmp_path):
|
2020-09-29 22:55:50 +05:30
|
|
|
default.save(tmp_path/'default')
|
2021-06-15 20:32:02 +05:30
|
|
|
new = Grid.load(tmp_path/'default.vti')
|
2022-03-12 02:52:12 +05:30
|
|
|
assert new == default
|
2020-08-23 12:19:49 +05:30
|
|
|
|
2020-12-11 01:23:11 +05:30
|
|
|
def test_invalid_no_material(self,tmp_path):
|
2021-06-15 20:32:02 +05:30
|
|
|
v = VTK.from_image_data(np.random.randint(5,10,3)*2,np.random.random(3) + 1.0)
|
|
|
|
v.save(tmp_path/'no_materialpoint.vti',parallel=False)
|
2022-03-07 15:58:17 +05:30
|
|
|
with pytest.raises(KeyError):
|
2021-06-15 20:32:02 +05:30
|
|
|
Grid.load(tmp_path/'no_materialpoint.vti')
|
2020-12-11 01:23:11 +05:30
|
|
|
|
|
|
|
def test_invalid_material_type(self):
|
2020-09-25 02:29:31 +05:30
|
|
|
with pytest.raises(TypeError):
|
2020-12-04 11:42:18 +05:30
|
|
|
Grid(np.zeros((3,3,3),dtype='complex'),np.ones(3))
|
2020-09-25 02:29:31 +05:30
|
|
|
|
|
|
|
def test_cast_to_int(self):
|
2020-12-04 11:42:18 +05:30
|
|
|
g = Grid(np.zeros((3,3,3)),np.ones(3))
|
2020-09-25 02:29:31 +05:30
|
|
|
assert g.material.dtype in np.sctypes['int']
|
2020-08-09 00:05:50 +05:30
|
|
|
|
2020-05-25 02:22:00 +05:30
|
|
|
def test_invalid_size(self,default):
|
|
|
|
with pytest.raises(ValueError):
|
2020-12-04 11:42:18 +05:30
|
|
|
Grid(default.material[1:,1:,1:],
|
2020-09-23 00:17:08 +05:30
|
|
|
size=np.ones(2))
|
|
|
|
|
2020-11-14 22:24:47 +05:30
|
|
|
def test_save_load_ASCII(self,default,tmp_path):
|
|
|
|
default.save_ASCII(tmp_path/'ASCII')
|
2020-11-18 21:15:54 +05:30
|
|
|
default.material -= 1
|
2022-03-12 02:52:12 +05:30
|
|
|
assert Grid.load_ASCII(tmp_path/'ASCII') == default
|
2020-05-25 02:22:00 +05:30
|
|
|
|
2020-08-08 23:12:34 +05:30
|
|
|
def test_invalid_origin(self,default):
|
2020-05-25 02:22:00 +05:30
|
|
|
with pytest.raises(ValueError):
|
2020-12-04 11:42:18 +05:30
|
|
|
Grid(default.material[1:,1:,1:],
|
2020-09-23 00:17:08 +05:30
|
|
|
size=np.ones(3),
|
|
|
|
origin=np.ones(4))
|
|
|
|
|
|
|
|
def test_invalid_materials_shape(self,default):
|
2020-09-24 02:57:15 +05:30
|
|
|
material = np.ones((3,3))
|
2020-08-08 23:12:34 +05:30
|
|
|
with pytest.raises(ValueError):
|
2020-12-04 11:42:18 +05:30
|
|
|
Grid(material,
|
2020-09-23 00:17:08 +05:30
|
|
|
size=np.ones(3))
|
2020-08-08 23:12:34 +05:30
|
|
|
|
2020-09-23 00:17:08 +05:30
|
|
|
def test_invalid_materials_type(self,default):
|
2020-09-24 02:57:15 +05:30
|
|
|
material = np.random.randint(1,300,(3,4,5))==1
|
2020-05-25 02:22:00 +05:30
|
|
|
with pytest.raises(TypeError):
|
2020-12-04 11:42:18 +05:30
|
|
|
Grid(material)
|
2020-09-23 00:17:08 +05:30
|
|
|
|
2019-11-23 18:32:59 +05:30
|
|
|
@pytest.mark.parametrize('directions,reflect',[
|
2019-11-25 18:31:40 +05:30
|
|
|
(['x'], False),
|
|
|
|
(['x','y','z'],True),
|
|
|
|
(['z','x','y'],False),
|
|
|
|
(['y','z'], False)
|
|
|
|
]
|
|
|
|
)
|
2023-04-24 10:41:14 +05:30
|
|
|
def test_mirror(self,default,update,res_path,directions,reflect):
|
2020-08-24 04:16:01 +05:30
|
|
|
modified = default.mirror(directions,reflect)
|
2020-10-10 13:11:11 +05:30
|
|
|
tag = f'directions_{"-".join(directions)}+reflect_{reflect}'
|
2023-04-24 10:41:14 +05:30
|
|
|
reference = res_path/f'mirror_{tag}.vti'
|
2020-10-10 13:11:11 +05:30
|
|
|
if update: modified.save(reference)
|
2022-03-12 02:52:12 +05:30
|
|
|
assert Grid.load(reference) == modified
|
2019-11-23 18:32:59 +05:30
|
|
|
|
2020-08-23 14:35:56 +05:30
|
|
|
@pytest.mark.parametrize('directions',[(1,2,'y'),('a','b','x'),[1]])
|
|
|
|
def test_mirror_invalid(self,default,directions):
|
|
|
|
with pytest.raises(ValueError):
|
|
|
|
default.mirror(directions)
|
|
|
|
|
2023-02-21 20:57:06 +05:30
|
|
|
@pytest.mark.parametrize('reflect',[True,False])
|
|
|
|
def test_mirror_order_invariant(self,default,reflect):
|
|
|
|
direction = np.array(['x','y','z'])
|
|
|
|
assert default.mirror(np.random.permutation(direction),reflect=reflect) \
|
|
|
|
== default.mirror(np.random.permutation(direction),reflect=reflect)
|
2020-08-25 04:29:41 +05:30
|
|
|
|
2020-08-24 04:16:01 +05:30
|
|
|
@pytest.mark.parametrize('directions',[
|
|
|
|
['x'],
|
|
|
|
['x','y','z'],
|
|
|
|
['z','x','y'],
|
|
|
|
['y','z'],
|
|
|
|
]
|
|
|
|
)
|
2023-04-24 10:41:14 +05:30
|
|
|
def test_flip(self,default,update,res_path,directions):
|
2020-08-24 04:16:01 +05:30
|
|
|
modified = default.flip(directions)
|
2020-10-10 13:11:11 +05:30
|
|
|
tag = f'directions_{"-".join(directions)}'
|
2023-04-24 10:41:14 +05:30
|
|
|
reference = res_path/f'flip_{tag}.vti'
|
2020-10-10 13:11:11 +05:30
|
|
|
if update: modified.save(reference)
|
2022-03-12 02:52:12 +05:30
|
|
|
assert Grid.load(reference) == modified
|
2019-11-23 18:32:59 +05:30
|
|
|
|
2023-02-21 20:57:06 +05:30
|
|
|
def test_flip_order_invariant(self,default):
|
|
|
|
direction = np.array(['x','y','z'])
|
|
|
|
assert default.flip(np.random.permutation(direction)) \
|
|
|
|
== default.flip(np.random.permutation(direction))
|
2020-09-23 00:17:08 +05:30
|
|
|
|
2023-02-21 20:57:06 +05:30
|
|
|
def test_flip_mirrored_invariant(self,default):
|
|
|
|
direction = np.random.permutation(['x','y','z'])
|
|
|
|
assert default.mirror(direction,True) == default.mirror(direction,True).flip(direction)
|
2020-08-25 12:04:04 +05:30
|
|
|
|
2023-02-21 20:57:06 +05:30
|
|
|
def test_flip_equal_halfspin(self,default):
|
|
|
|
direction = ['x','y','z']
|
|
|
|
i = np.random.choice(3)
|
|
|
|
assert default.rotate(Rotation.from_axis_angle(np.hstack((np.identity(3)[i],180)),degrees=True)) \
|
|
|
|
== default.flip(direction[:i]+direction[i+1:])
|
2020-09-23 00:17:08 +05:30
|
|
|
|
2020-08-25 20:47:49 +05:30
|
|
|
@pytest.mark.parametrize('direction',[['x'],['x','y']])
|
|
|
|
def test_flip_double(self,default,direction):
|
2022-03-12 02:52:12 +05:30
|
|
|
assert default == default.flip(direction).flip(direction)
|
2020-08-25 20:47:49 +05:30
|
|
|
|
2020-08-23 14:35:56 +05:30
|
|
|
@pytest.mark.parametrize('directions',[(1,2,'y'),('a','b','x'),[1]])
|
2020-08-25 04:29:41 +05:30
|
|
|
def test_flip_invalid(self,default,directions):
|
2020-08-23 14:35:56 +05:30
|
|
|
with pytest.raises(ValueError):
|
2020-08-25 04:29:41 +05:30
|
|
|
default.flip(directions)
|
|
|
|
|
2022-03-10 04:54:05 +05:30
|
|
|
@pytest.mark.parametrize('distance',[1.,np.sqrt(3)])
|
|
|
|
@pytest.mark.parametrize('selection',[None,1,[1],[1,2,3]])
|
2020-08-23 14:16:15 +05:30
|
|
|
@pytest.mark.parametrize('periodic',[True,False])
|
2023-04-24 10:41:14 +05:30
|
|
|
def test_clean_reference(self,default,update,res_path,distance,selection,periodic):
|
2022-03-10 04:54:05 +05:30
|
|
|
current = default.clean(distance,selection,periodic=periodic,rng_seed=0)
|
2023-04-24 10:41:14 +05:30
|
|
|
reference = res_path/f'clean_{distance}_{util.srepr(selection,"+")}_{periodic}.vti'
|
2022-03-10 04:54:05 +05:30
|
|
|
if update:
|
2020-09-21 01:34:28 +05:30
|
|
|
current.save(reference)
|
2022-03-12 02:52:12 +05:30
|
|
|
assert Grid.load(reference) == current
|
2019-11-25 18:31:40 +05:30
|
|
|
|
2022-12-14 00:02:19 +05:30
|
|
|
@pytest.mark.parametrize('selection',[list(np.random.randint(1,20,6)),np.random.randint(1,20,6)])
|
2022-03-04 15:09:02 +05:30
|
|
|
@pytest.mark.parametrize('invert',[True,False])
|
2022-03-10 04:54:05 +05:30
|
|
|
def test_clean_invert(self,default,selection,invert):
|
2022-12-14 00:02:19 +05:30
|
|
|
selection_inverse = np.setdiff1d(default.material,selection)
|
2022-03-10 04:54:05 +05:30
|
|
|
assert default.clean(selection=selection,invert_selection=invert,rng_seed=0) == \
|
|
|
|
default.clean(selection=selection_inverse,invert_selection=not invert,rng_seed=0)
|
2020-09-23 00:17:08 +05:30
|
|
|
|
2022-03-06 01:07:47 +05:30
|
|
|
def test_clean_selection_empty(self,random):
|
2022-03-10 04:54:05 +05:30
|
|
|
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)
|
2022-03-06 01:07:47 +05:30
|
|
|
|
2020-12-04 02:28:24 +05:30
|
|
|
@pytest.mark.parametrize('cells',[
|
2020-03-31 14:35:25 +05:30
|
|
|
(10,11,10),
|
|
|
|
[10,13,10],
|
|
|
|
np.array((10,10,10)),
|
|
|
|
np.array((8, 10,12)),
|
|
|
|
np.array((5, 4, 20)),
|
|
|
|
np.array((10,20,2))
|
2019-11-25 18:31:40 +05:30
|
|
|
]
|
|
|
|
)
|
2023-04-24 10:41:14 +05:30
|
|
|
def test_scale(self,default,update,res_path,cells):
|
2020-12-04 02:28:24 +05:30
|
|
|
modified = default.scale(cells)
|
|
|
|
tag = f'grid_{util.srepr(cells,"-")}'
|
2023-04-24 10:41:14 +05:30
|
|
|
reference = res_path/f'scale_{tag}.vti'
|
2020-10-10 13:11:11 +05:30
|
|
|
if update: modified.save(reference)
|
2022-03-12 02:52:12 +05:30
|
|
|
assert Grid.load(reference) == modified
|
2020-03-29 22:42:23 +05:30
|
|
|
|
2020-05-25 00:22:19 +05:30
|
|
|
def test_renumber(self,default):
|
2020-09-24 02:57:15 +05:30
|
|
|
material = default.material.copy()
|
|
|
|
for m in np.unique(material):
|
|
|
|
material[material==m] = material.max() + np.random.randint(1,30)
|
2020-10-28 14:01:55 +05:30
|
|
|
default.material -= 1
|
2020-12-04 11:42:18 +05:30
|
|
|
modified = Grid(material,
|
2020-09-23 00:17:08 +05:30
|
|
|
default.size,
|
|
|
|
default.origin)
|
2022-03-12 02:52:12 +05:30
|
|
|
assert not default == modified
|
|
|
|
assert default == modified.renumber()
|
2020-05-25 00:22:19 +05:30
|
|
|
|
2022-11-09 00:22:08 +05:30
|
|
|
def test_assemble(self):
|
|
|
|
cells = np.random.randint(8,16,3)
|
|
|
|
N = cells.prod()
|
|
|
|
g = Grid(np.arange(N).reshape(cells),np.ones(3))
|
|
|
|
idx = np.random.randint(0,N,N).reshape(cells)
|
|
|
|
assert (idx == g.assemble(idx).material).all
|
|
|
|
|
2020-05-25 00:22:19 +05:30
|
|
|
def test_substitute(self,default):
|
|
|
|
offset = np.random.randint(1,500)
|
2020-12-04 11:42:18 +05:30
|
|
|
modified = Grid(default.material + offset,
|
2020-09-23 00:17:08 +05:30
|
|
|
default.size,
|
|
|
|
default.origin)
|
2022-03-12 02:52:12 +05:30
|
|
|
assert not default == modified
|
|
|
|
assert default == modified.substitute(np.arange(default.material.max())+1+offset,
|
|
|
|
np.arange(default.material.max())+1)
|
2020-09-23 00:17:08 +05:30
|
|
|
|
2022-03-04 15:09:02 +05:30
|
|
|
def test_substitute_integer_list(self,random):
|
|
|
|
f = np.random.randint(30)
|
|
|
|
t = np.random.randint(30)
|
|
|
|
assert random.substitute(f,t) == random.substitute([f],[t])
|
|
|
|
|
2020-10-28 19:09:41 +05:30
|
|
|
def test_substitute_invariant(self,default):
|
|
|
|
f = np.unique(default.material.flatten())[:np.random.randint(1,default.material.max())]
|
|
|
|
t = np.random.permutation(f)
|
|
|
|
modified = default.substitute(f,t)
|
2022-03-12 02:52:12 +05:30
|
|
|
assert np.array_equiv(t,f) or modified != default
|
|
|
|
assert default == modified.substitute(t,f)
|
2020-10-28 19:09:41 +05:30
|
|
|
|
2020-11-01 01:16:21 +05:30
|
|
|
def test_sort(self):
|
2020-12-04 02:28:24 +05:30
|
|
|
cells = np.random.randint(5,20,3)
|
2020-12-04 11:42:18 +05:30
|
|
|
m = Grid(np.random.randint(1,20,cells)*3,np.ones(3)).sort().material.flatten(order='F')
|
2020-11-03 04:51:51 +05:30
|
|
|
for i,v in enumerate(m):
|
2020-11-03 05:01:37 +05:30
|
|
|
assert i==0 or v > m[:i].max() or v in m[:i]
|
2020-05-25 00:22:19 +05:30
|
|
|
|
|
|
|
@pytest.mark.parametrize('axis_angle',[np.array([1,0,0,86.7]), np.array([0,1,0,90.4]), np.array([0,0,1,90]),
|
|
|
|
np.array([1,0,0,175]),np.array([0,-1,0,178]),np.array([0,0,1,180])])
|
2020-05-25 02:22:00 +05:30
|
|
|
def test_rotate360(self,default,axis_angle):
|
2020-08-22 23:25:18 +05:30
|
|
|
modified = default.copy()
|
2020-05-25 00:22:19 +05:30
|
|
|
for i in range(np.rint(360/axis_angle[3]).astype(int)):
|
|
|
|
modified.rotate(Rotation.from_axis_angle(axis_angle,degrees=True))
|
2022-03-12 02:52:12 +05:30
|
|
|
assert default == modified
|
2020-05-25 00:22:19 +05:30
|
|
|
|
|
|
|
@pytest.mark.parametrize('Eulers',[[32.0,68.0,21.0],
|
|
|
|
[0.0,32.0,240.0]])
|
2023-04-24 10:41:14 +05:30
|
|
|
def test_rotate(self,default,update,res_path,Eulers):
|
2020-11-18 03:26:22 +05:30
|
|
|
modified = default.rotate(Rotation.from_Euler_angles(Eulers,degrees=True))
|
2020-10-10 13:11:11 +05:30
|
|
|
tag = f'Eulers_{util.srepr(Eulers,"-")}'
|
2023-04-24 10:41:14 +05:30
|
|
|
reference = res_path/f'rotate_{tag}.vti'
|
2020-10-10 13:11:11 +05:30
|
|
|
if update: modified.save(reference)
|
2022-03-12 02:52:12 +05:30
|
|
|
assert Grid.load(reference) == modified
|
2020-05-25 00:22:19 +05:30
|
|
|
|
2022-01-13 01:04:29 +05:30
|
|
|
def test_canvas_extend(self,default):
|
2020-12-04 02:28:24 +05:30
|
|
|
cells = default.cells
|
2022-01-13 01:04:29 +05:30
|
|
|
cells_add = np.random.randint(0,30,(3))
|
|
|
|
modified = default.canvas(cells + cells_add)
|
2020-12-04 02:28:24 +05:30
|
|
|
assert np.all(modified.material[:cells[0],:cells[1],:cells[2]] == default.material)
|
2020-09-23 00:17:08 +05:30
|
|
|
|
2022-01-13 01:04:29 +05:30
|
|
|
@pytest.mark.parametrize('sign',[+1,-1])
|
|
|
|
@pytest.mark.parametrize('extra_offset',[0,-1])
|
|
|
|
def test_canvas_move_out(self,sign,extra_offset):
|
|
|
|
g = Grid(np.zeros(np.random.randint(3,30,(3)),int),np.ones(3))
|
|
|
|
o = sign*np.ones(3)*g.cells.min() +extra_offset*sign
|
|
|
|
if extra_offset == 0:
|
|
|
|
assert np.all(g.canvas(offset=o).material == 1)
|
|
|
|
else:
|
|
|
|
assert np.all(np.unique(g.canvas(offset=o).material) == (0,1))
|
|
|
|
|
|
|
|
def test_canvas_cells(self,default):
|
|
|
|
g = Grid(np.zeros(np.random.randint(3,30,(3)),int),np.ones(3))
|
|
|
|
cells = np.random.randint(1,30,(3))
|
|
|
|
offset = np.random.randint(-30,30,(3))
|
|
|
|
assert np.all(g.canvas(cells,offset).cells == cells)
|
2020-08-09 00:05:50 +05:30
|
|
|
|
2020-08-27 03:26:20 +05:30
|
|
|
@pytest.mark.parametrize('center1,center2',[(np.random.random(3)*.5,np.random.random()*8),
|
2020-08-10 02:44:32 +05:30
|
|
|
(np.random.randint(4,8,(3)),np.random.randint(9,12,(3)))])
|
2020-08-22 23:25:18 +05:30
|
|
|
@pytest.mark.parametrize('diameter',[np.random.random(3)*.5,
|
2020-08-27 03:26:20 +05:30
|
|
|
np.random.randint(4,10,(3)),
|
|
|
|
np.random.rand(),
|
|
|
|
np.random.randint(30)])
|
|
|
|
@pytest.mark.parametrize('exponent',[np.random.random(3)*.5,
|
|
|
|
np.random.randint(4,10,(3)),
|
|
|
|
np.random.rand()*4,
|
|
|
|
np.random.randint(20)])
|
2020-08-27 13:03:09 +05:30
|
|
|
def test_add_primitive_shift(self,center1,center2,diameter,exponent):
|
2020-09-23 00:17:08 +05:30
|
|
|
"""Same volume fraction for periodic geometries and different center."""
|
2020-08-22 23:25:18 +05:30
|
|
|
o = np.random.random(3)-.5
|
|
|
|
g = np.random.randint(8,32,(3))
|
|
|
|
s = np.random.random(3)+.5
|
2020-12-04 11:42:18 +05:30
|
|
|
G_1 = Grid(np.ones(g,'i'),s,o).add_primitive(diameter,center1,exponent)
|
|
|
|
G_2 = Grid(np.ones(g,'i'),s,o).add_primitive(diameter,center2,exponent)
|
2020-09-24 02:57:15 +05:30
|
|
|
assert np.count_nonzero(G_1.material!=2) == np.count_nonzero(G_2.material!=2)
|
2020-09-23 00:17:08 +05:30
|
|
|
|
2020-08-27 03:26:20 +05:30
|
|
|
@pytest.mark.parametrize('center',[np.random.randint(4,10,(3)),
|
|
|
|
np.random.randint(2,10),
|
|
|
|
np.random.rand()*4,
|
|
|
|
np.random.rand(3)*10])
|
|
|
|
@pytest.mark.parametrize('inverse',[True,False])
|
|
|
|
@pytest.mark.parametrize('periodic',[True,False])
|
|
|
|
def test_add_primitive_rotation(self,center,inverse,periodic):
|
2020-11-13 11:20:57 +05:30
|
|
|
"""Rotation should not change result for sphere."""
|
|
|
|
g = np.random.randint(8,32,(3))
|
|
|
|
s = np.random.random(3)+.5
|
2020-08-27 03:26:20 +05:30
|
|
|
fill = np.random.randint(10)+2
|
2020-12-04 11:42:18 +05:30
|
|
|
G_1 = Grid(np.ones(g,'i'),s).add_primitive(.3,center,1,fill,inverse=inverse,periodic=periodic)
|
|
|
|
G_2 = Grid(np.ones(g,'i'),s).add_primitive(.3,center,1,fill,Rotation.from_random(),inverse,periodic=periodic)
|
2022-03-12 02:52:12 +05:30
|
|
|
assert G_1 == G_2
|
2020-08-27 03:26:20 +05:30
|
|
|
|
2022-08-29 17:14:50 +05:30
|
|
|
@pytest.mark.parametrize('exponent',[1,np.inf,np.random.random(3)*2.])
|
|
|
|
def test_add_primitive_shape_symmetry(self,exponent):
|
|
|
|
"""Shapes defined in the center should always produce a grid with reflection symmetry along the coordinate axis."""
|
|
|
|
o = np.random.random(3)-.5
|
|
|
|
s = np.random.random(3)*5.
|
|
|
|
grid = Grid(np.zeros(np.random.randint(8,32,3),'i'),s,o).add_primitive(np.random.random(3)*3.,o+s/2.,exponent)
|
|
|
|
for axis in [0,1,2]:
|
|
|
|
assert np.all(grid.material==np.flip(grid.material,axis=axis))
|
2020-09-23 00:17:08 +05:30
|
|
|
|
2022-03-06 01:07:47 +05:30
|
|
|
@pytest.mark.parametrize('selection',[1,None])
|
2022-02-27 20:46:09 +05:30
|
|
|
def test_vicinity_offset(self,selection):
|
2020-08-08 23:12:34 +05:30
|
|
|
offset = np.random.randint(2,4)
|
2022-03-10 04:54:05 +05:30
|
|
|
distance = np.random.randint(2,4)
|
2020-08-09 00:05:50 +05:30
|
|
|
|
2020-08-10 02:44:32 +05:30
|
|
|
g = np.random.randint(28,40,(3))
|
|
|
|
m = np.ones(g,'i')
|
2022-03-10 04:54:05 +05:30
|
|
|
x = (g*np.random.permutation(np.array([.5,1,1]))).astype(int)
|
2020-08-10 02:44:32 +05:30
|
|
|
m[slice(0,x[0]),slice(0,x[1]),slice(0,x[2])] = 2
|
2020-08-22 23:25:18 +05:30
|
|
|
m2 = m.copy()
|
2020-08-08 23:12:34 +05:30
|
|
|
for i in [0,1,2]:
|
2022-03-10 04:54:05 +05:30
|
|
|
m2[(np.roll(m,+distance,i)-m)!=0] += offset
|
|
|
|
m2[(np.roll(m,-distance,i)-m)!=0] += offset
|
2022-03-04 15:09:02 +05:30
|
|
|
if selection == 1:
|
2020-08-10 02:44:32 +05:30
|
|
|
m2[m==1] = 1
|
2020-08-09 00:05:50 +05:30
|
|
|
|
2022-03-10 04:54:05 +05:30
|
|
|
grid = Grid(m,np.random.rand(3)).vicinity_offset(distance,offset,selection=selection)
|
2020-08-09 00:05:50 +05:30
|
|
|
|
2020-12-04 11:42:18 +05:30
|
|
|
assert np.all(m2==grid.material)
|
2020-09-23 00:17:08 +05:30
|
|
|
|
2022-12-14 00:02:19 +05:30
|
|
|
@pytest.mark.parametrize('selection',[list(np.random.randint(1,20,6)),np.random.randint(1,20,6)])
|
2022-03-04 15:09:02 +05:30
|
|
|
@pytest.mark.parametrize('invert',[True,False])
|
2022-03-12 02:52:12 +05:30
|
|
|
def test_vicinity_offset_invert(self,random,selection,invert):
|
2022-12-14 00:02:19 +05:30
|
|
|
selection_inverse = np.setdiff1d(random.material,selection)
|
2022-03-12 02:52:12 +05:30
|
|
|
assert random.vicinity_offset(selection=selection ,invert_selection=not invert) == \
|
|
|
|
random.vicinity_offset(selection=selection_inverse,invert_selection= invert)
|
2022-03-04 15:09:02 +05:30
|
|
|
|
2022-03-06 01:07:47 +05:30
|
|
|
def test_vicinity_offset_selection_empty(self,random):
|
2022-03-10 05:31:45 +05:30
|
|
|
assert random.vicinity_offset(selection=None,invert_selection=False) == random.vicinity_offset() and \
|
|
|
|
random.vicinity_offset(selection=None,invert_selection=True ) == random.vicinity_offset()
|
2022-03-06 01:07:47 +05:30
|
|
|
|
2020-08-08 23:12:34 +05:30
|
|
|
@pytest.mark.parametrize('periodic',[True,False])
|
|
|
|
def test_vicinity_offset_invariant(self,default,periodic):
|
2022-02-27 20:46:09 +05:30
|
|
|
offset = default.vicinity_offset(selection=[default.material.max()+1,
|
2022-03-04 15:09:02 +05:30
|
|
|
default.material.min()-1])
|
2020-09-24 02:57:15 +05:30
|
|
|
assert np.all(offset.material==default.material)
|
2020-09-23 00:17:08 +05:30
|
|
|
|
2020-03-31 14:35:25 +05:30
|
|
|
@pytest.mark.parametrize('periodic',[True,False])
|
2020-03-29 23:58:54 +05:30
|
|
|
def test_tessellation_approaches(self,periodic):
|
2020-12-04 02:28:24 +05:30
|
|
|
cells = np.random.randint(10,20,3)
|
2020-03-29 22:42:23 +05:30
|
|
|
size = np.random.random(3) + 1.0
|
|
|
|
N_seeds= np.random.randint(10,30)
|
|
|
|
seeds = np.random.rand(N_seeds,3) * np.broadcast_to(size,(N_seeds,3))
|
2020-12-04 11:42:18 +05:30
|
|
|
Voronoi = Grid.from_Voronoi_tessellation( cells,size,seeds, np.arange(N_seeds)+5,periodic)
|
|
|
|
Laguerre = Grid.from_Laguerre_tessellation(cells,size,seeds,np.ones(N_seeds),np.arange(N_seeds)+5,periodic)
|
2022-03-12 02:52:12 +05:30
|
|
|
assert Laguerre == Voronoi
|
2020-03-29 22:42:23 +05:30
|
|
|
|
2020-03-29 23:58:54 +05:30
|
|
|
def test_Laguerre_weights(self):
|
2020-12-04 02:28:24 +05:30
|
|
|
cells = np.random.randint(10,20,3)
|
2020-03-29 22:42:23 +05:30
|
|
|
size = np.random.random(3) + 1.0
|
|
|
|
N_seeds= np.random.randint(10,30)
|
|
|
|
seeds = np.random.rand(N_seeds,3) * np.broadcast_to(size,(N_seeds,3))
|
|
|
|
weights= np.full((N_seeds),-np.inf)
|
2020-10-10 13:27:18 +05:30
|
|
|
ms = np.random.randint(N_seeds)
|
|
|
|
weights[ms] = np.random.random()
|
2020-12-04 11:42:18 +05:30
|
|
|
Laguerre = Grid.from_Laguerre_tessellation(cells,size,seeds,weights,periodic=np.random.random()>0.5)
|
2020-09-24 02:57:15 +05:30
|
|
|
assert np.all(Laguerre.material == ms)
|
2020-09-23 00:17:08 +05:30
|
|
|
|
2020-03-31 14:35:25 +05:30
|
|
|
@pytest.mark.parametrize('approach',['Laguerre','Voronoi'])
|
2020-03-29 23:58:54 +05:30
|
|
|
def test_tessellate_bicrystal(self,approach):
|
2020-12-04 02:28:24 +05:30
|
|
|
cells = np.random.randint(5,10,3)*2
|
2021-02-22 13:05:15 +05:30
|
|
|
size = cells.astype(float)
|
2020-03-29 23:58:54 +05:30
|
|
|
seeds = np.vstack((size*np.array([0.5,0.25,0.5]),size*np.array([0.5,0.75,0.5])))
|
2020-12-04 02:28:24 +05:30
|
|
|
material = np.zeros(cells)
|
|
|
|
material[:,cells[1]//2:,:] = 1
|
2020-03-29 23:58:54 +05:30
|
|
|
if approach == 'Laguerre':
|
2020-12-04 11:42:18 +05:30
|
|
|
grid = Grid.from_Laguerre_tessellation(cells,size,seeds,np.ones(2),periodic=np.random.random()>0.5)
|
2020-03-29 23:58:54 +05:30
|
|
|
elif approach == 'Voronoi':
|
2020-12-04 11:42:18 +05:30
|
|
|
grid = Grid.from_Voronoi_tessellation(cells,size,seeds, periodic=np.random.random()>0.5)
|
|
|
|
assert np.all(grid.material == material)
|
2020-09-30 10:40:15 +05:30
|
|
|
|
2020-10-01 02:57:49 +05:30
|
|
|
@pytest.mark.parametrize('surface',['Schwarz P',
|
|
|
|
'Double Primitive',
|
|
|
|
'Schwarz D',
|
|
|
|
'Complementary D',
|
|
|
|
'Double Diamond',
|
|
|
|
'Dprime',
|
|
|
|
'Gyroid',
|
|
|
|
'Gprime',
|
|
|
|
'Karcher K',
|
|
|
|
'Lidinoid',
|
|
|
|
'Neovius',
|
|
|
|
'Fisher-Koch S',
|
|
|
|
])
|
2020-09-30 10:40:15 +05:30
|
|
|
def test_minimal_surface_basic_properties(self,surface):
|
2020-12-04 02:28:24 +05:30
|
|
|
cells = np.random.randint(60,100,3)
|
|
|
|
size = np.ones(3)+np.random.rand(3)
|
2020-10-02 16:56:11 +05:30
|
|
|
threshold = 2*np.random.rand()-1.
|
2020-09-30 10:40:15 +05:30
|
|
|
periods = np.random.randint(2)+1
|
|
|
|
materials = np.random.randint(0,40,2)
|
2020-12-04 11:42:18 +05:30
|
|
|
grid = Grid.from_minimal_surface(cells,size,surface,threshold,periods,materials)
|
|
|
|
assert set(grid.material.flatten()) | set(materials) == set(materials) \
|
|
|
|
and (grid.size == size).all() and (grid.cells == cells).all()
|
2020-09-30 10:40:15 +05:30
|
|
|
|
2020-10-01 02:57:49 +05:30
|
|
|
@pytest.mark.parametrize('surface,threshold',[('Schwarz P',0),
|
|
|
|
('Double Primitive',-1./6.),
|
|
|
|
('Schwarz D',0),
|
|
|
|
('Complementary D',0),
|
|
|
|
('Double Diamond',-0.133),
|
|
|
|
('Dprime',-0.0395),
|
|
|
|
('Gyroid',0),
|
|
|
|
('Gprime',0.22913),
|
|
|
|
('Karcher K',0.17045),
|
|
|
|
('Lidinoid',0.14455),
|
|
|
|
('Neovius',0),
|
|
|
|
('Fisher-Koch S',0),
|
|
|
|
])
|
|
|
|
def test_minimal_surface_volume(self,surface,threshold):
|
2020-12-04 02:28:24 +05:30
|
|
|
cells = np.ones(3,dtype=int)*64
|
2020-12-04 11:42:18 +05:30
|
|
|
grid = Grid.from_minimal_surface(cells,np.ones(3),surface,threshold)
|
|
|
|
assert np.isclose(np.count_nonzero(grid.material==1)/np.prod(grid.cells),.5,rtol=1e-3)
|
2020-11-25 17:21:52 +05:30
|
|
|
|
2020-10-29 12:12:41 +05:30
|
|
|
def test_from_table(self):
|
2020-12-04 02:28:24 +05:30
|
|
|
cells = np.random.randint(60,100,3)
|
2020-10-29 12:12:41 +05:30
|
|
|
size = np.ones(3)+np.random.rand(3)
|
2020-12-04 03:30:49 +05:30
|
|
|
coords = grid_filters.coordinates0_point(cells,size).reshape(-1,3,order='F')
|
2022-03-12 03:01:35 +05:30
|
|
|
z = np.ones(cells.prod())
|
|
|
|
z[cells[:2].prod()*int(cells[2]/2):] = 0
|
|
|
|
t = Table({'coords':3,'z':1},np.column_stack((coords,z)))
|
2022-05-11 18:49:48 +05:30
|
|
|
t = t.set('indicator',t.get('coords')[:,0])
|
2021-04-01 00:00:07 +05:30
|
|
|
g = Grid.from_table(t,'coords',['indicator','z'])
|
2020-12-04 02:28:24 +05:30
|
|
|
assert g.N_materials == g.cells[0]*2 and (g.material[:,:,-1]-g.material[:,:,0] == cells[0]).all()
|
2020-11-01 01:16:21 +05:30
|
|
|
|
|
|
|
def test_from_table_recover(self,tmp_path):
|
2020-12-04 02:28:24 +05:30
|
|
|
cells = np.random.randint(60,100,3)
|
2020-11-01 01:16:21 +05:30
|
|
|
size = np.ones(3)+np.random.rand(3)
|
|
|
|
s = seeds.from_random(size,np.random.randint(60,100))
|
2020-12-04 11:42:18 +05:30
|
|
|
grid = Grid.from_Voronoi_tessellation(cells,size,s)
|
2020-12-04 03:30:49 +05:30
|
|
|
coords = grid_filters.coordinates0_point(cells,size)
|
2022-03-12 03:01:35 +05:30
|
|
|
t = Table({'c':3,'m':1},np.column_stack((coords.reshape(-1,3,order='F'),grid.material.flatten(order='F'))))
|
2022-03-12 02:52:12 +05:30
|
|
|
assert grid.sort().renumber() == Grid.from_table(t,'c',['m'])
|
2020-11-30 01:20:41 +05:30
|
|
|
|
2020-11-25 17:21:52 +05:30
|
|
|
@pytest.mark.parametrize('periodic',[True,False])
|
2020-11-30 01:20:41 +05:30
|
|
|
@pytest.mark.parametrize('direction',['x','y','z',['x','y'],'zy','xz',['x','y','z']])
|
2023-03-08 23:33:22 +05:30
|
|
|
@pytest.mark.xfail(vtkVersion.GetVTKMajorVersion()<8, reason='missing METADATA')
|
2023-04-24 10:41:14 +05:30
|
|
|
def test_get_grain_boundaries(self,update,res_path,periodic,direction):
|
|
|
|
grid = Grid.load(res_path/'get_grain_boundaries_8g12x15x20.vti')
|
2021-03-20 17:21:41 +05:30
|
|
|
current = grid.get_grain_boundaries(periodic,direction)
|
2020-11-30 01:20:41 +05:30
|
|
|
if update:
|
2023-04-24 10:41:14 +05:30
|
|
|
current.save(res_path/f'get_grain_boundaries_8g12x15x20_{direction}_{periodic}.vtu',parallel=False)
|
|
|
|
reference = VTK.load(res_path/f'get_grain_boundaries_8g12x15x20_{"".join(direction)}_{periodic}.vtu')
|
2020-11-30 01:20:41 +05:30
|
|
|
assert current.__repr__() == reference.__repr__()
|
2021-03-20 17:21:41 +05:30
|
|
|
|
2021-03-27 12:05:49 +05:30
|
|
|
@pytest.mark.parametrize('directions',[(1,2,'y'),('a','b','x'),[1]])
|
|
|
|
def test_get_grain_boundaries_invalid(self,default,directions):
|
|
|
|
with pytest.raises(ValueError):
|
|
|
|
default.get_grain_boundaries(directions=directions)
|
2021-03-20 17:21:41 +05:30
|
|
|
|
2023-04-24 10:41:14 +05:30
|
|
|
def test_load_DREAM3D(self,res_path):
|
|
|
|
grain = Grid.load_DREAM3D(res_path/'2phase_irregularGrid.dream3d','FeatureIds')
|
|
|
|
point = Grid.load_DREAM3D(res_path/'2phase_irregularGrid.dream3d')
|
2021-03-20 17:21:41 +05:30
|
|
|
|
|
|
|
assert np.allclose(grain.origin,point.origin) and \
|
|
|
|
np.allclose(grain.size,point.size) and \
|
|
|
|
(grain.sort().material == point.material+1).all()
|
2021-03-23 18:12:04 +05:30
|
|
|
|
2023-04-24 10:41:14 +05:30
|
|
|
def test_load_DREAM3D_reference(self,res_path,update):
|
|
|
|
current = Grid.load_DREAM3D(res_path/'measured.dream3d')
|
|
|
|
reference = Grid.load(res_path/'measured.vti')
|
2021-03-23 18:12:04 +05:30
|
|
|
if update:
|
2023-04-24 10:41:14 +05:30
|
|
|
current.save(res_path/'measured.vti')
|
2021-03-23 18:12:04 +05:30
|
|
|
|
2022-03-12 02:52:12 +05:30
|
|
|
assert current == reference
|
2021-06-16 02:49:08 +05:30
|
|
|
|
2023-04-24 10:41:14 +05:30
|
|
|
def test_load_Neper_reference(self,res_path,update):
|
2023-05-22 21:02:39 +05:30
|
|
|
current = Grid.load_Neper(res_path/'n10-id1_scaled.vtk').renumber()
|
2023-04-24 10:41:14 +05:30
|
|
|
reference = Grid.load(res_path/'n10-id1_scaled.vti')
|
2021-06-16 02:49:08 +05:30
|
|
|
if update:
|
2023-04-24 10:41:14 +05:30
|
|
|
current.save(res_path/'n10-id1_scaled.vti')
|
2021-06-16 02:49:08 +05:30
|
|
|
|
2022-03-12 02:52:12 +05:30
|
|
|
assert current == reference
|