diff --git a/Makefile b/Makefile index d38966bc5..dfbcbd5ae 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,9 @@ SHELL = /bin/sh -######################################################################################## -# Makefile for the installation of DAMASK -######################################################################################## + +################################################################################################### +# One-command-build invoking CMake (meant for developers, should not be part of the distribution) +################################################################################################### + .PHONY: all all: grid mesh diff --git a/python/damask/_colormap.py b/python/damask/_colormap.py index 639a5a04c..de63508b3 100644 --- a/python/damask/_colormap.py +++ b/python/damask/_colormap.py @@ -39,20 +39,20 @@ class Colormap(mpl.colors.ListedColormap): """ def __add__(self,other): - """Concatenate colormaps.""" + """Concatenate.""" return Colormap(np.vstack((self.colors,other.colors)), f'{self.name}+{other.name}') def __iadd__(self,other): - """Concatenate colormaps.""" + """Concatenate (in-place).""" return self.__add__(other) def __invert__(self): - """Return inverted colormap.""" + """Reverse.""" return self.reversed() def __repr__(self): - """Show colormap as matplotlib figure.""" + """Show as matplotlib figure.""" fig = plt.figure(self.name,figsize=(5,.5)) ax1 = fig.add_axes([0, 0, 1, 1]) ax1.set_axis_off() @@ -207,7 +207,7 @@ class Colormap(mpl.colors.ListedColormap): def reversed(self,name=None): """ - Make a reversed instance of the colormap. + Reverse. Parameters ---------- diff --git a/python/damask/_config.py b/python/damask/_config.py index 5be1d973c..989f28fcd 100644 --- a/python/damask/_config.py +++ b/python/damask/_config.py @@ -31,7 +31,7 @@ class NiceDumper(yaml.SafeDumper): return super().represent_data(data) def ignore_aliases(self, data): - """No references.""" + """Do not use references to existing objects.""" return True class Config(dict): diff --git a/python/damask/_configmaterial.py b/python/damask/_configmaterial.py index fb9b41932..a5fe837ee 100644 --- a/python/damask/_configmaterial.py +++ b/python/damask/_configmaterial.py @@ -9,14 +9,29 @@ from . import Orientation from . import util class ConfigMaterial(Config): - """Material configuration.""" + """ + Material configuration. + + Manipulate material configurations for storage in YAML format. + A complete material configuration file has the entries 'material', + 'phase', and 'homogenization'. For use in DAMASK, it needs to be + stored as 'material.yaml'. + """ _defaults = {'material': [], 'homogenization': {}, 'phase': {}} def __init__(self,d=_defaults): - """Initialize object with default dictionary keys.""" + """ + New material configuration. + + Parameters + ---------- + d : dictionary, optional + Initial content. Defaults to empty material, homogenization, and phase entries. + + """ super().__init__(d) diff --git a/python/damask/_grid.py b/python/damask/_grid.py index a76f7f2c4..18c9b0d25 100644 --- a/python/damask/_grid.py +++ b/python/damask/_grid.py @@ -17,11 +17,18 @@ from . import Rotation class Grid: - """Geometry definition for grid solvers.""" + """ + Geometry definition for grid solvers. + + Create and manipulate geometry definitions for storage as VTK + rectiliear grid files ('.vtr' extension). A grid contains the + material ID (referring to the entry in 'material.yaml') and + the physical size. + """ def __init__(self,material,size,origin=[0.0,0.0,0.0],comments=[]): """ - New grid definition from array of materials, size, and origin. + New geometry definition for grid solvers. Parameters ---------- diff --git a/python/damask/_orientation.py b/python/damask/_orientation.py index f05f47544..bbb682e82 100644 --- a/python/damask/_orientation.py +++ b/python/damask/_orientation.py @@ -47,19 +47,30 @@ class Orientation(Rotation): The Bravais lattice is one of Orientation.lattice_symmetries: - - aP : triclinic primitive - - mP : monoclinic primitive - - mS : ... base-centered - - oP : orthorhombic primitive - - oS : ... base-centered - - oI : ... body-centered - - oF : ... face-centered - - tP : tetragonal primitive - - tI : ... body-centered - - hP : hexagonal primitive - - cP : cubic primitive - - cI : ... body-centered - - cF : ... face-centered + - triclinic + - aP : primitive + + - monoclininic + - mP : primitive + - mS : base-centered + + - orthorhombic + - oP : primitive + - oS : base-centered + - oI : body-centered + - oF : face-centered + + - tetragonal + - tP : primitive + - tI : body-centered + + - hexagonal + - hP : primitive + + - cubic + - cP : primitive + - cI : body-centered + - cF : face-centered and inherits the corresponding crystal family. Specifying a Bravais lattice, compared to just the crystal family, @@ -111,7 +122,7 @@ class Orientation(Rotation): alpha = None,beta = None,gamma = None, degrees = False): """ - Initialize orientation object. + New orientation. Parameters ---------- diff --git a/python/damask/_result.py b/python/damask/_result.py index f247a8d07..415ddded9 100644 --- a/python/damask/_result.py +++ b/python/damask/_result.py @@ -26,14 +26,14 @@ h5py3 = h5py.__version__[0] == '3' class Result: """ - Read and write to DADF5 files. + Manipulate and read DADF5 files. DADF5 (DAMASK HDF5) files contain DAMASK results. """ def __init__(self,fname): """ - Open an existing DADF5 file. + New result view bound to a HDF5 file. Parameters ---------- diff --git a/python/damask/_rotation.py b/python/damask/_rotation.py index 40078e4d5..8d8a13d99 100644 --- a/python/damask/_rotation.py +++ b/python/damask/_rotation.py @@ -51,7 +51,7 @@ class Rotation: def __init__(self,rotation = np.array([1.0,0.0,0.0,0.0])): """ - Initialize rotation object. + New rotation. Parameters ---------- @@ -140,7 +140,7 @@ class Rotation: def __len__(self): - """Length of leading/leftmost dimension of Rotation array.""" + """Length of leading/leftmost dimension of array.""" return 0 if self.shape == () else self.shape[0] @@ -180,7 +180,7 @@ class Rotation: def __mul__(self,other): """ - Compose this rotation with other. + Compose with other. Parameters ---------- @@ -206,7 +206,7 @@ class Rotation: def __imul__(self,other): """ - Compose this rotation with other (in-place). + Compose with other (in-place). Parameters ---------- @@ -219,7 +219,7 @@ class Rotation: def __truediv__(self,other): """ - Compose this rotation with inverse of other. + Compose with inverse of other. Parameters ---------- @@ -239,7 +239,7 @@ class Rotation: def __itruediv__(self,other): """ - Compose this rotation with inverse of other (in-place). + Compose with inverse of other (in-place). Parameters ---------- @@ -252,7 +252,7 @@ class Rotation: def __matmul__(self,other): """ - Rotation of vector, second order tensor, or fourth order tensor. + Rotate vector, second order tensor, or fourth order tensor. Parameters ---------- @@ -301,7 +301,7 @@ class Rotation: def append(self,other): """ - Extend rotation array along first dimension with other array(s). + Extend array along first dimension with other array(s). Parameters ---------- @@ -313,19 +313,19 @@ class Rotation: def flatten(self,order = 'C'): - """Flatten quaternion array.""" + """Flatten array.""" return self.copy(rotation=self.quaternion.reshape((-1,4),order=order)) def reshape(self,shape,order = 'C'): - """Reshape quaternion array.""" + """Reshape array.""" if isinstance(shape,(int,np.integer)): shape = (shape,) return self.copy(rotation=self.quaternion.reshape(tuple(shape)+(4,),order=order)) def broadcast_to(self,shape,mode = 'right'): """ - Broadcast quaternion array to shape. + Broadcast array. Parameters ---------- @@ -343,7 +343,7 @@ class Rotation: def average(self,weights = None): """ - Average rotations along last dimension. + Average along last array dimension. Parameters ---------- @@ -382,7 +382,7 @@ class Rotation: def misorientation(self,other): """ - Calculate misorientation from self to other Rotation. + Calculate misorientation to other Rotation. Parameters ---------- diff --git a/python/damask/_table.py b/python/damask/_table.py index ee64ba017..fef84cca5 100644 --- a/python/damask/_table.py +++ b/python/damask/_table.py @@ -7,7 +7,7 @@ import numpy as np from . import util class Table: - """Store spreadsheet-like data.""" + """Manipulate multi-dimensional spreadsheet-like data.""" def __init__(self,data,shapes,comments=None): """ @@ -77,13 +77,11 @@ class Table: """ Load from ASCII table file. - In legacy style, the first line indicates the number of - subsequent header lines as "N header", with the last header line being - interpreted as column labels. - Alternatively, initial comments are marked by '#', with the first non-comment line + Initial comments are marked by '#', the first non-comment line containing the column labels. - Vector data column labels are indicated by '1_v, 2_v, ..., n_v'. - Tensor data column labels are indicated by '3x3:1_T, 3x3:2_T, ..., 3x3:9_T'. + + - Vector data column labels are indicated by '1_v, 2_v, ..., n_v'. + - Tensor data column labels are indicated by '3x3:1_T, 3x3:2_T, ..., 3x3:9_T'. Parameters ---------- @@ -97,21 +95,13 @@ class Table: f = fname f.seek(0) - try: - N_comment_lines,keyword = f.readline().strip().split(maxsplit=1) - if keyword != 'header': - raise ValueError - else: - comments = [f.readline().strip() for i in range(1,int(N_comment_lines))] - labels = f.readline().split() - except ValueError: - f.seek(0) - comments = [] + f.seek(0) + comments = [] + line = f.readline().strip() + while line.startswith('#'): + comments.append(line.lstrip('#').strip()) line = f.readline().strip() - while line.startswith('#'): - comments.append(line.lstrip('#').strip()) - line = f.readline().strip() - labels = line.split() + labels = line.split() shapes = {} for label in labels: @@ -391,7 +381,7 @@ class Table: return dup - def save(self,fname,legacy=False): + def save(self,fname): """ Save as plain text file. @@ -399,9 +389,6 @@ class Table: ---------- fname : file, str, or pathlib.Path Filename or file for writing. - legacy : Boolean, optional - Write table in legacy style, indicating header lines by "N header" - in contrast to using comment sign ('#') at beginning of lines. """ seen = set() @@ -416,13 +403,10 @@ class Table: labels += [f'{util.srepr(self.shapes[l],"x")}:{i+1}_{l}' \ for i in range(np.prod(self.shapes[l]))] - header = ([f'{len(self.comments)+1} header'] + self.comments) if legacy else \ - [f'# {comment}' for comment in self.comments] - try: fhandle = open(fname,'w',newline='\n') except TypeError: fhandle = fname - for line in header + [' '.join(labels)]: fhandle.write(line+'\n') + fhandle.write('\n'.join([f'# {c}' for c in self.comments] + [' '.join(labels)])+'\n') self.data.to_csv(fhandle,sep=' ',na_rep='nan',index=False,header=False) diff --git a/python/damask/_vtk.py b/python/damask/_vtk.py index b9f237297..ebd2f39a6 100644 --- a/python/damask/_vtk.py +++ b/python/damask/_vtk.py @@ -22,7 +22,7 @@ class VTK: def __init__(self,vtk_data): """ - Initialize from vtk dataset. + New spatial visualization. Parameters ---------- diff --git a/python/damask/util.py b/python/damask/util.py index 5f2a8b1ff..902e0409c 100644 --- a/python/damask/util.py +++ b/python/damask/util.py @@ -153,10 +153,12 @@ def scale_to_coprime(v): """Denominator of the square of a number.""" return fractions.Fraction(x ** 2).limit_denominator(MAX_DENOMINATOR).denominator - def lcm(a, b): + def lcm(a,b): """Least common multiple.""" - # Python 3.9 provides math.lcm, see https://stackoverflow.com/questions/51716916. - return a * b // np.gcd(a, b) + try: + return np.lcm(a,b) # numpy > 1.18 + except AttributeError: + return a * b // np.gcd(a, b) m = (np.array(v) * reduce(lcm, map(lambda x: int(get_square_denominator(x)),v)) ** 0.5).astype(int) m = m//reduce(np.gcd,m) @@ -405,7 +407,7 @@ class return_message: def __init__(self,message): """ - Sets return message. + Set return message. Parameters ---------- @@ -429,7 +431,7 @@ class _ProgressBar: def __init__(self,total,prefix,bar_length): """ - Inititalize a progress bar to current time as basis for ETA estimation. + Set current time as basis for ETA estimation. Parameters ---------- diff --git a/python/tests/reference/Orientation/cF_Bain.txt b/python/tests/reference/Orientation/cF_Bain.txt index 876cf3888..ae06eb2fb 100644 --- a/python/tests/reference/Orientation/cF_Bain.txt +++ b/python/tests/reference/Orientation/cF_Bain.txt @@ -1,4 +1,3 @@ -1 header 1_Eulers 2_Eulers 3_Eulers 1_pos 2_pos 180.0 45.00000000000001 180.0 1 1 270.0 45.00000000000001 90.0 1 2 diff --git a/python/tests/reference/Orientation/cF_GT.txt b/python/tests/reference/Orientation/cF_GT.txt index cefae431a..e73885048 100644 --- a/python/tests/reference/Orientation/cF_GT.txt +++ b/python/tests/reference/Orientation/cF_GT.txt @@ -1,4 +1,3 @@ -1 header 1_Eulers 2_Eulers 3_Eulers 1_pos 2_pos 146.75362934444064 9.976439066337804 256.395594327347 1 1 356.59977719102034 43.39784965440254 12.173896584899929 1 2 diff --git a/python/tests/reference/Orientation/cF_GT_prime.txt b/python/tests/reference/Orientation/cF_GT_prime.txt index 44a9b25ec..3a9021912 100644 --- a/python/tests/reference/Orientation/cF_GT_prime.txt +++ b/python/tests/reference/Orientation/cF_GT_prime.txt @@ -1,4 +1,3 @@ -1 header 1_Eulers 2_Eulers 3_Eulers 1_pos 2_pos 166.39559432734697 9.976439066337804 236.75362934444058 1 1 352.1156357053931 43.82007387041961 14.074783631236542 1 2 diff --git a/python/tests/reference/Orientation/cF_KS.txt b/python/tests/reference/Orientation/cF_KS.txt index 93fdcf07e..d63442cf3 100644 --- a/python/tests/reference/Orientation/cF_KS.txt +++ b/python/tests/reference/Orientation/cF_KS.txt @@ -1,4 +1,3 @@ -1 header 1_Eulers 2_Eulers 3_Eulers 1_pos 2_pos 114.20342833932975 10.52877936550932 204.20342833932972 1 1 94.3573968784815 80.40593177313954 311.22729452432543 1 2 diff --git a/python/tests/reference/Orientation/cF_NW.txt b/python/tests/reference/Orientation/cF_NW.txt index cc9c95a05..d22b86e1b 100644 --- a/python/tests/reference/Orientation/cF_NW.txt +++ b/python/tests/reference/Orientation/cF_NW.txt @@ -1,4 +1,3 @@ -1 header 1_Eulers 2_Eulers 3_Eulers 1_pos 2_pos 96.91733794010702 83.13253115922213 314.5844440567886 1 1 173.082662059893 83.13253115922211 45.41555594321143 1 2 diff --git a/python/tests/reference/Orientation/cF_Pitsch.txt b/python/tests/reference/Orientation/cF_Pitsch.txt index aa0c32365..b18e5212b 100644 --- a/python/tests/reference/Orientation/cF_Pitsch.txt +++ b/python/tests/reference/Orientation/cF_Pitsch.txt @@ -1,4 +1,3 @@ -1 header 1_Eulers 2_Eulers 3_Eulers 1_pos 2_pos 135.41555594321144 83.13253115922213 173.082662059893 1 1 260.26438968275465 90.0 135.0 1 2 diff --git a/python/tests/reference/Orientation/cI_Bain.txt b/python/tests/reference/Orientation/cI_Bain.txt index e0bc4f6c7..0bb55aaef 100644 --- a/python/tests/reference/Orientation/cI_Bain.txt +++ b/python/tests/reference/Orientation/cI_Bain.txt @@ -1,4 +1,3 @@ -1 header 1_Eulers 2_Eulers 3_Eulers 1_pos 2_pos 0.0 45.00000000000001 0.0 1 1 90.0 45.00000000000001 270.0 1 2 diff --git a/python/tests/reference/Orientation/cI_GT.txt b/python/tests/reference/Orientation/cI_GT.txt index 5d5102698..c2805c3e4 100644 --- a/python/tests/reference/Orientation/cI_GT.txt +++ b/python/tests/reference/Orientation/cI_GT.txt @@ -1,4 +1,3 @@ -1 header 1_Eulers 2_Eulers 3_Eulers 1_pos 2_pos 283.60440567265294 9.976439066337804 33.24637065555936 1 1 167.8261034151001 43.397849654402556 183.40022280897963 1 2 diff --git a/python/tests/reference/Orientation/cI_GT_prime.txt b/python/tests/reference/Orientation/cI_GT_prime.txt index e398d3139..1d0f6c3c6 100644 --- a/python/tests/reference/Orientation/cI_GT_prime.txt +++ b/python/tests/reference/Orientation/cI_GT_prime.txt @@ -1,4 +1,3 @@ -1 header 1_Eulers 2_Eulers 3_Eulers 1_pos 2_pos 303.24637065555936 9.976439066337804 13.604405672652977 1 1 165.92521636876344 43.82007387041961 187.88436429460683 1 2 diff --git a/python/tests/reference/Orientation/cI_KS.txt b/python/tests/reference/Orientation/cI_KS.txt index 34b393358..b35a07fb8 100644 --- a/python/tests/reference/Orientation/cI_KS.txt +++ b/python/tests/reference/Orientation/cI_KS.txt @@ -1,4 +1,3 @@ -1 header 1_Eulers 2_Eulers 3_Eulers 1_pos 2_pos 335.7965716606702 10.528779365509317 65.79657166067024 1 1 228.77270547567446 80.40593177313953 85.64260312151849 1 2 diff --git a/python/tests/reference/Orientation/cI_NW.txt b/python/tests/reference/Orientation/cI_NW.txt index 754c69bba..b39889f28 100644 --- a/python/tests/reference/Orientation/cI_NW.txt +++ b/python/tests/reference/Orientation/cI_NW.txt @@ -1,4 +1,3 @@ -1 header 1_Eulers 2_Eulers 3_Eulers 1_pos 2_pos 225.41555594321144 83.13253115922213 83.08266205989301 1 1 134.58444405678856 83.13253115922211 6.917337940107012 1 2 diff --git a/python/tests/reference/Orientation/cI_Pitsch.txt b/python/tests/reference/Orientation/cI_Pitsch.txt index ef28bbb4d..6e0efddc6 100644 --- a/python/tests/reference/Orientation/cI_Pitsch.txt +++ b/python/tests/reference/Orientation/cI_Pitsch.txt @@ -1,4 +1,3 @@ -1 header 1_Eulers 2_Eulers 3_Eulers 1_pos 2_pos 6.9173379401070045 83.13253115922213 44.58444405678856 1 1 45.0 89.99999999999999 279.7356103172453 1 2 diff --git a/python/tests/test_Table.py b/python/tests/test_Table.py index 8f617aff5..8afd6019e 100644 --- a/python/tests/test_Table.py +++ b/python/tests/test_Table.py @@ -60,13 +60,6 @@ class TestTable: new = Table.load(f) assert all(default.data==new.data) and default.shapes == new.shapes - def test_write_read_legacy_style(self,default,tmp_path): - with open(tmp_path/'legacy.txt','w') as f: - default.save(f,legacy=True) - with open(tmp_path/'legacy.txt') as f: - new = Table.load(f) - assert all(default.data==new.data) and default.shapes == new.shapes - def test_write_invalid_format(self,default,tmp_path): with pytest.raises(TypeError): default.save(tmp_path/'shouldnotbethere.txt',format='invalid')