Merge branch 'YAML-class-improvements' into 'development'
some improvements to the YAML-related classes in Python See merge request damask/DAMASK!710
This commit is contained in:
commit
750a0443ad
|
@ -43,7 +43,7 @@ class NiceDumper(SafeDumper):
|
||||||
return self.represent_data(data.tolist())
|
return self.represent_data(data.tolist())
|
||||||
if isinstance(data, Rotation):
|
if isinstance(data, Rotation):
|
||||||
return self.represent_data(data.quaternion.tolist())
|
return self.represent_data(data.quaternion.tolist())
|
||||||
if hasattr(data, 'dtype'):
|
if isinstance(data, np.generic):
|
||||||
return self.represent_data(data.item())
|
return self.represent_data(data.item())
|
||||||
|
|
||||||
return super().represent_data(data)
|
return super().represent_data(data)
|
||||||
|
@ -57,13 +57,23 @@ class Config(dict):
|
||||||
"""YAML-based configuration."""
|
"""YAML-based configuration."""
|
||||||
|
|
||||||
def __init__(self,
|
def __init__(self,
|
||||||
yml: Union[None, str, Dict[str, Any]] = None,
|
config: Optional[Union[str, Dict[str, Any]]] = None,
|
||||||
**kwargs):
|
**kwargs):
|
||||||
"""Initialize from YAML, dict, or key=value pairs."""
|
"""
|
||||||
if isinstance(yml,str):
|
New YAML-based configuration.
|
||||||
kwargs.update(yaml.load(yml, Loader=SafeLoader))
|
|
||||||
elif isinstance(yml,dict):
|
Parameters
|
||||||
kwargs.update(yml)
|
----------
|
||||||
|
config : dict or str, optional
|
||||||
|
Configuration. String needs to be valid YAML.
|
||||||
|
**kwargs: arbitray keyword-value pairs, optional
|
||||||
|
Top level entries of the configuration.
|
||||||
|
|
||||||
|
"""
|
||||||
|
if isinstance(config,str):
|
||||||
|
kwargs.update(yaml.load(config, Loader=SafeLoader))
|
||||||
|
elif isinstance(config,dict):
|
||||||
|
kwargs.update(config)
|
||||||
|
|
||||||
super().__init__(**kwargs)
|
super().__init__(**kwargs)
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
import numpy as np
|
|
||||||
import h5py
|
|
||||||
from typing import Optional, Union, Sequence, Dict, Any, Collection
|
from typing import Optional, Union, Sequence, Dict, Any, Collection
|
||||||
|
|
||||||
from ._typehints import FileHandle
|
import numpy as np
|
||||||
|
import h5py
|
||||||
|
|
||||||
|
from ._typehints import FileHandle, FloatSequence, StrSequence
|
||||||
from . import Config
|
from . import Config
|
||||||
from . import Rotation
|
from . import Rotation
|
||||||
from . import Orientation
|
from . import Orientation
|
||||||
|
@ -22,33 +23,34 @@ class ConfigMaterial(Config):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self,
|
def __init__(self,
|
||||||
d: Optional[Dict[str, Any]] = None,
|
config: Optional[Dict[str, Any]] = None,
|
||||||
**kwargs):
|
**kwargs):
|
||||||
"""
|
"""
|
||||||
New material configuration.
|
New material configuration.
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
----------
|
----------
|
||||||
d : dictionary or YAML string, optional
|
config : dict or str, optional
|
||||||
Initial content. Defaults to None, in which case empty entries for
|
Material configuration. String needs to be valid YAML.
|
||||||
|
Defaults to None, in which case empty entries for
|
||||||
any missing material, homogenization, and phase entry are created.
|
any missing material, homogenization, and phase entry are created.
|
||||||
kwargs : key=value pairs, optional
|
kwargs : key=value pairs, optional
|
||||||
Initial content specified as pairs of key=value.
|
Initial content specified as pairs of key=value.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
default: Collection
|
default: Collection
|
||||||
if d is None:
|
if config is None:
|
||||||
for section, default in {'material':[],'homogenization':{},'phase':{}}.items():
|
for section, default in {'material':[],'homogenization':{},'phase':{}}.items():
|
||||||
if section not in kwargs: kwargs.update({section:default})
|
if section not in kwargs: kwargs.update({section:default})
|
||||||
|
|
||||||
super().__init__(d,**kwargs)
|
super().__init__(config,**kwargs)
|
||||||
|
|
||||||
|
|
||||||
def save(self,
|
def save(self,
|
||||||
fname: FileHandle = 'material.yaml',
|
fname: FileHandle = 'material.yaml',
|
||||||
**kwargs):
|
**kwargs):
|
||||||
"""
|
"""
|
||||||
Save to yaml file.
|
Save to YAML file.
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
----------
|
----------
|
||||||
|
@ -65,7 +67,7 @@ class ConfigMaterial(Config):
|
||||||
def load(cls,
|
def load(cls,
|
||||||
fname: FileHandle = 'material.yaml') -> 'ConfigMaterial':
|
fname: FileHandle = 'material.yaml') -> 'ConfigMaterial':
|
||||||
"""
|
"""
|
||||||
Load from yaml file.
|
Load from YAML file.
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
----------
|
----------
|
||||||
|
@ -361,7 +363,7 @@ class ConfigMaterial(Config):
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
----------
|
----------
|
||||||
mapping: dictionary
|
mapping: dict
|
||||||
Mapping from old name to new name
|
Mapping from old name to new name
|
||||||
ID: list of ints, optional
|
ID: list of ints, optional
|
||||||
Limit renaming to selected material IDs.
|
Limit renaming to selected material IDs.
|
||||||
|
@ -394,7 +396,7 @@ class ConfigMaterial(Config):
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
----------
|
----------
|
||||||
mapping: dictionary
|
mapping: dict
|
||||||
Mapping from old name to new name
|
Mapping from old name to new name
|
||||||
ID: list of ints, optional
|
ID: list of ints, optional
|
||||||
Limit renaming to selected homogenization IDs.
|
Limit renaming to selected homogenization IDs.
|
||||||
|
@ -416,11 +418,11 @@ class ConfigMaterial(Config):
|
||||||
|
|
||||||
|
|
||||||
def material_add(self,*,
|
def material_add(self,*,
|
||||||
homogenization: Any = None,
|
homogenization: Optional[Union[str,StrSequence]] = None,
|
||||||
phase: Any = None,
|
phase: Optional[Union[str,StrSequence]] = None,
|
||||||
v: Any = None,
|
v: Optional[Union[float,FloatSequence]] = None,
|
||||||
O: Any = None,
|
O: Optional[Union[float,FloatSequence]] = None,
|
||||||
V_e: Any = None) -> 'ConfigMaterial':
|
V_e: Optional[Union[float,FloatSequence]] = None) -> 'ConfigMaterial':
|
||||||
"""
|
"""
|
||||||
Add material entries.
|
Add material entries.
|
||||||
|
|
||||||
|
@ -432,6 +434,7 @@ class ConfigMaterial(Config):
|
||||||
Phase label (per constituent).
|
Phase label (per constituent).
|
||||||
v: (array-like) of float, optional
|
v: (array-like) of float, optional
|
||||||
Constituent volume fraction (per constituent).
|
Constituent volume fraction (per constituent).
|
||||||
|
Defaults to 1/N_constituents
|
||||||
O: (array-like) of damask.Rotation or np.array/list of shape(4), optional
|
O: (array-like) of damask.Rotation or np.array/list of shape(4), optional
|
||||||
Orientation as unit quaternion (per constituent).
|
Orientation as unit quaternion (per constituent).
|
||||||
V_e: (array-like) of np.array/list of shape(3,3), optional
|
V_e: (array-like) of np.array/list of shape(3,3), optional
|
||||||
|
@ -444,9 +447,8 @@ class ConfigMaterial(Config):
|
||||||
|
|
||||||
Notes
|
Notes
|
||||||
-----
|
-----
|
||||||
First index of array-like values that are defined per
|
First index of array-like values that are defined per constituent
|
||||||
consituent runs over materials, whereas second index runs
|
runs over materials, whereas second index runs over constituents.
|
||||||
over constituents.
|
|
||||||
|
|
||||||
Examples
|
Examples
|
||||||
--------
|
--------
|
||||||
|
@ -533,32 +535,32 @@ class ConfigMaterial(Config):
|
||||||
_dim = {'O':(4,),'V_e':(3,3,)}
|
_dim = {'O':(4,),'V_e':(3,3,)}
|
||||||
_ex = dict((k, -len(v)) for k, v in _dim.items())
|
_ex = dict((k, -len(v)) for k, v in _dim.items())
|
||||||
|
|
||||||
N,n = 1,1
|
N_materials,N_constituents = 1,1
|
||||||
shaped : Dict[str, Union[None,np.ndarray]] = \
|
shaped : Dict[str, Union[None,np.ndarray]] = \
|
||||||
{'v': None,
|
{'v': None,
|
||||||
'phase': None,
|
'phase': None,
|
||||||
'homogenization': None,
|
'homogenization': None,
|
||||||
}
|
}
|
||||||
|
|
||||||
for k,v in kwargs.items():
|
for arg,value in kwargs.items():
|
||||||
shaped[k] = np.array(v)
|
shaped[arg] = np.array(value)
|
||||||
s = shaped[k].shape[:_ex.get(k,None)] # type: ignore
|
s = shaped[arg].shape[:_ex.get(arg,None)] # type: ignore
|
||||||
N = max(N,s[0]) if len(s)>0 else N
|
N_materials = max(N_materials,s[0]) if len(s)>0 else N_materials
|
||||||
n = max(n,s[1]) if len(s)>1 else n
|
N_constituents = max(N_constituents,s[1]) if len(s)>1 else N_constituents
|
||||||
|
|
||||||
shaped['v'] = np.array(1./n) if shaped['v'] is None else shaped['v']
|
shaped['v'] = np.array(1./N_constituents) if shaped['v'] is None else shaped['v']
|
||||||
|
|
||||||
mat: Sequence[dict] = [{'constituents':[{} for _ in range(n)]} for _ in range(N)]
|
mat: Sequence[dict] = [{'constituents':[{} for _ in range(N_constituents)]} for _ in range(N_materials)]
|
||||||
|
|
||||||
for k,v in shaped.items():
|
for k,v in shaped.items():
|
||||||
target = (N,n) + _dim.get(k,())
|
target = (N_materials,N_constituents) + _dim.get(k,())
|
||||||
obj = np.broadcast_to(np.array(v).reshape(util.shapeshifter(() if v is None else v.shape,
|
obj = np.broadcast_to(np.array(v).reshape(util.shapeshifter(() if v is None else v.shape,
|
||||||
target,
|
target,
|
||||||
mode = 'right')),
|
mode = 'right')),
|
||||||
target)
|
target)
|
||||||
for i in range(N):
|
for i in range(N_materials):
|
||||||
if k in _constituent_properties:
|
if k in _constituent_properties:
|
||||||
for j in range(n):
|
for j in range(N_constituents):
|
||||||
mat[i]['constituents'][j][k] = obj[i,j].item() if isinstance(obj[i,j],np.generic) else obj[i,j]
|
mat[i]['constituents'][j][k] = obj[i,j].item() if isinstance(obj[i,j],np.generic) else obj[i,j]
|
||||||
else:
|
else:
|
||||||
mat[i][k] = obj[i,0].item() if isinstance(obj[i,0],np.generic) else obj[i,0]
|
mat[i][k] = obj[i,0].item() if isinstance(obj[i,0],np.generic) else obj[i,0]
|
||||||
|
|
|
@ -8,6 +8,7 @@ import numpy as np
|
||||||
|
|
||||||
FloatSequence = Union[np.ndarray,Sequence[float]]
|
FloatSequence = Union[np.ndarray,Sequence[float]]
|
||||||
IntSequence = Union[np.ndarray,Sequence[int]]
|
IntSequence = Union[np.ndarray,Sequence[int]]
|
||||||
|
StrSequence = Union[np.ndarray,Sequence[str]]
|
||||||
FileHandle = Union[TextIO, str, Path]
|
FileHandle = Union[TextIO, str, Path]
|
||||||
CrystalFamily = Union[None,Literal['triclinic', 'monoclinic', 'orthorhombic', 'tetragonal', 'hexagonal', 'cubic']]
|
CrystalFamily = Union[None,Literal['triclinic', 'monoclinic', 'orthorhombic', 'tetragonal', 'hexagonal', 'cubic']]
|
||||||
CrystalLattice = Union[None,Literal['aP', 'mP', 'mS', 'oP', 'oS', 'oI', 'oF', 'tP', 'tI', 'hP', 'cP', 'cI', 'cF']]
|
CrystalLattice = Union[None,Literal['aP', 'mP', 'mS', 'oP', 'oS', 'oI', 'oF', 'tP', 'tI', 'hP', 'cP', 'cI', 'cF']]
|
||||||
|
|
|
@ -800,7 +800,7 @@ class ProgressBar:
|
||||||
prefix: str,
|
prefix: str,
|
||||||
bar_length: int):
|
bar_length: int):
|
||||||
"""
|
"""
|
||||||
Set current time as basis for ETA estimation.
|
New progress bar.
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
----------
|
----------
|
||||||
|
|
Loading…
Reference in New Issue