Merge branch 'ShowGrainBoundaries' into 'development'

Show grain boundaries

See merge request damask/DAMASK!297
This commit is contained in:
Philip Eisenlohr 2020-12-03 17:13:15 +01:00
commit ccf1a849fa
25 changed files with 657 additions and 85 deletions

View File

@ -897,3 +897,41 @@ class Geom:
origin = self.origin, origin = self.origin,
comments = self.comments+[util.execution_stamp('Geom','vicinity_offset')], comments = self.comments+[util.execution_stamp('Geom','vicinity_offset')],
) )
def get_grain_boundaries(self,periodic=True,directions='xyz'):
"""
Create VTK unstructured grid containing grain boundaries.
Parameters
----------
periodic : bool, optional
Show boundaries across periodicity. Defaults to True.
directions : iterable containing str, optional
Direction(s) along which the geometry is mirrored.
Valid entries are 'x', 'y', 'z'. Defaults to 'xyz'.
"""
valid = ['x','y','z']
if not set(directions).issubset(valid):
raise ValueError(f'Invalid direction {set(directions).difference(valid)} specified.')
o = [[0, self.grid[0]+1, np.prod(self.grid[:2]+1)+self.grid[0]+1, np.prod(self.grid[:2]+1)],
[0, np.prod(self.grid[:2]+1), np.prod(self.grid[:2]+1)+1, 1],
[0, 1, self.grid[0]+1+1, self.grid[0]+1]] # offset for connectivity
connectivity = []
for i,d in enumerate(['x','y','z']):
if d not in directions: continue
mask = self.material != np.roll(self.material,1,i)
for j in [0,1,2]:
mask = np.concatenate((mask,np.take(mask,[0],j)*(i==j)),j)
if i == 0 and not periodic: mask[0,:,:] = mask[-1,:,:] = False
if i == 1 and not periodic: mask[:,0,:] = mask[:,-1,:] = False
if i == 2 and not periodic: mask[:,:,0] = mask[:,:,-1] = False
base_nodes = np.argwhere(mask.flatten(order='F')).reshape(-1,1)
connectivity.append(np.block([base_nodes + o[i][k] for k in range(4)]))
coords = grid_filters.node_coord0(self.grid,self.size,self.origin).reshape(-1,3,order='F')
return VTK.from_unstructured_grid(coords,np.vstack(connectivity),'QUAD')

View File

@ -61,7 +61,7 @@ def update(request):
@pytest.fixture @pytest.fixture
def reference_dir_base(): def ref_path_base():
"""Directory containing reference results.""" """Directory containing reference results."""
return Path(__file__).parent/'reference' return Path(__file__).parent/'reference'

View File

