diff --git a/python/damask/_configmaterial.py b/python/damask/_configmaterial.py index 4f3eba816..6de2283f4 100644 --- a/python/damask/_configmaterial.py +++ b/python/damask/_configmaterial.py @@ -226,13 +226,13 @@ class ConfigMaterial(Config): return dup - def material_add(self,constituents,**kwargs): + def material_add(self,constituents=None,**kwargs): """ Add material entries. Parameters ---------- - constituents : dict + constituents : dict, optional Entries for 'constituents' as key-value pair. **kwargs Key-value pairs. @@ -263,13 +263,26 @@ class ConfigMaterial(Config): homogenization: SX """ - c = [{'constituents':u} for u in ConfigMaterial._constituents(**constituents)] + 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 = [copy.deepcopy(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(): if hasattr(v,'__len__') and not isinstance(v,str): - if len(v) != len(c): - raise ValueError('Cannot add entries of different length') for i,vv in enumerate(v): - c[i][k] = [w.item() for w in vv] if isinstance(vv,np.ndarray) else vv.item() + c[i][k] = vv.item() if isinstance(vv,np.generic) else vv else: for i in range(len(c)): c[i][k] = v @@ -293,7 +306,7 @@ class ConfigMaterial(Config): 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] = [w.item() for w in vv] if isinstance(vv,np.ndarray) else vv.item() + 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 diff --git a/python/tests/test_ConfigMaterial.py b/python/tests/test_ConfigMaterial.py index 0f2b6a90c..25c05d711 100644 --- a/python/tests/test_ConfigMaterial.py +++ b/python/tests/test_ConfigMaterial.py @@ -62,6 +62,12 @@ class TestConfigMaterial: del material_config['material'][0]['homogenization'] assert not material_config.is_complete + def test_incomplete_homogenization_N_constituents(self,reference_dir): + material_config = ConfigMaterial.load(reference_dir/'material.yaml') + for h in material_config['homogenization'].keys(): + del material_config['homogenization'][h]['N_constituents'] + assert not material_config.is_complete + def test_incomplete_phase_lattice(self,reference_dir): material_config = ConfigMaterial.load(reference_dir/'material.yaml') del material_config['phase']['Aluminum']['lattice'] @@ -85,9 +91,36 @@ class TestConfigMaterial: 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] + assert m['c'] == 1 and c['b'] == 0 and (c['a'] == [i,1]).all() - def test__constituents(self): + 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)