Merge remote-tracking branch 'origin/development' into internal-restructure

This commit is contained in:
Sharan Roongta 2021-02-25 22:38:22 +01:00
commit c39533ce8e
23 changed files with 200 additions and 290 deletions

@ -1 +1 @@
Subproject commit 3efdf7dd9de96fe6c55240ecf6d0d78d9d0e36ec
Subproject commit 0289c1bbfec1a1aef77a8cbaeed134035549e738

View File

@ -1 +1 @@
v3.0.0-alpha2-503-g8a1c73ebc
v3.0.0-alpha2-530-g0d0226f70

View File

@ -1,8 +0,0 @@
[SX]
type isostrain
Ngrains 1
{./Homogenization_Damage_NonLocal.config}
{./Homogenization_Thermal_Conduction.config}
{./Homogenization_VacancyFlux_CahnHilliard.config}
{./Homogenization_Porosity_PhaseField.config}
{./Homogenization_HydrogenFlux_CahnHilliard.config}

View File

@ -1,9 +1,9 @@
# Kuo, J. C., Mikrostrukturmechanik von Bikristallen mit Kippkorngrenzen. Shaker-Verlag 2004. http://edoc.mpg.de/204079
Aluminum:
lattice: aP
mechanics:
lattice: aP
elasticity: {C_11: 110.9e9, C_12: 58.34e9, type: hooke}
output: [F, P, Fe, Fp, Lp]
output: [F, P, F_e, F_p, L_p]
elasticity: {type: hooke, C_11: 110.9e9, C_12: 58.34e9}
plasticity:
type: isotropic
output: [xi]

View File

@ -1,9 +1,8 @@
# Maiti and Eisenlohr 2018 Scripta Materialia
Air:
lattice: aP
mechanics:
lattice: aP
elasticity: {C_11: 10e9, C_12: 0.0, type: hooke}
output: [F, P, Fe, Fp, Lp]
output: [F, P, F_e, F_p, L_p]
elasticity: {type: hooke, C_11: 1e8, C_12: 1e6}
plasticity:
type: isotropic
output: [xi]
@ -14,4 +13,4 @@ Air:
M: 3
h_0: 1e6
a: 2
dilatation: true
dilatation: True

View File

@ -1,21 +0,0 @@
[Aluminum]
elasticity hooke
plasticity phenopowerlaw
(output) resistance_slip
(output) accumulatedshear_slip
lattice_structure fcc
Nslip 12 # per family
c11 106.75e9
c12 60.41e9
c44 28.34e9
gdot0_slip 0.001
n_slip 20
tau0_slip 31e6 # per family
tausat_slip 63e6 # per family
a_slip 2.25
h0_slipslip 75e6
interaction_slipslip 1 1 1.4 1.4 1.4 1.4

View File

@ -0,0 +1,16 @@
Aluminum:
lattice: cF
mechanics:
output: [F, P, F_e, F_p, L_p, O]
elasticity: {C_11: 106.75e9, C_12: 60.41e9, C_44: 28.34e9, type: hooke}
plasticity:
N_sl: [12]
a_sl: 2.25
dot_gamma_0_sl: 0.001
h_0_sl_sl: 75e6
h_sl_sl: [1, 1, 1.4, 1.4, 1.4, 1.4]
n_sl: 20
output: [xi_sl, gamma_sl]
type: phenopowerlaw
xi_0_sl: [31e6]
xi_inf_sl: [63e6]

View File

@ -2,8 +2,8 @@
# Tasan et.al. 2015 International Journal of Plasticity
# Diehl et.al. 2015 Meccanica
Ferrite:
lattice: cI
mechanics:
lattice: cI
elasticity: {C_11: 233.3e9, C_12: 135.5e9, C_44: 118.0e9, type: hooke}
plasticity:
N_sl: [12, 12]

View File

@ -2,8 +2,8 @@
# Tasan et.al. 2015 International Journal of Plasticity
# Diehl et.al. 2015 Meccanica
Martensite:
lattice: cI
mechanics:
lattice: cI
elasticity: {C_11: 417.4e9, C_12: 242.4e9, C_44: 211.1e9, type: hooke}
plasticity:
N_sl: [12, 12]

View File