@ -0,0 +1,30 @@
<?xml version="1.0"?>
<VTKFile type="RectilinearGrid" version="0.1" byte_order="LittleEndian" header_type="UInt32" compressor="vtkZLibDataCompressor">
<RectilinearGrid WholeExtent="0 12 0 15 0 20">
<FieldData>
<Array type="String" Name="comments" NumberOfTuples="1" format="binary">
AQAAAACAAABJAAAATwAAAA==eF4FwVEKgCAMANCO4mcRG5sTUy/QOVZKQUqB4Pl7L2vT/uBe3ob91FrMECQk0PrdCsEHuI4gzsVNspktWQJmsNFwTOKT8EpMtEw/IaUSzA==
</Array>
</FieldData>
<Piece Extent="0 12 0 15 0 20">
<PointData>
</PointData>
<CellData>
<DataArray type="Int32" Name="material" format="binary" RangeMin="0" RangeMax="7">
AQAAAACAAABAOAAA2AAAAA==eF7t0TEOwgAQA8EkkPD/H1PQ4pMsbXdryd1U9nH8zzs0Rf/rFfqE6lmfQv27zbf761mfQv27zbf761mfQv27zbf761mfQv27zbf761mfQv27zbf761mfQv27zbf761mfQv27zbf761mfQv27zbf761mfQv27zbf761l/ht6h+tm/Qj+heta3f+ln3+6vZ337l3727f561rd/6Wff7q9nffuXfvbt/nrWt3/pZ9/ur2d9+5d+9u3+eta3f+ln3+6vZ337l3727f561rd/6Wff7q9n/ReDyzIp
</DataArray>
</CellData>
<Coordinates>
<DataArray type="Float64" Name="x" format="binary" RangeMin="0" RangeMax="1.2">
AQAAAACAAABoAAAAOQAAAA==eF5jYICAmWCw0x5Cn7Q3BoPLUP5N+/9gcB8q/tg+DQyeQeVf2p8BgzdQde+h4h+h6j/bAwAS5DYX
</DataArray>
<DataArray type="Float64" Name="y" format="binary" RangeMin="0" RangeMax="1.5">
AQAAAACAAACAAAAARQAAAA==eF5jYICAWTNBYKc9hD5pb2IMApeh/Jv2EFUPoOKP7dPTQOAZVP6l/dkzIPAGqu4DVPwjVP1nqPwXqL5vUHU/7AHEUzT8
</DataArray>
<DataArray type="Float64" Name="z" format="binary" RangeMin="0" RangeMax="2">
AQAAAACAAACoAAAAVQAAAA==eF5jYICAWTNBYKc9hD5pb2IMApeh/Jv2EFUPoOKP7dPTQOAZVP6l/dkzIPAGqu4DVPwjVP1nqPwXqL5vUHU/oOp+QtX9hqr7A1X3D6qOwQEAqKdGHg==
</DataArray>
</Coordinates>
</Piece>
</RectilinearGrid>
</VTKFile>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -10,9 +10,9 @@ from PIL import ImageChops
from damask import Colormap from damask import Colormap
@pytest.fixture @pytest.fixture
def reference_dir(reference_dir_base): def ref_path(ref_path_base):
"""Directory containing reference results.""" """Directory containing reference results."""
return reference_dir_base/'Colormap' return ref_path_base/'Colormap'
class TestColormap: class TestColormap:
@ -131,13 +131,13 @@ class TestColormap:
assert (np.allclose(c.colors[:len(c.colors)//2],c.colors[len(c.colors)//2:])) assert (np.allclose(c.colors[:len(c.colors)//2],c.colors[len(c.colors)//2:]))
@pytest.mark.parametrize('bounds',[None,[2,10]]) @pytest.mark.parametrize('bounds',[None,[2,10]])
def test_shade(self,reference_dir,update,bounds): def test_shade(self,ref_path,update,bounds):
data = np.add(*np.indices((10, 11))) data = np.add(*np.indices((10, 11)))
img_current = Colormap.from_predefined('orientation').shade(data,bounds=bounds) img_current = Colormap.from_predefined('orientation').shade(data,bounds=bounds)
if update: if update:
img_current.save(reference_dir/f'shade_{bounds}.png') img_current.save(ref_path/f'shade_{bounds}.png')
else: else:
img_reference = Image.open(reference_dir/f'shade_{bounds}.png') img_reference = Image.open(ref_path/f'shade_{bounds}.png')
diff = ImageChops.difference(img_reference.convert('RGB'),img_current.convert('RGB')) diff = ImageChops.difference(img_reference.convert('RGB'),img_current.convert('RGB'))
assert not diff.getbbox() assert not diff.getbbox()
@ -149,14 +149,14 @@ class TestColormap:
('GOM','.legend'), ('GOM','.legend'),
('gmsh','.msh') ('gmsh','.msh')
]) ])
def test_compare_reference(self,format,ext,tmp_path,reference_dir,update): def test_compare_reference(self,format,ext,tmp_path,ref_path,update):
name = 'binary' name = 'binary'
c = Colormap.from_predefined(name) # noqa c = Colormap.from_predefined(name) # noqa
if update: if update:
os.chdir(reference_dir) os.chdir(ref_path)
eval(f'c.save_{format}()') eval(f'c.save_{format}()')
else: else:
os.chdir(tmp_path) os.chdir(tmp_path)
eval(f'c.save_{format}()') eval(f'c.save_{format}()')
time.sleep(.5) time.sleep(.5)
assert filecmp.cmp(tmp_path/(name+ext),reference_dir/(name+ext)) assert filecmp.cmp(tmp_path/(name+ext),ref_path/(name+ext))

View File

