2022-03-27 02:45:26 +05:30
|
|
|
import sys
|
2020-09-19 16:31:19 +05:30
|
|
|
import os
|
|
|
|
import pytest
|
2020-10-29 12:12:41 +05:30
|
|
|
import numpy as np
|
2020-09-19 16:31:19 +05:30
|
|
|
|
2020-09-30 11:23:25 +05:30
|
|
|
from damask import ConfigMaterial
|
2020-10-29 12:12:41 +05:30
|
|
|
from damask import Table
|
2021-02-23 09:14:12 +05:30
|
|
|
from damask import Rotation
|
2021-03-20 17:21:41 +05:30
|
|
|
from damask import Grid
|
2020-09-19 16:31:19 +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/'ConfigMaterial'
|
2020-09-19 16:31:19 +05:30
|
|
|
|
|
|
|
|
2020-09-30 12:19:55 +05:30
|
|
|
class TestConfigMaterial:
|
|
|
|
|
2023-02-02 01:01:04 +05:30
|
|
|
def test_init_empty(self):
|
|
|
|
c = ConfigMaterial()
|
|
|
|
assert len(c) == 3
|
|
|
|
assert c['homogenization'] == {}
|
|
|
|
assert c['phase'] == {}
|
|
|
|
assert c['material'] == []
|
|
|
|
|
|
|
|
def test_init_d(self):
|
|
|
|
c = ConfigMaterial(config={'phase':4})
|
|
|
|
assert len(c) == 1
|
|
|
|
assert c['phase'] == 4
|
|
|
|
|
|
|
|
@pytest.mark.parametrize('kwargs',[{'homogenization':{'SX':{}}},
|
|
|
|
{'phase':{'Aluminum':{}}},
|
|
|
|
{'material':[{'A':1},{'B':2}]}])
|
|
|
|
def test_init_some(self,kwargs):
|
|
|
|
c = ConfigMaterial(**kwargs)
|
|
|
|
assert len(c) == 3
|
|
|
|
for k,v in kwargs.items():
|
|
|
|
if k in kwargs: assert v == kwargs[k]
|
|
|
|
|
2020-09-19 16:31:19 +05:30
|
|
|
@pytest.mark.parametrize('fname',[None,'test.yaml'])
|
2023-04-24 10:41:14 +05:30
|
|
|
def test_load_save(self,res_path,tmp_path,fname):
|
|
|
|
reference = ConfigMaterial.load(res_path/'material.yaml')
|
2020-09-19 16:31:19 +05:30
|
|
|
os.chdir(tmp_path)
|
|
|
|
if fname is None:
|
|
|
|
reference.save()
|
2020-09-30 11:23:25 +05:30
|
|
|
new = ConfigMaterial.load('material.yaml')
|
2020-09-19 16:31:19 +05:30
|
|
|
else:
|
|
|
|
reference.save(fname)
|
2020-09-30 11:23:25 +05:30
|
|
|
new = ConfigMaterial.load(fname)
|
2020-09-19 16:31:19 +05:30
|
|
|
assert reference == new
|
|
|
|
|
2023-04-24 10:41:14 +05:30
|
|
|
def test_valid_complete(self,res_path):
|
|
|
|
material_config = ConfigMaterial.load(res_path/'material.yaml')
|
2020-09-19 16:31:19 +05:30
|
|
|
assert material_config.is_valid and material_config.is_complete
|
|
|
|
|
2023-04-24 10:41:14 +05:30
|
|
|
def test_invalid_lattice(self,res_path):
|
|
|
|
material_config = ConfigMaterial.load(res_path/'material.yaml')
|
2020-09-19 16:31:19 +05:30
|
|
|
material_config['phase']['Aluminum']['lattice']='fxc'
|
|
|
|
assert not material_config.is_valid
|
2020-09-30 12:19:55 +05:30
|
|
|
|
2023-04-24 10:41:14 +05:30
|
|
|
def test_invalid_orientation(self,res_path):
|
|
|
|
material_config = ConfigMaterial.load(res_path/'material.yaml')
|
2020-10-02 21:19:52 +05:30
|
|
|
material_config['material'][0]['constituents'][0]['O']=[0,0,0,0]
|
2020-09-19 16:31:19 +05:30
|
|
|
assert not material_config.is_valid
|
2020-09-30 12:19:55 +05:30
|
|
|
|
2022-03-27 02:43:54 +05:30
|
|
|
@pytest.mark.xfail(sys.platform == 'win32', reason='utf8 "not equal" might cause trouble')
|
2023-04-24 10:41:14 +05:30
|
|
|
def test_invalid_fraction(self,res_path):
|
|
|
|
material_config = ConfigMaterial.load(res_path/'material.yaml')
|
2021-02-04 18:16:01 +05:30
|
|
|
material_config['material'][0]['constituents'][0]['v']=.9
|
2020-09-19 16:31:19 +05:30
|
|
|
assert not material_config.is_valid
|
|
|
|
|
2020-10-02 21:19:52 +05:30
|
|
|
@pytest.mark.parametrize('item',['homogenization','phase','material'])
|
2023-04-24 10:41:14 +05:30
|
|
|
def test_incomplete_missing(self,res_path,item):
|
|
|
|
material_config = ConfigMaterial.load(res_path/'material.yaml')
|
2020-09-19 16:31:19 +05:30
|
|
|
del material_config[item]
|
|
|
|
assert not material_config.is_complete
|
2020-09-30 12:19:55 +05:30
|
|
|
|
2020-10-02 21:19:52 +05:30
|
|
|
@pytest.mark.parametrize('item',['O','phase'])
|
2023-04-24 10:41:14 +05:30
|
|
|
def test_incomplete_material_constituent(self,res_path,item):
|
|
|
|
material_config = ConfigMaterial.load(res_path/'material.yaml')
|
2020-10-02 21:19:52 +05:30
|
|
|
del material_config['material'][0]['constituents'][0][item]
|
2020-09-30 12:19:55 +05:30
|
|
|
assert not material_config.is_complete
|
|
|
|
|
2023-04-24 10:41:14 +05:30
|
|
|
def test_incomplete_material_homogenization(self,res_path):
|
|
|
|
material_config = ConfigMaterial.load(res_path/'material.yaml')
|
2020-10-02 21:19:52 +05:30
|
|
|
del material_config['material'][0]['homogenization']
|
2020-09-30 12:19:55 +05:30
|
|
|
assert not material_config.is_complete
|
|
|
|
|
2023-04-24 10:41:14 +05:30
|
|
|
def test_incomplete_wrong_phase(self,res_path):
|
|
|
|
material_config = ConfigMaterial.load(res_path/'material.yaml')
|
2020-10-02 21:19:52 +05:30
|
|
|
new = material_config.material_rename_phase({'Steel':'FeNbC'})
|
2020-09-19 16:31:19 +05:30
|
|
|
assert not new.is_complete
|
2020-09-30 12:19:55 +05:30
|
|
|
|
2023-04-24 10:41:14 +05:30
|
|
|
def test_incomplete_wrong_homogenization(self,res_path):
|
|
|
|
material_config = ConfigMaterial.load(res_path/'material.yaml')
|
2020-10-02 21:19:52 +05:30
|
|
|
new = material_config.material_rename_homogenization({'Taylor':'isostrain'})
|
2020-09-19 16:31:19 +05:30
|
|
|
assert not new.is_complete
|
2020-10-29 12:12:41 +05:30
|
|
|
|
2023-04-24 10:41:14 +05:30
|
|
|
def test_empty_phase(self,res_path):
|
|
|
|
material_config = ConfigMaterial.load(res_path/'material.yaml')
|
2022-11-11 05:44:16 +05:30
|
|
|
material_config['phase'] = None
|
|
|
|
assert not material_config.is_complete
|
|
|
|
|
2023-04-24 10:41:14 +05:30
|
|
|
def test_empty_homogenization(self,res_path):
|
|
|
|
material_config = ConfigMaterial.load(res_path/'material.yaml')
|
2022-11-11 05:44:16 +05:30
|
|
|
material_config['homogenization'] = None
|
|
|
|
assert not material_config.is_complete
|
|
|
|
|
2020-10-29 12:12:41 +05:30
|
|
|
def test_from_table(self):
|
|
|
|
N = np.random.randint(3,10)
|
2021-04-01 00:00:07 +05:30
|
|
|
a = np.vstack((np.hstack((np.arange(N),np.arange(N)[::-1])),
|
2023-02-02 01:01:04 +05:30
|
|
|
np.zeros(N*2),np.ones(N*2),np.zeros(N*2),np.zeros(N*2),
|
2021-04-01 00:00:07 +05:30
|
|
|
np.ones(N*2),
|
|
|
|
)).T
|
2022-03-12 03:01:35 +05:30
|
|
|
t = Table({'varying':1,'constant':4,'ones':1},a)
|
2021-04-01 00:00:07 +05:30
|
|
|
c = ConfigMaterial.from_table(t,**{'phase':'varying','O':'constant','homogenization':'ones'})
|
2020-10-29 12:12:41 +05:30
|
|
|
assert len(c['material']) == N
|
2022-02-14 10:24:16 +05:30
|
|
|
for i,m in enumerate(c['material']):
|
2023-02-02 01:01:04 +05:30
|
|
|
assert m['homogenization'] == 1 and (m['constituents'][0]['O'] == [0,1,0,0]).all()
|
2022-02-14 10:24:16 +05:30
|
|
|
|
2023-04-24 10:41:14 +05:30
|
|
|
def test_updated_dicts(self,res_path):
|
2022-11-10 03:28:51 +05:30
|
|
|
m1 = ConfigMaterial().material_add(phase=['Aluminum'],O=[1.0,0.0,0.0,0.0],homogenization='SX')
|
2023-04-24 10:41:14 +05:30
|
|
|
m2 = ConfigMaterial.load(res_path/'material.yaml')
|
2022-11-11 05:44:16 +05:30
|
|
|
for k in m2['phase']:
|
|
|
|
m2 = m2.material_add(phase=[k],O=[1.0,0.0,0.0,0.0],homogenization='SX')
|
|
|
|
assert not m2['phase'].get(k) is None
|
|
|
|
assert m1['phase'].get('Aluminum') is None
|
|
|
|
assert m1['homogenization'].get('SX') is None
|
2022-11-10 03:28:51 +05:30
|
|
|
|
2022-02-14 10:24:16 +05:30
|
|
|
def test_from_table_with_constant(self):
|
|
|
|
N = np.random.randint(3,10)
|
|
|
|
a = np.vstack((np.hstack((np.arange(N),np.arange(N)[::-1])),
|
2023-02-02 01:01:04 +05:30
|
|
|
np.zeros(N*2),np.ones(N*2),np.zeros(N*2),np.zeros(N*2),
|
2022-02-14 10:24:16 +05:30
|
|
|
np.ones(N*2),
|
|
|
|
)).T
|
2022-03-12 03:01:35 +05:30
|
|
|
t = Table({'varying':1,'constant':4,'ones':1},a)
|
2022-02-14 10:24:16 +05:30
|
|
|
c = ConfigMaterial.from_table(t,**{'phase':'varying','O':'constant','homogenization':1})
|
|
|
|
assert len(c['material']) == N
|
2021-02-23 22:20:13 +05:30
|
|
|
for i,m in enumerate(c['material']):
|
2023-02-02 01:01:04 +05:30
|
|
|
assert m['homogenization'] == 1 and (m['constituents'][0]['O'] == [0,1,0,0]).all()
|
2021-02-23 09:14:12 +05:30
|
|
|
|
|
|
|
@pytest.mark.parametrize('N,n,kw',[
|
|
|
|
(1,1,{'phase':'Gold',
|
|
|
|
'O':[1,0,0,0],
|
2022-05-18 03:26:05 +05:30
|
|
|
'V_e':np.eye(3),
|
2021-02-23 09:14:12 +05:30
|
|
|
'homogenization':'SX'}),
|
|
|
|
(3,1,{'phase':'Gold',
|
|
|
|
'O':Rotation.from_random(3),
|
2022-05-18 03:26:05 +05:30
|
|
|
'V_e':np.broadcast_to(np.eye(3),(3,3,3)),
|
2021-02-23 09:14:12 +05:30
|
|
|
'homogenization':'SX'}),
|
|
|
|
(2,3,{'phase':np.broadcast_to(['a','b','c'],(2,3)),
|
|
|
|
'O':Rotation.from_random((2,3)),
|
2022-05-18 03:26:05 +05:30
|
|
|
'V_e':np.broadcast_to(np.eye(3),(2,3,3,3)),
|
2021-02-23 09:14:12 +05:30
|
|
|
'homogenization':['SX','PX']}),
|
|
|
|
])
|
|
|
|
def test_material_add(self,kw,N,n):
|
|
|
|
m = ConfigMaterial().material_add(**kw)
|
|
|
|
assert len(m['material']) == N
|
|
|
|
assert len(m['material'][0]['constituents']) == n
|
2021-03-20 17:21:41 +05:30
|
|
|
|
2023-02-02 01:01:04 +05:30
|
|
|
@pytest.mark.parametrize('shape',[(),(4,),(5,2)])
|
|
|
|
@pytest.mark.parametrize('kw',[{'V_e':np.random.rand(3,3)},
|
|
|
|
{'O':np.random.rand(4)},
|
|
|
|
{'v':np.array(2)}])
|
|
|
|
def test_material_add_invalid(self,kw,shape):
|
|
|
|
kw = {arg:np.broadcast_to(val,shape+val.shape) for arg,val in kw.items()}
|
|
|
|
with pytest.raises(ValueError):
|
|
|
|
ConfigMaterial().material_add(**kw)
|
2021-03-20 17:21:41 +05:30
|
|
|
|
2023-02-03 02:43:17 +05:30
|
|
|
@pytest.mark.parametrize('v',[2,np.ones(3)*2,np.ones((2,2))])
|
|
|
|
def test_material_add_invalid_v(self,v):
|
|
|
|
with pytest.raises(ValueError):
|
|
|
|
ConfigMaterial().material_add(v=v)
|
|
|
|
|
2021-03-20 17:21:41 +05:30
|
|
|
@pytest.mark.parametrize('cell_ensemble_data',[None,'CellEnsembleData'])
|
2023-04-24 10:41:14 +05:30
|
|
|
def test_load_DREAM3D(self,res_path,cell_ensemble_data):
|
|
|
|
grain_c = ConfigMaterial.load_DREAM3D(res_path/'2phase_irregularGrid.dream3d','Grain Data',
|
2021-03-20 17:21:41 +05:30
|
|
|
cell_ensemble_data = cell_ensemble_data)
|
2023-04-24 10:41:14 +05:30
|
|
|
point_c = ConfigMaterial.load_DREAM3D(res_path/'2phase_irregularGrid.dream3d',
|
2021-03-20 17:21:41 +05:30
|
|
|
cell_ensemble_data = cell_ensemble_data)
|
|
|
|
|
2021-03-23 18:12:04 +05:30
|
|
|
assert point_c.is_valid and grain_c.is_valid and \
|
|
|
|
len(point_c['material'])+1 == len(grain_c['material'])
|
2021-03-20 17:21:41 +05:30
|
|
|
|
2023-04-24 10:41:14 +05:30
|
|
|
grain_m = Grid.load_DREAM3D(res_path/'2phase_irregularGrid.dream3d','FeatureIds').material.flatten()
|
|
|
|
point_m = Grid.load_DREAM3D(res_path/'2phase_irregularGrid.dream3d').material.flatten()
|
2021-03-20 17:21:41 +05:30
|
|
|
|
|
|
|
for i in np.unique(point_m):
|
|
|
|
j = int(grain_m[(point_m==i).nonzero()[0][0]])
|
|
|
|
assert np.allclose(point_c['material'][i]['constituents'][0]['O'],
|
|
|
|
grain_c['material'][j]['constituents'][0]['O'])
|
|
|
|
assert point_c['material'][i]['constituents'][0]['phase'] == \
|
|
|
|
grain_c['material'][j]['constituents'][0]['phase']
|
2021-03-23 18:12:04 +05:30
|
|
|
|
|
|
|
|
2023-04-24 10:41:14 +05:30
|
|
|
def test_load_DREAM3D_reference(self,tmp_path,res_path,update):
|
|
|
|
cur = ConfigMaterial.load_DREAM3D(res_path/'measured.dream3d')
|
|
|
|
ref = ConfigMaterial.load(res_path/'measured.material.yaml')
|
2021-03-23 18:12:04 +05:30
|
|
|
if update:
|
2023-04-24 10:41:14 +05:30
|
|
|
cur.save(res_path/'measured.material.yaml')
|
2021-03-26 03:02:09 +05:30
|
|
|
for i,m in enumerate(ref['material']):
|
2021-04-05 21:54:03 +05:30
|
|
|
assert Rotation(m['constituents'][0]['O']).isclose(Rotation(cur['material'][i]['constituents'][0]['O']))
|
2021-03-26 03:02:09 +05:30
|
|
|
assert cur.is_valid and cur['phase'] == ref['phase'] and cur['homogenization'] == ref['homogenization']
|