better name, subclassing for easy extension to load

This commit is contained in:
Martin Diehl 2020-09-30 07:53:25 +02:00
parent e1d459aab8
commit b383a4530e
5 changed files with 95 additions and 75 deletions

View File

@ -18,7 +18,8 @@ from ._lattice import Symmetry, Lattice# noqa
from ._orientation import Orientation # noqa from ._orientation import Orientation # noqa
from ._result import Result # noqa from ._result import Result # noqa
from ._geom import Geom # noqa from ._geom import Geom # noqa
from ._material import Material # noqa from ._config import Config # noqa
from ._configmaterial import ConfigMaterial # noqa
from . import solver # noqa from . import solver # noqa
from . import util # noqa from . import util # noqa
from . import seeds # noqa from . import seeds # noqa

66
python/damask/_config.py Normal file
View File

@ -0,0 +1,66 @@
from io import StringIO
import abc
import yaml
import numpy as np
class NiceDumper(yaml.SafeDumper):
"""Make YAML readable for humans."""
def write_line_break(self, data=None):
super().write_line_break(data)
if len(self.indents) == 1:
super().write_line_break()
def increase_indent(self, flow=False, indentless=False):
return super().increase_indent(flow, False)
class Config(dict):
"""YAML-based configuration."""
def __repr__(self):
"""Show as in file."""
output = StringIO()
self.save(output)
output.seek(0)
return ''.join(output.readlines())
@classmethod
def load(cls,fname):
"""Load from yaml file."""
try:
fhandle = open(fname)
except TypeError:
fhandle = fname
return cls(yaml.safe_load(fhandle))
def save(self,fname='material.yaml'):
"""
Save to yaml file.
Parameters
----------
fname : file, str, or pathlib.Path
Filename or file for reading.
"""
try:
fhandle = open(fname,'w')
except TypeError:
fhandle = fname
fhandle.write(yaml.dump(dict(self),width=256,default_flow_style=None,Dumper=NiceDumper))
@property
@abc.abstractmethod
def is_complete(self):
"""Check for completeness."""
pass
@property
@abc.abstractmethod
def is_valid(self):
"""Check for valid file layout."""
pass

View File

@ -1,61 +1,14 @@
from io import StringIO
import copy import copy
import yaml
import numpy as np import numpy as np
from . import Config
from . import Lattice from . import Lattice
from . import Rotation from . import Rotation
class NiceDumper(yaml.SafeDumper): class ConfigMaterial(Config):
"""Make YAML readable for humans."""
def write_line_break(self, data=None):
super().write_line_break(data)
if len(self.indents) == 1:
super().write_line_break()
def increase_indent(self, flow=False, indentless=False):
return super().increase_indent(flow, False)
class Material(dict):
"""Material configuration.""" """Material configuration."""
def __repr__(self):
"""Show as in file."""
output = StringIO()
self.save(output)
output.seek(0)
return ''.join(output.readlines())
@staticmethod
def load(fname):
"""Load from yaml file."""
try:
fhandle = open(fname)
except TypeError:
fhandle = fname
return Material(yaml.safe_load(fhandle))
def save(self,fname='material.yaml'):
"""
Save to yaml file.
Parameters
----------
fname : file, str, or pathlib.Path
Filename or file for reading.
"""
try:
fhandle = open(fname,'w')
except TypeError:
fhandle = fname
fhandle.write(yaml.dump(dict(self),width=256,default_flow_style=None,Dumper=NiceDumper))
@property @property
def is_complete(self): def is_complete(self):
"""Check for completeness.""" """Check for completeness."""

View File

@ -2,60 +2,60 @@ import os
import pytest import pytest
from damask import Material from damask import ConfigMaterial
@pytest.fixture @pytest.fixture
def reference_dir(reference_dir_base): def reference_dir(reference_dir_base):
"""Directory containing reference results.""" """Directory containing reference results."""
return reference_dir_base/'Material' return reference_dir_base/'ConfigMaterial'
class TestMaterial: class TestMaterial:
@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,reference_dir,tmp_path,fname):
reference = Material.load(reference_dir/'material.yaml') reference = ConfigMaterial.load(reference_dir/'material.yaml')
os.chdir(tmp_path) os.chdir(tmp_path)
if fname is None: if fname is None:
reference.save() reference.save()
new = Material.load('material.yaml') new = ConfigMaterial.load('material.yaml')
else: else:
reference.save(fname) reference.save(fname)
new = Material.load(fname) new = ConfigMaterial.load(fname)
assert reference == new assert reference == new
def test_valid_complete(self,reference_dir): def test_valid_complete(self,reference_dir):
material_config = Material.load(reference_dir/'material.yaml') material_config = ConfigMaterial.load(reference_dir/'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,reference_dir):
material_config = Material.load(reference_dir/'material.yaml') material_config = ConfigMaterial.load(reference_dir/'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,reference_dir):
material_config = Material.load(reference_dir/'material.yaml') material_config = ConfigMaterial.load(reference_dir/'material.yaml')
material_config['microstructure'][0]['constituents'][0]['orientation']=[0,0,0,0] material_config['microstructure'][0]['constituents'][0]['orientation']=[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,reference_dir):
material_config = Material.load(reference_dir/'material.yaml') material_config = ConfigMaterial.load(reference_dir/'material.yaml')
material_config['microstructure'][0]['constituents'][0]['fraction']=.9 material_config['microstructure'][0]['constituents'][0]['fraction']=.9
assert not material_config.is_valid assert not material_config.is_valid
@pytest.mark.parametrize('item',['homogenization','phase','microstructure']) @pytest.mark.parametrize('item',['homogenization','phase','microstructure'])
def test_incomplete_missing(self,reference_dir,item): def test_incomplete_missing(self,reference_dir,item):
material_config = Material.load(reference_dir/'material.yaml') material_config = ConfigMaterial.load(reference_dir/'material.yaml')
del material_config[item] del material_config[item]
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,reference_dir):
material_config = Material.load(reference_dir/'material.yaml') material_config = ConfigMaterial.load(reference_dir/'material.yaml')
new = material_config.microstructure_rename_phase({'Steel':'FeNbC'}) new = material_config.microstructure_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,reference_dir):
material_config = Material.load(reference_dir/'material.yaml') material_config = ConfigMaterial.load(reference_dir/'material.yaml')
new = material_config.microstructure_rename_homogenization({'Taylor':'isostrain'}) new = material_config.microstructure_rename_homogenization({'Taylor':'isostrain'})
assert not new.is_complete assert not new.is_complete