2019-11-23 17:29:41 +05:30
|
|
|
import pytest
|
|
|
|
import numpy as np
|
|
|
|
|
|
|
|
from damask import Geom
|
2020-05-25 00:22:19 +05:30
|
|
|
from damask import Rotation
|
2020-06-25 01:04:51 +05:30
|
|
|
from damask import util
|
2019-11-23 17:29:41 +05:30
|
|
|
|
|
|
|
|
|
|
|
def geom_equal(a,b):
|
|
|
|
return np.all(a.get_microstructure() == b.get_microstructure()) and \
|
2020-05-25 00:22:19 +05:30
|
|
|
np.all(a.get_grid() == b.get_grid()) and \
|
|
|
|
np.allclose(a.get_size(), b.get_size())
|
2019-11-23 17:29:41 +05:30
|
|
|
|
|
|
|
@pytest.fixture
|
|
|
|
def default():
|
|
|
|
"""Simple geometry."""
|
|
|
|
x=np.concatenate((np.ones(40,dtype=int),
|
|
|
|
np.arange(2,42),
|
|
|
|
np.ones(40,dtype=int)*2,
|
2020-08-08 23:54:36 +05:30
|
|
|
np.arange(1,41))).reshape(8,5,4,order='F')
|
2019-11-23 17:29:41 +05:30
|
|
|
return Geom(x,[8e-6,5e-6,4e-6])
|
|
|
|
|
|
|
|
@pytest.fixture
|
|
|
|
def reference_dir(reference_dir_base):
|
2019-11-27 17:49:58 +05:30
|
|
|
"""Directory containing reference results."""
|
2020-07-31 20:34:14 +05:30
|
|
|
return reference_dir_base/'Geom'
|
2019-11-23 17:29:41 +05:30
|
|
|
|
|
|
|
|
|
|
|
class TestGeom:
|
2020-03-29 23:37:09 +05:30
|
|
|
|
2020-08-24 04:16:01 +05:30
|
|
|
@pytest.mark.parametrize('flavor',['plain','explicit'])
|
|
|
|
def test_duplicate(self,default,flavor):
|
|
|
|
if flavor == 'plain':
|
|
|
|
modified = default.duplicate()
|
|
|
|
elif flavor == 'explicit':
|
|
|
|
modified = default.duplicate(
|
|
|
|
default.get_microstructure(),
|
|
|
|
default.get_size(),
|
|
|
|
default.get_origin()
|
|
|
|
)
|
|
|
|
print(modified)
|
|
|
|
assert geom_equal(default,modified)
|
|
|
|
|
2019-11-23 17:29:41 +05:30
|
|
|
def test_update(self,default):
|
2020-08-22 23:25:18 +05:30
|
|
|
modified = default.copy()
|
2019-11-23 17:29:41 +05:30
|
|
|
modified.update(
|
|
|
|
default.get_microstructure(),
|
|
|
|
default.get_size(),
|
|
|
|
default.get_origin()
|
|
|
|
)
|
2020-05-25 02:22:00 +05:30
|
|
|
print(modified)
|
2020-08-24 04:16:01 +05:30
|
|
|
assert geom_equal(default,modified)
|
2019-11-23 17:29:41 +05:30
|
|
|
|
2020-08-08 22:11:47 +05:30
|
|
|
@pytest.mark.parametrize('masked',[True,False])
|
|
|
|
def test_set_microstructure(self,default,masked):
|
|
|
|
old = default.get_microstructure()
|
|
|
|
new = np.random.randint(200,size=default.grid)
|
2020-08-09 00:05:50 +05:30
|
|
|
default.set_microstructure(np.ma.MaskedArray(new,np.full_like(new,masked)))
|
2020-08-10 02:44:32 +05:30
|
|
|
assert np.all(default.microstructure==(old if masked else new))
|
2020-08-09 00:05:50 +05:30
|
|
|
|
2019-11-23 17:29:41 +05:30
|
|
|
|
|
|
|
def test_write_read_str(self,default,tmpdir):
|
2020-08-24 04:16:01 +05:30
|
|
|
default.to_file(tmpdir/'default.geom')
|
|
|
|
new = Geom.from_file(tmpdir/'default.geom')
|
|
|
|
assert geom_equal(default,new)
|
2019-11-23 17:29:41 +05:30
|
|
|
|
|
|
|
def test_write_read_file(self,default,tmpdir):
|
2020-08-24 04:16:01 +05:30
|
|
|
with open(tmpdir/'default.geom','w') as f:
|
2019-11-23 17:29:41 +05:30
|
|
|
default.to_file(f)
|
2020-08-24 04:16:01 +05:30
|
|
|
with open(tmpdir/'default.geom') as f:
|
2019-11-23 17:29:41 +05:30
|
|
|
new = Geom.from_file(f)
|
2020-08-24 04:16:01 +05:30
|
|
|
assert geom_equal(default,new)
|
2019-11-23 17:29:41 +05:30
|
|
|
|
2020-08-09 00:05:50 +05:30
|
|
|
def test_write_show(self,default,tmpdir):
|
2020-08-24 04:16:01 +05:30
|
|
|
with open(tmpdir/'str.geom','w') as f:
|
2020-08-09 00:05:50 +05:30
|
|
|
f.write(default.show())
|
2020-08-24 04:16:01 +05:30
|
|
|
with open(tmpdir/'str.geom') as f:
|
2020-08-09 00:05:50 +05:30
|
|
|
new = Geom.from_file(f)
|
2020-08-24 04:16:01 +05:30
|
|
|
assert geom_equal(default,new)
|
|
|
|
|
|
|
|
def test_export_import_vtk(self,default,tmpdir):
|
|
|
|
default.to_vtk(tmpdir/'default')
|
|
|
|
assert geom_equal(default,Geom.from_vtk(tmpdir/'default.vtr'))
|
2020-08-09 00:05:50 +05:30
|
|
|
|
|
|
|
|
2019-11-25 16:34:57 +05:30
|
|
|
@pytest.mark.parametrize('pack',[True,False])
|
|
|
|
def test_pack(self,default,tmpdir,pack):
|
2020-08-24 04:16:01 +05:30
|
|
|
default.to_file(tmpdir/'default.geom',pack=pack)
|
|
|
|
new = Geom.from_file(tmpdir/'default.geom')
|
2019-11-25 13:58:59 +05:30
|
|
|
assert geom_equal(new,default)
|
|
|
|
|
2020-05-25 02:22:00 +05:30
|
|
|
def test_invalid_combination(self,default):
|
|
|
|
with pytest.raises(ValueError):
|
2020-08-24 04:16:01 +05:30
|
|
|
default.update(default.microstructure[1:,1:,1:],size=np.ones(3), autosize=True)
|
2020-05-25 02:22:00 +05:30
|
|
|
|
|
|
|
def test_invalid_size(self,default):
|
|
|
|
with pytest.raises(ValueError):
|
|
|
|
default.update(default.microstructure[1:,1:,1:],size=np.ones(2))
|
|
|
|
|
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-08-08 23:12:34 +05:30
|
|
|
default.update(default.microstructure[1:,1:,1:],origin=np.ones(4))
|
|
|
|
|
|
|
|
def test_invalid_microstructure_size(self,default):
|
2020-08-22 23:25:18 +05:30
|
|
|
microstructure = np.ones((3,3))
|
2020-08-08 23:12:34 +05:30
|
|
|
with pytest.raises(ValueError):
|
|
|
|
default.update(microstructure)
|
|
|
|
|
|
|
|
def test_invalid_microstructure_type(self,default):
|
2020-08-22 23:25:18 +05:30
|
|
|
microstructure = np.random.randint(1,300,(3,4,5))==1
|
2020-08-08 23:12:34 +05:30
|
|
|
with pytest.raises(TypeError):
|
|
|
|
default.update(microstructure)
|
2020-05-25 02:22:00 +05:30
|
|
|
|
|
|
|
def test_invalid_homogenization(self,default):
|
|
|
|
with pytest.raises(TypeError):
|
|
|
|
default.set_homogenization(homogenization=0)
|
|
|
|
|
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)
|
|
|
|
]
|
|
|
|
)
|
2019-11-23 18:32:59 +05:30
|
|
|
def test_mirror(self,default,update,reference_dir,directions,reflect):
|
2020-08-24 04:16:01 +05:30
|
|
|
modified = default.mirror(directions,reflect)
|
2020-06-25 01:04:51 +05:30
|
|
|
tag = f'directions={"-".join(directions)}_reflect={reflect}'
|
2020-07-31 20:34:14 +05:30
|
|
|
reference = reference_dir/f'mirror_{tag}.geom'
|
2019-11-23 18:32:59 +05:30
|
|
|
if update: modified.to_file(reference)
|
2020-08-24 04:16:01 +05:30
|
|
|
assert geom_equal(Geom.from_file(reference),
|
|
|
|
modified)
|
|
|
|
|
|
|
|
@pytest.mark.parametrize('directions',[
|
|
|
|
['x'],
|
|
|
|
['x','y','z'],
|
|
|
|
['z','x','y'],
|
|
|
|
['y','z'],
|
|
|
|
]
|
|
|
|
)
|
|
|
|
def test_flip(self,default,update,reference_dir,directions):
|
|
|
|
modified = default.flip(directions)
|
|
|
|
tag = f'directions={"-".join(directions)}'
|
|
|
|
reference = reference_dir/f'flip_{tag}.geom'
|
|
|
|
if update: modified.to_file(reference)
|
|
|
|
assert geom_equal(Geom.from_file(reference),
|
|
|
|
modified)
|
2019-11-23 18:32:59 +05:30
|
|
|
|
2020-03-31 14:35:25 +05:30
|
|
|
@pytest.mark.parametrize('stencil',[1,2,3,4])
|
2019-11-23 18:32:59 +05:30
|
|
|
def test_clean(self,default,update,reference_dir,stencil):
|
2020-08-24 04:16:01 +05:30
|
|
|
modified = default.clean(stencil)
|
2020-06-25 01:04:51 +05:30
|
|
|
tag = f'stencil={stencil}'
|
2020-07-31 20:34:14 +05:30
|
|
|
reference = reference_dir/f'clean_{tag}.geom'
|
2019-11-23 17:29:41 +05:30
|
|
|
if update: modified.to_file(reference)
|
2020-08-24 04:16:01 +05:30
|
|
|
assert geom_equal(Geom.from_file(reference),
|
|
|
|
modified)
|
2019-11-25 18:31:40 +05:30
|
|
|
|
|
|
|
@pytest.mark.parametrize('grid',[
|
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
|
|
|
]
|
|
|
|
)
|
|
|
|
def test_scale(self,default,update,reference_dir,grid):
|
2020-08-24 04:16:01 +05:30
|
|
|
modified = default.scale(grid)
|
2020-06-25 01:04:51 +05:30
|
|
|
tag = f'grid={util.srepr(grid,"-")}'
|
2020-07-31 20:34:14 +05:30
|
|
|
reference = reference_dir/f'scale_{tag}.geom'
|
2019-11-25 18:31:40 +05:30
|
|
|
if update: modified.to_file(reference)
|
2020-08-24 04:16:01 +05:30
|
|
|
assert geom_equal(Geom.from_file(reference),
|
|
|
|
modified)
|
2020-03-29 22:42:23 +05:30
|
|
|
|
2020-05-25 00:22:19 +05:30
|
|
|
def test_renumber(self,default):
|
2020-08-24 04:16:01 +05:30
|
|
|
microstructure = default.get_microstructure()
|
2020-05-25 00:22:19 +05:30
|
|
|
for m in np.unique(microstructure):
|
|
|
|
microstructure[microstructure==m] = microstructure.max() + np.random.randint(1,30)
|
2020-08-24 04:16:01 +05:30
|
|
|
modified = default.duplicate(microstructure)
|
2020-05-25 00:22:19 +05:30
|
|
|
assert not geom_equal(modified,default)
|
2020-08-24 04:16:01 +05:30
|
|
|
assert geom_equal(default,
|
|
|
|
modified.renumber())
|
2020-05-25 00:22:19 +05:30
|
|
|
|
|
|
|
def test_substitute(self,default):
|
|
|
|
offset = np.random.randint(1,500)
|
2020-08-24 04:16:01 +05:30
|
|
|
modified = default.duplicate(default.get_microstructure() + offset)
|
2020-05-25 00:22:19 +05:30
|
|
|
assert not geom_equal(modified,default)
|
2020-08-24 04:16:01 +05:30
|
|
|
assert geom_equal(default,
|
|
|
|
modified.substitute(np.arange(default.microstructure.max())+1+offset,
|
|
|
|
np.arange(default.microstructure.max())+1))
|
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))
|
2020-08-24 04:16:01 +05:30
|
|
|
assert geom_equal(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]])
|
|
|
|
def test_rotate(self,default,update,reference_dir,Eulers):
|
2020-08-24 04:16:01 +05:30
|
|
|
modified = default.rotate(Rotation.from_Eulers(Eulers,degrees=True))
|
2020-06-25 01:04:51 +05:30
|
|
|
tag = f'Eulers={util.srepr(Eulers,"-")}'
|
2020-07-31 20:34:14 +05:30
|
|
|
reference = reference_dir/f'rotate_{tag}.geom'
|
2020-05-25 00:22:19 +05:30
|
|
|
if update: modified.to_file(reference)
|
2020-08-24 04:16:01 +05:30
|
|
|
assert geom_equal(Geom.from_file(reference),
|
|
|
|
modified)
|
2020-05-25 00:22:19 +05:30
|
|
|
|
2020-05-25 02:22:00 +05:30
|
|
|
def test_canvas(self,default):
|
2020-08-24 04:16:01 +05:30
|
|
|
grid = default.grid
|
2020-05-25 02:22:00 +05:30
|
|
|
grid_add = np.random.randint(0,30,(3))
|
2020-08-24 04:16:01 +05:30
|
|
|
modified = default.canvas(grid + grid_add)
|
|
|
|
assert np.all(modified.microstructure[:grid[0],:grid[1],:grid[2]] == default.microstructure)
|
2020-08-09 00:05:50 +05:30
|
|
|
|
2020-08-22 23:25:18 +05:30
|
|
|
@pytest.mark.parametrize('center1,center2',[(np.random.random(3)*.5,np.random.random(3)),
|
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-24 04:16:01 +05:30
|
|
|
np.random.randint(4,10,(3))])
|
2020-08-22 23:25:18 +05:30
|
|
|
def test_add_primitive(self,diameter,center1,center2):
|
|
|
|
"""Same volume fraction for periodic microstructures and different center."""
|
|
|
|
o = np.random.random(3)-.5
|
|
|
|
g = np.random.randint(8,32,(3))
|
|
|
|
s = np.random.random(3)+.5
|
2020-08-24 04:16:01 +05:30
|
|
|
G_1 = Geom(np.ones(g,'i'),s,o).add_primitive(diameter,center1,1)
|
|
|
|
G_2 = Geom(np.ones(g,'i'),s,o).add_primitive(diameter,center2,1)
|
2020-08-22 23:25:18 +05:30
|
|
|
assert np.count_nonzero(G_1.microstructure!=2) == np.count_nonzero(G_2.microstructure!=2)
|
2020-08-08 23:44:30 +05:30
|
|
|
|
2020-08-08 23:12:34 +05:30
|
|
|
@pytest.mark.parametrize('trigger',[[1],[]])
|
|
|
|
def test_vicinity_offset(self,trigger):
|
|
|
|
offset = np.random.randint(2,4)
|
|
|
|
vicinity = 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')
|
|
|
|
x = (g*np.random.permutation(np.array([.5,1,1]))).astype('i')
|
|
|
|
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]:
|
2020-08-10 02:44:32 +05:30
|
|
|
m2[(np.roll(m,+vicinity,i)-m)!=0] += offset
|
|
|
|
m2[(np.roll(m,-vicinity,i)-m)!=0] += offset
|
2020-08-08 23:12:34 +05:30
|
|
|
if len(trigger) > 0:
|
2020-08-10 02:44:32 +05:30
|
|
|
m2[m==1] = 1
|
2020-08-09 00:05:50 +05:30
|
|
|
|
2020-08-24 04:16:01 +05:30
|
|
|
geom = Geom(m,np.random.rand(3)).vicinity_offset(vicinity,offset,trigger=trigger)
|
2020-08-09 00:05:50 +05:30
|
|
|
|
2020-08-08 23:12:34 +05:30
|
|
|
assert np.all(m2==geom.microstructure)
|
2020-05-25 00:22:19 +05:30
|
|
|
|
2020-08-08 23:12:34 +05:30
|
|
|
@pytest.mark.parametrize('periodic',[True,False])
|
|
|
|
def test_vicinity_offset_invariant(self,default,periodic):
|
|
|
|
old = default.get_microstructure()
|
2020-08-09 00:05:50 +05:30
|
|
|
default.vicinity_offset(trigger=[old.max()+1,old.min()-1])
|
2020-08-08 23:12:34 +05:30
|
|
|
assert np.all(old==default.microstructure)
|
2020-08-09 00:05:50 +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-03-29 22:42:23 +05:30
|
|
|
grid = np.random.randint(10,20,3)
|
|
|
|
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))
|
|
|
|
Voronoi = Geom.from_Voronoi_tessellation( grid,size,seeds, periodic)
|
|
|
|
Laguerre = Geom.from_Laguerre_tessellation(grid,size,seeds,np.ones(N_seeds),periodic)
|
|
|
|
assert geom_equal(Laguerre,Voronoi)
|
|
|
|
|
2020-03-29 23:58:54 +05:30
|
|
|
def test_Laguerre_weights(self):
|
2020-03-29 22:42:23 +05:30
|
|
|
grid = np.random.randint(10,20,3)
|
|
|
|
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)
|
|
|
|
ms = np.random.randint(1, N_seeds+1)
|
|
|
|
weights[ms-1] = np.random.random()
|
|
|
|
Laguerre = Geom.from_Laguerre_tessellation(grid,size,seeds,weights,np.random.random()>0.5)
|
|
|
|
assert np.all(Laguerre.microstructure == ms)
|
2020-03-29 23:58:54 +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):
|
|
|
|
grid = np.random.randint(5,10,3)*2
|
|
|
|
size = grid.astype(np.float)
|
|
|
|
seeds = np.vstack((size*np.array([0.5,0.25,0.5]),size*np.array([0.5,0.75,0.5])))
|
|
|
|
microstructure = np.ones(grid)
|
|
|
|
microstructure[:,grid[1]//2:,:] = 2
|
|
|
|
if approach == 'Laguerre':
|
|
|
|
geom = Geom.from_Laguerre_tessellation(grid,size,seeds,np.ones(2),np.random.random()>0.5)
|
|
|
|
elif approach == 'Voronoi':
|
|
|
|
geom = Geom.from_Voronoi_tessellation(grid,size,seeds, np.random.random()>0.5)
|
|
|
|
assert np.all(geom.microstructure == microstructure)
|