@ -1,27 +0,0 @@
# parameters fitted by D. Ma to:
# I. Kovács, G. Vörös
# On the mathematical description of the tensile stress-strain curves of polycrystalline face centered cubic metals
# International Journal of Plasticity, Volume 12, Issue 1, 1996, Pages 3543
# DOI: 10.1016/S0749-6419(95)00043-7
[gold_phenopowerlaw]
elasticity hooke
plasticity phenopowerlaw
(output) resistance_slip
lattice_structure fcc
Nslip 12 # per family
c11 191.0e9
c12 162.0e9
c44 42.20e9
gdot0_slip 0.001
n_slip 83.3
tau0_slip 26.25e6 # per family
tausat_slip 53.00e6 # per family
a_slip 1.0
h0_slipslip 75e6
interaction_slipslip 1 1 1.4 1.4 1.4 1.4

View File

@ -0,0 +1,21 @@
# parameters fitted by D. Ma to:
# On the mathematical description of the tensile stress-strain curves of polycrystalline face centered cubic metals
# International Journal of Plasticity, Volume 12, Issue 1, 1996, Pages 35-43
# DOI: 10.1016/S0749-6419(95)00043-7
Gold:
lattice: cF
mechanics:
output: [F, P, F_e, F_p, L_p, O]
elasticity: {type: hooke, C_11: 191e9, C_12: 162e9, C_44: 42.2e9}
plasticity:
type: phenopowerlaw
output: [xi_sl]
N_sl: [12]
n_sl: 83
dot_gamma_0_sl: 0.001
h_0_sl_sl: 75e6
h_sl_sl: [1, 1, 1.4, 1.4, 1.4, 1.4]
a_sl: 1.0
xi_0_sl: [26e6]
xi_inf_sl: [53e6]

View File

@ -1,56 +0,0 @@
#-------------------#
<phase>
#-------------------#
/echo/
[Mg]
plasticity phenopowerlaw
elasticity hooke
(output) resistance_slip
(output) resistance_twin
lattice_structure hex
c/a 1.62350 # from Tromans 2011, Elastic Anisotropy of HCP Metal Crystals and Polycrystals
c11 59.3e9 # - " -
c33 61.5e9 # - " -
c44 16.4e9 # - " -
c12 25.7e9 # - " -
c13 21.4e9 # - " -
# basal prism prism pyr(a) pyr(c+a) pyr(c+a)
Nslip 3 3 0 6 0 6 # from Agnew et al 2006, Validating a polycrystal model for the elastoplastic response of mg alloy AZ32 using in situ neutron diffraction
# T1 C1 T2 C2
Ntwin 6 0 0 6 # - " -
# basal prism prism pyr(a) pyr(c+a) pyr(c+a)
tau0_slip 10.0e6 55.0e6 0 60.0e6 0.0 60.0e6 # - " - table 1, pyr(a) set to pyr(c+a)
tausat_slip 40.0e6 135.0e6 0 150.0e6 0.0 150.0e6 # - " - table 1, pyr(a) set to pyr(c+a)
# T1 C1 T2 C2
tau0_twin 40e6 0.0 0.0 60.0e6 # - " - table 1, compressive twin guessed by Steffi, tensile twin modified to match experimental results
h0_twintwin 50.0e6 # - " - table 1, same range as theta_0
h0_slipslip 500.0e6 # - " - table 1, same range as theta_0
h0_twinslip 150.0e6 # guessing
interaction_slipslip 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 # just guessing
interaction_twintwin 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 # - " -
interaction_sliptwin 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 # - " -
interaction_twinslip 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 # - " -
####################################################
# open for discussion
####################################################
n_twin 20
n_slip 20
gdot0_twin 0.001
gdot0_slip 0.001
twin_b 0
twin_c 0
twin_d 20
twin_e 20
a_slip 2.25
s_pr 10.0 # push-up factor for slip saturation due to twinning

View File

