parent
111a1a76c6
commit
be9e00347b
8
Makefile
8
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
|
||||
|
||||
|
|
|
@ -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
|
||||
----------
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
----------
|
||||
|
|
|
@ -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
|
||||
----------
|
||||
|
|
|
@ -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
|
||||
----------
|
||||
|
|
|
@ -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
|
||||
----------
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -22,7 +22,7 @@ class VTK:
|
|||
|
||||
def __init__(self,vtk_data):
|
||||
"""
|
||||
Initialize from vtk dataset.
|
||||
New spatial visualization.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
|
|
|
@ -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
|
||||
----------
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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')
|
||||
|
|
Loading…
Reference in New Issue