@ -7,16 +7,16 @@ from damask import ConfigMaterial
from damask import Table from damask import Table
@pytest.fixture @pytest.fixture
def reference_dir(reference_dir_base): def ref_path(ref_path_base):
"""Directory containing reference results.""" """Directory containing reference results."""
return reference_dir_base/'ConfigMaterial' return ref_path_base/'ConfigMaterial'
class TestConfigMaterial: class TestConfigMaterial:
@pytest.mark.parametrize('fname',[None,'test.yaml']) @pytest.mark.parametrize('fname',[None,'test.yaml'])
def test_load_save(self,reference_dir,tmp_path,fname): def test_load_save(self,ref_path,tmp_path,fname):
reference = ConfigMaterial.load(reference_dir/'material.yaml') reference = ConfigMaterial.load(ref_path/'material.yaml')
os.chdir(tmp_path) os.chdir(tmp_path)
if fname is None: if fname is None:
reference.save() reference.save()
@ -26,60 +26,60 @@ class TestConfigMaterial:
new = ConfigMaterial.load(fname) new = ConfigMaterial.load(fname)
assert reference == new assert reference == new
def test_valid_complete(self,reference_dir): def test_valid_complete(self,ref_path):
material_config = ConfigMaterial.load(reference_dir/'material.yaml') material_config = ConfigMaterial.load(ref_path/'material.yaml')
assert material_config.is_valid and material_config.is_complete assert material_config.is_valid and material_config.is_complete
def test_invalid_lattice(self,reference_dir): def test_invalid_lattice(self,ref_path):
material_config = ConfigMaterial.load(reference_dir/'material.yaml') material_config = ConfigMaterial.load(ref_path/'material.yaml')
material_config['phase']['Aluminum']['lattice']='fxc' material_config['phase']['Aluminum']['lattice']='fxc'
assert not material_config.is_valid assert not material_config.is_valid
def test_invalid_orientation(self,reference_dir): def test_invalid_orientation(self,ref_path):
material_config = ConfigMaterial.load(reference_dir/'material.yaml') material_config = ConfigMaterial.load(ref_path/'material.yaml')
material_config['material'][0]['constituents'][0]['O']=[0,0,0,0] material_config['material'][0]['constituents'][0]['O']=[0,0,0,0]
assert not material_config.is_valid assert not material_config.is_valid
def test_invalid_fraction(self,reference_dir): def test_invalid_fraction(self,ref_path):
material_config = ConfigMaterial.load(reference_dir/'material.yaml') material_config = ConfigMaterial.load(ref_path/'material.yaml')
material_config['material'][0]['constituents'][0]['fraction']=.9 material_config['material'][0]['constituents'][0]['fraction']=.9
assert not material_config.is_valid assert not material_config.is_valid
@pytest.mark.parametrize('item',['homogenization','phase','material']) @pytest.mark.parametrize('item',['homogenization','phase','material'])
def test_incomplete_missing(self,reference_dir,item): def test_incomplete_missing(self,ref_path,item):
material_config = ConfigMaterial.load(reference_dir/'material.yaml') material_config = ConfigMaterial.load(ref_path/'material.yaml')
del material_config[item] del material_config[item]
assert not material_config.is_complete assert not material_config.is_complete
@pytest.mark.parametrize('item',['O','phase']) @pytest.mark.parametrize('item',['O','phase'])
def test_incomplete_material_constituent(self,reference_dir,item): def test_incomplete_material_constituent(self,ref_path,item):
material_config = ConfigMaterial.load(reference_dir/'material.yaml') material_config = ConfigMaterial.load(ref_path/'material.yaml')
del material_config['material'][0]['constituents'][0][item] del material_config['material'][0]['constituents'][0][item]
assert not material_config.is_complete assert not material_config.is_complete
def test_incomplete_material_homogenization(self,reference_dir): def test_incomplete_material_homogenization(self,ref_path):
material_config = ConfigMaterial.load(reference_dir/'material.yaml') material_config = ConfigMaterial.load(ref_path/'material.yaml')
del material_config['material'][0]['homogenization'] del material_config['material'][0]['homogenization']
assert not material_config.is_complete assert not material_config.is_complete
def test_incomplete_homogenization_N_constituents(self,reference_dir): def test_incomplete_homogenization_N_constituents(self,ref_path):
material_config = ConfigMaterial.load(reference_dir/'material.yaml') material_config = ConfigMaterial.load(ref_path/'material.yaml')
for h in material_config['homogenization'].keys(): for h in material_config['homogenization'].keys():
del material_config['homogenization'][h]['N_constituents'] del material_config['homogenization'][h]['N_constituents']
assert not material_config.is_complete assert not material_config.is_complete
def test_incomplete_phase_lattice(self,reference_dir): def test_incomplete_phase_lattice(self,ref_path):
material_config = ConfigMaterial.load(reference_dir/'material.yaml') material_config = ConfigMaterial.load(ref_path/'material.yaml')
del material_config['phase']['Aluminum']['lattice'] del material_config['phase']['Aluminum']['lattice']
assert not material_config.is_complete assert not material_config.is_complete
def test_incomplete_wrong_phase(self,reference_dir): def test_incomplete_wrong_phase(self,ref_path):
material_config = ConfigMaterial.load(reference_dir/'material.yaml') material_config = ConfigMaterial.load(ref_path/'material.yaml')
new = material_config.material_rename_phase({'Steel':'FeNbC'}) new = material_config.material_rename_phase({'Steel':'FeNbC'})
assert not new.is_complete assert not new.is_complete
def test_incomplete_wrong_homogenization(self,reference_dir): def test_incomplete_wrong_homogenization(self,ref_path):
material_config = ConfigMaterial.load(reference_dir/'material.yaml') material_config = ConfigMaterial.load(ref_path/'material.yaml')
new = material_config.material_rename_homogenization({'Taylor':'isostrain'}) new = material_config.material_rename_homogenization({'Taylor':'isostrain'})
assert not new.is_complete assert not new.is_complete