@ -0,0 +1,31 @@
# Tromans 2011, Elastic Anisotropy of HCP Metal Crystals and Polycrystals
Magnesium:
lattice: hP
c/a: 1.62350
mechanics:
output: [F, P, F_e, F_p, L_p, O]
elasticity: {C_11: 59.3e9, C_12: 25.7e9, C_13: 21.4e9, C_33: 61.5e9, C_44: 16.4e9, type: hooke}
plasticity:
N_sl: [3, 3, 0, 6, 0, 6]
N_tw: [6, 0, 0, 6]
h_0_tw_tw: 50.0e6
h_0_sl_sl: 500.0e6
h_0_tw_sl: 150.0e6
h_sl_sl: [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
h_tw_tw: [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
h_sl_tw: [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
h_tw_sl: [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
output: [xi_sl, xi_tw]
type: phenopowerlaw
xi_0_sl: [10.0e6, 55.0e6, 0, 60.0e6, 0.0, 60.0e6]
xi_inf_sl: [40.0e6, 135.0e6, 0, 150.0e6, 0.0, 150.0e6]
xi_0_tw: [40e6, 0.0, 0.0, 60.0e6]
####################################################
# open for discussion
####################################################
a_sl: 2.25
dot_gamma_0_sl: 0.001
dot_gamma_0_tw: 0.001
n_sl: 20
n_tw: 20
f_sl_sat_tw: 10.0

View File

@ -1,23 +0,0 @@
[cpTi-alpha]
plasticity phenopowerlaw
elasticity hooke
lattice_structure hex
covera_ratio 1.587
# M. Levy, Handbook of Elastic Properties of Solids, Liquids, and Gases (2001)
c11 160.0e9
c12 90.0e9
c13 66.0e9
c33 181.7e9
c44 46.5e9
# C. Zambaldi, "Orientation informed nanoindentation of a-titanium: Indentation pileup in hexagonal metals deforming by prismatic slip", J. Mater. Res., Vol. 27, No. 1, Jan 14, 2012
gdot0_slip 0.001
n_slip 20
nslip 3 3 0 6
tau0_slip 349.3e6 150e6 0 1107.9e6
tausat_slip 568.6e6 1502.2e6 0 3420.1e6
a_slip 2
h0_slipslip 15e6
interaction_slipslip 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1

View File

@ -0,0 +1,19 @@
# M. Levy, Handbook of Elastic Properties of Solids, Liquids, and Gases (2001)
# C. Zambaldi, "Orientation informed nanoindentation of a-titanium: Indentation pileup in hexagonal metals deforming by prismatic slip", J. Mater. Res., Vol. 27, No. 1, Jan 14, 2012
Ti-alpha:
lattice: hP
c/a: 1.587
mechanics:
output: [F, P, F_e, F_p, L_p, O]
elasticity: {C_11: 160.0e9, C_12: 90.0e9, C_13: 66.0e9, C_33: 181.7e9, C_44: 46.5e9, type: hooke}
plasticity:
N_sl: [3, 3, 0, 0, 12]
a_sl: 2.0
dot_gamma_0_sl: 0.001
h_0_sl_sl: 200e6
h_sl_sl: [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
n_sl: 20
output: [gamma_sl]
type: phenopowerlaw
xi_0_sl: [349e6, 150e6, 0, 0, 1107e6]
xi_inf_sl: [568e6, 1502e6, 0, 0, 3420e6]

View File

@ -1,2 +0,0 @@
[001]
(gauss) phi1 0.000 Phi 0.000 phi2 0.000

View File

@ -1,2 +0,0 @@
[101]
(gauss) phi1 0.000 Phi 45.000 phi2 90.000

View File

@ -1,2 +0,0 @@
[111]
(gauss) phi1 0.000 Phi 54.7356 phi2 45.000

View File

@ -1,2 +0,0 @@
[123]
(gauss) phi1 209.805 Phi 29.206 phi2 63.435

View File

@ -1,20 +0,0 @@
# The material.config file needs to specify five parts:
# homogenization, microstructure, crystallite, phase, and texture.
# You can either put the full text in here or include suited separate files
<homogenization>
{./Homogenization_Isostrain_SX.config}
<microstructure>
[one_only]
crystallite 1
(constituent) phase 1 texture 1 fraction 1.0
<crystallite>
{./Crystallite_All.config}
<phase>
{./Phase_Phenopowerlaw_Aluminum.config}
<texture>
{./Texture_Gauss_001.config}

View File

@ -3,6 +3,7 @@ import numpy as np
from . import Config
from . import Rotation
from . import Orientation
from . import util
class ConfigMaterial(Config):
"""Material configuration."""
@ -46,7 +47,7 @@ class ConfigMaterial(Config):
@staticmethod
def from_table(table,constituents={},**kwargs):
def from_table(table,**kwargs):
"""
Load from an ASCII table.
@ -54,12 +55,9 @@ class ConfigMaterial(Config):
----------
table : damask.Table
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
Keyword arguments where the key is the name and the value specifies
the label of the data column in the table
Keyword arguments where the key is the name and the value specifies
the label of the data column in the table.
Examples
--------
@ -70,7 +68,8 @@ class ConfigMaterial(Config):
pos pos pos qu qu qu qu phase homog
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
>>> cm.from_table(t,{'O':'qu','phase':'phase'},homogenization='homog')
1 1 1 0 0.8 0.19 0.24 -0.51 Steel SX
>>> cm.from_table(t,O='qu',phase='phase',homogenization='homog')
material:
- constituents:
- O: [0.19, 0.8, 0.24, -0.51]
@ -86,16 +85,13 @@ class ConfigMaterial(Config):
phase: {}
"""
constituents_ = {k:table.get(v) for k,v in constituents.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(np.hstack(list(kwargs_.values())),return_index=True,axis=0)
idx = np.sort(idx)
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
@ -153,7 +149,7 @@ class ConfigMaterial(Config):
@property
def is_valid(self):
"""Check for valid file layout."""
"""Check for valid content."""
ok = True
if 'phase' in self:
@ -162,8 +158,7 @@ class ConfigMaterial(Config):
try:
Orientation(lattice=v['lattice'])
except KeyError:
s = v['lattice']
print(f"Invalid lattice: '{s}' in phase '{k}'")
print(f"Invalid lattice '{v['lattice']}' in phase '{k}'")
ok = False
if 'material' in self:
@ -171,16 +166,15 @@ class ConfigMaterial(Config):
if 'constituents' in m:
v = 0.0
for c in m['constituents']:
v+= float(c['v'])
v += float(c['v'])
if 'O' in c:
try:
Rotation.from_quaternion(c['O'])
except ValueError:
o = c['O']
print(f"Invalid orientation: '{o}' in material '{i}'")
print(f"Invalid orientation '{c['O']}' in material '{i}'")
ok = False
if not np.isclose(v,1.0):
print(f"Invalid total fraction (v) '{v}' in material '{i}'")
print(f"Total fraction v = {v} ≠ 1 in material '{i}'")
ok = False
return ok
@ -199,6 +193,11 @@ class ConfigMaterial(Config):
constituent: list of ints, optional
Limit renaming to selected constituents.
Returns
-------
cfg : damask.ConfigMaterial
Updated material configuration.
"""
dup = self.copy()
for i,m in enumerate(dup['material']):
@ -223,6 +222,11 @@ class ConfigMaterial(Config):
ID: list of ints, optional
Limit renaming to selected homogenization IDs.
Returns
-------
cfg : damask.ConfigMaterial
Updated material configuration.
"""
dup = self.copy()
for i,m in enumerate(dup['material']):
@ -234,24 +238,27 @@ class ConfigMaterial(Config):
return dup
def material_add(self,constituents=None,**kwargs):
def material_add(self,**kwargs):
"""
Add material entries.
Parameters
----------
constituents : dict, optional
Entries for 'constituents' as key-value pair.
**kwargs
Key-value pairs.
Returns
-------
cfg : damask.ConfigMaterial
Updated material configuration.
Examples
--------
>>> import numpy as np
>>> import damask
>>> O = damask.Rotation.from_random(3)
>>> phase = ['Aluminum','Steel','Aluminum']
>>> m = damask.ConfigMaterial().material_add(constituents={'phase':phase,'O':O},
... homogenization='SX')
>>> m = damask.ConfigMaterial().material_add(phase = ['Aluminum','Steel'],
... O = damask.Rotation.from_random(2),
... homogenization = 'SX')
>>> m
material:
- constituents:
@ -264,63 +271,59 @@ class ConfigMaterial(Config):
v: 1.0
phase: Steel
homogenization: SX
homogenization: {}
phase: {}
>>> m = damask.ConfigMaterial().material_add(phase = np.array(['Austenite','Martensite']).reshape(1,2),
... O = damask.Rotation.from_random((2,2)),
... v = np.array([0.2,0.8]).reshape(1,2),
... homogenization = ['A','B'])
>>> m
material:
- constituents:
- O: [0.0886257, -0.144848, 0.615674, -0.769487]
v: 1.0
phase: Aluminum
homogenization: SX
- phase: Austenite
O: [0.659802978293224, 0.6953785848195171, 0.22426295326327111, -0.17554139512785227]
v: 0.2
- phase: Martensite
O: [0.49356745891301596, 0.2841806579193434, -0.7487679215072818, -0.339085707289975]
v: 0.8
homogenization: A
- constituents:
- phase: Austenite
O: [0.26542221365204055, 0.7268854930702071, 0.4474726435701472, -0.44828201137283735]
v: 0.2
- phase: Martensite
O: [0.6545817158479885, -0.08004812803625233, -0.6226561293931374, 0.4212059104577611]
v: 0.8
homogenization: B
homogenization: {}
phase: {}
"""
length = -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')
N,n,shaped = 1,1,{}
for k,v in kwargs.items():
if hasattr(v,'__len__') and not isinstance(v,str):
for i,vv in enumerate(v):
c[i][k] = vv.item() if isinstance(vv,np.generic) else vv
else:
for i in range(len(c)):
c[i][k] = v
shaped[k] = np.array(v)
s = shaped[k].shape[:-1] if k=='O' else shaped[k].shape
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():
target = (N,n,4) if k=='O' else (N,n)
obj = np.broadcast_to(v.reshape(util.shapeshifter(v.shape,target,mode='right')),target)
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:
mat[i][k] = obj[i,0].item() if isinstance(obj[i,0],np.generic) else obj[i,0]
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
@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

View File

@ -122,7 +122,7 @@ class Grid:
@size.setter
def size(self,size):
if len(size) != 3 or any(np.array(size) <= 0):
if len(size) != 3 or any(np.array(size) < 0):
raise ValueError(f'invalid size {size}')
else:
self._size = np.array(size)
@ -303,7 +303,7 @@ class Grid:
Need to be ordered (1./x fast, 3./z slow).
labels : str or list of str
Label(s) of the columns containing the material definition.
Each unique combintation of values results in one material ID.
Each unique combination of values results in one material ID.
"""
cells,size,origin = grid_filters.cellsSizeOrigin_coordinates0_point(table.get(coordinates))

View File

@ -5,6 +5,7 @@ import numpy as np
from damask import ConfigMaterial
from damask import Table
from damask import Rotation
@pytest.fixture
def ref_path(ref_path_base):
@ -85,42 +86,25 @@ class TestConfigMaterial:
def test_from_table(self):
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
t = Table(a,{'varying':2,'constant':2})
c = ConfigMaterial.from_table(t,constituents={'a':'varying','b':'1_constant'},c='2_constant')
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':1,'constant':4})
c = ConfigMaterial.from_table(t,**{'phase':'varying','O':'constant','homogenization':'4_constant'})
assert len(c['material']) == N
for i,m in enumerate(c['material']):
c = m['constituents'][0]
assert m['c'] == 1 and c['b'] == 0 and (c['a'] == [i,1]).all()
assert m['homogenization'] == 1 and (m['constituents'][0]['O'] == [1,0,1,1]).all()
def test_constituents(self):
c = ConfigMaterial._constituents(c=1,v=[2,3])
assert c[0][0]['c'] == c[1][0]['c'] == 1
assert c[0][0]['v'] == c[1][0]['v'] -1 ==2
@pytest.mark.parametrize('constituents',[{'W':1,'X':[2,3]},{'Y':4},{'Z':[5,6]}])
@pytest.mark.parametrize('a',[[7.,8.],9.])
@pytest.mark.parametrize('b',['bd',['efg','hi']])
def test_material_add(self,tmp_path,constituents,a,b):
len_c = len(ConfigMaterial()._constituents(1,**constituents))
len_a = len(a) if isinstance(a,list) else 1
len_b = len(b) if isinstance(b,list) else 1
m = ConfigMaterial().material_add(constituents,a=a,b=b)
m.save()
assert len(m['material']) == np.max([len_a,len_b,len_c])
@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)
@pytest.mark.parametrize('N,n,kw',[
(1,1,{'phase':'Gold',
'O':[1,0,0,0],
'homogenization':'SX'}),
(3,1,{'phase':'Gold',
'O':Rotation.from_random(3),
'homogenization':'SX'}),
(2,3,{'phase':np.broadcast_to(['a','b','c'],(2,3)),
'O':Rotation.from_random((2,3)),
'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