shortened material_add and allow for multi-constituent; broken from_table...
This commit is contained in:
parent
0461c404f7
commit
4a00254dba
|
@ -3,6 +3,7 @@ import numpy as np
|
||||||
from . import Config
|
from . import Config
|
||||||
from . import Rotation
|
from . import Rotation
|
||||||
from . import Orientation
|
from . import Orientation
|
||||||
|
from . import util
|
||||||
|
|
||||||
class ConfigMaterial(Config):
|
class ConfigMaterial(Config):
|
||||||
"""Material configuration."""
|
"""Material configuration."""
|
||||||
|
@ -46,7 +47,7 @@ class ConfigMaterial(Config):
|
||||||
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def from_table(table,constituents={},**kwargs):
|
def from_table(table,**kwargs):
|
||||||
"""
|
"""
|
||||||
Load from an ASCII table.
|
Load from an ASCII table.
|
||||||
|
|
||||||
|
@ -54,12 +55,9 @@ class ConfigMaterial(Config):
|
||||||
----------
|
----------
|
||||||
table : damask.Table
|
table : damask.Table
|
||||||
Table that contains material information.
|
Table that contains material information.
|
||||||
constituents : dict, optional
|
|
||||||
Entries for 'constituents'. The key is the name and the value specifies
|
|
||||||
the label of the data column in the table
|
|
||||||
**kwargs
|
**kwargs
|
||||||
Keyword arguments where the key is the name and the value specifies
|
Keyword arguments where the key is the name and the value specifies
|
||||||
the label of the data column in the table
|
the label of the data column in the table.
|
||||||
|
|
||||||
Examples
|
Examples
|
||||||
--------
|
--------
|
||||||
|
@ -70,7 +68,7 @@ class ConfigMaterial(Config):
|
||||||
pos pos pos qu qu qu qu phase homog
|
pos pos pos qu qu qu qu phase homog
|
||||||
0 0 0 0 0.19 0.8 0.24 -0.51 Aluminum SX
|
0 0 0 0 0.19 0.8 0.24 -0.51 Aluminum SX
|
||||||
1 1 0 0 0.8 0.19 0.24 -0.51 Steel SX
|
1 1 0 0 0.8 0.19 0.24 -0.51 Steel SX
|
||||||
>>> cm.from_table(t,{'O':'qu','phase':'phase'},homogenization='homog')
|
>>> cm.from_table(t,O='qu',phase='phase',homogenization='homog')
|
||||||
material:
|
material:
|
||||||
- constituents:
|
- constituents:
|
||||||
- O: [0.19, 0.8, 0.24, -0.51]
|
- O: [0.19, 0.8, 0.24, -0.51]
|
||||||
|
@ -86,16 +84,17 @@ class ConfigMaterial(Config):
|
||||||
phase: {}
|
phase: {}
|
||||||
|
|
||||||
"""
|
"""
|
||||||
constituents_ = {k:table.get(v) for k,v in constituents.items()}
|
# constituents_ = {k:table.get(v) for k,v in constituents.items()}
|
||||||
kwargs_ = {k:table.get(v) for k,v in kwargs.items()}
|
kwargs_ = {k:table.get(v) for k,v in kwargs.items()}
|
||||||
|
|
||||||
_,idx = np.unique(np.hstack(list({**constituents_,**kwargs_}.values())),return_index=True,axis=0)
|
_,idx = np.unique(kwargs_.values(),return_index=True,axis=0)
|
||||||
|
# _,idx = np.unique(np.hstack(list({**constituents_,**kwargs_}.values())),return_index=True,axis=0)
|
||||||
|
|
||||||
idx = np.sort(idx)
|
idx = np.sort(idx)
|
||||||
constituents_ = {k:np.atleast_1d(v[idx].squeeze()) for k,v in constituents_.items()}
|
# constituents_ = {k:np.atleast_1d(v[idx].squeeze()) for k,v in constituents_.items()}
|
||||||
kwargs_ = {k:np.atleast_1d(v[idx].squeeze()) for k,v in kwargs_.items()}
|
kwargs_ = {k:np.atleast_1d(v[idx].squeeze()) for k,v in kwargs_.items()}
|
||||||
|
|
||||||
return ConfigMaterial().material_add(constituents_,**kwargs_)
|
return ConfigMaterial().material_add(**kwargs_)
|
||||||
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
@ -234,7 +233,7 @@ class ConfigMaterial(Config):
|
||||||
return dup
|
return dup
|
||||||
|
|
||||||
|
|
||||||
def material_add(self,constituents=None,**kwargs):
|
def material_add(self,**kwargs):
|
||||||
"""
|
"""
|
||||||
Add material entries.
|
Add material entries.
|
||||||
|
|
||||||
|
@ -248,9 +247,8 @@ class ConfigMaterial(Config):
|
||||||
Examples
|
Examples
|
||||||
--------
|
--------
|
||||||
>>> import damask
|
>>> import damask
|
||||||
>>> O = damask.Rotation.from_random(3)
|
>>> m = damask.ConfigMaterial().material_add(phase = ['Aluminum','Steel','Aluminum'],
|
||||||
>>> phase = ['Aluminum','Steel','Aluminum']
|
... O = damask.Rotation.from_random(3)},
|
||||||
>>> m = damask.ConfigMaterial().material_add(constituents={'phase':phase,'O':O},
|
|
||||||
... homogenization = 'SX')
|
... homogenization = 'SX')
|
||||||
>>> m
|
>>> m
|
||||||
material:
|
material:
|
||||||
|
@ -273,54 +271,30 @@ class ConfigMaterial(Config):
|
||||||
phase: {}
|
phase: {}
|
||||||
|
|
||||||
"""
|
"""
|
||||||
length = -1
|
N,n,shaped = 1,1,{}
|
||||||
for v in kwargs.values():
|
|
||||||
if hasattr(v,'__len__') and not isinstance(v,str):
|
|
||||||
if length != -1 and len(v) != length:
|
|
||||||
raise ValueError('Cannot add entries of different length')
|
|
||||||
else:
|
|
||||||
length = len(v)
|
|
||||||
length = max(1,length)
|
|
||||||
|
|
||||||
c = [{} for _ in range(length)] if constituents is None else \
|
|
||||||
[{'constituents':u} for u in ConfigMaterial._constituents(**constituents)]
|
|
||||||
|
|
||||||
if len(c) == 1: c = [c[0] for _ in range(length)]
|
|
||||||
|
|
||||||
if length != 1 and length != len(c):
|
|
||||||
raise ValueError('Cannot add entries of different length')
|
|
||||||
|
|
||||||
for k,v in kwargs.items():
|
for k,v in kwargs.items():
|
||||||
if hasattr(v,'__len__') and not isinstance(v,str):
|
shaped[k] = np.array(v)
|
||||||
for i,vv in enumerate(v):
|
s = shaped[k].shape[:-1] if k=='O' else shaped[k].shape
|
||||||
c[i][k] = vv.item() if isinstance(vv,np.generic) else vv
|
N = max(N,s[0]) if len(s)>0 else N
|
||||||
|
n = max(n,s[1]) if len(s)>1 else n
|
||||||
|
|
||||||
|
mat = [{'constituents':[{} for _ in range(n)]} for _ in range(N)]
|
||||||
|
|
||||||
|
if 'v' not in kwargs:
|
||||||
|
shaped['v'] = np.broadcast_to(1/n,(N,n))
|
||||||
|
|
||||||
|
for k,v in shaped.items():
|
||||||
|
obj = np.broadcast_to(v.reshape(util.shapeshifter(v.shape,(N,n,4))),(N,n,4)) if k=='O' else \
|
||||||
|
np.broadcast_to(v.reshape(util.shapeshifter(v.shape,(N,n ))),(N,n))
|
||||||
|
for i in range(N):
|
||||||
|
if k in ['phase','O','v']:
|
||||||
|
for j in range(n):
|
||||||
|
mat[i]['constituents'][j][k] = obj[i,j].item() if isinstance(obj[i,j],np.generic) else obj[i,j]
|
||||||
else:
|
else:
|
||||||
for i in range(len(c)):
|
mat[i][k] = obj[i,0].item() if isinstance(obj[i,0],np.generic) else obj[i,0]
|
||||||
c[i][k] = v
|
|
||||||
dup = self.copy()
|
dup = self.copy()
|
||||||
dup['material'] = dup['material'] + c if 'material' in dup else c
|
dup['material'] = dup['material'] + mat if 'material' in dup else mat
|
||||||
|
|
||||||
return dup
|
return dup
|
||||||
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def _constituents(N=1,**kwargs):
|
|
||||||
"""Construct list of constituents."""
|
|
||||||
N_material=1
|
|
||||||
for v in kwargs.values():
|
|
||||||
if hasattr(v,'__len__') and not isinstance(v,str): N_material = len(v)
|
|
||||||
|
|
||||||
if N == 1:
|
|
||||||
m = [[{'v':1.0}] for _ in range(N_material)]
|
|
||||||
for k,v in kwargs.items():
|
|
||||||
if hasattr(v,'__len__') and not isinstance(v,str):
|
|
||||||
if len(v) != N_material:
|
|
||||||
raise ValueError('Cannot add entries of different length')
|
|
||||||
for i,vv in enumerate(np.array(v)):
|
|
||||||
m[i][0][k] = vv.item() if isinstance(vv,np.generic) else vv
|
|
||||||
else:
|
|
||||||
for i in range(N_material):
|
|
||||||
m[i][0][k] = v
|
|
||||||
return m
|
|
||||||
else:
|
|
||||||
raise NotImplementedError
|
|
||||||
|
|
|
@ -5,6 +5,7 @@ import numpy as np
|
||||||
|
|
||||||
from damask import ConfigMaterial
|
from damask import ConfigMaterial
|
||||||
from damask import Table
|
from damask import Table
|
||||||
|
from damask import Rotation
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def ref_path(ref_path_base):
|
def ref_path(ref_path_base):
|
||||||
|
@ -85,42 +86,28 @@ class TestConfigMaterial:
|
||||||
|
|
||||||
def test_from_table(self):
|
def test_from_table(self):
|
||||||
N = np.random.randint(3,10)
|
N = np.random.randint(3,10)
|
||||||
a = np.vstack((np.hstack((np.arange(N),np.arange(N)[::-1])),np.ones(N*2),np.zeros(N*2),np.ones(N*2))).T
|
a = np.vstack((np.hstack((np.arange(N),np.arange(N)[::-1])),np.ones(N*2),np.zeros(N*2),np.ones(N*2),np.ones(N*2))).T
|
||||||
t = Table(a,{'varying':2,'constant':2})
|
print(a)
|
||||||
c = ConfigMaterial.from_table(t,constituents={'a':'varying','b':'1_constant'},c='2_constant')
|
t = Table(a,{'varying':1,'constant':4})
|
||||||
|
c = ConfigMaterial.from_table(t,**{'phase':'varying','O':'constant'})
|
||||||
assert len(c['material']) == N
|
assert len(c['material']) == N
|
||||||
for i,m in enumerate(c['material']):
|
print(c)
|
||||||
c = m['constituents'][0]
|
# for i,m in enumerate(c['material']):
|
||||||
assert m['c'] == 1 and c['b'] == 0 and (c['a'] == [i,1]).all()
|
# c = m['constituents'][0]
|
||||||
|
# assert m['c'] == 1 and c['b'] == 0 and (c['a'] == [i,1]).all()
|
||||||
|
|
||||||
def test_constituents(self):
|
@pytest.mark.parametrize('N,n,kw',[
|
||||||
c = ConfigMaterial._constituents(c=1,v=[2,3])
|
(1,1,{'phase':'Gold',
|
||||||
assert c[0][0]['c'] == c[1][0]['c'] == 1
|
'O':[1,0,0,0],
|
||||||
assert c[0][0]['v'] == c[1][0]['v'] -1 ==2
|
'homogenization':'SX'}),
|
||||||
|
(3,1,{'phase':'Gold',
|
||||||
@pytest.mark.parametrize('constituents',[{'W':1,'X':[2,3]},{'Y':4},{'Z':[5,6]}])
|
'O':Rotation.from_random(3),
|
||||||
@pytest.mark.parametrize('a',[[7.,8.],9.])
|
'homogenization':'SX'}),
|
||||||
@pytest.mark.parametrize('b',['bd',['efg','hi']])
|
(2,3,{'phase':np.broadcast_to(['a','b','c'],(2,3)),
|
||||||
def test_material_add(self,tmp_path,constituents,a,b):
|
'O':Rotation.from_random((2,3)),
|
||||||
len_c = len(ConfigMaterial()._constituents(1,**constituents))
|
'homogenization':['SX','PX']}),
|
||||||
len_a = len(a) if isinstance(a,list) else 1
|
])
|
||||||
len_b = len(b) if isinstance(b,list) else 1
|
def test_material_add(self,kw,N,n):
|
||||||
m = ConfigMaterial().material_add(constituents,a=a,b=b)
|
m = ConfigMaterial().material_add(**kw)
|
||||||
m.save()
|
assert len(m['material']) == N
|
||||||
assert len(m['material']) == np.max([len_a,len_b,len_c])
|
assert len(m['material'][0]['constituents']) == n
|
||||||
|
|
||||||
@pytest.mark.parametrize('constituents',[{'W':1,'X':np.array([2,3])},{'Y':4},{'Z':np.array([5,6])}])
|
|
||||||
@pytest.mark.parametrize('a',[np.array([7,8]),9])
|
|
||||||
def test_material_add_np(self,tmp_path,constituents,a):
|
|
||||||
len_c = len(ConfigMaterial()._constituents(1,**constituents))
|
|
||||||
len_a = len(a) if isinstance(a,np.ndarray) else 1
|
|
||||||
m = ConfigMaterial().material_add(constituents,ld=a)
|
|
||||||
m.save()
|
|
||||||
assert len(m['material']) == np.max([len_a,len_c])
|
|
||||||
|
|
||||||
@pytest.mark.parametrize('constituents',[{'X':np.array([2,3,4,5])},{'Y':4}])
|
|
||||||
@pytest.mark.parametrize('a',[np.array([1,2,3]),[4,5,6]])
|
|
||||||
@pytest.mark.parametrize('b',[np.array([6.,7.]),[8.,9.]])
|
|
||||||
def test_material_add_invalid(self,constituents,a,b):
|
|
||||||
with pytest.raises(ValueError):
|
|
||||||
ConfigMaterial().material_add(constituents,a=a,u=b)
|
|
||||||
|
|
Loading…
Reference in New Issue