View File

@ -26,9 +26,9 @@ def default():
return Geom(x,[8e-6,5e-6,4e-6]) return Geom(x,[8e-6,5e-6,4e-6])
@pytest.fixture @pytest.fixture
def reference_dir(reference_dir_base): def ref_path(ref_path_base):
"""Directory containing reference results.""" """Directory containing reference results."""
return reference_dir_base/'Geom' return ref_path_base/'Geom'
class TestGeom: class TestGeom:
@ -37,6 +37,10 @@ class TestGeom:
def _patch_execution_stamp(self, patch_execution_stamp): def _patch_execution_stamp(self, patch_execution_stamp):
print('patched damask.util.execution_stamp') print('patched damask.util.execution_stamp')
@pytest.fixture(autouse=True)
def _patch_datetime_now(self, patch_datetime_now):
print('patched datetime.datetime.now')
def test_diff_equal(self,default): def test_diff_equal(self,default):
assert str(default.diff(default)) == '' assert str(default.diff(default)) == ''
@ -104,10 +108,10 @@ class TestGeom:
(['y','z'], False) (['y','z'], False)
] ]
) )
def test_mirror(self,default,update,reference_dir,directions,reflect): def test_mirror(self,default,update,ref_path,directions,reflect):
modified = default.mirror(directions,reflect) modified = default.mirror(directions,reflect)
tag = f'directions_{"-".join(directions)}+reflect_{reflect}' tag = f'directions_{"-".join(directions)}+reflect_{reflect}'
reference = reference_dir/f'mirror_{tag}.vtr' reference = ref_path/f'mirror_{tag}.vtr'
if update: modified.save(reference) if update: modified.save(reference)
assert geom_equal(Geom.load(reference), assert geom_equal(Geom.load(reference),
modified) modified)
@ -126,10 +130,10 @@ class TestGeom:
['y','z'], ['y','z'],
] ]
) )
def test_flip(self,default,update,reference_dir,directions): def test_flip(self,default,update,ref_path,directions):
modified = default.flip(directions) modified = default.flip(directions)
tag = f'directions_{"-".join(directions)}' tag = f'directions_{"-".join(directions)}'
reference = reference_dir/f'flip_{tag}.vtr' reference = ref_path/f'flip_{tag}.vtr'
if update: modified.save(reference) if update: modified.save(reference)
assert geom_equal(Geom.load(reference), assert geom_equal(Geom.load(reference),
modified) modified)
@ -153,9 +157,9 @@ class TestGeom:
@pytest.mark.parametrize('stencil',[1,2,3,4]) @pytest.mark.parametrize('stencil',[1,2,3,4])
@pytest.mark.parametrize('selection',[None,[1],[1,2,3]]) @pytest.mark.parametrize('selection',[None,[1],[1,2,3]])
@pytest.mark.parametrize('periodic',[True,False]) @pytest.mark.parametrize('periodic',[True,False])
def test_clean(self,default,update,reference_dir,stencil,selection,periodic): def test_clean(self,default,update,ref_path,stencil,selection,periodic):
current = default.clean(stencil,selection,periodic) current = default.clean(stencil,selection,periodic)
reference = reference_dir/f'clean_{stencil}_{"+".join(map(str,[None] if selection is None else selection))}_{periodic}' reference = ref_path/f'clean_{stencil}_{"+".join(map(str,[None] if selection is None else selection))}_{periodic}'
if update and stencil > 1: if update and stencil > 1:
current.save(reference) current.save(reference)
assert geom_equal(Geom.load(reference) if stencil > 1 else default, assert geom_equal(Geom.load(reference) if stencil > 1 else default,
@ -172,10 +176,10 @@ class TestGeom:
np.array((10,20,2)) np.array((10,20,2))
] ]
) )
def test_scale(self,default,update,reference_dir,grid): def test_scale(self,default,update,ref_path,grid):
modified = default.scale(grid) modified = default.scale(grid)
tag = f'grid_{util.srepr(grid,"-")}' tag = f'grid_{util.srepr(grid,"-")}'
reference = reference_dir/f'scale_{tag}.vtr' reference = ref_path/f'scale_{tag}.vtr'
if update: modified.save(reference) if update: modified.save(reference)
assert geom_equal(Geom.load(reference), assert geom_equal(Geom.load(reference),
modified) modified)
@ -228,10 +232,10 @@ class TestGeom:
@pytest.mark.parametrize('Eulers',[[32.0,68.0,21.0], @pytest.mark.parametrize('Eulers',[[32.0,68.0,21.0],
[0.0,32.0,240.0]]) [0.0,32.0,240.0]])
def test_rotate(self,default,update,reference_dir,Eulers): def test_rotate(self,default,update,ref_path,Eulers):
modified = default.rotate(Rotation.from_Euler_angles(Eulers,degrees=True)) modified = default.rotate(Rotation.from_Euler_angles(Eulers,degrees=True))
tag = f'Eulers_{util.srepr(Eulers,"-")}' tag = f'Eulers_{util.srepr(Eulers,"-")}'
reference = reference_dir/f'rotate_{tag}.vtr' reference = ref_path/f'rotate_{tag}.vtr'
if update: modified.save(reference) if update: modified.save(reference)
assert geom_equal(Geom.load(reference), assert geom_equal(Geom.load(reference),
modified) modified)
@ -406,3 +410,13 @@ class TestGeom:
coords = grid_filters.cell_coord0(grid,size) coords = grid_filters.cell_coord0(grid,size)
t = Table(np.column_stack((coords.reshape(-1,3,order='F'),geom.material.flatten(order='F'))),{'c':3,'m':1}) t = Table(np.column_stack((coords.reshape(-1,3,order='F'),geom.material.flatten(order='F'))),{'c':3,'m':1})
assert geom_equal(geom.sort().renumber(),Geom.from_table(t,'c',['m'])) assert geom_equal(geom.sort().renumber(),Geom.from_table(t,'c',['m']))
@pytest.mark.parametrize('periodic',[True,False])
@pytest.mark.parametrize('direction',['x','y','z',['x','y'],'zy','xz',['x','y','z']])
def test_get_grain_boundaries(self,update,ref_path,periodic,direction):
geom=Geom.load(ref_path/'get_grain_boundaries_8g12x15x20.vtr')
current=geom.get_grain_boundaries(periodic,direction)
if update:
current.save(ref_path/f'get_grain_boundaries_8g12x15x20_{direction}_{periodic}.vtu',parallel=False)
reference=VTK.load(ref_path/f'get_grain_boundaries_8g12x15x20_{"".join(direction)}_{periodic}.vtu')
assert current.__repr__() == reference.__repr__()

