From c6c1878b13be5dfff792707109584931ba2b1614 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sun, 12 Apr 2020 15:19:32 +0200 Subject: [PATCH 01/29] asterisk is the emphasize sign for restructured text not really needed here --- python/damask/_vtk.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/python/damask/_vtk.py b/python/damask/_vtk.py index 4505a5ebc..58b43dc1f 100644 --- a/python/damask/_vtk.py +++ b/python/damask/_vtk.py @@ -120,9 +120,9 @@ class VTK: Parameters ---------- fname : str - Filename for reading. Valid extensions are *.vtr, *.vtu, *.vtp, and *.vtk. + Filename for reading. Valid extensions are .vtr, .vtu, .vtp, and .vtk. dataset_type : str, optional - Name of the vtk.vtkDataSet subclass when opening an *.vtk file. Valid types are vtkRectilinearGrid, + Name of the vtk.vtkDataSet subclass when opening an .vtk file. Valid types are vtkRectilinearGrid, vtkUnstructuredGrid, and vtkPolyData. """ From b6b98bd14f56fadaae4796fcfdbd582db1cd0497 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sun, 12 Apr 2020 15:20:09 +0200 Subject: [PATCH 02/29] more meaningful --- python/damask/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/damask/__init__.py b/python/damask/__init__.py index 9a01e8e62..0f343a581 100644 --- a/python/damask/__init__.py +++ b/python/damask/__init__.py @@ -1,4 +1,4 @@ -"""Main aggregator.""" +"""Tools for pre and post processing of DAMASK simulations.""" import os as _os import re as _re From aaeec16c66b4729b3d5ddec147bccbbc29535b6a Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sun, 12 Apr 2020 15:34:29 +0200 Subject: [PATCH 03/29] proper indentation for sphinx --- python/damask/_orientation.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/python/damask/_orientation.py b/python/damask/_orientation.py index 76475e057..aa1ba06ef 100644 --- a/python/damask/_orientation.py +++ b/python/damask/_orientation.py @@ -8,8 +8,8 @@ class Orientation: Crystallographic orientation. A crystallographic orientation contains a rotation and a lattice. - """ + """ __slots__ = ['rotation','lattice'] def __repr__(self): @@ -46,8 +46,10 @@ class Orientation: Disorientation between myself and given other orientation. Rotation axis falls into SST if SST == True. - (Currently requires same symmetry for both orientations. - Look into A. Heinz and P. Neumann 1991 for cases with differing sym.) + + Currently requires same symmetry for both orientations. + Look into A. Heinz and P. Neumann 1991 for cases with differing sym. + """ if self.lattice.symmetry != other.lattice.symmetry: raise NotImplementedError('disorientation between different symmetry classes not supported yet.') From 93c75cada3b872775c78b433452cd9dfd8aefd78 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sun, 12 Apr 2020 15:38:38 +0200 Subject: [PATCH 04/29] numpydoc style --- python/damask/_rotation.py | 39 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/python/damask/_rotation.py b/python/damask/_rotation.py index bea7aa5e6..e730ed845 100644 --- a/python/damask/_rotation.py +++ b/python/damask/_rotation.py @@ -11,33 +11,32 @@ def iszero(a): class Rotation: u""" Orientation stored with functionality for conversion to different representations. + The following conventions apply: + + - coordinate frames are right-handed. + - a rotation angle ω is taken to be positive for a counterclockwise rotation + when viewing from the end point of the rotation axis towards the origin. + - rotations will be interpreted in the passive sense. + - Euler angle triplets are implemented using the Bunge convention, + with the angular ranges as [0, 2π],[0, π],[0, 2π]. + - the rotation angle ω is limited to the interval [0, π]. + - the real part of a quaternion is positive, Re(q) > 0 + - P = -1 (as default). + + Examples + -------- + Rotate vector "a" (defined in coordinate system "A") to + coordinates "b" expressed in system "B": + + - b = Q * a + - b = np.dot(Q.asMatrix(),a) References ---------- D. Rowenhorst et al., Modelling and Simulation in Materials Science and Engineering 23:083501, 2015 https://doi.org/10.1088/0965-0393/23/8/083501 - Conventions - ----------- - Convention 1: Coordinate frames are right-handed. - Convention 2: A rotation angle ω is taken to be positive for a counterclockwise rotation - when viewing from the end point of the rotation axis towards the origin. - Convention 3: Rotations will be interpreted in the passive sense. - Convention 4: Euler angle triplets are implemented using the Bunge convention, - with the angular ranges as [0, 2π],[0, π],[0, 2π]. - Convention 5: The rotation angle ω is limited to the interval [0, π]. - Convention 6: the real part of a quaternion is positive, Re(q) > 0 - Convention 7: P = -1 (as default). - - Usage - ----- - Vector "a" (defined in coordinate system "A") is passively rotated - resulting in new coordinates "b" when expressed in system "B". - b = Q * a - b = np.dot(Q.asMatrix(),a) - """ - __slots__ = ['quaternion'] def __init__(self,quaternion = np.array([1.0,0.0,0.0,0.0])): From 66b928c5afce0891bd13793c42e0fafc8bba5324 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Wed, 13 May 2020 10:47:49 +0200 Subject: [PATCH 05/29] using doctest style https://docs.python.org/3/library/doctest.html https://numpy.org/doc/stable/docs/howto_document.html#sections (section 15) --- python/damask/_lattice.py | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/python/damask/_lattice.py b/python/damask/_lattice.py index 42aa0e9bd..f33cc66f7 100644 --- a/python/damask/_lattice.py +++ b/python/damask/_lattice.py @@ -229,19 +229,20 @@ class Symmetry: Return inverse pole figure color if requested. Bases are computed from - basis = {'cubic' : np.linalg.inv(np.array([[0.,0.,1.], # direction of red - [1.,0.,1.]/np.sqrt(2.), # direction of green - [1.,1.,1.]/np.sqrt(3.)]).T), # direction of blue - 'hexagonal' : np.linalg.inv(np.array([[0.,0.,1.], # direction of red - [1.,0.,0.], # direction of green - [np.sqrt(3.),1.,0.]/np.sqrt(4.)]).T), # direction of blue - 'tetragonal' : np.linalg.inv(np.array([[0.,0.,1.], # direction of red - [1.,0.,0.], # direction of green - [1.,1.,0.]/np.sqrt(2.)]).T), # direction of blue - 'orthorhombic' : np.linalg.inv(np.array([[0.,0.,1.], # direction of red - [1.,0.,0.], # direction of green - [0.,1.,0.]]).T), # direction of blue - } + >>> basis = {'cubic' : np.linalg.inv(np.array([[0.,0.,1.], # direction of red + ... [1.,0.,1.]/np.sqrt(2.), # direction of green + ... [1.,1.,1.]/np.sqrt(3.)]).T), # direction of blue + ... 'hexagonal' : np.linalg.inv(np.array([[0.,0.,1.], # direction of red + ... [1.,0.,0.], # direction of green + ... [np.sqrt(3.),1.,0.]/np.sqrt(4.)]).T), # direction of blue + ... 'tetragonal' : np.linalg.inv(np.array([[0.,0.,1.], # direction of red + ... [1.,0.,0.], # direction of green + ... [1.,1.,0.]/np.sqrt(2.)]).T), # direction of blue + ... 'orthorhombic': np.linalg.inv(np.array([[0.,0.,1.], # direction of red + ... [1.,0.,0.], # direction of green + ... [0.,1.,0.]]).T), # direction of blue + ... } + """ if self.lattice == 'cubic': basis = {'improper':np.array([ [-1. , 0. , 1. ], From b5b9bfaa99d1dc676b3177c22536a1607047148c Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Wed, 13 May 2020 11:09:37 +0200 Subject: [PATCH 06/29] need space at end of definition list --- python/damask/_orientation.py | 1 + python/damask/_result.py | 7 ++++--- python/damask/_rotation.py | 2 ++ 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/python/damask/_orientation.py b/python/damask/_orientation.py index 64fb98f45..a558ec85d 100644 --- a/python/damask/_orientation.py +++ b/python/damask/_orientation.py @@ -10,6 +10,7 @@ class Orientation: A crystallographic orientation contains a rotation and a lattice. """ + __slots__ = ['rotation','lattice'] def __repr__(self): diff --git a/python/damask/_result.py b/python/damask/_result.py index 9171682ff..a660885fe 100644 --- a/python/damask/_result.py +++ b/python/damask/_result.py @@ -316,9 +316,10 @@ class Result: Return groups that contain all requested datasets. Only groups within - - inc?????/constituent/*_*/* - - inc?????/materialpoint/*_*/* - - inc?????/geometry/* + - inc*/constituent/*/* + - inc*/materialpoint/*/* + - inc*/geometry/* + are considered as they contain user-relevant data. Single strings will be treated as list with one entry. diff --git a/python/damask/_rotation.py b/python/damask/_rotation.py index a7427e1f9..162a118b9 100644 --- a/python/damask/_rotation.py +++ b/python/damask/_rotation.py @@ -16,6 +16,7 @@ def iszero(a): class Rotation: u""" Orientation stored with functionality for conversion to different representations. + The following conventions apply: - coordinate frames are right-handed. @@ -42,6 +43,7 @@ class Rotation: https://doi.org/10.1088/0965-0393/23/8/083501 """ + __slots__ = ['quaternion'] def __init__(self,quaternion = np.array([1.0,0.0,0.0,0.0])): From 376e45d7bfe7f505a02e90dc80c80ee8fa00f53a Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sat, 23 May 2020 13:55:00 +0200 Subject: [PATCH 07/29] don't even start to compile --- cmake/Compiler-GNU.cmake | 3 +++ cmake/Compiler-Intel.cmake | 4 ++++ src/DAMASK_interface.f90 | 25 ------------------------- 3 files changed, 7 insertions(+), 25 deletions(-) diff --git a/cmake/Compiler-GNU.cmake b/cmake/Compiler-GNU.cmake index 858e91134..ebba8c0bf 100644 --- a/cmake/Compiler-GNU.cmake +++ b/cmake/Compiler-GNU.cmake @@ -1,6 +1,9 @@ ################################################################################################### # GNU Compiler ################################################################################################### +if (CMAKE_Fortran_COMPILER_VERSION VERSION_LESS 8.0) + message (FATAL_ERROR "GCC Compiler version: ${CMAKE_Fortran_COMPILER_VERSION} not supported") +endif () if (OPENMP) set (OPENMP_FLAGS "-fopenmp") diff --git a/cmake/Compiler-Intel.cmake b/cmake/Compiler-Intel.cmake index 1a2c2c455..6d96ff42d 100644 --- a/cmake/Compiler-Intel.cmake +++ b/cmake/Compiler-Intel.cmake @@ -1,6 +1,10 @@ ################################################################################################### # Intel Compiler ################################################################################################### +if (CMAKE_Fortran_COMPILER_VERSION VERSION_LESS 18.0) + message (FATAL_ERROR "Intel Compiler version: ${CMAKE_Fortran_COMPILER_VERSION} not supported") +endif () + if (OPENMP) set (OPENMP_FLAGS "-qopenmp -parallel") endif () diff --git a/src/DAMASK_interface.f90 b/src/DAMASK_interface.f90 index 8e4369840..67c7d99da 100644 --- a/src/DAMASK_interface.f90 +++ b/src/DAMASK_interface.f90 @@ -9,8 +9,6 @@ !> by DAMASK. Interpretating the command line arguments to get load case, geometry file, !> and working directory. !-------------------------------------------------------------------------------------------------- -#define GCC_MIN 6 -#define INTEL_MIN 1700 #define PETSC_MAJOR 3 #define PETSC_MINOR_MIN 10 #define PETSC_MINOR_MAX 13 @@ -50,29 +48,6 @@ contains !-------------------------------------------------------------------------------------------------- subroutine DAMASK_interface_init #include -#if defined(__GFORTRAN__) && __GNUC__PETSC_MINOR_MAX =================================================================================================== From 594fcb2b72f93b467f852e99e92690571da30473 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sun, 24 May 2020 15:10:53 +0200 Subject: [PATCH 08/29] seems more appropriate --- python/damask/_geom.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/damask/_geom.py b/python/damask/_geom.py index 892000b7c..7c2fbd82e 100644 --- a/python/damask/_geom.py +++ b/python/damask/_geom.py @@ -242,7 +242,7 @@ class Geom: def get_grid(self): """Return the grid discretization.""" - return np.array(self.microstructure.shape) + return np.as:array(self.microstructure.shape) def get_homogenization(self): From b4de27bf6171f8efda6f073c582a14f8cded40a9 Mon Sep 17 00:00:00 2001 From: Test User Date: Mon, 25 May 2020 14:54:13 +0200 Subject: [PATCH 09/29] [skip ci] updated version information after successful test of v2.0.3-2514-g873b9fa8 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 3ba40668a..6d4d1897c 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -v2.0.3-2504-gcee9daff +v2.0.3-2514-g873b9fa8 From c9ff18e4087c001620b6f00ed66bb2fc89f5987f Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Mon, 25 May 2020 15:50:48 +0200 Subject: [PATCH 10/29] not used --- processing/pre/geom_rotate.py | 1 - processing/pre/geom_translate.py | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/processing/pre/geom_rotate.py b/processing/pre/geom_rotate.py index bbfeceb0b..9a65a0e2b 100755 --- a/processing/pre/geom_rotate.py +++ b/processing/pre/geom_rotate.py @@ -5,7 +5,6 @@ import sys from io import StringIO from optparse import OptionParser -from scipy import ndimage import numpy as np import damask diff --git a/processing/pre/geom_translate.py b/processing/pre/geom_translate.py index 25164b794..44c7e8718 100755 --- a/processing/pre/geom_translate.py +++ b/processing/pre/geom_translate.py @@ -49,7 +49,7 @@ for name in filenames: geom = damask.Geom.from_file(StringIO(''.join(sys.stdin.read())) if name is None else name) geom.renumber(sub[0::2],sub[1::2],origin=geom.origin+options.origin) - geom.microstructure+= option.microstructure + geom.microstructure+= options.microstructure damask.util.croak(geom) geom.add_comments(scriptID + ' ' + ' '.join(sys.argv[1:])) geom.to_file(sys.stdout if name is None else name,pack=False) From 784d6d09d9b5a336541c67332fb00183e4555c36 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Mon, 25 May 2020 15:54:22 +0200 Subject: [PATCH 11/29] cleaning --- python/damask/_geom.py | 11 +++++------ python/tests/test_Lattice.py | 5 ++--- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/python/damask/_geom.py b/python/damask/_geom.py index 12dbcc181..53c7322cc 100644 --- a/python/damask/_geom.py +++ b/python/damask/_geom.py @@ -10,7 +10,6 @@ from . import VTK from . import util from . import Environment from . import grid_filters -from . import Rotation class Geom: @@ -605,7 +604,7 @@ class Geom: origin = self.origin-(np.asarray(microstructure_in.shape)-self.grid)*.5 * self.size/self.grid - #self.add_comments('geom.py:renumber v{}'.format(version) + #self.add_comments('geom.py:rotate v{}'.format(version) return self.update(microstructure_in,origin=origin,rescale=True) @@ -613,11 +612,10 @@ class Geom: """Crop or enlarge/pad microstructure.""" if fill is None: fill = np.nanmax(self.microstructure) + 1 if offset is None: offset = 0 - dtype = float if np.isnan(fill) or int(fill) != fill or self.microstructure.dtype==np.float else int + dtype = float if int(fill) != fill or self.microstructure.dtype==np.float else int canvas = np.full(self.grid if grid is None else grid, - fill if fill is not None else np.nanmax(self.microstructure)+1, - self.microstructure.dtype) + fill if fill is not None else np.nanmax(self.microstructure)+1,dtype) l = np.clip( offset, 0,np.minimum(self.grid +offset,grid)) # noqa r = np.clip( offset+self.grid,0,np.minimum(self.grid*2+offset,grid)) @@ -626,7 +624,7 @@ class Geom: canvas[l[0]:r[0],l[1]:r[1],l[2]:r[2]] = self.microstructure[L[0]:R[0],L[1]:R[1],L[2]:R[2]] - #self.add_comments('geom.py:renumber v{}'.format(version) + #self.add_comments('geom.py:canvas v{}'.format(version) return self.update(canvas,origin=self.origin+offset*self.size/self.grid,rescale=True) @@ -636,4 +634,5 @@ class Geom: for from_ms,to_ms in zip(from_microstructure,to_microstructure): substituted[self.microstructure==from_ms] = to_ms + #self.add_comments('geom.py:substitute v{}'.format(version) return self.update(substituted) diff --git a/python/tests/test_Lattice.py b/python/tests/test_Lattice.py index 6a2cc5034..fb8ce8ea5 100644 --- a/python/tests/test_Lattice.py +++ b/python/tests/test_Lattice.py @@ -4,14 +4,13 @@ import pytest import numpy as np from damask import Symmetry -from damask import Lattice class TestSymmetry: @pytest.mark.parametrize('invalid_symmetry',['fcc','bcc','hello']) def test_invalid_symmetry(self,invalid_symmetry): with pytest.raises(KeyError): - s = Symmetry(invalid_symmetry) + s = Symmetry(invalid_symmetry) # noqa def test_equal(self): symmetry = random.choice(Symmetry.lattices) @@ -37,6 +36,6 @@ class TestSymmetry: @pytest.mark.parametrize('function',['inFZ','inDisorientationSST']) def test_invalid_argument(self,function): - s = Symmetry() + s = Symmetry() # noqa with pytest.raises(ValueError): eval('s.{}(np.ones(4))'.format(function)) From f07eaf19d049178eaf78757eb340cf2eeb398738 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Mon, 25 May 2020 16:37:08 +0200 Subject: [PATCH 12/29] fixed broadcasting + corresponding test --- python/damask/_rotation.py | 10 +++++----- python/tests/test_Rotation.py | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/python/damask/_rotation.py b/python/damask/_rotation.py index c147194d3..f90c5fcc0 100644 --- a/python/damask/_rotation.py +++ b/python/damask/_rotation.py @@ -12,7 +12,7 @@ _R1 = (3.*np.pi/4.)**(1./3.) class Rotation: u""" Orientation stored with functionality for conversion to different representations. - + The following conventions apply: - coordinate frames are right-handed. @@ -161,10 +161,10 @@ class Rotation: if self.shape == (): q = np.broadcast_to(self.quaternion,shape+(4,)) else: - q = np.block([np.broadcast_to(self.quaternion[...,0:1],shape), - np.broadcast_to(self.quaternion[...,1:2],shape), - np.broadcast_to(self.quaternion[...,2:3],shape), - np.broadcast_to(self.quaternion[...,3:4],shape)]).reshape(shape+(4,)) + q = np.block([np.broadcast_to(self.quaternion[...,0:1],shape).reshape(shape+(1,)), + np.broadcast_to(self.quaternion[...,1:2],shape).reshape(shape+(1,)), + np.broadcast_to(self.quaternion[...,2:3],shape).reshape(shape+(1,)), + np.broadcast_to(self.quaternion[...,3:4],shape).reshape(shape+(1,))]) return self.__class__(q) diff --git a/python/tests/test_Rotation.py b/python/tests/test_Rotation.py index 75fddf6fe..5a1cd145d 100644 --- a/python/tests/test_Rotation.py +++ b/python/tests/test_Rotation.py @@ -873,7 +873,7 @@ class TestRotation: rot.shape + (np.random.randint(8,32),) rot_broadcast = rot.broadcast_to(tuple(new_shape)) for i in range(rot_broadcast.shape[-1]): - assert (rot_broadcast.quaternion[...,i,:], rot.quaternion) + assert np.allclose(rot_broadcast.quaternion[...,i,:], rot.quaternion) @pytest.mark.parametrize('function,invalid',[(Rotation.from_quaternion, np.array([-1,0,0,0])), From b1b8d02320f59a50b1057b2780c51afc44c61771 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Mon, 25 May 2020 16:41:23 +0200 Subject: [PATCH 13/29] typo --- python/damask/_geom.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/damask/_geom.py b/python/damask/_geom.py index fe4e9a17f..2609fe537 100644 --- a/python/damask/_geom.py +++ b/python/damask/_geom.py @@ -242,7 +242,7 @@ class Geom: def get_grid(self): """Return the grid discretization.""" - return np.as:array(self.microstructure.shape) + return np.asarray(self.microstructure.shape) def get_homogenization(self): From 248f199a7b4e57dcb8fe9ef9919461790aabbcd1 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Mon, 25 May 2020 18:50:31 +0200 Subject: [PATCH 14/29] track creation time --- python/damask/_result.py | 3 +++ src/results.f90 | 21 +++++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/python/damask/_result.py b/python/damask/_result.py index 3a43850ed..e4402e1d8 100644 --- a/python/damask/_result.py +++ b/python/damask/_result.py @@ -2,6 +2,7 @@ import multiprocessing import re import glob import os +import datetime import xml.etree.ElementTree as ET import xml.dom.minidom from functools import partial @@ -1016,6 +1017,8 @@ class Result: with h5py.File(self.fname, 'a') as f: try: # ToDo: Replace if exists? dataset = f[result[0]].create_dataset(result[1]['label'],data=result[1]['data']) + now = datetime.datetime.now().astimezone() + dataset.attrs['Created'] = now.strftime('%Y-%m-%d %H:%M:%S%z').encode() for l,v in result[1]['meta'].items(): dataset.attrs[l]=v.encode() except OSError as err: diff --git a/src/results.f90 b/src/results.f90 index b5410f5f4..9b634079e 100644 --- a/src/results.f90 +++ b/src/results.f90 @@ -311,6 +311,8 @@ subroutine results_writeScalarDataset_real(group,dataset,label,description,SIuni call HDF5_addAttribute(groupHandle,'Unit',SIunit,label) if (HDF5_objectExists(groupHandle,label)) & call HDF5_addAttribute(groupHandle,'Creator','DAMASK '//DAMASKVERSION,label) + if (HDF5_objectExists(groupHandle,label)) & + call HDF5_addAttribute(groupHandle,'Created',now()) call HDF5_closeGroup(groupHandle) end subroutine results_writeScalarDataset_real @@ -340,6 +342,8 @@ subroutine results_writeVectorDataset_real(group,dataset,label,description,SIuni call HDF5_addAttribute(groupHandle,'Unit',SIunit,label) if (HDF5_objectExists(groupHandle,label)) & call HDF5_addAttribute(groupHandle,'Creator','DAMASK '//DAMASKVERSION,label) + if (HDF5_objectExists(groupHandle,label)) & + call HDF5_addAttribute(groupHandle,'Created',now()) call HDF5_closeGroup(groupHandle) end subroutine results_writeVectorDataset_real @@ -391,6 +395,8 @@ subroutine results_writeTensorDataset_real(group,dataset,label,description,SIuni call HDF5_addAttribute(groupHandle,'Unit',SIunit,label) if (HDF5_objectExists(groupHandle,label)) & call HDF5_addAttribute(groupHandle,'Creator','DAMASK '//DAMASKVERSION,label) + if (HDF5_objectExists(groupHandle,label)) & + call HDF5_addAttribute(groupHandle,'Created',now()) call HDF5_closeGroup(groupHandle) end subroutine results_writeTensorDataset_real @@ -421,6 +427,8 @@ subroutine results_writeVectorDataset_int(group,dataset,label,description,SIunit call HDF5_addAttribute(groupHandle,'Unit',SIunit,label) if (HDF5_objectExists(groupHandle,label)) & call HDF5_addAttribute(groupHandle,'Creator','DAMASK '//DAMASKVERSION,label) + if (HDF5_objectExists(groupHandle,label)) & + call HDF5_addAttribute(groupHandle,'Created',now()) call HDF5_closeGroup(groupHandle) end subroutine results_writeVectorDataset_int @@ -451,6 +459,8 @@ subroutine results_writeTensorDataset_int(group,dataset,label,description,SIunit call HDF5_addAttribute(groupHandle,'Unit',SIunit,label) if (HDF5_objectExists(groupHandle,label)) & call HDF5_addAttribute(groupHandle,'Creator','DAMASK '//DAMASKVERSION,label) + if (HDF5_objectExists(groupHandle,label)) & + call HDF5_addAttribute(groupHandle,'Created',now()) call HDF5_closeGroup(groupHandle) end subroutine results_writeTensorDataset_int @@ -481,6 +491,8 @@ subroutine results_writeScalarDataset_rotation(group,dataset,label,description,l call HDF5_addAttribute(groupHandle,'Lattice',lattice_structure,label) if (HDF5_objectExists(groupHandle,label)) & call HDF5_addAttribute(groupHandle,'Creator','DAMASK '//DAMASKVERSION,label) + if (HDF5_objectExists(groupHandle,label)) & + call HDF5_addAttribute(groupHandle,'Created',now()) call HDF5_closeGroup(groupHandle) end subroutine results_writeScalarDataset_rotation @@ -755,6 +767,15 @@ subroutine results_mapping_materialpoint(homogenizationAt,memberAtLocal,label) end subroutine results_mapping_materialpoint +character(len=24) function now() + + character(len=5) :: zone + integer, dimension(8) :: values + + write(now,'(i4.4,5(a,i2.2),a)') & + values(1),'-',values(2),'-',values(3),' ',values(5),':',values(6),':',values(7),zone + +end function now !!-------------------------------------------------------------------------------------------------- !!> @brief adds the backward mapping from spatial position and constituent ID to results From b6812d58b0ba09f1fa95b043ff0a157b932b1dea Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Mon, 25 May 2020 20:10:43 +0200 Subject: [PATCH 15/29] bugfix --- processing/pre/geom_translate.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/processing/pre/geom_translate.py b/processing/pre/geom_translate.py index 44c7e8718..6609e3f7e 100755 --- a/processing/pre/geom_translate.py +++ b/processing/pre/geom_translate.py @@ -48,8 +48,9 @@ for name in filenames: damask.util.report(scriptName,name) geom = damask.Geom.from_file(StringIO(''.join(sys.stdin.read())) if name is None else name) - geom.renumber(sub[0::2],sub[1::2],origin=geom.origin+options.origin) - geom.microstructure+= options.microstructure + geom.substitute(sub[0::2],sub[1::2]) + geom.set_origin(geom.origin+options.origin) + geom.set_microstructure(geom.microstructure+options.microstructure) damask.util.croak(geom) geom.add_comments(scriptID + ' ' + ' '.join(sys.argv[1:])) geom.to_file(sys.stdout if name is None else name,pack=False) From b9e16ea95110599f6c18a94f87ee2c01e0e22874 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Mon, 25 May 2020 19:12:31 +0200 Subject: [PATCH 16/29] overwriting datasets makes sense in special cases but prevent user from accidently doing that and store the information --- python/damask/_result.py | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/python/damask/_result.py b/python/damask/_result.py index e4402e1d8..244c11c69 100644 --- a/python/damask/_result.py +++ b/python/damask/_result.py @@ -89,6 +89,8 @@ class Result: self.fname = os.path.abspath(fname) + self._allow_overwrite = False + def __repr__(self): """Show selected data.""" @@ -163,6 +165,16 @@ class Result: self.selection[what] = diff_sorted + def enable_overwrite(self): + print(util.bcolors().WARNING,util.bcolors().BOLD, + 'Warning: Enabled overwrite of existing datasets!', + util.bcolors().ENDC) + self._allow_overwrite = True + + def disable_overwrite(self): + self._allow_overwrite = False + + def incs_in_range(self,start,end): selected = [] for i,inc in enumerate([int(i[3:]) for i in self.increments]): @@ -1015,8 +1027,13 @@ class Result: continue lock.acquire() with h5py.File(self.fname, 'a') as f: - try: # ToDo: Replace if exists? - dataset = f[result[0]].create_dataset(result[1]['label'],data=result[1]['data']) + try: + if self._allow_overwrite and result[0]+'/'+result[1]['label'] in f: + dataset = f[result[0]+'/'+result[1]['label']] + datset = result[1]['data'] + dataset.attrs['Overwritten'] = True + else: + dataset = f[result[0]].create_dataset(result[1]['label'],data=result[1]['data']) now = datetime.datetime.now().astimezone() dataset.attrs['Created'] = now.strftime('%Y-%m-%d %H:%M:%S%z').encode() for l,v in result[1]['meta'].items(): From eced5d0a3c9fa1046d1efae156888bfc71978b37 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Mon, 25 May 2020 19:34:17 +0200 Subject: [PATCH 17/29] bugfixes for date reporting --- src/results.f90 | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/results.f90 b/src/results.f90 index 9b634079e..d1db96f47 100644 --- a/src/results.f90 +++ b/src/results.f90 @@ -312,7 +312,7 @@ subroutine results_writeScalarDataset_real(group,dataset,label,description,SIuni if (HDF5_objectExists(groupHandle,label)) & call HDF5_addAttribute(groupHandle,'Creator','DAMASK '//DAMASKVERSION,label) if (HDF5_objectExists(groupHandle,label)) & - call HDF5_addAttribute(groupHandle,'Created',now()) + call HDF5_addAttribute(groupHandle,'Created',now(),label) call HDF5_closeGroup(groupHandle) end subroutine results_writeScalarDataset_real @@ -343,7 +343,7 @@ subroutine results_writeVectorDataset_real(group,dataset,label,description,SIuni if (HDF5_objectExists(groupHandle,label)) & call HDF5_addAttribute(groupHandle,'Creator','DAMASK '//DAMASKVERSION,label) if (HDF5_objectExists(groupHandle,label)) & - call HDF5_addAttribute(groupHandle,'Created',now()) + call HDF5_addAttribute(groupHandle,'Created',now(),label) call HDF5_closeGroup(groupHandle) end subroutine results_writeVectorDataset_real @@ -396,7 +396,7 @@ subroutine results_writeTensorDataset_real(group,dataset,label,description,SIuni if (HDF5_objectExists(groupHandle,label)) & call HDF5_addAttribute(groupHandle,'Creator','DAMASK '//DAMASKVERSION,label) if (HDF5_objectExists(groupHandle,label)) & - call HDF5_addAttribute(groupHandle,'Created',now()) + call HDF5_addAttribute(groupHandle,'Created',now(),label) call HDF5_closeGroup(groupHandle) end subroutine results_writeTensorDataset_real @@ -428,7 +428,7 @@ subroutine results_writeVectorDataset_int(group,dataset,label,description,SIunit if (HDF5_objectExists(groupHandle,label)) & call HDF5_addAttribute(groupHandle,'Creator','DAMASK '//DAMASKVERSION,label) if (HDF5_objectExists(groupHandle,label)) & - call HDF5_addAttribute(groupHandle,'Created',now()) + call HDF5_addAttribute(groupHandle,'Created',now(),label) call HDF5_closeGroup(groupHandle) end subroutine results_writeVectorDataset_int @@ -460,7 +460,7 @@ subroutine results_writeTensorDataset_int(group,dataset,label,description,SIunit if (HDF5_objectExists(groupHandle,label)) & call HDF5_addAttribute(groupHandle,'Creator','DAMASK '//DAMASKVERSION,label) if (HDF5_objectExists(groupHandle,label)) & - call HDF5_addAttribute(groupHandle,'Created',now()) + call HDF5_addAttribute(groupHandle,'Created',now(),label) call HDF5_closeGroup(groupHandle) end subroutine results_writeTensorDataset_int @@ -492,7 +492,7 @@ subroutine results_writeScalarDataset_rotation(group,dataset,label,description,l if (HDF5_objectExists(groupHandle,label)) & call HDF5_addAttribute(groupHandle,'Creator','DAMASK '//DAMASKVERSION,label) if (HDF5_objectExists(groupHandle,label)) & - call HDF5_addAttribute(groupHandle,'Created',now()) + call HDF5_addAttribute(groupHandle,'Created',now(),label) call HDF5_closeGroup(groupHandle) end subroutine results_writeScalarDataset_rotation @@ -772,6 +772,7 @@ character(len=24) function now() character(len=5) :: zone integer, dimension(8) :: values + call date_and_time(values=values,zone=zone) write(now,'(i4.4,5(a,i2.2),a)') & values(1),'-',values(2),'-',values(3),' ',values(5),':',values(6),':',values(7),zone From 5d0a2aac8fd9e866428175f1779a4ee8e34bc8c3 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Mon, 25 May 2020 19:35:36 +0200 Subject: [PATCH 18/29] polishing reporting --- python/damask/_result.py | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/python/damask/_result.py b/python/damask/_result.py index 244c11c69..412c66f6f 100644 --- a/python/damask/_result.py +++ b/python/damask/_result.py @@ -502,7 +502,7 @@ class Result: 'meta': { 'Unit': x['meta']['Unit'], 'Description': 'Absolute value of {} ({})'.format(x['label'],x['meta']['Description']), - 'Creator': 'result.py:add_abs v{}'.format(version) + 'Creator': 'damask.Result.add_abs v{}'.format(version) } } def add_absolute(self,x): @@ -530,7 +530,7 @@ class Result: 'meta': { 'Unit': kwargs['unit'], 'Description': '{} (formula: {})'.format(kwargs['description'],kwargs['formula']), - 'Creator': 'result.py:add_calculation v{}'.format(version) + 'Creator': 'damask.Result.add_calculation v{}'.format(version) } } def add_calculation(self,label,formula,unit='n/a',description=None,vectorized=True): @@ -569,7 +569,7 @@ class Result: 'Description': 'Cauchy stress calculated from {} ({}) '.format(P['label'], P['meta']['Description'])+\ 'and {} ({})'.format(F['label'],F['meta']['Description']), - 'Creator': 'result.py:add_Cauchy v{}'.format(version) + 'Creator': 'damask.Result.add_Cauchy v{}'.format(version) } } def add_Cauchy(self,P='P',F='F'): @@ -595,7 +595,7 @@ class Result: 'meta': { 'Unit': T['meta']['Unit'], 'Description': 'Determinant of tensor {} ({})'.format(T['label'],T['meta']['Description']), - 'Creator': 'result.py:add_determinant v{}'.format(version) + 'Creator': 'damask.Result.add_determinant v{}'.format(version) } } def add_determinant(self,T): @@ -619,7 +619,7 @@ class Result: 'meta': { 'Unit': T['meta']['Unit'], 'Description': 'Deviator of tensor {} ({})'.format(T['label'],T['meta']['Description']), - 'Creator': 'result.py:add_deviator v{}'.format(version) + 'Creator': 'damask.Result.add_deviator v{}'.format(version) } } def add_deviator(self,T): @@ -643,7 +643,7 @@ class Result: 'meta' : { 'Unit': T_sym['meta']['Unit'], 'Description': 'Eigenvalues of {} ({})'.format(T_sym['label'],T_sym['meta']['Description']), - 'Creator': 'result.py:add_eigenvalues v{}'.format(version) + 'Creator': 'damask.Result.add_eigenvalues v{}'.format(version) } } def add_eigenvalues(self,T_sym): @@ -667,7 +667,7 @@ class Result: 'meta' : { 'Unit': '1', 'Description': 'Eigenvectors of {} ({})'.format(T_sym['label'],T_sym['meta']['Description']), - 'Creator': 'result.py:add_eigenvectors v{}'.format(version) + 'Creator': 'damask.Result.add_eigenvectors v{}'.format(version) } } def add_eigenvectors(self,T_sym): @@ -703,7 +703,7 @@ class Result: 'Unit': 'RGB (8bit)', 'Lattice': lattice, 'Description': 'Inverse Pole Figure (IPF) colors along sample direction [{} {} {}]'.format(*m), - 'Creator': 'result.py:add_IPFcolor v{}'.format(version) + 'Creator': 'damask.Result.add_IPFcolor v{}'.format(version) } } def add_IPFcolor(self,q,l): @@ -729,7 +729,7 @@ class Result: 'meta': { 'Unit': T_sym['meta']['Unit'], 'Description': 'Maximum shear component of {} ({})'.format(T_sym['label'],T_sym['meta']['Description']), - 'Creator': 'result.py:add_maximum_shear v{}'.format(version) + 'Creator': 'damask.Result.add_maximum_shear v{}'.format(version) } } def add_maximum_shear(self,T_sym): @@ -756,7 +756,7 @@ class Result: 'meta': { 'Unit': T_sym['meta']['Unit'], 'Description': 'Mises equivalent {} of {} ({})'.format(t,T_sym['label'],T_sym['meta']['Description']), - 'Creator': 'result.py:add_Mises v{}'.format(version) + 'Creator': 'damask.Result.add_Mises v{}'.format(version) } } def add_Mises(self,T_sym): @@ -792,7 +792,7 @@ class Result: 'meta': { 'Unit': x['meta']['Unit'], 'Description': '{}-norm of {} {} ({})'.format(o,t,x['label'],x['meta']['Description']), - 'Creator': 'result.py:add_norm v{}'.format(version) + 'Creator': 'damask.Result.add_norm v{}'.format(version) } } def add_norm(self,x,ord=None): @@ -820,7 +820,7 @@ class Result: 'Description': '2. Kirchhoff stress calculated from {} ({}) '.format(P['label'], P['meta']['Description'])+\ 'and {} ({})'.format(F['label'],F['meta']['Description']), - 'Creator': 'result.py:add_PK2 v{}'.format(version) + 'Creator': 'damask.Result.add_PK2 v{}'.format(version) } } def add_PK2(self,P='P',F='F'): @@ -856,7 +856,7 @@ class Result: 'Unit': '1', 'Description': '{} coordinates of stereographic projection of pole (direction/plane) in crystal frame'\ .format('Polar' if polar else 'Cartesian'), - 'Creator' : 'result.py:add_pole v{}'.format(version) + 'Creator' : 'damask.Result.add_pole v{}'.format(version) } } def add_pole(self,q,p,polar=False): @@ -884,7 +884,7 @@ class Result: 'meta': { 'Unit': F['meta']['Unit'], 'Description': 'Rotational part of {} ({})'.format(F['label'],F['meta']['Description']), - 'Creator': 'result.py:add_rotational_part v{}'.format(version) + 'Creator': 'damask.Result.add_rotational_part v{}'.format(version) } } def add_rotational_part(self,F): @@ -908,7 +908,7 @@ class Result: 'meta': { 'Unit': T['meta']['Unit'], 'Description': 'Spherical component of tensor {} ({})'.format(T['label'],T['meta']['Description']), - 'Creator': 'result.py:add_spherical v{}'.format(version) + 'Creator': 'damask.Result.add_spherical v{}'.format(version) } } def add_spherical(self,T): @@ -932,7 +932,7 @@ class Result: 'meta': { 'Unit': F['meta']['Unit'], 'Description': 'Strain tensor of {} ({})'.format(F['label'],F['meta']['Description']), - 'Creator': 'result.py:add_strain_tensor v{}'.format(version) + 'Creator': 'damask.Result.add_strain_tensor v{}'.format(version) } } def add_strain_tensor(self,F='F',t='V',m=0.0): @@ -964,7 +964,7 @@ class Result: 'Unit': F['meta']['Unit'], 'Description': '{} stretch tensor of {} ({})'.format('Left' if t == 'V' else 'Right', F['label'],F['meta']['Description']), - 'Creator': 'result.py:add_stretch_tensor v{}'.format(version) + 'Creator': 'damask.Result.add_stretch_tensor v{}'.format(version) } } def add_stretch_tensor(self,F='F',t='V'): From d9d089c359a737acc63861961670650f80f3d6a6 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Mon, 25 May 2020 19:57:32 +0200 Subject: [PATCH 19/29] avoid repetition and do correct encode/decode --- python/damask/_result.py | 42 +++++++++++++++++++++++----------------- 1 file changed, 24 insertions(+), 18 deletions(-) diff --git a/python/damask/_result.py b/python/damask/_result.py index 412c66f6f..34c6e9437 100644 --- a/python/damask/_result.py +++ b/python/damask/_result.py @@ -1,5 +1,6 @@ import multiprocessing import re +import inspect import glob import os import datetime @@ -502,7 +503,7 @@ class Result: 'meta': { 'Unit': x['meta']['Unit'], 'Description': 'Absolute value of {} ({})'.format(x['label'],x['meta']['Description']), - 'Creator': 'damask.Result.add_abs v{}'.format(version) + 'Creator': 'add_absolute' } } def add_absolute(self,x): @@ -530,7 +531,7 @@ class Result: 'meta': { 'Unit': kwargs['unit'], 'Description': '{} (formula: {})'.format(kwargs['description'],kwargs['formula']), - 'Creator': 'damask.Result.add_calculation v{}'.format(version) + 'Creator': 'add_calculation' } } def add_calculation(self,label,formula,unit='n/a',description=None,vectorized=True): @@ -569,7 +570,7 @@ class Result: 'Description': 'Cauchy stress calculated from {} ({}) '.format(P['label'], P['meta']['Description'])+\ 'and {} ({})'.format(F['label'],F['meta']['Description']), - 'Creator': 'damask.Result.add_Cauchy v{}'.format(version) + 'Creator': 'add_Cauchy' } } def add_Cauchy(self,P='P',F='F'): @@ -595,7 +596,7 @@ class Result: 'meta': { 'Unit': T['meta']['Unit'], 'Description': 'Determinant of tensor {} ({})'.format(T['label'],T['meta']['Description']), - 'Creator': 'damask.Result.add_determinant v{}'.format(version) + 'Creator': 'add_determinant' } } def add_determinant(self,T): @@ -619,7 +620,7 @@ class Result: 'meta': { 'Unit': T['meta']['Unit'], 'Description': 'Deviator of tensor {} ({})'.format(T['label'],T['meta']['Description']), - 'Creator': 'damask.Result.add_deviator v{}'.format(version) + 'Creator': 'add_deviator' } } def add_deviator(self,T): @@ -643,7 +644,7 @@ class Result: 'meta' : { 'Unit': T_sym['meta']['Unit'], 'Description': 'Eigenvalues of {} ({})'.format(T_sym['label'],T_sym['meta']['Description']), - 'Creator': 'damask.Result.add_eigenvalues v{}'.format(version) + 'Creator': 'add_eigenvalues' } } def add_eigenvalues(self,T_sym): @@ -667,7 +668,7 @@ class Result: 'meta' : { 'Unit': '1', 'Description': 'Eigenvectors of {} ({})'.format(T_sym['label'],T_sym['meta']['Description']), - 'Creator': 'damask.Result.add_eigenvectors v{}'.format(version) + 'Creator': 'add_eigenvectors' } } def add_eigenvectors(self,T_sym): @@ -703,7 +704,7 @@ class Result: 'Unit': 'RGB (8bit)', 'Lattice': lattice, 'Description': 'Inverse Pole Figure (IPF) colors along sample direction [{} {} {}]'.format(*m), - 'Creator': 'damask.Result.add_IPFcolor v{}'.format(version) + 'Creator': 'add_IPFcolor' } } def add_IPFcolor(self,q,l): @@ -729,7 +730,7 @@ class Result: 'meta': { 'Unit': T_sym['meta']['Unit'], 'Description': 'Maximum shear component of {} ({})'.format(T_sym['label'],T_sym['meta']['Description']), - 'Creator': 'damask.Result.add_maximum_shear v{}'.format(version) + 'Creator': 'add_maximum_shear' } } def add_maximum_shear(self,T_sym): @@ -756,7 +757,7 @@ class Result: 'meta': { 'Unit': T_sym['meta']['Unit'], 'Description': 'Mises equivalent {} of {} ({})'.format(t,T_sym['label'],T_sym['meta']['Description']), - 'Creator': 'damask.Result.add_Mises v{}'.format(version) + 'Creator': 'add_Mises' } } def add_Mises(self,T_sym): @@ -792,7 +793,7 @@ class Result: 'meta': { 'Unit': x['meta']['Unit'], 'Description': '{}-norm of {} {} ({})'.format(o,t,x['label'],x['meta']['Description']), - 'Creator': 'damask.Result.add_norm v{}'.format(version) + 'Creator': 'add_norm' } } def add_norm(self,x,ord=None): @@ -820,7 +821,7 @@ class Result: 'Description': '2. Kirchhoff stress calculated from {} ({}) '.format(P['label'], P['meta']['Description'])+\ 'and {} ({})'.format(F['label'],F['meta']['Description']), - 'Creator': 'damask.Result.add_PK2 v{}'.format(version) + 'Creator': 'add_PK2' } } def add_PK2(self,P='P',F='F'): @@ -856,7 +857,7 @@ class Result: 'Unit': '1', 'Description': '{} coordinates of stereographic projection of pole (direction/plane) in crystal frame'\ .format('Polar' if polar else 'Cartesian'), - 'Creator' : 'damask.Result.add_pole v{}'.format(version) + 'Creator' : 'add_pole' } } def add_pole(self,q,p,polar=False): @@ -884,7 +885,7 @@ class Result: 'meta': { 'Unit': F['meta']['Unit'], 'Description': 'Rotational part of {} ({})'.format(F['label'],F['meta']['Description']), - 'Creator': 'damask.Result.add_rotational_part v{}'.format(version) + 'Creator': 'add_rotational_part' } } def add_rotational_part(self,F): @@ -908,7 +909,7 @@ class Result: 'meta': { 'Unit': T['meta']['Unit'], 'Description': 'Spherical component of tensor {} ({})'.format(T['label'],T['meta']['Description']), - 'Creator': 'damask.Result.add_spherical v{}'.format(version) + 'Creator': 'add_spherical' } } def add_spherical(self,T): @@ -932,7 +933,7 @@ class Result: 'meta': { 'Unit': F['meta']['Unit'], 'Description': 'Strain tensor of {} ({})'.format(F['label'],F['meta']['Description']), - 'Creator': 'damask.Result.add_strain_tensor v{}'.format(version) + 'Creator': 'add_strain_tensor' } } def add_strain_tensor(self,F='F',t='V',m=0.0): @@ -964,7 +965,7 @@ class Result: 'Unit': F['meta']['Unit'], 'Description': '{} stretch tensor of {} ({})'.format('Left' if t == 'V' else 'Right', F['label'],F['meta']['Description']), - 'Creator': 'damask.Result.add_stretch_tensor v{}'.format(version) + 'Creator': 'add_stretch_tensor' } } def add_stretch_tensor(self,F='F',t='V'): @@ -1031,13 +1032,18 @@ class Result: if self._allow_overwrite and result[0]+'/'+result[1]['label'] in f: dataset = f[result[0]+'/'+result[1]['label']] datset = result[1]['data'] - dataset.attrs['Overwritten'] = True + dataset.attrs['Overwritten'] = 'Yes'.encode() else: dataset = f[result[0]].create_dataset(result[1]['label'],data=result[1]['data']) + now = datetime.datetime.now().astimezone() dataset.attrs['Created'] = now.strftime('%Y-%m-%d %H:%M:%S%z').encode() + for l,v in result[1]['meta'].items(): dataset.attrs[l]=v.encode() + creator = 'damask.Result.{} v{}'.format(dataset.attrs['Creator'].decode(),version) + dataset.attrs['Creator'] = creator.encode() + except OSError as err: print('Could not add dataset: {}.'.format(err)) lock.release() From d6877da2b675ba3a1bd9e16b757d50942f897084 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Mon, 25 May 2020 19:59:29 +0200 Subject: [PATCH 20/29] single source of truth --- python/damask/_result.py | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/python/damask/_result.py b/python/damask/_result.py index 34c6e9437..2ff3701e6 100644 --- a/python/damask/_result.py +++ b/python/damask/_result.py @@ -503,7 +503,7 @@ class Result: 'meta': { 'Unit': x['meta']['Unit'], 'Description': 'Absolute value of {} ({})'.format(x['label'],x['meta']['Description']), - 'Creator': 'add_absolute' + 'Creator': inspect.stack()[0][3][1:] } } def add_absolute(self,x): @@ -531,7 +531,7 @@ class Result: 'meta': { 'Unit': kwargs['unit'], 'Description': '{} (formula: {})'.format(kwargs['description'],kwargs['formula']), - 'Creator': 'add_calculation' + 'Creator': inspect.stack()[0][3][1:] } } def add_calculation(self,label,formula,unit='n/a',description=None,vectorized=True): @@ -570,7 +570,7 @@ class Result: 'Description': 'Cauchy stress calculated from {} ({}) '.format(P['label'], P['meta']['Description'])+\ 'and {} ({})'.format(F['label'],F['meta']['Description']), - 'Creator': 'add_Cauchy' + 'Creator': inspect.stack()[0][3][1:] } } def add_Cauchy(self,P='P',F='F'): @@ -596,7 +596,7 @@ class Result: 'meta': { 'Unit': T['meta']['Unit'], 'Description': 'Determinant of tensor {} ({})'.format(T['label'],T['meta']['Description']), - 'Creator': 'add_determinant' + 'Creator': inspect.stack()[0][3][1:] } } def add_determinant(self,T): @@ -620,7 +620,7 @@ class Result: 'meta': { 'Unit': T['meta']['Unit'], 'Description': 'Deviator of tensor {} ({})'.format(T['label'],T['meta']['Description']), - 'Creator': 'add_deviator' + 'Creator': inspect.stack()[0][3][1:] } } def add_deviator(self,T): @@ -644,7 +644,7 @@ class Result: 'meta' : { 'Unit': T_sym['meta']['Unit'], 'Description': 'Eigenvalues of {} ({})'.format(T_sym['label'],T_sym['meta']['Description']), - 'Creator': 'add_eigenvalues' + 'Creator': inspect.stack()[0][3][1:] } } def add_eigenvalues(self,T_sym): @@ -668,7 +668,7 @@ class Result: 'meta' : { 'Unit': '1', 'Description': 'Eigenvectors of {} ({})'.format(T_sym['label'],T_sym['meta']['Description']), - 'Creator': 'add_eigenvectors' + 'Creator': inspect.stack()[0][3][1:] } } def add_eigenvectors(self,T_sym): @@ -704,7 +704,7 @@ class Result: 'Unit': 'RGB (8bit)', 'Lattice': lattice, 'Description': 'Inverse Pole Figure (IPF) colors along sample direction [{} {} {}]'.format(*m), - 'Creator': 'add_IPFcolor' + 'Creator': inspect.stack()[0][3][1:] } } def add_IPFcolor(self,q,l): @@ -730,7 +730,7 @@ class Result: 'meta': { 'Unit': T_sym['meta']['Unit'], 'Description': 'Maximum shear component of {} ({})'.format(T_sym['label'],T_sym['meta']['Description']), - 'Creator': 'add_maximum_shear' + 'Creator': inspect.stack()[0][3][1:] } } def add_maximum_shear(self,T_sym): @@ -757,7 +757,7 @@ class Result: 'meta': { 'Unit': T_sym['meta']['Unit'], 'Description': 'Mises equivalent {} of {} ({})'.format(t,T_sym['label'],T_sym['meta']['Description']), - 'Creator': 'add_Mises' + 'Creator': inspect.stack()[0][3][1:] } } def add_Mises(self,T_sym): @@ -793,7 +793,7 @@ class Result: 'meta': { 'Unit': x['meta']['Unit'], 'Description': '{}-norm of {} {} ({})'.format(o,t,x['label'],x['meta']['Description']), - 'Creator': 'add_norm' + 'Creator': inspect.stack()[0][3][1:] } } def add_norm(self,x,ord=None): @@ -821,7 +821,7 @@ class Result: 'Description': '2. Kirchhoff stress calculated from {} ({}) '.format(P['label'], P['meta']['Description'])+\ 'and {} ({})'.format(F['label'],F['meta']['Description']), - 'Creator': 'add_PK2' + 'Creator': inspect.stack()[0][3][1:] } } def add_PK2(self,P='P',F='F'): @@ -854,10 +854,10 @@ class Result: 'data': coords, 'label': 'p^{}_[{} {} {})'.format(u'rφ' if polar else 'xy',*m), 'meta' : { - 'Unit': '1', + 'Unit': '1', 'Description': '{} coordinates of stereographic projection of pole (direction/plane) in crystal frame'\ .format('Polar' if polar else 'Cartesian'), - 'Creator' : 'add_pole' + 'Creator': inspect.stack()[0][3][1:] } } def add_pole(self,q,p,polar=False): @@ -885,7 +885,7 @@ class Result: 'meta': { 'Unit': F['meta']['Unit'], 'Description': 'Rotational part of {} ({})'.format(F['label'],F['meta']['Description']), - 'Creator': 'add_rotational_part' + 'Creator': inspect.stack()[0][3][1:] } } def add_rotational_part(self,F): @@ -909,7 +909,7 @@ class Result: 'meta': { 'Unit': T['meta']['Unit'], 'Description': 'Spherical component of tensor {} ({})'.format(T['label'],T['meta']['Description']), - 'Creator': 'add_spherical' + 'Creator': inspect.stack()[0][3][1:] } } def add_spherical(self,T): @@ -933,7 +933,7 @@ class Result: 'meta': { 'Unit': F['meta']['Unit'], 'Description': 'Strain tensor of {} ({})'.format(F['label'],F['meta']['Description']), - 'Creator': 'add_strain_tensor' + 'Creator': inspect.stack()[0][3][1:] } } def add_strain_tensor(self,F='F',t='V',m=0.0): @@ -965,7 +965,7 @@ class Result: 'Unit': F['meta']['Unit'], 'Description': '{} stretch tensor of {} ({})'.format('Left' if t == 'V' else 'Right', F['label'],F['meta']['Description']), - 'Creator': 'add_stretch_tensor' + 'Creator': inspect.stack()[0][3][1:] } } def add_stretch_tensor(self,F='F',t='V'): From 20e3bdd857794fe842848ec5f54d91ea5bb27802 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Mon, 25 May 2020 21:42:12 +0200 Subject: [PATCH 21/29] adjusted names --- DAMASK_prerequisites.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DAMASK_prerequisites.sh b/DAMASK_prerequisites.sh index b72f19b7a..25a2e46e0 100755 --- a/DAMASK_prerequisites.sh +++ b/DAMASK_prerequisites.sh @@ -110,7 +110,7 @@ for executable in icc icpc ifort ;do done firstLevel "MPI Wrappers" -for executable in mpicc mpiCC mpiicc mpic++ mpicpc mpicxx mpifort mpif90 mpif77; do +for executable in mpicc mpiCC mpiicc mpic++ mpiicpc mpicxx mpifort mpiifort mpif90 mpif77; do getDetails $executable '-show' done From e8992e7b72aeac5ea58fa1b98a4cd11a380c6e1f Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Mon, 25 May 2020 22:09:46 +0200 Subject: [PATCH 22/29] documentation --- src/results.f90 | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/results.f90 b/src/results.f90 index d1db96f47..21173c512 100644 --- a/src/results.f90 +++ b/src/results.f90 @@ -767,6 +767,10 @@ subroutine results_mapping_materialpoint(homogenizationAt,memberAtLocal,label) end subroutine results_mapping_materialpoint + +!-------------------------------------------------------------------------------------------------- +!> @brief current date and time (including time zone information) +!-------------------------------------------------------------------------------------------------- character(len=24) function now() character(len=5) :: zone @@ -778,6 +782,7 @@ character(len=24) function now() end function now + !!-------------------------------------------------------------------------------------------------- !!> @brief adds the backward mapping from spatial position and constituent ID to results !!-------------------------------------------------------------------------------------------------- From 9076fbe5259de0bd7a2e0319e5a4686374bf17e9 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Mon, 25 May 2020 23:05:31 +0200 Subject: [PATCH 23/29] testing overwrite functionality --- python/tests/test_Result.py | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/python/tests/test_Result.py b/python/tests/test_Result.py index 4eacdee4c..4de8598f7 100644 --- a/python/tests/test_Result.py +++ b/python/tests/test_Result.py @@ -1,8 +1,11 @@ +import time import shutil import os +from datetime import datetime import pytest import numpy as np +import h5py import damask from damask import Result @@ -81,9 +84,34 @@ class TestResult: default.pick('invalid',True) def test_add_invalid(self,default): - with pytest.raises(Exception): + with pytest.raises(TypeError): default.add_calculation('#invalid#*2') + @pytest.mark.parametrize('overwrite',['off','on']) + def test_add_overwrite(self,default,overwrite): + default.pick('times',default.times_in_range(0,np.inf)[-1]) + + default.add_Cauchy() + dset = default.groups_with_datasets('sigma')[0]+'/sigma' + with h5py.File(default.fname,'r') as f: + created_first = f[dset].attrs['Created'].decode() + created_first = datetime.strptime(created_first,'%Y-%m-%d %H:%M:%S%z') + + if overwrite == 'on': + default.enable_overwrite() + else: + default.disable_overwrite() + + time.sleep(2.) + default.add_Cauchy() + with h5py.File(default.fname,'r') as f: + created_second = f[dset].attrs['Created'].decode() + created_second = datetime.strptime(created_second,'%Y-%m-%d %H:%M:%S%z') + if overwrite == 'on': + assert created_first < created_second + else: + assert created_first == created_second + def test_add_absolute(self,default): default.add_absolute('Fe') loc = {'Fe': default.get_dataset_location('Fe'), From 9855c617470ebfbe1a85e705fb1a68e4c58f033d Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Mon, 25 May 2020 23:39:19 +0200 Subject: [PATCH 24/29] store vtk file in tmp directory --- python/tests/test_Result.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/python/tests/test_Result.py b/python/tests/test_Result.py index 4de8598f7..6d1961823 100644 --- a/python/tests/test_Result.py +++ b/python/tests/test_Result.py @@ -292,5 +292,6 @@ class TestResult: assert np.allclose(in_memory,in_file) @pytest.mark.parametrize('output',['F',[],['F','P']]) - def test_vtk(self,default,output): + def test_vtk(self,tmp_path,default,output): + os.chdir(tmp_path) default.to_vtk(output) From 6f7c7005b0d0d1d61d77144ebd843451ccd0bf28 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Mon, 25 May 2020 23:54:06 +0200 Subject: [PATCH 25/29] bugfix: - proper overwrite - no out of bounds error for empty time selection (just pick nothin) --- python/damask/_result.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/python/damask/_result.py b/python/damask/_result.py index 2ff3701e6..021b66d4a 100644 --- a/python/damask/_result.py +++ b/python/damask/_result.py @@ -146,6 +146,7 @@ class Result: choice = [] for c in iterator: idx = np.searchsorted(self.times,c) + if idx >= len(self.times): continue if np.isclose(c,self.times[idx]): choice.append(self.increments[idx]) elif np.isclose(c,self.times[idx+1]): @@ -1031,7 +1032,7 @@ class Result: try: if self._allow_overwrite and result[0]+'/'+result[1]['label'] in f: dataset = f[result[0]+'/'+result[1]['label']] - datset = result[1]['data'] + dataset[...] = result[1]['data'] dataset.attrs['Overwritten'] = 'Yes'.encode() else: dataset = f[result[0]].create_dataset(result[1]['label'],data=result[1]['data']) From 7f09c90c7db51763f263d2ec43b3cca8cd9cd3ef Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Tue, 26 May 2020 06:39:11 +0200 Subject: [PATCH 26/29] different h5py versions seem to throw different errors --- python/damask/_result.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/damask/_result.py b/python/damask/_result.py index 021b66d4a..d0f437d72 100644 --- a/python/damask/_result.py +++ b/python/damask/_result.py @@ -1045,7 +1045,7 @@ class Result: creator = 'damask.Result.{} v{}'.format(dataset.attrs['Creator'].decode(),version) dataset.attrs['Creator'] = creator.encode() - except OSError as err: + except (OSError,RuntimeError) as err: print('Could not add dataset: {}.'.format(err)) lock.release() From 88c49fc4f4498a75cabe0cb58b81648084fb25da Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Tue, 26 May 2020 06:48:52 +0200 Subject: [PATCH 27/29] also check values --- python/tests/test_Result.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/python/tests/test_Result.py b/python/tests/test_Result.py index 6d1961823..92e61771f 100644 --- a/python/tests/test_Result.py +++ b/python/tests/test_Result.py @@ -92,9 +92,9 @@ class TestResult: default.pick('times',default.times_in_range(0,np.inf)[-1]) default.add_Cauchy() - dset = default.groups_with_datasets('sigma')[0]+'/sigma' + loc = default.get_dataset_location('sigma')[0] with h5py.File(default.fname,'r') as f: - created_first = f[dset].attrs['Created'].decode() + created_first = f[loc].attrs['Created'].decode() created_first = datetime.strptime(created_first,'%Y-%m-%d %H:%M:%S%z') if overwrite == 'on': @@ -103,14 +103,14 @@ class TestResult: default.disable_overwrite() time.sleep(2.) - default.add_Cauchy() + default.add_calculation('sigma','#sigma#*0.0+311.','not the Cauchy stress') with h5py.File(default.fname,'r') as f: - created_second = f[dset].attrs['Created'].decode() + created_second = f[loc].attrs['Created'].decode() created_second = datetime.strptime(created_second,'%Y-%m-%d %H:%M:%S%z') if overwrite == 'on': - assert created_first < created_second + assert created_first < created_second and np.allclose(default.read_dataset(loc),311.) else: - assert created_first == created_second + assert created_first == created_second and not np.allclose(default.read_dataset(loc),311.) def test_add_absolute(self,default): default.add_absolute('Fe') From 670e08468be1cc67d53dc1b41796bd5113c4ca94 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Tue, 26 May 2020 06:49:29 +0200 Subject: [PATCH 28/29] reorder tests depend on other functionality that should be tested first --- python/tests/test_Result.py | 58 ++++++++++++++++++------------------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/python/tests/test_Result.py b/python/tests/test_Result.py index 92e61771f..772cf4734 100644 --- a/python/tests/test_Result.py +++ b/python/tests/test_Result.py @@ -83,35 +83,6 @@ class TestResult: with pytest.raises(AttributeError): default.pick('invalid',True) - def test_add_invalid(self,default): - with pytest.raises(TypeError): - default.add_calculation('#invalid#*2') - - @pytest.mark.parametrize('overwrite',['off','on']) - def test_add_overwrite(self,default,overwrite): - default.pick('times',default.times_in_range(0,np.inf)[-1]) - - default.add_Cauchy() - loc = default.get_dataset_location('sigma')[0] - with h5py.File(default.fname,'r') as f: - created_first = f[loc].attrs['Created'].decode() - created_first = datetime.strptime(created_first,'%Y-%m-%d %H:%M:%S%z') - - if overwrite == 'on': - default.enable_overwrite() - else: - default.disable_overwrite() - - time.sleep(2.) - default.add_calculation('sigma','#sigma#*0.0+311.','not the Cauchy stress') - with h5py.File(default.fname,'r') as f: - created_second = f[loc].attrs['Created'].decode() - created_second = datetime.strptime(created_second,'%Y-%m-%d %H:%M:%S%z') - if overwrite == 'on': - assert created_first < created_second and np.allclose(default.read_dataset(loc),311.) - else: - assert created_first == created_second and not np.allclose(default.read_dataset(loc),311.) - def test_add_absolute(self,default): default.add_absolute('Fe') loc = {'Fe': default.get_dataset_location('Fe'), @@ -291,6 +262,35 @@ class TestResult: in_file = default.read_dataset(loc['V(F)'],0) assert np.allclose(in_memory,in_file) + def test_add_invalid(self,default): + with pytest.raises(TypeError): + default.add_calculation('#invalid#*2') + + @pytest.mark.parametrize('overwrite',['off','on']) + def test_add_overwrite(self,default,overwrite): + default.pick('times',default.times_in_range(0,np.inf)[-1]) + + default.add_Cauchy() + loc = default.get_dataset_location('sigma')[0] + with h5py.File(default.fname,'r') as f: + created_first = f[loc].attrs['Created'].decode() + created_first = datetime.strptime(created_first,'%Y-%m-%d %H:%M:%S%z') + + if overwrite == 'on': + default.enable_overwrite() + else: + default.disable_overwrite() + + time.sleep(2.) + default.add_calculation('sigma','#sigma#*0.0+311.','not the Cauchy stress') + with h5py.File(default.fname,'r') as f: + created_second = f[loc].attrs['Created'].decode() + created_second = datetime.strptime(created_second,'%Y-%m-%d %H:%M:%S%z') + if overwrite == 'on': + assert created_first < created_second and np.allclose(default.read_dataset(loc),311.) + else: + assert created_first == created_second and not np.allclose(default.read_dataset(loc),311.) + @pytest.mark.parametrize('output',['F',[],['F','P']]) def test_vtk(self,tmp_path,default,output): os.chdir(tmp_path) From 5ad7fe04d0ac1436670a4bd871a7621b75af793a Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Tue, 26 May 2020 07:15:27 +0200 Subject: [PATCH 29/29] bugfix: used wrong type --- python/tests/test_Result.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/python/tests/test_Result.py b/python/tests/test_Result.py index 772cf4734..11395b23f 100644 --- a/python/tests/test_Result.py +++ b/python/tests/test_Result.py @@ -271,9 +271,10 @@ class TestResult: default.pick('times',default.times_in_range(0,np.inf)[-1]) default.add_Cauchy() - loc = default.get_dataset_location('sigma')[0] + loc = default.get_dataset_location('sigma') + print(loc) with h5py.File(default.fname,'r') as f: - created_first = f[loc].attrs['Created'].decode() + created_first = f[loc[0]].attrs['Created'].decode() created_first = datetime.strptime(created_first,'%Y-%m-%d %H:%M:%S%z') if overwrite == 'on': @@ -284,7 +285,7 @@ class TestResult: time.sleep(2.) default.add_calculation('sigma','#sigma#*0.0+311.','not the Cauchy stress') with h5py.File(default.fname,'r') as f: - created_second = f[loc].attrs['Created'].decode() + created_second = f[loc[0]].attrs['Created'].decode() created_second = datetime.strptime(created_second,'%Y-%m-%d %H:%M:%S%z') if overwrite == 'on': assert created_first < created_second and np.allclose(default.read_dataset(loc),311.)