Merge remote-tracking branch 'origin/development' into drop-old-DADF5-support
This commit is contained in:
commit
d4a46b9be8
2
PRIVATE
2
PRIVATE
|
@ -1 +1 @@
|
||||||
Subproject commit afffa8d04e110282e514a4e57d0bad9c76effe01
|
Subproject commit 7f0594060779d9a8a4e774d558134309ab77b96e
|
|
@ -61,6 +61,11 @@ class Config(dict):
|
||||||
other : damask.Config or dict
|
other : damask.Config or dict
|
||||||
Key-value pairs that update self.
|
Key-value pairs that update self.
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
updated : damask.Config
|
||||||
|
Updated configuration.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
duplicate = self.copy()
|
duplicate = self.copy()
|
||||||
duplicate.update(other)
|
duplicate.update(other)
|
||||||
|
@ -81,6 +86,11 @@ class Config(dict):
|
||||||
keys : iterable or scalar
|
keys : iterable or scalar
|
||||||
Label of the key(s) to remove.
|
Label of the key(s) to remove.
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
updated : damask.Config
|
||||||
|
Updated configuration.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
duplicate = self.copy()
|
duplicate = self.copy()
|
||||||
for k in keys if isinstance(keys, Iterable) and not isinstance(keys, str) else [keys]:
|
for k in keys if isinstance(keys, Iterable) and not isinstance(keys, str) else [keys]:
|
||||||
|
@ -98,6 +108,11 @@ class Config(dict):
|
||||||
fname : file, str, or pathlib.Path
|
fname : file, str, or pathlib.Path
|
||||||
Filename or file for writing.
|
Filename or file for writing.
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
loaded : damask.Config
|
||||||
|
Configuration from file.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
fhandle = open(fname)
|
fhandle = open(fname)
|
||||||
|
|
|
@ -54,7 +54,12 @@ class ConfigMaterial(Config):
|
||||||
Parameters
|
Parameters
|
||||||
----------
|
----------
|
||||||
fname : file, str, or pathlib.Path, optional
|
fname : file, str, or pathlib.Path, optional
|
||||||
Filename or file for writing. Defaults to 'material.yaml'.
|
Filename or file to read from. Defaults to 'material.yaml'.
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
loaded : damask.ConfigMaterial
|
||||||
|
Material configuration from file.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return super(ConfigMaterial,cls).load(fname)
|
return super(ConfigMaterial,cls).load(fname)
|
||||||
|
@ -103,6 +108,11 @@ class ConfigMaterial(Config):
|
||||||
and grain- or cell-wise data. Defaults to None, in which case
|
and grain- or cell-wise data. Defaults to None, in which case
|
||||||
it is set as the path that contains _SIMPL_GEOMETRY/SPACING.
|
it is set as the path that contains _SIMPL_GEOMETRY/SPACING.
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
loaded : damask.ConfigMaterial
|
||||||
|
Material configuration from file.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
b = util.DREAM3D_base_group(fname) if base_group is None else base_group
|
b = util.DREAM3D_base_group(fname) if base_group is None else base_group
|
||||||
c = util.DREAM3D_cell_data_group(fname) if cell_data is None else cell_data
|
c = util.DREAM3D_cell_data_group(fname) if cell_data is None else cell_data
|
||||||
|
@ -146,6 +156,11 @@ class ConfigMaterial(Config):
|
||||||
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.
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
new : damask.ConfigMaterial
|
||||||
|
Material configuration from values in table.
|
||||||
|
|
||||||
Examples
|
Examples
|
||||||
--------
|
--------
|
||||||
>>> import damask
|
>>> import damask
|
||||||
|
|
|
@ -1012,6 +1012,11 @@ class Grid:
|
||||||
Direction(s) along which the boundaries are determined.
|
Direction(s) along which the boundaries are determined.
|
||||||
Valid entries are 'x', 'y', 'z'. Defaults to 'xyz'.
|
Valid entries are 'x', 'y', 'z'. Defaults to 'xyz'.
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
grain_boundaries : damask.VTK
|
||||||
|
VTK-based geometry of grain boundary network.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
valid = ['x','y','z']
|
valid = ['x','y','z']
|
||||||
if not set(directions).issubset(valid):
|
if not set(directions).issubset(valid):
|
||||||
|
|
|
@ -59,17 +59,17 @@ class Result:
|
||||||
"""
|
"""
|
||||||
Add data to and export data from a DADF5 file.
|
Add data to and export data from a DADF5 file.
|
||||||
|
|
||||||
A DADF5 (DAMASK HDF5) file contain DAMASK results.
|
A DADF5 (DAMASK HDF5) file contains DAMASK results.
|
||||||
Its group/folder structure reflects the layout in material.yaml.
|
Its group/folder structure reflects the layout in material.yaml.
|
||||||
|
|
||||||
This class provides a customable view on the DADF5 file.
|
This class provides a customizable view on the DADF5 file.
|
||||||
Upon initialization, all attributes are visible.
|
Upon initialization, all attributes are visible.
|
||||||
Derived quantities are added to the file and existing data is
|
Derived quantities are added to the file and existing data is
|
||||||
exported based on the current view.
|
exported based on the current view.
|
||||||
|
|
||||||
Examples
|
Examples
|
||||||
--------
|
--------
|
||||||
Open 'my_file.hdf5', which needs to contain deformation gradient 'F'
|
Open 'my_file.hdf5', which is assumed to contain deformation gradient 'F'
|
||||||
and first Piola-Kirchhoff stress 'P', add the Mises equivalent of the
|
and first Piola-Kirchhoff stress 'P', add the Mises equivalent of the
|
||||||
Cauchy stress, and export it to VTK (file) and numpy.ndarray (memory).
|
Cauchy stress, and export it to VTK (file) and numpy.ndarray (memory).
|
||||||
|
|
||||||
|
@ -224,12 +224,12 @@ class Result:
|
||||||
|
|
||||||
def modification_enable(self):
|
def modification_enable(self):
|
||||||
"""
|
"""
|
||||||
Allow to modify existing data.
|
Allow modification of existing data.
|
||||||
|
|
||||||
Returns
|
Returns
|
||||||
-------
|
-------
|
||||||
modified_view : damask.Result
|
modified_view : damask.Result
|
||||||
View where data is not write-protected.
|
View without write-protection of existing data.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
print(util.warn('Warning: Modification of existing datasets allowed!'))
|
print(util.warn('Warning: Modification of existing datasets allowed!'))
|
||||||
|
@ -239,12 +239,12 @@ class Result:
|
||||||
|
|
||||||
def modification_disable(self):
|
def modification_disable(self):
|
||||||
"""
|
"""
|
||||||
Disallow to modify existing data (default case).
|
Prevent modification of existing data (default case).
|
||||||
|
|
||||||
Returns
|
Returns
|
||||||
-------
|
-------
|
||||||
modified_view : damask.Result
|
modified_view : damask.Result
|
||||||
View where data is write-protected.
|
View with write-protection of existing data.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
dup = self.copy()
|
dup = self.copy()
|
||||||
|
@ -316,7 +316,7 @@ class Result:
|
||||||
Returns
|
Returns
|
||||||
-------
|
-------
|
||||||
view : damask.Result
|
view : damask.Result
|
||||||
View with where selected attributes are visible.
|
View with only the selected attributes being visible.
|
||||||
|
|
||||||
Examples
|
Examples
|
||||||
--------
|
--------
|
||||||
|
@ -326,7 +326,7 @@ class Result:
|
||||||
>>> r = damask.Result('my_file.hdf5')
|
>>> r = damask.Result('my_file.hdf5')
|
||||||
>>> r_first = r.view('increment',0)
|
>>> r_first = r.view('increment',0)
|
||||||
|
|
||||||
Get a view that shows all results of in simulation time [10,40]:
|
Get a view that shows all results between simulation times of 10 to 40:
|
||||||
|
|
||||||
>>> import damask
|
>>> import damask
|
||||||
>>> r = damask.Result('my_file.hdf5')
|
>>> r = damask.Result('my_file.hdf5')
|
||||||
|
@ -351,7 +351,7 @@ class Result:
|
||||||
Returns
|
Returns
|
||||||
-------
|
-------
|
||||||
modified_view : damask.Result
|
modified_view : damask.Result
|
||||||
View with more visible attributes.
|
View with additional visible attributes.
|
||||||
|
|
||||||
Examples
|
Examples
|
||||||
--------
|
--------
|
||||||
|
@ -368,7 +368,7 @@ class Result:
|
||||||
|
|
||||||
def view_less(self,what,datasets):
|
def view_less(self,what,datasets):
|
||||||
"""
|
"""
|
||||||
Delete from view.
|
Remove from view.
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
----------
|
----------
|
||||||
|
@ -381,11 +381,11 @@ class Result:
|
||||||
Returns
|
Returns
|
||||||
-------
|
-------
|
||||||
modified_view : damask.Result
|
modified_view : damask.Result
|
||||||
View with less visible attributes.
|
View with fewer visible attributes.
|
||||||
|
|
||||||
Examples
|
Examples
|
||||||
--------
|
--------
|
||||||
Get a view that does not show the undeformed configuration:
|
Get a view that omits the undeformed configuration:
|
||||||
|
|
||||||
>>> import damask
|
>>> import damask
|
||||||
>>> r_all = damask.Result('my_file.hdf5')
|
>>> r_all = damask.Result('my_file.hdf5')
|
||||||
|
@ -570,16 +570,17 @@ class Result:
|
||||||
'creator': 'add_calculation'
|
'creator': 'add_calculation'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
def add_calculation(self,name,formula,unit='n/a',description=None):
|
def add_calculation(self,formula,name,unit='n/a',description=None):
|
||||||
"""
|
"""
|
||||||
Add result of a general formula.
|
Add result of a general formula.
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
----------
|
----------
|
||||||
|
formula : str
|
||||||
|
Formula to calculate resulting dataset.
|
||||||
|
Existing datasets are referenced by '#TheirName#'.
|
||||||
name : str
|
name : str
|
||||||
Name of resulting dataset.
|
Name of resulting dataset.
|
||||||
formula : str
|
|
||||||
Formula to calculate resulting dataset. Existing datasets are referenced by '#TheirName#'.
|
|
||||||
unit : str, optional
|
unit : str, optional
|
||||||
Physical unit of the result.
|
Physical unit of the result.
|
||||||
description : str, optional
|
description : str, optional
|
||||||
|
@ -593,11 +594,11 @@ class Result:
|
||||||
|
|
||||||
>>> import damask
|
>>> import damask
|
||||||
>>> r = damask.Result('my_file.hdf5')
|
>>> r = damask.Result('my_file.hdf5')
|
||||||
>>> r.add_calculation('rho_mob_total','np.sum(#rho_mob#,axis=1)',
|
>>> r.add_calculation('np.sum(#rho_mob#,axis=1)','rho_mob_total',
|
||||||
... '1/m²','total mobile dislocation density')
|
... '1/m²','total mobile dislocation density')
|
||||||
>>> r.add_calculation('rho_dip_total','np.sum(#rho_dip#,axis=1)',
|
>>> r.add_calculation(''np.sum(#rho_dip#,axis=1)',rho_dip_total',
|
||||||
... '1/m²','total dislocation dipole density')
|
... '1/m²','total dislocation dipole density')
|
||||||
>>> r.add_calculation('rho_total','#rho_dip_total#+#rho_mob_total',
|
>>> r.add_calculation('#rho_dip_total#+#rho_mob_total','rho_total',
|
||||||
... '1/m²','total dislocation density')
|
... '1/m²','total dislocation density')
|
||||||
|
|
||||||
Add Mises equivalent of the Cauchy stress without storage of
|
Add Mises equivalent of the Cauchy stress without storage of
|
||||||
|
@ -609,7 +610,7 @@ class Result:
|
||||||
... return damask.mechanics.equivalent_stress_Mises(sigma)
|
... return damask.mechanics.equivalent_stress_Mises(sigma)
|
||||||
>>> r = damask.Result('my_file.hdf5')
|
>>> r = damask.Result('my_file.hdf5')
|
||||||
>>> r.enable_user_function(equivalent_stress)
|
>>> r.enable_user_function(equivalent_stress)
|
||||||
>>> r.add_calculation('sigma_vM','equivalent_stress(#F#,#P#)','Pa',
|
>>> r.add_calculation('equivalent_stress(#F#,#P#)','sigma_vM','Pa',
|
||||||
... 'Mises equivalent of the Cauchy stress')
|
... 'Mises equivalent of the Cauchy stress')
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
@ -1378,7 +1379,7 @@ class Result:
|
||||||
Parameters
|
Parameters
|
||||||
----------
|
----------
|
||||||
output : (list of) str, optional
|
output : (list of) str, optional
|
||||||
Names of the datasets included in the VTK file.
|
Names of the datasets to export to the VTK file.
|
||||||
Defaults to '*', in which case all datasets are exported.
|
Defaults to '*', in which case all datasets are exported.
|
||||||
mode : {'cell', 'point'}
|
mode : {'cell', 'point'}
|
||||||
Export in cell format or point format.
|
Export in cell format or point format.
|
||||||
|
@ -1502,7 +1503,7 @@ class Result:
|
||||||
in the DADF5 file.
|
in the DADF5 file.
|
||||||
|
|
||||||
Multi-phase data is fused into a single output.
|
Multi-phase data is fused into a single output.
|
||||||
`place` is equivalent to `read` if only one phase/homogenization
|
`place` is equivalent to `get` if only one phase/homogenization
|
||||||
and one constituent is present.
|
and one constituent is present.
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
|
@ -1518,7 +1519,7 @@ class Result:
|
||||||
Remove branches with no data. Defaults to True.
|
Remove branches with no data. Defaults to True.
|
||||||
constituents : (list of) int, optional
|
constituents : (list of) int, optional
|
||||||
Constituents to consider.
|
Constituents to consider.
|
||||||
Defaults to 'None', in which case all constituents are considered.
|
Defaults to None, in which case all constituents are considered.
|
||||||
fill_float : float
|
fill_float : float
|
||||||
Fill value for non-existent entries of floating point type.
|
Fill value for non-existent entries of floating point type.
|
||||||
Defaults to NaN.
|
Defaults to NaN.
|
||||||
|
|
|
@ -46,9 +46,9 @@ class VTK:
|
||||||
grid : iterable of int, len (3)
|
grid : iterable of int, len (3)
|
||||||
Number of cells along each dimension.
|
Number of cells along each dimension.
|
||||||
size : iterable of float, len (3)
|
size : iterable of float, len (3)
|
||||||
Physical lengths along each dimension.
|
Physical length along each dimension.
|
||||||
origin : iterable of float, len (3), optional
|
origin : iterable of float, len (3), optional
|
||||||
Spatial origin coordinates.
|
Coordinates of grid origin.
|
||||||
|
|
||||||
Returns
|
Returns
|
||||||
-------
|
-------
|
||||||
|
@ -161,7 +161,7 @@ class VTK:
|
||||||
|
|
||||||
"""
|
"""
|
||||||
if not os.path.isfile(fname): # vtk has a strange error handling
|
if not os.path.isfile(fname): # vtk has a strange error handling
|
||||||
raise FileNotFoundError(f'no such file: {fname}')
|
raise FileNotFoundError(f'No such file: {fname}')
|
||||||
ext = Path(fname).suffix
|
ext = Path(fname).suffix
|
||||||
if ext == '.vtk' or dataset_type is not None:
|
if ext == '.vtk' or dataset_type is not None:
|
||||||
reader = vtk.vtkGenericDataObjectReader()
|
reader = vtk.vtkGenericDataObjectReader()
|
||||||
|
|
|
@ -493,7 +493,7 @@ def node_to_point(node_data):
|
||||||
|
|
||||||
def coordinates0_valid(coordinates0):
|
def coordinates0_valid(coordinates0):
|
||||||
"""
|
"""
|
||||||
Check whether coordinates lie on a regular grid.
|
Check whether coordinates form a regular grid.
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
----------
|
----------
|
||||||
|
@ -503,7 +503,7 @@ def coordinates0_valid(coordinates0):
|
||||||
Returns
|
Returns
|
||||||
-------
|
-------
|
||||||
valid : bool
|
valid : bool
|
||||||
Wheter the coordinates lie on a regular grid.
|
Whether the coordinates form a regular grid.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
"""Run simulations directly from python."""
|
"""Run simulations directly from Python."""
|
||||||
|
|
||||||
from ._marc import Marc # noqa
|
from ._marc import Marc # noqa
|
||||||
|
|
|
@ -110,14 +110,14 @@ class TestResult:
|
||||||
def test_add_calculation(self,default,tmp_path,mode):
|
def test_add_calculation(self,default,tmp_path,mode):
|
||||||
|
|
||||||
if mode == 'direct':
|
if mode == 'direct':
|
||||||
default.add_calculation('x','2.0*np.abs(#F#)-1.0','-','my notes')
|
default.add_calculation('2.0*np.abs(#F#)-1.0','x','-','my notes')
|
||||||
else:
|
else:
|
||||||
with open(tmp_path/'f.py','w') as f:
|
with open(tmp_path/'f.py','w') as f:
|
||||||
f.write("import numpy as np\ndef my_func(field):\n return 2.0*np.abs(field)-1.0\n")
|
f.write("import numpy as np\ndef my_func(field):\n return 2.0*np.abs(field)-1.0\n")
|
||||||
sys.path.insert(0,str(tmp_path))
|
sys.path.insert(0,str(tmp_path))
|
||||||
import f
|
import f
|
||||||
default.enable_user_function(f.my_func)
|
default.enable_user_function(f.my_func)
|
||||||
default.add_calculation('x','my_func(#F#)','-','my notes')
|
default.add_calculation('my_func(#F#)','x','-','my notes')
|
||||||
|
|
||||||
in_memory = 2.0*np.abs(default.place('F'))-1.0
|
in_memory = 2.0*np.abs(default.place('F'))-1.0
|
||||||
in_file = default.place('x')
|
in_file = default.place('x')
|
||||||
|
@ -193,14 +193,14 @@ class TestResult:
|
||||||
|
|
||||||
def test_add_Mises_invalid(self,default):
|
def test_add_Mises_invalid(self,default):
|
||||||
default.add_stress_Cauchy('P','F')
|
default.add_stress_Cauchy('P','F')
|
||||||
default.add_calculation('sigma_y','#sigma#',unit='y')
|
default.add_calculation('#sigma#','sigma_y',unit='y')
|
||||||
default.add_equivalent_Mises('sigma_y')
|
default.add_equivalent_Mises('sigma_y')
|
||||||
assert default.get('sigma_y_vM') is None
|
assert default.get('sigma_y_vM') is None
|
||||||
|
|
||||||
def test_add_Mises_stress_strain(self,default):
|
def test_add_Mises_stress_strain(self,default):
|
||||||
default.add_stress_Cauchy('P','F')
|
default.add_stress_Cauchy('P','F')
|
||||||
default.add_calculation('sigma_y','#sigma#',unit='y')
|
default.add_calculation('#sigma#','sigma_y',unit='y')
|
||||||
default.add_calculation('sigma_x','#sigma#',unit='x')
|
default.add_calculation('#sigma#','sigma_x',unit='x')
|
||||||
default.add_equivalent_Mises('sigma_y',kind='strain')
|
default.add_equivalent_Mises('sigma_y',kind='strain')
|
||||||
default.add_equivalent_Mises('sigma_x',kind='stress')
|
default.add_equivalent_Mises('sigma_x',kind='stress')
|
||||||
assert not np.allclose(default.place('sigma_y_vM'),default.place('sigma_x_vM'))
|
assert not np.allclose(default.place('sigma_y_vM'),default.place('sigma_x_vM'))
|
||||||
|
@ -285,7 +285,7 @@ class TestResult:
|
||||||
|
|
||||||
time.sleep(2.)
|
time.sleep(2.)
|
||||||
try:
|
try:
|
||||||
last.add_calculation('sigma','#sigma#*0.0+311.','not the Cauchy stress')
|
last.add_calculation('#sigma#*0.0+311.','sigma','not the Cauchy stress')
|
||||||
except ValueError:
|
except ValueError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@ -362,7 +362,7 @@ class TestResult:
|
||||||
def test_XDMF(self,tmp_path,single_phase,update,ref_path):
|
def test_XDMF(self,tmp_path,single_phase,update,ref_path):
|
||||||
for shape in [('scalar',()),('vector',(3,)),('tensor',(3,3)),('matrix',(12,))]:
|
for shape in [('scalar',()),('vector',(3,)),('tensor',(3,3)),('matrix',(12,))]:
|
||||||
for dtype in ['f4','f8','i1','i2','i4','i8','u1','u2','u4','u8']:
|
for dtype in ['f4','f8','i1','i2','i4','i8','u1','u2','u4','u8']:
|
||||||
single_phase.add_calculation(f'{shape[0]}_{dtype}',f"np.ones(np.shape(#F#)[0:1]+{shape[1]},'{dtype}')")
|
single_phase.add_calculation(f"np.ones(np.shape(#F#)[0:1]+{shape[1]},'{dtype}')",f'{shape[0]}_{dtype}')
|
||||||
fname = os.path.splitext(os.path.basename(single_phase.fname))[0]+'.xdmf'
|
fname = os.path.splitext(os.path.basename(single_phase.fname))[0]+'.xdmf'
|
||||||
os.chdir(tmp_path)
|
os.chdir(tmp_path)
|
||||||
single_phase.save_XDMF()
|
single_phase.save_XDMF()
|
||||||
|
|
Loading…
Reference in New Issue