View File

@ -10,9 +10,9 @@ from damask import util
@pytest.fixture @pytest.fixture
def reference_dir(reference_dir_base): def ref_path(ref_path_base):
"""Directory containing reference results.""" """Directory containing reference results."""
return reference_dir_base/'Orientation' return ref_path_base/'Orientation'
@pytest.fixture @pytest.fixture
def set_of_rodrigues(set_of_quaternions): def set_of_rodrigues(set_of_quaternions):
@ -414,8 +414,8 @@ class TestOrientation:
@pytest.mark.parametrize('model',['Bain','KS','GT','GT_prime','NW','Pitsch']) @pytest.mark.parametrize('model',['Bain','KS','GT','GT_prime','NW','Pitsch'])
@pytest.mark.parametrize('lattice',['cF','cI']) @pytest.mark.parametrize('lattice',['cF','cI'])
def test_relationship_reference(self,update,reference_dir,model,lattice): def test_relationship_reference(self,update,ref_path,model,lattice):
reference = reference_dir/f'{lattice}_{model}.txt' reference = ref_path/f'{lattice}_{model}.txt'
o = Orientation(lattice=lattice) o = Orientation(lattice=lattice)
eu = o.related(model).as_Euler_angles(degrees=True) eu = o.related(model).as_Euler_angles(degrees=True)
if update: if update:
@ -525,10 +525,10 @@ class TestOrientation:
== o.shape + (o.symmetry_operations.shape if with_symmetry else ()) + vector.shape == o.shape + (o.symmetry_operations.shape if with_symmetry else ()) + vector.shape
@pytest.mark.parametrize('lattice',['hP','cI','cF']) @pytest.mark.parametrize('lattice',['hP','cI','cF'])
def test_Schmid(self,update,reference_dir,lattice): def test_Schmid(self,update,ref_path,lattice):
L = Orientation(lattice=lattice) L = Orientation(lattice=lattice)
for mode in L.kinematics: for mode in L.kinematics:
reference = reference_dir/f'{lattice}_{mode}.txt' reference = ref_path/f'{lattice}_{mode}.txt'
P = L.Schmid(mode) P = L.Schmid(mode)
if update: if update:
table = Table(P.reshape(-1,9),{'Schmid':(3,3,)}) table = Table(P.reshape(-1,9),{'Schmid':(3,3,)})

View File

@ -16,25 +16,25 @@ from damask import mechanics
from damask import grid_filters from damask import grid_filters
@pytest.fixture @pytest.fixture
def default(tmp_path,reference_dir): def default(tmp_path,ref_path):
"""Small Result file in temp location for modification.""" """Small Result file in temp location for modification."""
fname = '12grains6x7x8_tensionY.hdf5' fname = '12grains6x7x8_tensionY.hdf5'
shutil.copy(reference_dir/fname,tmp_path) shutil.copy(ref_path/fname,tmp_path)
f = Result(tmp_path/fname) f = Result(tmp_path/fname)
f.pick('times',20.0) f.pick('times',20.0)
return f return f
@pytest.fixture @pytest.fixture
def single_phase(tmp_path,reference_dir): def single_phase(tmp_path,ref_path):
"""Single phase Result file in temp location for modification.""" """Single phase Result file in temp location for modification."""
fname = '6grains6x7x8_single_phase_tensionY.hdf5' fname = '6grains6x7x8_single_phase_tensionY.hdf5'
shutil.copy(reference_dir/fname,tmp_path) shutil.copy(ref_path/fname,tmp_path)
return Result(tmp_path/fname) return Result(tmp_path/fname)
@pytest.fixture @pytest.fixture
def reference_dir(reference_dir_base): def ref_path(ref_path_base):
"""Directory containing reference results.""" """Directory containing reference results."""
return reference_dir_base/'Result' return ref_path_base/'Result'
class TestResult: class TestResult:
@ -373,7 +373,7 @@ class TestResult:
os.chdir(tmp_path) os.chdir(tmp_path)
single_phase.save_VTK(mode=mode) single_phase.save_VTK(mode=mode)
def test_XDMF(self,tmp_path,single_phase,update,reference_dir): def test_XDMF(self,tmp_path,single_phase,update,ref_path):
for shape in [('scalar',()),('vector',(3,)),('tensor',(3,3)),('matrix',(12,))]: for shape in [('scalar',()),('vector',(3,)),('tensor',(3,3)),('matrix',(12,))]:
for dtype in ['f4','f8','i1','i2','i4','i8','u1','u2','u4','u8']: for dtype in ['f4','f8','i1','i2','i4','i8','u1','u2','u4','u8']:
single_phase.add_calculation(f'{shape[0]}_{dtype}',f"np.ones(np.shape(#F#)[0:1]+{shape[1]},'{dtype}')") single_phase.add_calculation(f'{shape[0]}_{dtype}',f"np.ones(np.shape(#F#)[0:1]+{shape[1]},'{dtype}')")
@ -381,8 +381,8 @@ class TestResult:
os.chdir(tmp_path) os.chdir(tmp_path)
single_phase.save_XDMF() single_phase.save_XDMF()
if update: if update:
shutil.copy(tmp_path/fname,reference_dir/fname) shutil.copy(tmp_path/fname,ref_path/fname)
assert sorted(open(tmp_path/fname).read()) == sorted(open(reference_dir/fname).read()) # XML is not ordered assert sorted(open(tmp_path/fname).read()) == sorted(open(ref_path/fname).read()) # XML is not ordered
def test_XDMF_invalid(self,default): def test_XDMF_invalid(self,default):
with pytest.raises(TypeError): with pytest.raises(TypeError):

View File

@ -11,9 +11,9 @@ n = 1000
atol=1.e-4 atol=1.e-4
@pytest.fixture @pytest.fixture
def reference_dir(reference_dir_base): def ref_path(ref_path_base):
"""Directory containing reference results.""" """Directory containing reference results."""
return reference_dir_base/'Rotation' return ref_path_base/'Rotation'
@pytest.fixture @pytest.fixture
def set_of_rotations(set_of_quaternions): def set_of_rotations(set_of_quaternions):
@ -1016,12 +1016,12 @@ class TestRotation:
@pytest.mark.parametrize('fractions',[True,False]) @pytest.mark.parametrize('fractions',[True,False])
@pytest.mark.parametrize('degrees',[True,False]) @pytest.mark.parametrize('degrees',[True,False])
@pytest.mark.parametrize('N',[2**13,2**14,2**15]) @pytest.mark.parametrize('N',[2**13,2**14,2**15])
def test_ODF_cell(self,reference_dir,fractions,degrees,N): def test_ODF_cell(self,ref_path,fractions,degrees,N):
steps = np.array([144,36,36]) steps = np.array([144,36,36])
limits = np.array([360.,90.,90.]) limits = np.array([360.,90.,90.])
rng = tuple(zip(np.zeros(3),limits)) rng = tuple(zip(np.zeros(3),limits))
weights = Table.load(reference_dir/'ODF_experimental_cell.txt').get('intensity').flatten() weights = Table.load(ref_path/'ODF_experimental_cell.txt').get('intensity').flatten()
Eulers = grid_filters.cell_coord0(steps,limits) Eulers = grid_filters.cell_coord0(steps,limits)
Eulers = np.radians(Eulers) if not degrees else Eulers Eulers = np.radians(Eulers) if not degrees else Eulers
@ -1032,12 +1032,12 @@ class TestRotation:
@pytest.mark.parametrize('degrees',[True,False]) @pytest.mark.parametrize('degrees',[True,False])
@pytest.mark.parametrize('N',[2**13,2**14,2**15]) @pytest.mark.parametrize('N',[2**13,2**14,2**15])
def test_ODF_node(self,reference_dir,degrees,N): def test_ODF_node(self,ref_path,degrees,N):
steps = np.array([144,36,36]) steps = np.array([144,36,36])
limits = np.array([360.,90.,90.]) limits = np.array([360.,90.,90.])
rng = tuple(zip(-limits/steps*.5,limits-limits/steps*.5)) rng = tuple(zip(-limits/steps*.5,limits-limits/steps*.5))
weights = Table.load(reference_dir/'ODF_experimental.txt').get('intensity') weights = Table.load(ref_path/'ODF_experimental.txt').get('intensity')
weights = weights.reshape(steps+1,order='F')[:-1,:-1,:-1].reshape(-1,order='F') weights = weights.reshape(steps+1,order='F')[:-1,:-1,:-1].reshape(-1,order='F')
Eulers = grid_filters.node_coord0(steps,limits)[:-1,:-1,:-1] Eulers = grid_filters.node_coord0(steps,limits)[:-1,:-1,:-1]

View File

@ -11,9 +11,9 @@ def default():
return Table(x,{'F':(3,3),'v':(3,),'s':(1,)},['test data','contains only ones']) return Table(x,{'F':(3,3),'v':(3,),'s':(1,)},['test data','contains only ones'])
@pytest.fixture @pytest.fixture
def reference_dir(reference_dir_base): def ref_path(ref_path_base):
"""Directory containing reference results.""" """Directory containing reference results."""
return reference_dir_base/'Table' return ref_path_base/'Table'
class TestTable: class TestTable:
@ -67,23 +67,23 @@ class TestTable:
default.save(tmp_path/'shouldnotbethere.txt',format='invalid') default.save(tmp_path/'shouldnotbethere.txt',format='invalid')
@pytest.mark.parametrize('mode',['str','path']) @pytest.mark.parametrize('mode',['str','path'])
def test_read_ang(self,reference_dir,mode): def test_read_ang(self,ref_path,mode):
if mode == 'path': if mode == 'path':
new = Table.load_ang(reference_dir/'simple.ang') new = Table.load_ang(ref_path/'simple.ang')
elif mode == 'str': elif mode == 'str':
new = Table.load_ang(str(reference_dir/'simple.ang')) new = Table.load_ang(str(ref_path/'simple.ang'))
assert new.data.shape == (4,10) and \ assert new.data.shape == (4,10) and \
new.labels == ['eu', 'pos', 'IQ', 'CI', 'ID', 'intensity', 'fit'] new.labels == ['eu', 'pos', 'IQ', 'CI', 'ID', 'intensity', 'fit']
def test_read_ang_file(self,reference_dir): def test_read_ang_file(self,ref_path):
f = open(reference_dir/'simple.ang') f = open(ref_path/'simple.ang')
new = Table.load_ang(f) new = Table.load_ang(f)
assert new.data.shape == (4,10) and \ assert new.data.shape == (4,10) and \
new.labels == ['eu', 'pos', 'IQ', 'CI', 'ID', 'intensity', 'fit'] new.labels == ['eu', 'pos', 'IQ', 'CI', 'ID', 'intensity', 'fit']
@pytest.mark.parametrize('fname',['datatype-mix.txt','whitespace-mix.txt']) @pytest.mark.parametrize('fname',['datatype-mix.txt','whitespace-mix.txt'])
def test_read_strange(self,reference_dir,fname): def test_read_strange(self,ref_path,fname):
with open(reference_dir/fname) as f: with open(ref_path/fname) as f:
Table.load(f) Table.load(f)
def test_set(self,default): def test_set(self,default):

View File

@ -9,9 +9,9 @@ from damask import VTK
from damask import grid_filters from damask import grid_filters
@pytest.fixture @pytest.fixture
def reference_dir(reference_dir_base): def ref_path(ref_path_base):
"""Directory containing reference results.""" """Directory containing reference results."""
return reference_dir_base/'VTK' return ref_path_base/'VTK'
@pytest.fixture @pytest.fixture
def default(): def default():
@ -140,18 +140,18 @@ class TestVTK:
new = VTK.load(tmp_path/'with_comments.vtr') new = VTK.load(tmp_path/'with_comments.vtr')
assert new.get_comments() == ['this is a comment'] assert new.get_comments() == ['this is a comment']
def test_compare_reference_polyData(self,update,reference_dir,tmp_path): def test_compare_reference_polyData(self,update,ref_path,tmp_path):
points=np.dstack((np.linspace(0.,1.,10),np.linspace(0.,2.,10),np.linspace(-1.,1.,10))).squeeze() points=np.dstack((np.linspace(0.,1.,10),np.linspace(0.,2.,10),np.linspace(-1.,1.,10))).squeeze()
polyData = VTK.from_poly_data(points) polyData = VTK.from_poly_data(points)
polyData.add(points,'coordinates') polyData.add(points,'coordinates')
if update: if update:
polyData.save(reference_dir/'polyData') polyData.save(ref_path/'polyData')
else: else:
reference = VTK.load(reference_dir/'polyData.vtp') reference = VTK.load(ref_path/'polyData.vtp')
assert polyData.__repr__() == reference.__repr__() and \ assert polyData.__repr__() == reference.__repr__() and \
np.allclose(polyData.get('coordinates'),points) np.allclose(polyData.get('coordinates'),points)
def test_compare_reference_rectilinearGrid(self,update,reference_dir,tmp_path): def test_compare_reference_rectilinearGrid(self,update,ref_path,tmp_path):
grid = np.array([5,6,7],int) grid = np.array([5,6,7],int)
size = np.array([.6,1.,.5]) size = np.array([.6,1.,.5])
rectilinearGrid = VTK.from_rectilinear_grid(grid,size) rectilinearGrid = VTK.from_rectilinear_grid(grid,size)
@ -160,8 +160,8 @@ class TestVTK:
rectilinearGrid.add(c,'cell') rectilinearGrid.add(c,'cell')
rectilinearGrid.add(n,'node') rectilinearGrid.add(n,'node')
if update: if update:
rectilinearGrid.save(reference_dir/'rectilinearGrid') rectilinearGrid.save(ref_path/'rectilinearGrid')
else: else:
reference = VTK.load(reference_dir/'rectilinearGrid.vtr') reference = VTK.load(ref_path/'rectilinearGrid.vtr')
assert rectilinearGrid.__repr__() == reference.__repr__() and \ assert rectilinearGrid.__repr__() == reference.__repr__() and \
np.allclose(rectilinearGrid.get('cell'),c) np.allclose(rectilinearGrid.get('cell'),c)