Merge branch 'development' into 'vtk-to-file-method'

# Conflicts:
#   python/tests/test_VTK.py
This commit is contained in:
Philip Eisenlohr 2020-08-31 21:10:29 +02:00
commit 6785062a10
54 changed files with 979 additions and 756 deletions

@ -1 +1 @@
Subproject commit a16d1e45a2ed925e12244b0879b9d7e5a58d973b Subproject commit 1ca2223c68475bbcb9da633353dbe4a98c18db0d

2
README
View File

@ -8,6 +8,6 @@ Max-Planck-Str. 1
40237 Düsseldorf 40237 Düsseldorf
Germany Germany
Email: DAMASK@mpie.de damask@mpie.de
https://damask.mpie.de https://damask.mpie.de
https://magit1.mpie.de https://magit1.mpie.de

View File

@ -1 +1 @@
v3.0.0-alpha-27-g68c2908b v3.0.0-alpha-51-g31282973

View File

@ -169,7 +169,7 @@ for name in filenames:
# undo any changes involving immutable microstructures # undo any changes involving immutable microstructures
microstructure = np.where(immutable, microstructure_original,microstructure) microstructure = np.where(immutable, microstructure_original,microstructure)
damask.util.croak(geom.update(microstructure[0:grid_original[0],0:grid_original[1],0:grid_original[2]])) geom=geom.duplicate(microstructure[0:grid_original[0],0:grid_original[1],0:grid_original[2]])
geom.add_comments(scriptID + ' ' + ' '.join(sys.argv[1:])) geom.add_comments(scriptID + ' ' + ' '.join(sys.argv[1:]))
geom.to_file(sys.stdout if name is None else name,pack=False) geom.to_file(sys.stdout if name is None else name,pack=False)

View File

@ -2,4 +2,3 @@
omit = tests/* omit = tests/*
damask/_asciitable.py damask/_asciitable.py
damask/_test.py damask/_test.py
damask/config/*

View File

@ -24,5 +24,4 @@ from . import solver # noqa
Environment = _ Environment = _
from ._asciitable import ASCIItable # noqa from ._asciitable import ASCIItable # noqa
from ._test import Test # noqa from ._test import Test # noqa
from .config import Material # noqa
from .util import extendableOption # noqa from .util import extendableOption # noqa

View File

@ -280,7 +280,7 @@ class Colormap(mpl.colors.ListedColormap):
colors+=[i]+c colors+=[i]+c
out = [{ out = [{
'Creator':util.version_date('Colormap'), 'Creator':util.execution_stamp('Colormap'),
'ColorSpace':'RGB', 'ColorSpace':'RGB',
'Name':colormap.name, 'Name':colormap.name,
'DefaultMap':True, 'DefaultMap':True,
@ -296,7 +296,7 @@ class Colormap(mpl.colors.ListedColormap):
def _export_ASCII(colormap,fhandle=None): def _export_ASCII(colormap,fhandle=None):
"""Write colormap to ASCII table.""" """Write colormap to ASCII table."""
labels = {'RGBA':4} if colormap.colors.shape[1] == 4 else {'RGB': 3} labels = {'RGBA':4} if colormap.colors.shape[1] == 4 else {'RGB': 3}
t = Table(colormap.colors,labels,f'Creator: {util.version_date("Colormap")}') t = Table(colormap.colors,labels,f'Creator: {util.execution_stamp("Colormap")}')
if fhandle is None: if fhandle is None:
with open(colormap.name.replace(' ','_')+'.txt', 'w') as f: with open(colormap.name.replace(' ','_')+'.txt', 'w') as f:

View File

@ -24,15 +24,15 @@ class Geom:
Parameters Parameters
---------- ----------
microstructure : numpy.ndarray microstructure : numpy.ndarray
microstructure array (3D) Microstructure array (3D)
size : list or numpy.ndarray size : list or numpy.ndarray
physical size of the microstructure in meter. Physical size of the microstructure in meter.
origin : list or numpy.ndarray, optional origin : list or numpy.ndarray, optional
physical origin of the microstructure in meter. Physical origin of the microstructure in meter.
homogenization : int, optional homogenization : int, optional
homogenization index. Homogenization index.
comments : list of str, optional comments : list of str, optional
comments lines. Comment lines.
""" """
self.set_microstructure(microstructure) self.set_microstructure(microstructure)
@ -63,63 +63,73 @@ class Geom:
return self.__copy__() return self.__copy__()
def update(self,microstructure=None,size=None,origin=None,rescale=False): def duplicate(self,microstructure=None,size=None,origin=None,comments=None,autosize=False):
""" """
Update microstructure and size. Create a duplicate having updated microstructure, size, and origin.
Parameters Parameters
---------- ----------
microstructure : numpy.ndarray, optional microstructure : numpy.ndarray, optional
microstructure array (3D). Microstructure array (3D).
size : list or numpy.ndarray, optional size : list or numpy.ndarray, optional
physical size of the microstructure in meter. Physical size of the microstructure in meter.
origin : list or numpy.ndarray, optional origin : list or numpy.ndarray, optional
physical origin of the microstructure in meter. Physical origin of the microstructure in meter.
rescale : bool, optional comments : list of str, optional
ignore size parameter and rescale according to change of grid points. Comment lines.
autosize : bool, optional
Ignore size parameter and rescale according to change of grid points.
""" """
if size is not None and autosize:
raise ValueError('Auto-sizing conflicts with explicit size parameter.')
grid_old = self.get_grid() grid_old = self.get_grid()
size_old = self.get_size() dup = self.copy()
origin_old = self.get_origin() dup.set_microstructure(microstructure)
unique_old = self.N_microstructure dup.set_origin(origin)
max_old = np.nanmax(self.microstructure)
if size is not None and rescale: if comments is not None:
raise ValueError('Either set size explicitly or rescale automatically') dup.set_comments(comments)
self.set_microstructure(microstructure)
self.set_origin(origin)
if size is not None: if size is not None:
self.set_size(size) dup.set_size(size)
elif rescale: elif autosize:
self.set_size(self.get_grid()/grid_old*self.size) dup.set_size(dup.get_grid()/grid_old*self.get_size())
message = [f'grid a b c: {util.srepr(grid_old," x ")}'] return dup
if np.any(grid_old != self.get_grid()):
message[-1] = util.delete(message[-1])
message.append(util.emph(f'grid a b c: {util.srepr(self.get_grid()," x ")}'))
message.append(f'size x y z: {util.srepr(size_old," x ")}')
if np.any(size_old != self.get_size()):
message[-1] = util.delete(message[-1])
message.append(util.emph(f'size x y z: {util.srepr(self.get_size()," x ")}'))
message.append(f'origin x y z: {util.srepr(origin_old," ")}') def diff(self,other):
if np.any(origin_old != self.get_origin()): """
message[-1] = util.delete(message[-1]) Report property differences of self relative to other.
message.append(util.emph(f'origin x y z: {util.srepr(self.get_origin()," ")}'))
message.append(f'# microstructures: {unique_old}') Parameters
if unique_old != self.N_microstructure: ----------
message[-1] = util.delete(message[-1]) other : Geom
message.append(util.emph(f'# microstructures: {self.N_microstructure}')) Geometry to compare self against.
message.append(f'max microstructure: {max_old}') """
if max_old != np.nanmax(self.microstructure): message = []
message[-1] = util.delete(message[-1]) if np.any(other.get_grid() != self.get_grid()):
message.append(util.emph(f'max microstructure: {np.nanmax(self.microstructure)}')) message.append(util.delete(f'grid a b c: {util.srepr(other.get_grid()," x ")}'))
message.append(util.emph( f'grid a b c: {util.srepr( self.get_grid()," x ")}'))
if np.any(other.get_size() != self.get_size()):
message.append(util.delete(f'size x y z: {util.srepr(other.get_size()," x ")}'))
message.append(util.emph( f'size x y z: {util.srepr( self.get_size()," x ")}'))
if np.any(other.get_origin() != self.get_origin()):
message.append(util.delete(f'origin x y z: {util.srepr(other.get_origin()," ")}'))
message.append(util.emph( f'origin x y z: {util.srepr( self.get_origin()," ")}'))
if other.N_microstructure != self.N_microstructure:
message.append(util.delete(f'# materialpoints: {other.N_microstructure}'))
message.append(util.emph( f'# materialpoints: { self.N_microstructure}'))
if np.nanmax(other.microstructure) != np.nanmax(self.microstructure):
message.append(util.delete(f'max materialpoint: {np.nanmax(other.microstructure)}'))
message.append(util.emph( f'max materialpoint: {np.nanmax( self.microstructure)}'))
return util.return_message(message) return util.return_message(message)
@ -131,7 +141,7 @@ class Geom:
Parameters Parameters
---------- ----------
comments : list of str comments : list of str
new comments. All comments.
""" """
self.comments = [] self.comments = []
@ -145,7 +155,7 @@ class Geom:
Parameters Parameters
---------- ----------
comments : list of str comments : list of str
new comments. New comments.
""" """
self.comments += [str(c) for c in comments] if isinstance(comments,list) else [str(comments)] self.comments += [str(c) for c in comments] if isinstance(comments,list) else [str(comments)]
@ -172,6 +182,10 @@ class Geom:
else: else:
self.microstructure = np.copy(microstructure) self.microstructure = np.copy(microstructure)
if self.microstructure.dtype in np.sctypes['float'] and \
np.all(self.microstructure == self.microstructure.astype(int).astype(float)):
self.microstructure = self.microstructure.astype(int)
if len(self.microstructure.shape) != 3: if len(self.microstructure.shape) != 3:
raise ValueError(f'Invalid microstructure shape {microstructure.shape}') raise ValueError(f'Invalid microstructure shape {microstructure.shape}')
elif self.microstructure.dtype not in np.sctypes['float'] + np.sctypes['int']: elif self.microstructure.dtype not in np.sctypes['float'] + np.sctypes['int']:
@ -185,7 +199,7 @@ class Geom:
Parameters Parameters
---------- ----------
size : list or numpy.ndarray size : list or numpy.ndarray
physical size of the microstructure in meter. Physical size of the microstructure in meter.
""" """
if size is not None: if size is not None:
@ -202,7 +216,7 @@ class Geom:
Parameters Parameters
---------- ----------
origin : list or numpy.ndarray origin : list or numpy.ndarray
physical origin of the microstructure in meter Physical origin of the microstructure in meter.
""" """
if origin is not None: if origin is not None:
@ -219,12 +233,12 @@ class Geom:
Parameters Parameters
---------- ----------
homogenization : int homogenization : int
homogenization index Homogenization index.
""" """
if homogenization is not None: if homogenization is not None:
if not isinstance(homogenization,int) or homogenization < 1: if not isinstance(homogenization,int) or homogenization < 1:
raise TypeError(f'Invalid homogenization {homogenization}') raise TypeError(f'Invalid homogenization {homogenization}.')
else: else:
self.homogenization = homogenization self.homogenization = homogenization
@ -286,13 +300,16 @@ class Geom:
f = fname f = fname
f.seek(0) f.seek(0)
try:
header_length,keyword = f.readline().split()[:2] header_length,keyword = f.readline().split()[:2]
header_length = int(header_length) header_length = int(header_length)
content = f.readlines() except ValueError:
header_length,keyword = (-1, 'invalid')
if not keyword.startswith('head') or header_length < 3: if not keyword.startswith('head') or header_length < 3:
raise TypeError('Header length information missing or invalid') raise TypeError('Header length information missing or invalid')
content = f.readlines()
comments = [] comments = []
for i,line in enumerate(content[:header_length]): for i,line in enumerate(content[:header_length]):
items = line.split('#')[0].lower().strip().split() items = line.split('#')[0].lower().strip().split()
@ -345,11 +362,12 @@ class Geom:
""" """
v = VTK.from_file(fname if str(fname).endswith('.vtr') else str(fname)+'.vtr') v = VTK.from_file(fname if str(fname).endswith('.vtr') else str(fname)+'.vtr')
grid = np.array(v.geom.GetDimensions())-1 comments = v.get_comments()
bbox = np.array(v.geom.GetBounds()).reshape(3,2).T grid = np.array(v.vtk_data.GetDimensions())-1
bbox = np.array(v.vtk_data.GetBounds()).reshape(3,2).T
size = bbox[1] - bbox[0] size = bbox[1] - bbox[0]
return Geom(v.get('materialpoint').reshape(grid,order='F'),size,bbox[0]) return Geom(v.get('materialpoint').reshape(grid,order='F'),size,bbox[0],comments=comments)
@staticmethod @staticmethod
@ -398,8 +416,9 @@ class Geom:
else: else:
microstructure = microstructure.reshape(grid) microstructure = microstructure.reshape(grid)
creator = util.version_date('Geom','from_Laguerre_tessellation') return Geom(microstructure+1,size,homogenization=1,
return Geom(microstructure+1,size,homogenization=1,comments=creator) comments=util.execution_stamp('Geom','from_Laguerre_tessellation'),
)
@staticmethod @staticmethod
@ -423,8 +442,9 @@ class Geom:
KDTree = spatial.cKDTree(seeds,boxsize=size) if periodic else spatial.cKDTree(seeds) KDTree = spatial.cKDTree(seeds,boxsize=size) if periodic else spatial.cKDTree(seeds)
devNull,microstructure = KDTree.query(coords) devNull,microstructure = KDTree.query(coords)
creator = util.version_date('Geom','from_Voronoi_tessellation') return Geom(microstructure.reshape(grid)+1,size,homogenization=1,
return Geom(microstructure.reshape(grid)+1,size,homogenization=1,comments=creator) comments=util.execution_stamp('Geom','from_Voronoi_tessellation'),
)
def to_file(self,fname,pack=None): def to_file(self,fname,pack=None):
@ -511,6 +531,7 @@ class Geom:
""" """
v = VTK.from_rectilinearGrid(self.grid,self.size,self.origin) v = VTK.from_rectilinearGrid(self.grid,self.size,self.origin)
v.add(self.microstructure.flatten(order='F'),'materialpoint') v.add(self.microstructure.flatten(order='F'),'materialpoint')
v.add_comments(self.comments)
if fname: if fname:
v.to_file(fname if str(fname).endswith('.vtr') else str(fname)+'.vtr') v.to_file(fname if str(fname).endswith('.vtr') else str(fname)+'.vtr')
@ -518,9 +539,9 @@ class Geom:
sys.stdout.write(v.__repr__()) sys.stdout.write(v.__repr__())
def show(self): def as_ASCII(self):
"""Show raw content (as in file).""" """Format geometry as human-readable ASCII."""
f=StringIO() f = StringIO()
self.to_file(f) self.to_file(f)
f.seek(0) f.seek(0)
return ''.join(f.readlines()) return ''.join(f.readlines())
@ -550,10 +571,10 @@ class Geom:
R : damask.Rotation, optional R : damask.Rotation, optional
Rotation of primitive. Defaults to no rotation. Rotation of primitive. Defaults to no rotation.
inverse : Boolean, optional inverse : Boolean, optional
Retain original microstructure within primitive and fill Retain original microstructure within primitive and fill outside.
outside. Defaults to False. Defaults to False.
periodic : Boolean, optional periodic : Boolean, optional
Repeat primitive over boundaries. Defaults to False. Repeat primitive over boundaries. Defaults to True.
""" """
# normalized 'radius' and center # normalized 'radius' and center
@ -563,11 +584,11 @@ class Geom:
(np.array(center) - self.origin)/self.size (np.array(center) - self.origin)/self.size
coords = grid_filters.cell_coord0(self.grid,np.ones(3)) \ coords = grid_filters.cell_coord0(self.grid,np.ones(3)) \
- (np.ones(3)*0.5 if periodic else c) # center if periodic - ((np.ones(3)-(1./self.grid if np.array(center).dtype in np.sctypes['int'] else 0))*0.5 if periodic else c) # periodic center is always at CoG
coords_rot = R.broadcast_to(tuple(self.grid))@coords coords_rot = R.broadcast_to(tuple(self.grid))@coords
with np.errstate(over='ignore',under='ignore'): with np.errstate(all='ignore'):
mask = np.where(np.sum(np.abs(coords_rot/r)**(2.0**exponent),axis=-1) < 1,True,False) mask = np.where(np.sum(np.power(coords_rot/r,2.0**exponent),axis=-1) > 1.0,True,False)
if periodic: # translate back to center if periodic: # translate back to center
mask = np.roll(mask,((c-np.ones(3)*.5)*self.grid).astype(int),(0,1,2)) mask = np.roll(mask,((c-np.ones(3)*.5)*self.grid).astype(int),(0,1,2))
@ -575,8 +596,9 @@ class Geom:
fill_ = np.full_like(self.microstructure,np.nanmax(self.microstructure)+1 if fill is None else fill) fill_ = np.full_like(self.microstructure,np.nanmax(self.microstructure)+1 if fill is None else fill)
ms = np.ma.MaskedArray(fill_,np.logical_not(mask) if inverse else mask) ms = np.ma.MaskedArray(fill_,np.logical_not(mask) if inverse else mask)
self.add_comments(util.version_date('Geom','add_primitive')) return self.duplicate(ms,
return self.update(ms) comments=self.get_comments()+[util.execution_stamp('Geom','add_primitive')],
)
def mirror(self,directions,reflect=False): def mirror(self,directions,reflect=False):
@ -589,10 +611,10 @@ class Geom:
Direction(s) along which the microstructure is mirrored. Direction(s) along which the microstructure is mirrored.
Valid entries are 'x', 'y', 'z'. Valid entries are 'x', 'y', 'z'.
reflect : bool, optional reflect : bool, optional
Reflect (include) outermost layers. Reflect (include) outermost layers. Defaults to False.
""" """
valid = {'x','y','z'} valid = ['x','y','z']
if not set(directions).issubset(valid): if not set(directions).issubset(valid):
raise ValueError(f'Invalid direction {set(directions).difference(valid)} specified.') raise ValueError(f'Invalid direction {set(directions).difference(valid)} specified.')
@ -606,8 +628,31 @@ class Geom:
if 'x' in directions: if 'x' in directions:
ms = np.concatenate([ms,ms[limits[0]:limits[1]:-1,:,:]],0) ms = np.concatenate([ms,ms[limits[0]:limits[1]:-1,:,:]],0)
self.add_comments(util.version_date('Geom','mirror')) return self.duplicate(ms,
return self.update(ms,rescale=True) comments=self.get_comments()+[util.execution_stamp('Geom','mirror')],
autosize=True)
def flip(self,directions):
"""
Flip microstructure along given directions.
Parameters
----------
directions : iterable containing str
Direction(s) along which the microstructure is flipped.
Valid entries are 'x', 'y', 'z'.
"""
valid = ['x','y','z']
if not set(directions).issubset(valid):
raise ValueError(f'Invalid direction {set(directions).difference(valid)} specified.')
ms = np.flip(self.microstructure, (valid.index(d) for d in directions if d in valid))
return self.duplicate(ms,
comments=self.get_comments()+[util.execution_stamp('Geom','flip')],
)
def scale(self,grid,periodic=True): def scale(self,grid,periodic=True):
@ -622,16 +667,15 @@ class Geom:
Assume geometry to be periodic. Defaults to True. Assume geometry to be periodic. Defaults to True.
""" """
self.add_comments(util.version_date('Geom','scale')) return self.duplicate(ndimage.interpolation.zoom(
return self.update(
ndimage.interpolation.zoom(
self.microstructure, self.microstructure,
grid/self.get_grid(), grid/self.get_grid(),
output=self.microstructure.dtype, output=self.microstructure.dtype,
order=0, order=0,
mode=('wrap' if periodic else 'nearest'), mode=('wrap' if periodic else 'nearest'),
prefilter=False prefilter=False
) ),
comments=self.get_comments()+[util.execution_stamp('Geom','scale')],
) )
@ -657,14 +701,14 @@ class Geom:
else: else:
return me return me
self.add_comments(util.version_date('Geom','clean')) return self.duplicate(ndimage.filters.generic_filter(
return self.update(ndimage.filters.generic_filter(
self.microstructure, self.microstructure,
mostFrequent, mostFrequent,
size=(stencil if selection is None else stencil//2*2+1,)*3, size=(stencil if selection is None else stencil//2*2+1,)*3,
mode=('wrap' if periodic else 'nearest'), mode=('wrap' if periodic else 'nearest'),
extra_keywords=dict(selection=selection), extra_keywords=dict(selection=selection),
).astype(self.microstructure.dtype) ).astype(self.microstructure.dtype),
comments=self.get_comments()+[util.execution_stamp('Geom','clean')],
) )
@ -674,8 +718,9 @@ class Geom:
for i, oldID in enumerate(np.unique(self.microstructure)): for i, oldID in enumerate(np.unique(self.microstructure)):
renumbered = np.where(self.microstructure == oldID, i+1, renumbered) renumbered = np.where(self.microstructure == oldID, i+1, renumbered)
self.add_comments(util.version_date('Geom','renumber')) return self.duplicate(renumbered,
return self.update(renumbered) comments=self.get_comments()+[util.execution_stamp('Geom','renumber')],
)
def rotate(self,R,fill=None): def rotate(self,R,fill=None):
@ -709,8 +754,11 @@ class Geom:
origin = self.origin-(np.asarray(microstructure_in.shape)-self.grid)*.5 * self.size/self.grid origin = self.origin-(np.asarray(microstructure_in.shape)-self.grid)*.5 * self.size/self.grid
self.add_comments(util.version_date('Geom','rotate')) return self.duplicate(microstructure_in,
return self.update(microstructure_in,origin=origin,rescale=True) origin=origin,
comments=self.get_comments()+[util.execution_stamp('Geom','rotate')],
autosize=True,
)
def canvas(self,grid=None,offset=None,fill=None): def canvas(self,grid=None,offset=None,fill=None):
@ -724,16 +772,14 @@ class Geom:
offset : numpy.ndarray of shape (3) offset : numpy.ndarray of shape (3)
Offset (measured in grid points) from old to new microstructure[0,0,0]. Offset (measured in grid points) from old to new microstructure[0,0,0].
fill : int or float, optional fill : int or float, optional
Microstructure index to fill the corners. Defaults to microstructure.max() + 1. Microstructure index to fill the background. Defaults to microstructure.max() + 1.
""" """
if fill is None: fill = np.nanmax(self.microstructure) + 1
if offset is None: offset = 0 if offset is None: offset = 0
dtype = float if int(fill) != fill or self.microstructure.dtype==np.float else int if fill is None: fill = np.nanmax(self.microstructure) + 1
dtype = float if int(fill) != fill or self.microstructure.dtype in np.sctypes['float'] else int
canvas = np.full(self.grid if grid is None else grid, canvas = np.full(self.grid if grid is None else grid,fill,dtype)
np.nanmax(self.microstructure)+1 if fill is None else fill,
dtype)
LL = np.clip( offset, 0,np.minimum(self.grid, grid+offset)) LL = np.clip( offset, 0,np.minimum(self.grid, grid+offset))
UR = np.clip( offset+grid, 0,np.minimum(self.grid, grid+offset)) UR = np.clip( offset+grid, 0,np.minimum(self.grid, grid+offset))
@ -742,8 +788,11 @@ class Geom:
canvas[ll[0]:ur[0],ll[1]:ur[1],ll[2]:ur[2]] = self.microstructure[LL[0]:UR[0],LL[1]:UR[1],LL[2]:UR[2]] canvas[ll[0]:ur[0],ll[1]:ur[1],ll[2]:ur[2]] = self.microstructure[LL[0]:UR[0],LL[1]:UR[1],LL[2]:UR[2]]
self.add_comments(util.version_date('Geom','canvas')) return self.duplicate(canvas,
return self.update(canvas,origin=self.origin+offset*self.size/self.grid,rescale=True) origin=self.origin+offset*self.size/self.grid,
comments=self.get_comments()+[util.execution_stamp('Geom','canvas')],
autosize=True,
)
def substitute(self,from_microstructure,to_microstructure): def substitute(self,from_microstructure,to_microstructure):
@ -762,8 +811,9 @@ class Geom:
for from_ms,to_ms in zip(from_microstructure,to_microstructure): for from_ms,to_ms in zip(from_microstructure,to_microstructure):
substituted[self.microstructure==from_ms] = to_ms substituted[self.microstructure==from_ms] = to_ms
self.add_comments(util.version_date('Geom','substitute')) return self.duplicate(substituted,
return self.update(substituted) comments=self.get_comments()+[util.execution_stamp('Geom','substitute')],
)
def vicinity_offset(self,vicinity=1,offset=None,trigger=[],periodic=True): def vicinity_offset(self,vicinity=1,offset=None,trigger=[],periodic=True):
@ -804,9 +854,10 @@ class Geom:
mask = ndimage.filters.generic_filter(self.microstructure, mask = ndimage.filters.generic_filter(self.microstructure,
tainted_neighborhood, tainted_neighborhood,
size=1+2*vicinity, size=1+2*vicinity,
mode=('wrap' if periodic else 'nearest'), mode='wrap' if periodic else 'nearest',
extra_keywords={'trigger':trigger}) extra_keywords={'trigger':trigger})
microstructure = np.ma.MaskedArray(self.microstructure + offset_, np.logical_not(mask)) microstructure = np.ma.MaskedArray(self.microstructure + offset_, np.logical_not(mask))
self.add_comments(util.version_date('Geom','vicinity_offset')) return self.duplicate(microstructure,
return self.update(microstructure) comments=self.get_comments()+[util.execution_stamp('Geom','vicinity_offset')],
)

View File

@ -164,16 +164,16 @@ class Symmetry:
with np.errstate(invalid='ignore'): with np.errstate(invalid='ignore'):
# using '*'/prod for 'and' # using '*'/prod for 'and'
if self.system == 'cubic': if self.system == 'cubic':
return np.where(np.prod(np.sqrt(2)-1. >= rho_abs,axis=-1) * \ return np.where(np.prod(np.sqrt(2)-1. >= rho_abs,axis=-1) *
(1. >= np.sum(rho_abs,axis=-1)),True,False) (1. >= np.sum(rho_abs,axis=-1)),True,False)
elif self.system == 'hexagonal': elif self.system == 'hexagonal':
return np.where(np.prod(1. >= rho_abs,axis=-1) * \ return np.where(np.prod(1. >= rho_abs,axis=-1) *
(2. >= np.sqrt(3)*rho_abs[...,0] + rho_abs[...,1]) * \ (2. >= np.sqrt(3)*rho_abs[...,0] + rho_abs[...,1]) *
(2. >= np.sqrt(3)*rho_abs[...,1] + rho_abs[...,0]) * \ (2. >= np.sqrt(3)*rho_abs[...,1] + rho_abs[...,0]) *
(2. >= np.sqrt(3) + rho_abs[...,2]),True,False) (2. >= np.sqrt(3) + rho_abs[...,2]),True,False)
elif self.system == 'tetragonal': elif self.system == 'tetragonal':
return np.where(np.prod(1. >= rho_abs[...,:2],axis=-1) * \ return np.where(np.prod(1. >= rho_abs[...,:2],axis=-1) *
(np.sqrt(2) >= rho_abs[...,0] + rho_abs[...,1]) * \ (np.sqrt(2) >= rho_abs[...,0] + rho_abs[...,1]) *
(np.sqrt(2) >= rho_abs[...,2] + 1.),True,False) (np.sqrt(2) >= rho_abs[...,2] + 1.),True,False)
elif self.system == 'orthorhombic': elif self.system == 'orthorhombic':
return np.where(np.prod(1. >= rho_abs,axis=-1),True,False) return np.where(np.prod(1. >= rho_abs,axis=-1),True,False)
@ -321,6 +321,7 @@ class Lattice: # ToDo: Make a subclass of Symmetry!
""" """
lattices = { lattices = {
'iso': {'system':None},
'triclinic':{'system':None}, 'triclinic':{'system':None},
'bct': {'system':'tetragonal'}, 'bct': {'system':'tetragonal'},
'hex': {'system':'hexagonal'}, 'hex': {'system':'hexagonal'},

View File

@ -1,6 +1,5 @@
import multiprocessing as mp import multiprocessing as mp
import re import re
import inspect
import glob import glob
import os import os
import datetime import datetime
@ -401,6 +400,7 @@ class Result:
if sets is True: if sets is True:
groups.append(group) groups.append(group)
else: else:
if group in f.keys():
match = [e for e_ in [glob.fnmatch.filter(f[group].keys(),s) for s in sets] for e in e_] match = [e for e_ in [glob.fnmatch.filter(f[group].keys(),s) for s in sets] for e in e_]
if len(set(match)) == len(sets): groups.append(group) if len(set(match)) == len(sets): groups.append(group)
return groups return groups
@ -536,7 +536,7 @@ class Result:
'meta': { 'meta': {
'Unit': x['meta']['Unit'], 'Unit': x['meta']['Unit'],
'Description': f"Absolute value of {x['label']} ({x['meta']['Description']})", 'Description': f"Absolute value of {x['label']} ({x['meta']['Description']})",
'Creator': inspect.stack()[0][3][1:] 'Creator': 'add_absolute'
} }
} }
def add_absolute(self,x): def add_absolute(self,x):
@ -564,7 +564,7 @@ class Result:
'meta': { 'meta': {
'Unit': kwargs['unit'], 'Unit': kwargs['unit'],
'Description': f"{kwargs['description']} (formula: {kwargs['formula']})", 'Description': f"{kwargs['description']} (formula: {kwargs['formula']})",
'Creator': inspect.stack()[0][3][1:] 'Creator': 'add_calculation'
} }
} }
def add_calculation(self,label,formula,unit='n/a',description=None): def add_calculation(self,label,formula,unit='n/a',description=None):
@ -598,7 +598,7 @@ class Result:
'Description': "Cauchy stress calculated " 'Description': "Cauchy stress calculated "
f"from {P['label']} ({P['meta']['Description']})" f"from {P['label']} ({P['meta']['Description']})"
f" and {F['label']} ({F['meta']['Description']})", f" and {F['label']} ({F['meta']['Description']})",
'Creator': inspect.stack()[0][3][1:] 'Creator': 'add_Cauchy'
} }
} }
def add_Cauchy(self,P='P',F='F'): def add_Cauchy(self,P='P',F='F'):
@ -624,7 +624,7 @@ class Result:
'meta': { 'meta': {
'Unit': T['meta']['Unit'], 'Unit': T['meta']['Unit'],
'Description': f"Determinant of tensor {T['label']} ({T['meta']['Description']})", 'Description': f"Determinant of tensor {T['label']} ({T['meta']['Description']})",
'Creator': inspect.stack()[0][3][1:] 'Creator': 'add_determinant'
} }
} }
def add_determinant(self,T): def add_determinant(self,T):
@ -648,7 +648,7 @@ class Result:
'meta': { 'meta': {
'Unit': T['meta']['Unit'], 'Unit': T['meta']['Unit'],
'Description': f"Deviator of tensor {T['label']} ({T['meta']['Description']})", 'Description': f"Deviator of tensor {T['label']} ({T['meta']['Description']})",
'Creator': inspect.stack()[0][3][1:] 'Creator': 'add_deviator'
} }
} }
def add_deviator(self,T): def add_deviator(self,T):
@ -679,7 +679,7 @@ class Result:
'meta' : { 'meta' : {
'Unit': T_sym['meta']['Unit'], 'Unit': T_sym['meta']['Unit'],
'Description': f"{label} eigenvalue of {T_sym['label']} ({T_sym['meta']['Description']})", 'Description': f"{label} eigenvalue of {T_sym['label']} ({T_sym['meta']['Description']})",
'Creator': inspect.stack()[0][3][1:] 'Creator': 'add_eigenvalue'
} }
} }
def add_eigenvalue(self,T_sym,eigenvalue='max'): def add_eigenvalue(self,T_sym,eigenvalue='max'):
@ -712,7 +712,7 @@ class Result:
'Unit': '1', 'Unit': '1',
'Description': f"Eigenvector corresponding to {label} eigenvalue" 'Description': f"Eigenvector corresponding to {label} eigenvalue"
f" of {T_sym['label']} ({T_sym['meta']['Description']})", f" of {T_sym['label']} ({T_sym['meta']['Description']})",
'Creator': inspect.stack()[0][3][1:] 'Creator': 'add_eigenvector'
} }
} }
def add_eigenvector(self,T_sym,eigenvalue='max'): def add_eigenvector(self,T_sym,eigenvalue='max'):
@ -745,7 +745,7 @@ class Result:
'Unit': '8-bit RGB', 'Unit': '8-bit RGB',
'Lattice': q['meta']['Lattice'], 'Lattice': q['meta']['Lattice'],
'Description': 'Inverse Pole Figure (IPF) colors along sample direction [{} {} {}]'.format(*m), 'Description': 'Inverse Pole Figure (IPF) colors along sample direction [{} {} {}]'.format(*m),
'Creator': inspect.stack()[0][3][1:] 'Creator': 'add_IPF_color'
} }
} }
def add_IPF_color(self,q,l): def add_IPF_color(self,q,l):
@ -771,7 +771,7 @@ class Result:
'meta': { 'meta': {
'Unit': T_sym['meta']['Unit'], 'Unit': T_sym['meta']['Unit'],
'Description': f"Maximum shear component of {T_sym['label']} ({T_sym['meta']['Description']})", 'Description': f"Maximum shear component of {T_sym['label']} ({T_sym['meta']['Description']})",
'Creator': inspect.stack()[0][3][1:] 'Creator': 'add_maximum_shear'
} }
} }
def add_maximum_shear(self,T_sym): def add_maximum_shear(self,T_sym):
@ -798,7 +798,7 @@ class Result:
'meta': { 'meta': {
'Unit': T_sym['meta']['Unit'], 'Unit': T_sym['meta']['Unit'],
'Description': f"Mises equivalent {t} of {T_sym['label']} ({T_sym['meta']['Description']})", 'Description': f"Mises equivalent {t} of {T_sym['label']} ({T_sym['meta']['Description']})",
'Creator': inspect.stack()[0][3][1:] 'Creator': 'add_Mises'
} }
} }
def add_Mises(self,T_sym): def add_Mises(self,T_sym):
@ -834,7 +834,7 @@ class Result:
'meta': { 'meta': {
'Unit': x['meta']['Unit'], 'Unit': x['meta']['Unit'],
'Description': f"{o}-norm of {t} {x['label']} ({x['meta']['Description']})", 'Description': f"{o}-norm of {t} {x['label']} ({x['meta']['Description']})",
'Creator': inspect.stack()[0][3][1:] 'Creator': 'add_norm'
} }
} }
def add_norm(self,x,ord=None): def add_norm(self,x,ord=None):
@ -862,7 +862,7 @@ class Result:
'Description': "2. Piola-Kirchhoff stress calculated " 'Description': "2. Piola-Kirchhoff stress calculated "
f"from {P['label']} ({P['meta']['Description']})" f"from {P['label']} ({P['meta']['Description']})"
f" and {F['label']} ({F['meta']['Description']})", f" and {F['label']} ({F['meta']['Description']})",
'Creator': inspect.stack()[0][3][1:] 'Creator': 'add_PK2'
} }
} }
def add_PK2(self,P='P',F='F'): def add_PK2(self,P='P',F='F'):
@ -898,7 +898,7 @@ class Result:
'Unit': '1', 'Unit': '1',
'Description': '{} coordinates of stereographic projection of pole (direction/plane) in crystal frame'\ 'Description': '{} coordinates of stereographic projection of pole (direction/plane) in crystal frame'\
.format('Polar' if polar else 'Cartesian'), .format('Polar' if polar else 'Cartesian'),
'Creator': inspect.stack()[0][3][1:] 'Creator': 'add_pole'
} }
} }
def add_pole(self,q,p,polar=False): def add_pole(self,q,p,polar=False):
@ -926,7 +926,7 @@ class Result:
'meta': { 'meta': {
'Unit': F['meta']['Unit'], 'Unit': F['meta']['Unit'],
'Description': f"Rotational part of {F['label']} ({F['meta']['Description']})", 'Description': f"Rotational part of {F['label']} ({F['meta']['Description']})",
'Creator': inspect.stack()[0][3][1:] 'Creator': 'add_rotational_part'
} }
} }
def add_rotational_part(self,F): def add_rotational_part(self,F):
@ -950,7 +950,7 @@ class Result:
'meta': { 'meta': {
'Unit': T['meta']['Unit'], 'Unit': T['meta']['Unit'],
'Description': f"Spherical component of tensor {T['label']} ({T['meta']['Description']})", 'Description': f"Spherical component of tensor {T['label']} ({T['meta']['Description']})",
'Creator': inspect.stack()[0][3][1:] 'Creator': 'add_spherical'
} }
} }
def add_spherical(self,T): def add_spherical(self,T):
@ -974,7 +974,7 @@ class Result:
'meta': { 'meta': {
'Unit': F['meta']['Unit'], 'Unit': F['meta']['Unit'],
'Description': f"Strain tensor of {F['label']} ({F['meta']['Description']})", 'Description': f"Strain tensor of {F['label']} ({F['meta']['Description']})",
'Creator': inspect.stack()[0][3][1:] 'Creator': 'add_strain_tensor'
} }
} }
def add_strain_tensor(self,F='F',t='V',m=0.0): def add_strain_tensor(self,F='F',t='V',m=0.0):
@ -1006,7 +1006,7 @@ class Result:
'Unit': F['meta']['Unit'], 'Unit': F['meta']['Unit'],
'Description': '{} stretch tensor of {} ({})'.format('Left' if t.upper() == 'V' else 'Right', 'Description': '{} stretch tensor of {} ({})'.format('Left' if t.upper() == 'V' else 'Right',
F['label'],F['meta']['Description']), F['label'],F['meta']['Description']),
'Creator': inspect.stack()[0][3][1:] 'Creator': 'add_stretch_tensor'
} }
} }
def add_stretch_tensor(self,F='F',t='V'): def add_stretch_tensor(self,F='F',t='V'):
@ -1065,6 +1065,10 @@ class Result:
lock = mp.Manager().Lock() lock = mp.Manager().Lock()
groups = self.groups_with_datasets(datasets.values()) groups = self.groups_with_datasets(datasets.values())
if len(groups) == 0:
print('No matching dataset found, no data was added.')
return
default_arg = partial(self._job,func=func,datasets=datasets,args=args,lock=lock) default_arg = partial(self._job,func=func,datasets=datasets,args=args,lock=lock)
for result in util.show_progress(pool.imap_unordered(default_arg,groups),len(groups)): for result in util.show_progress(pool.imap_unordered(default_arg,groups),len(groups)):

View File

@ -49,7 +49,7 @@ class Table:
def _add_comment(self,label,shape,info): def _add_comment(self,label,shape,info):
if info is not None: if info is not None:
specific = f'{label}{" "+str(shape) if np.prod(shape,dtype=int) > 1 else ""}: {info}' specific = f'{label}{" "+str(shape) if np.prod(shape,dtype=int) > 1 else ""}: {info}'
general = util.version_date('Table') general = util.execution_stamp('Table')
self.comments.append(f'{specific} / {general}') self.comments.append(f'{specific} / {general}')
@ -136,7 +136,7 @@ class Table:
content = f.readlines() content = f.readlines()
comments = [util.version_date('Table','from_ang')] comments = [util.execution_stamp('Table','from_ang')]
for line in content: for line in content:
if line.startswith('#'): if line.startswith('#'):
comments.append(line.strip()) comments.append(line.strip())

View File

@ -20,18 +20,19 @@ class VTK:
High-level interface to VTK. High-level interface to VTK.
""" """
def __init__(self,geom): def __init__(self,vtk_data):
""" """
Set geometry and topology. Initialize from vtk dataset.
Parameters Parameters
---------- ----------
geom : subclass of vtk.vtkDataSet vtk_data : subclass of vtk.vtkDataSet
Description of geometry and topology. Valid types are vtk.vtkRectilinearGrid, Description of geometry and topology, optionally with attached data.
vtk.vtkUnstructuredGrid, or vtk.vtkPolyData. Valid types are vtk.vtkRectilinearGrid, vtk.vtkUnstructuredGrid,
or vtk.vtkPolyData.
""" """
self.geom = geom self.vtk_data = vtk_data
@staticmethod @staticmethod
@ -51,15 +52,15 @@ class VTK:
Spatial origin. Spatial origin.
""" """
geom = vtk.vtkRectilinearGrid() vtk_data = vtk.vtkRectilinearGrid()
geom.SetDimensions(*(grid+1)) vtk_data.SetDimensions(*(grid+1))
coord = [np_to_vtk(np.linspace(origin[i],origin[i]+size[i],grid[i]+1),deep=True) for i in [0,1,2]] coord = [np_to_vtk(np.linspace(origin[i],origin[i]+size[i],grid[i]+1),deep=True) for i in [0,1,2]]
[coord[i].SetName(n) for i,n in enumerate(['x','y','z'])] [coord[i].SetName(n) for i,n in enumerate(['x','y','z'])]
geom.SetXCoordinates(coord[0]) vtk_data.SetXCoordinates(coord[0])
geom.SetYCoordinates(coord[1]) vtk_data.SetYCoordinates(coord[1])
geom.SetZCoordinates(coord[2]) vtk_data.SetZCoordinates(coord[2])
return VTK(geom) return VTK(vtk_data)
@staticmethod @staticmethod
@ -87,11 +88,11 @@ class VTK:
connectivity),axis=1).ravel() connectivity),axis=1).ravel()
cells.SetCells(connectivity.shape[0],np_to_vtkIdTypeArray(T,deep=True)) cells.SetCells(connectivity.shape[0],np_to_vtkIdTypeArray(T,deep=True))
geom = vtk.vtkUnstructuredGrid() vtk_data = vtk.vtkUnstructuredGrid()
geom.SetPoints(vtk_nodes) vtk_data.SetPoints(vtk_nodes)
geom.SetCells(eval(f'vtk.VTK_{cell_type.split("_",1)[-1].upper()}'),cells) vtk_data.SetCells(eval(f'vtk.VTK_{cell_type.split("_",1)[-1].upper()}'),cells)
return VTK(geom) return VTK(vtk_data)
@staticmethod @staticmethod
@ -110,10 +111,10 @@ class VTK:
vtk_points = vtk.vtkPoints() vtk_points = vtk.vtkPoints()
vtk_points.SetData(np_to_vtk(points)) vtk_points.SetData(np_to_vtk(points))
geom = vtk.vtkPolyData() vtk_data = vtk.vtkPolyData()
geom.SetPoints(vtk_points) vtk_data.SetPoints(vtk_points)
return VTK(geom) return VTK(vtk_data)
@staticmethod @staticmethod
@ -131,18 +132,20 @@ class VTK:
""" """
ext = Path(fname).suffix ext = Path(fname).suffix
if ext == '.vtk' or dataset_type: if ext == '.vtk' or dataset_type is not None:
reader = vtk.vtkGenericDataObjectReader() reader = vtk.vtkGenericDataObjectReader()
reader.SetFileName(str(fname)) reader.SetFileName(str(fname))
reader.Update()
if dataset_type is None: if dataset_type is None:
raise TypeError('Dataset type for *.vtk file not given.') raise TypeError('Dataset type for *.vtk file not given.')
elif dataset_type.lower().endswith('rectilineargrid'): elif dataset_type.lower().endswith('rectilineargrid'):
geom = reader.GetRectilinearGridOutput() reader.Update()
vtk_data = reader.GetRectilinearGridOutput()
elif dataset_type.lower().endswith('unstructuredgrid'): elif dataset_type.lower().endswith('unstructuredgrid'):
geom = reader.GetUnstructuredGridOutput() reader.Update()
vtk_data = reader.GetUnstructuredGridOutput()
elif dataset_type.lower().endswith('polydata'): elif dataset_type.lower().endswith('polydata'):
geom = reader.GetPolyDataOutput() reader.Update()
vtk_data = reader.GetPolyDataOutput()
else: else:
raise TypeError(f'Unknown dataset type {dataset_type} for vtk file') raise TypeError(f'Unknown dataset type {dataset_type} for vtk file')
else: else:
@ -157,9 +160,9 @@ class VTK:
reader.SetFileName(str(fname)) reader.SetFileName(str(fname))
reader.Update() reader.Update()
geom = reader.GetOutput() vtk_data = reader.GetOutput()
return VTK(geom) return VTK(vtk_data)
@staticmethod @staticmethod
def _write(writer): def _write(writer):
@ -177,11 +180,11 @@ class VTK:
Write data in parallel background process. Defaults to True. Write data in parallel background process. Defaults to True.
""" """
if isinstance(self.geom,vtk.vtkRectilinearGrid): if isinstance(self.vtk_data,vtk.vtkRectilinearGrid):
writer = vtk.vtkXMLRectilinearGridWriter() writer = vtk.vtkXMLRectilinearGridWriter()
elif isinstance(self.geom,vtk.vtkUnstructuredGrid): elif isinstance(self.vtk_data,vtk.vtkUnstructuredGrid):
writer = vtk.vtkXMLUnstructuredGridWriter() writer = vtk.vtkXMLUnstructuredGridWriter()
elif isinstance(self.geom,vtk.vtkPolyData): elif isinstance(self.vtk_data,vtk.vtkPolyData):
writer = vtk.vtkXMLPolyDataWriter() writer = vtk.vtkXMLPolyDataWriter()
default_ext = writer.GetDefaultFileExtension() default_ext = writer.GetDefaultFileExtension()
@ -191,7 +194,7 @@ class VTK:
writer.SetFileName(str(Path(fname).with_suffix('.'+default_ext))) writer.SetFileName(str(Path(fname).with_suffix('.'+default_ext)))
writer.SetCompressorTypeToZLib() writer.SetCompressorTypeToZLib()
writer.SetDataModeToBinary() writer.SetDataModeToBinary()
writer.SetInputData(self.geom) writer.SetInputData(self.vtk_data)
if parallel: if parallel:
try: try:
@ -218,8 +221,8 @@ class VTK:
Data label. Data label.
""" """
N_points = self.geom.GetNumberOfPoints() N_points = self.vtk_data.GetNumberOfPoints()
N_cells = self.geom.GetNumberOfCells() N_cells = self.vtk_data.GetNumberOfCells()
if isinstance(data,np.ndarray): if isinstance(data,np.ndarray):
if label is None: if label is None:
@ -232,9 +235,9 @@ class VTK:
d.SetName(label) d.SetName(label)
if data.shape[0] == N_cells: if data.shape[0] == N_cells:
self.geom.GetCellData().AddArray(d) self.vtk_data.GetCellData().AddArray(d)
elif data.shape[0] == N_points: elif data.shape[0] == N_points:
self.geom.GetPointData().AddArray(d) self.vtk_data.GetPointData().AddArray(d)
else: else:
raise ValueError(f'Invalid shape {data.shape[0]}') raise ValueError(f'Invalid shape {data.shape[0]}')
elif isinstance(data,pd.DataFrame): elif isinstance(data,pd.DataFrame):
@ -259,22 +262,22 @@ class VTK:
Data label. Data label.
""" """
celldata = self.geom.GetCellData() cell_data = self.vtk_data.GetCellData()
for a in range(celldata.GetNumberOfArrays()): for a in range(cell_data.GetNumberOfArrays()):
if celldata.GetArrayName(a) == label: if cell_data.GetArrayName(a) == label:
return vtk_to_np(celldata.GetArray(a)) return vtk_to_np(cell_data.GetArray(a))
pointdata = self.geom.GetPointData() point_data = self.vtk_data.GetPointData()
for a in range(celldata.GetNumberOfArrays()): for a in range(point_data.GetNumberOfArrays()):
if pointdata.GetArrayName(a) == label: if point_data.GetArrayName(a) == label:
return vtk_to_np(pointdata.GetArray(a)) return vtk_to_np(point_data.GetArray(a))
raise ValueError(f'array "{label}" not found') raise ValueError(f'array "{label}" not found')
def get_comments(self): def get_comments(self):
"""Return the comments.""" """Return the comments."""
fielddata = self.geom.GetFieldData() fielddata = self.vtk_data.GetFieldData()
for a in range(fielddata.GetNumberOfArrays()): for a in range(fielddata.GetNumberOfArrays()):
if fielddata.GetArrayName(a) == 'comments': if fielddata.GetArrayName(a) == 'comments':
comments = fielddata.GetAbstractArray(a) comments = fielddata.GetAbstractArray(a)
@ -284,7 +287,7 @@ class VTK:
def set_comments(self,comments): def set_comments(self,comments):
""" """
Set Comments. Set comments.
Parameters Parameters
---------- ----------
@ -296,12 +299,12 @@ class VTK:
s.SetName('comments') s.SetName('comments')
for c in [comments] if isinstance(comments,str) else comments: for c in [comments] if isinstance(comments,str) else comments:
s.InsertNextValue(c) s.InsertNextValue(c)
self.geom.GetFieldData().AddArray(s) self.vtk_data.GetFieldData().AddArray(s)
def add_comments(self,comments): def add_comments(self,comments):
""" """
Add Comments. Add comments.
Parameters Parameters
---------- ----------
@ -309,15 +312,15 @@ class VTK:
Comments to add. Comments to add.
""" """
self.set_comments(self.get_comments + ([comments] if isinstance(comments,str) else comments)) self.set_comments(self.get_comments() + ([comments] if isinstance(comments,str) else comments))
def __repr__(self): def __repr__(self):
"""ASCII representation of the VTK data.""" """ASCII representation of the VTK data."""
writer = vtk.vtkDataSetWriter() writer = vtk.vtkDataSetWriter()
writer.SetHeader(f'# {util.version_date("VTK")}') writer.SetHeader(f'# {util.execution_stamp("VTK")}')
writer.WriteToOutputStringOn() writer.WriteToOutputStringOn()
writer.SetInputData(self.geom) writer.SetInputData(self.vtk_data)
writer.Write() writer.Write()
return writer.GetOutputString() return writer.GetOutputString()
@ -329,7 +332,7 @@ class VTK:
See http://compilatrix.com/article/vtk-1 for further ideas. See http://compilatrix.com/article/vtk-1 for further ideas.
""" """
mapper = vtk.vtkDataSetMapper() mapper = vtk.vtkDataSetMapper()
mapper.SetInputData(self.geom) mapper.SetInputData(self.vtk_data)
actor = vtk.vtkActor() actor = vtk.vtkActor()
actor.SetMapper(mapper) actor.SetMapper(mapper)

View File

@ -1,3 +0,0 @@
"""Aggregator for configuration file handling."""
from .material import Material # noqa

View File

@ -1,282 +0,0 @@
import re
import os
from damask import util
class Section():
def __init__(self,data = {'__order__':[]},part = ''):
"""New material.config section."""
classes = {
'homogenization':Homogenization,
'microstructure':Microstructure,
'crystallite':Crystallite,
'phase':Phase,
'texture':Texture,
}
self.parameters = {}
for key in data:
self.parameters[key] = data[key] if isinstance(data[key], list) else [data[key]]
if '__order__' not in self.parameters:
self.parameters['__order__'] = list(self.parameters.keys())
if part.lower() in classes:
self.__class__ = classes[part.lower()]
self.__init__(data)
def add_multiKey(self,key,data):
multiKey = '(%s)'%key
if multiKey not in self.parameters: self.parameters[multiKey] = []
if multiKey not in self.parameters['__order__']: self.parameters['__order__'] += [multiKey]
self.parameters[multiKey] += [[item] for item in data] if isinstance(data, list) else [[data]]
def data(self):
return self.parameters
class Homogenization(Section):
def __init__(self,data = {'__order__':[]}):
"""New material.config <homogenization> section."""
Section.__init__(self,data)
class Crystallite(Section):
def __init__(self,data = {'__order__':[]}):
"""New material.config <crystallite> section."""
Section.__init__(self,data)
class Phase(Section):
def __init__(self,data = {'__order__':[]}):
"""New material.config <Phase> section."""
Section.__init__(self,data)
class Microstructure(Section):
def __init__(self,data = {'__order__':[]}):
"""New material.config <microstructure> section."""
Section.__init__(self,data)
class Texture(Section):
def __init__(self,data = {'__order__':[]}):
"""New material.config <texture> section."""
Section.__init__(self,data)
def add_component(self,theType,properties):
scatter = properties['scatter'] if 'scatter' in list(map(str.lower,list(properties.keys()))) else 0.0
fraction = properties['fraction'] if 'fraction' in list(map(str.lower,list(properties.keys()))) else 1.0
try:
multiKey = theType.lower()
except AttributeError:
pass
if multiKey == 'gauss':
self.add_multiKey(multiKey,'phi1 %g\tPhi %g\tphi2 %g\tscatter %g\tfraction %g'%(
properties['eulers'][0],
properties['eulers'][1],
properties['eulers'][2],
scatter,
fraction,
)
)
class Material():
"""Read, manipulate, and write material.config files."""
def __init__(self,verbose=True):
"""Generates ordered list of parts."""
self.parts = [
'homogenization',
'crystallite',
'phase',
'texture',
'microstructure',
]
self.data = {
'homogenization': {'__order__': []},
'microstructure': {'__order__': []},
'crystallite': {'__order__': []},
'phase': {'__order__': []},
'texture': {'__order__': []},
}
self.verbose = verbose
def __repr__(self):
"""Returns current data structure in material.config format."""
me = []
for part in self.parts:
if self.verbose: print(f'processing <{part}>')
me += ['',
'#'*100,
f'<{part}>',
'#'*100,
]
for section in self.data[part]['__order__']:
me += [f'[{section}] {"#"+"-"*max(0,96-len(section))}']
for key in self.data[part][section]['__order__']:
if key.startswith('(') and key.endswith(')'): # multiple (key)
me += [f'{key}\t{" ".join(values)}' for values in self.data[part][section][key]]
else: # plain key
me += [f'{key}\t{util.srepr(self.data[part][section][key]," ")}']
return '\n'.join(me) + '\n'
def parse(self, part=None, sections=[], content=None):
re_part = re.compile(r'^<(.+)>$') # pattern for part
re_sec = re.compile(r'^\[(.+)\]$') # pattern for section
name_section = ''
active = False
for line in content:
line = line.split('#')[0].strip() # kill comments and extra whitespace
line = line.split('/echo/')[0].strip() # remove '/echo/' tags
line = line.lower() # be case insensitive
if line: # content survives...
match_part = re_part.match(line)
if match_part: # found <...> separator
active = (match_part.group(1) == part) # only active in <part>
continue
if active:
match_sec = re_sec.match(line)
if match_sec: # found [section]
name_section = match_sec.group(1) # remember name ...
if '__order__' not in self.data[part]: self.data[part]['__order__'] = []
self.data[part]['__order__'].append(name_section) # ... and position
self.data[part][name_section] = {'__order__':[]}
continue
if sections == [] or name_section in sections: # possibly restrict to subset
items = line.split()
if items[0] not in self.data[part][name_section]: # first encounter of key?
self.data[part][name_section][items[0]] = [] # create item
self.data[part][name_section]['__order__'].append(items[0])
if items[0].startswith('(') and items[0].endswith(')'): # multiple "(key)"
self.data[part][name_section][items[0]].append(items[1:])
else: # plain key
self.data[part][name_section][items[0]] = items[1:]
def read(self,filename=None):
"""Read material.config file."""
def recursiveRead(filename):
"""Takes care of include statements like '{}'."""
result = []
re_include = re.compile(r'^{(.+)}$')
with open(filename) as f: lines = f.readlines()
for line in lines:
match = re_include.match(line.split()[0]) if line.strip() else False
result += [line] if not match else \
recursiveRead(match.group(1) if match.group(1).startswith('/') else
os.path.normpath(os.path.join(os.path.dirname(filename),match.group(1))))
return result
c = recursiveRead(filename)
for p in self.parts:
self.parse(part=p, content=c)
def write(self,filename='material.config', overwrite=False):
"""Write to material.config."""
i = 0
outname = filename
while os.path.exists(outname) and not overwrite:
i += 1
outname = f'{filename}_{i}'
if self.verbose: print(f'Writing material data to {outname}')
with open(outname,'w') as f:
f.write(str(self))
return outname
def add_section(self, part=None, section=None, initialData=None, merge=False):
"""Add Update."""
part = part.lower()
section = section.lower()
if part not in self.parts: raise Exception(f'invalid part {part}')
if not isinstance(initialData, dict):
initialData = initialData.data()
if section not in self.data[part]: self.data[part]['__order__'] += [section]
if section in self.data[part] and merge:
for existing in self.data[part][section]['__order__']: # replace existing
if existing in initialData['__order__']:
if existing.startswith('(') and existing.endswith(')'): # multiple (key)
self.data[part][section][existing] += initialData[existing] # add new multiple entries to existing ones
else: # regular key
self.data[part][section][existing] = initialData[existing] # plain replice
for new in initialData['__order__']: # merge new content
if new not in self.data[part][section]['__order__']:
self.data[part][section][new] = initialData[new]
self.data[part][section]['__order__'] += [new]
else:
self.data[part][section] = initialData
def add_microstructure(self, section='',
components={}, # dict of phase,texture, and fraction lists
):
"""Experimental! Needs expansion to multi-constituent microstructures..."""
microstructure = Microstructure()
# make keys lower case (http://stackoverflow.com/questions/764235/dictionary-to-lowercase-in-python)
components=dict((k.lower(), v) for k,v in components.items())
for key in ['phase','texture','fraction','crystallite']:
if isinstance(components[key], list):
for i, x in enumerate(components[key]):
try:
components[key][i] = x.lower()
except AttributeError:
pass
else:
try:
components[key] = [components[key].lower()]
except AttributeError:
components[key] = [components[key]]
for (phase,texture,fraction,crystallite) in zip(components['phase'],components['texture'],
components['fraction'],components['crystallite']):
microstructure.add_multiKey('constituent','phase %i\ttexture %i\tfraction %g\ncrystallite %i'%(
self.data['phase']['__order__'].index(phase)+1,
self.data['texture']['__order__'].index(texture)+1,
fraction,
self.data['crystallite']['__order__'].index(crystallite)+1))
self.add_section('microstructure',section,microstructure)
def change_value(self, part=None,
section=None,
key=None,
value=None):
if not isinstance(value,list):
if not isinstance(value,str):
value = '%s'%value
value = [value]
newlen = len(value)
oldval = self.data[part.lower()][section.lower()][key.lower()]
oldlen = len(oldval)
print('changing %s:%s:%s from %s to %s '%(part.lower(),section.lower(),key.lower(),oldval,value))
self.data[part.lower()][section.lower()][key.lower()] = value
if newlen is not oldlen:
print('Length of value was changed from %i to %i!'%(oldlen,newlen))
def add_value(self, part=None,
section=None,
key=None,
value=None):
if not isinstance(value,list):
if not isinstance(value,str):
value = '%s'%value
value = [value]
print('adding %s:%s:%s with value %s '%(part.lower(),section.lower(),key.lower(),value))
self.data[part.lower()][section.lower()][key.lower()] = value
self.data[part.lower()][section.lower()]['__order__'] += [key.lower()]

View File

@ -22,7 +22,7 @@ __all__=[
'scale_to_coprime', 'scale_to_coprime',
'return_message', 'return_message',
'extendableOption', 'extendableOption',
'version_date' 'execution_stamp'
] ]
#################################################################################################### ####################################################################################################
@ -178,10 +178,10 @@ def scale_to_coprime(v):
return m return m
def version_date(class_name,function_name=None): def execution_stamp(class_name,function_name=None):
"""tbd.""" """Timestamp the execution of a (function within a) class."""
_function_name = '' if function_name is None else f'.{function_name}'
now = datetime.datetime.now().astimezone().strftime('%Y-%m-%d %H:%M:%S%z') now = datetime.datetime.now().astimezone().strftime('%Y-%m-%d %H:%M:%S%z')
_function_name = '' if function_name is None else f'.{function_name}'
return f'damask.{class_name}{_function_name} v{version} ({now})' return f'damask.{class_name}{_function_name} v{version} ({now})'

View File

@ -16,12 +16,11 @@ setuptools.setup(
packages=setuptools.find_packages(), packages=setuptools.find_packages(),
include_package_data=True, include_package_data=True,
install_requires = [ install_requires = [
"pandas", "pandas", # requires numpy
"scipy", "scipy",
"h5py", "h5py", # requires numpy
"vtk", "vtk",
"matplotlib", "matplotlib", # requires numpy, pillow
"PIL",
], ],
classifiers = [ classifiers = [
"Intended Audience :: Science/Research", "Intended Audience :: Science/Research",

View File

@ -26,13 +26,13 @@ def patch_datetime_now(monkeypatch):
monkeypatch.setattr(datetime, 'datetime', mydatetime) monkeypatch.setattr(datetime, 'datetime', mydatetime)
@pytest.fixture @pytest.fixture
def version_date(monkeypatch): def execution_stamp(monkeypatch):
"""Set damask.util.version_date for reproducible tests results.""" """Set damask.util.execution_stamp for reproducible tests results."""
def version_date(class_name,function_name=None): def execution_stamp(class_name,function_name=None):
_function_name = '' if function_name is None else f'.{function_name}' _function_name = '' if function_name is None else f'.{function_name}'
return f'damask.{class_name}{_function_name} v{patched_version} ({patched_date})' return f'damask.{class_name}{_function_name} v{patched_version} ({patched_date})'
monkeypatch.setattr(damask.util, 'version_date', version_date) monkeypatch.setattr(damask.util, 'execution_stamp', execution_stamp)
def pytest_addoption(parser): def pytest_addoption(parser):

View File

@ -1,25 +0,0 @@
<?xml version="1.0"?>
<VTKFile type="RectilinearGrid" version="0.1" byte_order="LittleEndian" header_type="UInt32" compressor="vtkZLibDataCompressor">
<RectilinearGrid WholeExtent="0 20 0 18 0 8">
<Piece Extent="0 20 0 18 0 8">
<PointData>
</PointData>
<CellData>
<DataArray type="Int32" Name="materialpoint" format="binary" RangeMin="1" RangeMax="2">
AQAAAACAAAAALQAANQAAAA==eF7t1CECACAMxLBj/380fhYwIyK2spWkmnWgt6b3AF65/avfegAAAAAAAAAAAMy0AfYtC2k=
</DataArray>
</CellData>
<Coordinates>
<DataArray type="Float64" Name="x" format="binary" RangeMin="0" RangeMax="1">
AQAAAACAAACoAAAAVQAAAA==eF5jYICAWTNBYKU9hN5pb2IMAoeh/JP2EFUXoOKX7dPTQOAaVP6m/dkzIHAHqu4BVPwhVP1jqPwTqL5nUHUvoOpeQtW9hqp7A1X3Dqrugz0ASSZF3Q==
</DataArray>
<DataArray type="Float64" Name="y" format="binary" RangeMin="0" RangeMax="1">
AQAAAACAAACYAAAAVgAAAA==eF5jYIAAmeOFQLTGHkLvsQ8Fg6NQ/hn7IjDjIlT8qr1F32MgugGVv2MPMeUBVN1D+8cQBVD1T+3BymSeQ/W9sF8FBq+g+t/Yg4Ut3kHN+WAPAAVdQE4=
</DataArray>
<DataArray type="Float64" Name="z" format="binary" RangeMin="0" RangeMax="1">
AQAAAACAAABIAAAAIgAAAA==eF5jYEAGB+wh9AUofQNKP4DST6D0Cyj9Bkp/sAcAAU8I6Q==
</DataArray>
</Coordinates>
</Piece>
</RectilinearGrid>
</VTKFile>

View File

@ -0,0 +1,25 @@
<?xml version="1.0"?>
<VTKFile type="RectilinearGrid" version="0.1" byte_order="LittleEndian" header_type="UInt32" compressor="vtkZLibDataCompressor">
<RectilinearGrid WholeExtent="0 8 0 5 0 4">
<Piece Extent="0 8 0 5 0 4">
<PointData>
</PointData>
<CellData>
<DataArray type="Int64" Name="materialpoint" format="binary" RangeMin="1" RangeMax="41">
AQAAAACAAAAABQAAYwAAAA==eF7t0scBgkAAAEHBgBEwgDmBsf8GfTANCN/bzzSwUa8pCrYyZp8DDjliwjEnnHLGORdMmTHnkiuuuWHBklvuuOeBR5545oVX3nhnxZoPPvnimx9+GQc7GT5sqvjvhz+ZtAcJ
</DataArray>
</CellData>
<Coordinates>
<DataArray type="Float64" Name="x" format="binary" RangeMin="0" RangeMax="0.000008">
AQAAAACAAABIAAAAOgAAAA==eF5jYICA3rdbF3w/tsEOQh+wC3kiUFisdRLKv2D3IeNxx9YfV6DiN+22x9tFGsbchco/sAMA/fQl6g==
</DataArray>
<DataArray type="Float64" Name="y" format="binary" RangeMin="0" RangeMax="0.000005">
AQAAAACAAAAwAAAAKwAAAA==eF5jYICAvrdbF3w/tsEOQh+wC30iUFisdRLKv2D3MeNxx9YfV+wAD5wZgw==
</DataArray>
<DataArray type="Float64" Name="z" format="binary" RangeMin="0" RangeMax="0.000004">
AQAAAACAAAAoAAAAIwAAAA==eF5jYICA3rdbF3w/tsEOQh+wC3kiUFisdRLKv2AHAFVBE/w=
</DataArray>
</Coordinates>
</Piece>
</RectilinearGrid>
</VTKFile>

View File

@ -0,0 +1,25 @@
<?xml version="1.0"?>
<VTKFile type="RectilinearGrid" version="0.1" byte_order="LittleEndian" header_type="UInt32" compressor="vtkZLibDataCompressor">
<RectilinearGrid WholeExtent="0 8 0 5 0 4">
<Piece Extent="0 8 0 5 0 4">
<PointData>
</PointData>
<CellData>
<DataArray type="Int64" Name="materialpoint" format="binary" RangeMin="1" RangeMax="41">
AQAAAACAAAAABQAAYwAAAA==eF7t0scBgkAAAEHBgBEwgDmBsf8GfTANCN/bzzSwUa8pCrYyZp8DDjliwjEnnHLGORdMmTHnkiuuuWHBklvuuOeBR5545oVX3nhnxZoPPvnimx9+GQc7GT5sqvjvhz+ZtAcJ
</DataArray>
</CellData>
<Coordinates>
<DataArray type="Float64" Name="x" format="binary" RangeMin="0" RangeMax="0.000008">
AQAAAACAAABIAAAAOgAAAA==eF5jYICA3rdbF3w/tsEOQh+wC3kiUFisdRLKv2D3IeNxx9YfV6DiN+22x9tFGsbchco/sAMA/fQl6g==
</DataArray>
<DataArray type="Float64" Name="y" format="binary" RangeMin="0" RangeMax="0.000005">
AQAAAACAAAAwAAAAKwAAAA==eF5jYICAvrdbF3w/tsEOQh+wC30iUFisdRLKv2D3MeNxx9YfV+wAD5wZgw==
</DataArray>
<DataArray type="Float64" Name="z" format="binary" RangeMin="0" RangeMax="0.000004">
AQAAAACAAAAoAAAAIwAAAA==eF5jYICA3rdbF3w/tsEOQh+wC3kiUFisdRLKv2AHAFVBE/w=
</DataArray>
</Coordinates>
</Piece>
</RectilinearGrid>
</VTKFile>

View File

@ -0,0 +1,25 @@
<?xml version="1.0"?>
<VTKFile type="RectilinearGrid" version="0.1" byte_order="LittleEndian" header_type="UInt32" compressor="vtkZLibDataCompressor">
<RectilinearGrid WholeExtent="0 8 0 5 0 4">
<Piece Extent="0 8 0 5 0 4">
<PointData>
</PointData>
<CellData>
<DataArray type="Int64" Name="materialpoint" format="binary" RangeMin="1" RangeMax="41">
AQAAAACAAAAABQAAYwAAAA==eF7t0scBgkAAAEHBgBEwgDmBsf8GfTANCN/bzzSwUa8pCrYyZp8DDjliwjEnnHLGORdMmTHnkiuuuWHBklvuuOeBR5545oVX3nhnxZoPPvnimx9+GQc7GT5sqvjvhz+ZtAcJ
</DataArray>
</CellData>
<Coordinates>
<DataArray type="Float64" Name="x" format="binary" RangeMin="0" RangeMax="0.000008">
AQAAAACAAABIAAAAOgAAAA==eF5jYICA3rdbF3w/tsEOQh+wC3kiUFisdRLKv2D3IeNxx9YfV6DiN+22x9tFGsbchco/sAMA/fQl6g==
</DataArray>
<DataArray type="Float64" Name="y" format="binary" RangeMin="0" RangeMax="0.000005">
AQAAAACAAAAwAAAAKwAAAA==eF5jYICAvrdbF3w/tsEOQh+wC30iUFisdRLKv2D3MeNxx9YfV+wAD5wZgw==
</DataArray>
<DataArray type="Float64" Name="z" format="binary" RangeMin="0" RangeMax="0.000004">
AQAAAACAAAAoAAAAIwAAAA==eF5jYICA3rdbF3w/tsEOQh+wC3kiUFisdRLKv2AHAFVBE/w=
</DataArray>
</Coordinates>
</Piece>
</RectilinearGrid>
</VTKFile>

View File

@ -0,0 +1,25 @@
<?xml version="1.0"?>
<VTKFile type="RectilinearGrid" version="0.1" byte_order="LittleEndian" header_type="UInt32" compressor="vtkZLibDataCompressor">
<RectilinearGrid WholeExtent="0 8 0 5 0 4">
<Piece Extent="0 8 0 5 0 4">
<PointData>
</PointData>
<CellData>
<DataArray type="Int64" Name="materialpoint" format="binary" RangeMin="1" RangeMax="41">
AQAAAACAAAAABQAAYwAAAA==eF7t0scBgkAAAEHBgBEwgDmBsf8GfTANCN/bzzSwUa8pCrYyZp8DDjliwjEnnHLGORdMmTHnkiuuuWHBklvuuOeBR5545oVX3nhnxZoPPvnimx9+GQc7GT5sqvjvhz+ZtAcJ
</DataArray>
</CellData>
<Coordinates>
<DataArray type="Float64" Name="x" format="binary" RangeMin="0" RangeMax="0.000008">
AQAAAACAAABIAAAAOgAAAA==eF5jYICA3rdbF3w/tsEOQh+wC3kiUFisdRLKv2D3IeNxx9YfV6DiN+22x9tFGsbchco/sAMA/fQl6g==
</DataArray>
<DataArray type="Float64" Name="y" format="binary" RangeMin="0" RangeMax="0.000005">
AQAAAACAAAAwAAAAKwAAAA==eF5jYICAvrdbF3w/tsEOQh+wC30iUFisdRLKv2D3MeNxx9YfV+wAD5wZgw==
</DataArray>
<DataArray type="Float64" Name="z" format="binary" RangeMin="0" RangeMax="0.000004">
AQAAAACAAAAoAAAAIwAAAA==eF5jYICA3rdbF3w/tsEOQh+wC3kiUFisdRLKv2AHAFVBE/w=
</DataArray>
</Coordinates>
</Piece>
</RectilinearGrid>
</VTKFile>

View File

@ -0,0 +1,25 @@
<?xml version="1.0"?>
<VTKFile type="RectilinearGrid" version="0.1" byte_order="LittleEndian" header_type="UInt32" compressor="vtkZLibDataCompressor">
<RectilinearGrid WholeExtent="0 8 0 5 0 4">
<Piece Extent="0 8 0 5 0 4">
<PointData>
</PointData>
<CellData>
<DataArray type="Int64" Name="materialpoint" format="binary" RangeMin="1" RangeMax="41">
AQAAAACAAAAABQAAYwAAAA==eF7t0scBgkAAAEHBgBEwgDmBsf8GfTANCN/bzzSwUa8pCrYyZp8DDjliwjEnnHLGORdMmTHnkiuuuWHBklvuuOeBR5545oVX3nhnxZoPPvnimx9+GQc7GT5sqvjvhz+ZtAcJ
</DataArray>
</CellData>
<Coordinates>
<DataArray type="Float64" Name="x" format="binary" RangeMin="0" RangeMax="0.000008">
AQAAAACAAABIAAAAOgAAAA==eF5jYICA3rdbF3w/tsEOQh+wC3kiUFisdRLKv2D3IeNxx9YfV6DiN+22x9tFGsbchco/sAMA/fQl6g==
</DataArray>
<DataArray type="Float64" Name="y" format="binary" RangeMin="0" RangeMax="0.000005">
AQAAAACAAAAwAAAAKwAAAA==eF5jYICAvrdbF3w/tsEOQh+wC30iUFisdRLKv2D3MeNxx9YfV+wAD5wZgw==
</DataArray>
<DataArray type="Float64" Name="z" format="binary" RangeMin="0" RangeMax="0.000004">
AQAAAACAAAAoAAAAIwAAAA==eF5jYICA3rdbF3w/tsEOQh+wC3kiUFisdRLKv2AHAFVBE/w=
</DataArray>
</Coordinates>
</Piece>
</RectilinearGrid>
</VTKFile>

View File

@ -0,0 +1,25 @@
<?xml version="1.0"?>
<VTKFile type="RectilinearGrid" version="0.1" byte_order="LittleEndian" header_type="UInt32" compressor="vtkZLibDataCompressor">
<RectilinearGrid WholeExtent="0 8 0 5 0 4">
<Piece Extent="0 8 0 5 0 4">
<PointData>
</PointData>
<CellData>
<DataArray type="Int64" Name="materialpoint" format="binary" RangeMin="1" RangeMax="41">
AQAAAACAAAAABQAAYwAAAA==eF7t0scBgkAAAEHBgBEwgDmBsf8GfTANCN/bzzSwUa8pCrYyZp8DDjliwjEnnHLGORdMmTHnkiuuuWHBklvuuOeBR5545oVX3nhnxZoPPvnimx9+GQc7GT5sqvjvhz+ZtAcJ
</DataArray>
</CellData>
<Coordinates>
<DataArray type="Float64" Name="x" format="binary" RangeMin="0" RangeMax="0.000008">
AQAAAACAAABIAAAAOgAAAA==eF5jYICA3rdbF3w/tsEOQh+wC3kiUFisdRLKv2D3IeNxx9YfV6DiN+22x9tFGsbchco/sAMA/fQl6g==
</DataArray>
<DataArray type="Float64" Name="y" format="binary" RangeMin="0" RangeMax="0.000005">
AQAAAACAAAAwAAAAKwAAAA==eF5jYICAvrdbF3w/tsEOQh+wC30iUFisdRLKv2D3MeNxx9YfV+wAD5wZgw==
</DataArray>
<DataArray type="Float64" Name="z" format="binary" RangeMin="0" RangeMax="0.000004">
AQAAAACAAAAoAAAAIwAAAA==eF5jYICA3rdbF3w/tsEOQh+wC3kiUFisdRLKv2AHAFVBE/w=
</DataArray>
</Coordinates>
</Piece>
</RectilinearGrid>
</VTKFile>

View File

@ -0,0 +1,25 @@
<?xml version="1.0"?>
<VTKFile type="RectilinearGrid" version="0.1" byte_order="LittleEndian" header_type="UInt32" compressor="vtkZLibDataCompressor">
<RectilinearGrid WholeExtent="0 8 0 5 0 4">
<Piece Extent="0 8 0 5 0 4">
<PointData>
</PointData>
<CellData>
<DataArray type="Int64" Name="materialpoint" format="binary" RangeMin="1" RangeMax="41">
AQAAAACAAAAABQAAZwAAAA==eF7t0rcOgmAAhVEgNmyo2AuoWN//BR04EwsJcfzvcvabL47qxcFOJg177HPAIUdMOeaEU844Z8YFl1wx55obbrnjngceeeKZFxYseeWNd1Z88MkX3/zwy+Z/wf8YOqzX1uEPlgwHCA==
</DataArray>
</CellData>
<Coordinates>
<DataArray type="Float64" Name="x" format="binary" RangeMin="0" RangeMax="0.000008">
AQAAAACAAABIAAAAOgAAAA==eF5jYICA3rdbF3w/tsEOQh+wC3kiUFisdRLKv2D3IeNxx9YfV6DiN+22x9tFGsbchco/sAMA/fQl6g==
</DataArray>
<DataArray type="Float64" Name="y" format="binary" RangeMin="0" RangeMax="0.000005">
AQAAAACAAAAwAAAAKwAAAA==eF5jYICAvrdbF3w/tsEOQh+wC30iUFisdRLKv2D3MeNxx9YfV+wAD5wZgw==
</DataArray>
<DataArray type="Float64" Name="z" format="binary" RangeMin="0" RangeMax="0.000004">
AQAAAACAAAAoAAAAIwAAAA==eF5jYICA3rdbF3w/tsEOQh+wC3kiUFisdRLKv2AHAFVBE/w=
</DataArray>
</Coordinates>
</Piece>
</RectilinearGrid>
</VTKFile>

View File

@ -0,0 +1,25 @@
<?xml version="1.0"?>
<VTKFile type="RectilinearGrid" version="0.1" byte_order="LittleEndian" header_type="UInt32" compressor="vtkZLibDataCompressor">
<RectilinearGrid WholeExtent="0 8 0 5 0 4">
<Piece Extent="0 8 0 5 0 4">
<PointData>
</PointData>
<CellData>
<DataArray type="Int64" Name="materialpoint" format="binary" RangeMin="1" RangeMax="41">
AQAAAACAAAAABQAAagAAAA==eF7t0rkOglAARFExLrgCKuKuqLj8/w9acCoSY7B+05x+cqNOvSj4l92GPfY54JAxRxxzwilnnDNhyowLLrlizjULbrjljnseeOSJZ15Y8sob76z44JMvvtn8L9jObz2GDuv96vADk5QHBg==
</DataArray>
</CellData>
<Coordinates>
<DataArray type="Float64" Name="x" format="binary" RangeMin="0" RangeMax="0.000008">
AQAAAACAAABIAAAAOgAAAA==eF5jYICA3rdbF3w/tsEOQh+wC3kiUFisdRLKv2D3IeNxx9YfV6DiN+22x9tFGsbchco/sAMA/fQl6g==
</DataArray>
<DataArray type="Float64" Name="y" format="binary" RangeMin="0" RangeMax="0.000005">
AQAAAACAAAAwAAAAKwAAAA==eF5jYICAvrdbF3w/tsEOQh+wC30iUFisdRLKv2D3MeNxx9YfV+wAD5wZgw==
</DataArray>
<DataArray type="Float64" Name="z" format="binary" RangeMin="0" RangeMax="0.000004">
AQAAAACAAAAoAAAAIwAAAA==eF5jYICA3rdbF3w/tsEOQh+wC3kiUFisdRLKv2AHAFVBE/w=
</DataArray>
</Coordinates>
</Piece>
</RectilinearGrid>
</VTKFile>

View File

@ -1,23 +1,23 @@
<?xml version="1.0"?> <?xml version="1.0"?>
<VTKFile type="RectilinearGrid" version="0.1" byte_order="LittleEndian" header_type="UInt32" compressor="vtkZLibDataCompressor"> <VTKFile type="RectilinearGrid" version="0.1" byte_order="LittleEndian" header_type="UInt32" compressor="vtkZLibDataCompressor">
<RectilinearGrid WholeExtent="0 20 0 18 0 8"> <RectilinearGrid WholeExtent="0 8 0 5 0 4">
<Piece Extent="0 20 0 18 0 8"> <Piece Extent="0 8 0 5 0 4">
<PointData> <PointData>
</PointData> </PointData>
<CellData> <CellData>
<DataArray type="Int32" Name="materialpoint" format="binary" RangeMin="1" RangeMax="2"> <DataArray type="Int64" Name="materialpoint" format="binary" RangeMin="1" RangeMax="41">
AQAAAACAAAAALQAANQAAAA==eF7t1CECACAMxLBj/380fhYwIyK2spWkmnWgt6b3AF65/avfegAAAAAAAAAAAMy0AfYtC2k= AQAAAACAAAAABQAAZAAAAA==eF7t0scRglAAQEEBAyZUMCuomPtv0ANbgMNw/O+yDbyo1xQFWxkzYZ8DDjliyjEnnHLGOTMuuOSKOQuuueGWO+554JEnnlmy4oVX3ljzzgeffPHND7+Mg50aPmz698MfmvQHCg==
</DataArray> </DataArray>
</CellData> </CellData>
<Coordinates> <Coordinates>
<DataArray type="Float64" Name="x" format="binary" RangeMin="0" RangeMax="1"> <DataArray type="Float64" Name="x" format="binary" RangeMin="0" RangeMax="0.000008">
AQAAAACAAACoAAAAVQAAAA==eF5jYICAWTNBYKU9hN5pb2IMAoeh/JP2EFUXoOKX7dPTQOAaVP6m/dkzIHAHqu4BVPwhVP1jqPwTqL5nUHUvoOpeQtW9hqp7A1X3Dqrugz0ASSZF3Q== AQAAAACAAABIAAAAOgAAAA==eF5jYICA3rdbF3w/tsEOQh+wC3kiUFisdRLKv2D3IeNxx9YfV6DiN+22x9tFGsbchco/sAMA/fQl6g==
</DataArray> </DataArray>
<DataArray type="Float64" Name="y" format="binary" RangeMin="0" RangeMax="1"> <DataArray type="Float64" Name="y" format="binary" RangeMin="0" RangeMax="0.000005">
AQAAAACAAACYAAAAVgAAAA==eF5jYIAAmeOFQLTGHkLvsQ8Fg6NQ/hn7IjDjIlT8qr1F32MgugGVv2MPMeUBVN1D+8cQBVD1T+3BymSeQ/W9sF8FBq+g+t/Yg4Ut3kHN+WAPAAVdQE4= AQAAAACAAAAwAAAAKwAAAA==eF5jYICAvrdbF3w/tsEOQh+wC30iUFisdRLKv2D3MeNxx9YfV+wAD5wZgw==
</DataArray> </DataArray>
<DataArray type="Float64" Name="z" format="binary" RangeMin="0" RangeMax="1"> <DataArray type="Float64" Name="z" format="binary" RangeMin="0" RangeMax="0.000004">
AQAAAACAAABIAAAAIgAAAA==eF5jYEAGB+wh9AUofQNKP4DST6D0Cyj9Bkp/sAcAAU8I6Q== AQAAAACAAAAoAAAAIwAAAA==eF5jYICA3rdbF3w/tsEOQh+wC3kiUFisdRLKv2AHAFVBE/w=
</DataArray> </DataArray>
</Coordinates> </Coordinates>
</Piece> </Piece>

View File

@ -1,23 +1,23 @@
<?xml version="1.0"?> <?xml version="1.0"?>
<VTKFile type="RectilinearGrid" version="0.1" byte_order="LittleEndian" header_type="UInt32" compressor="vtkZLibDataCompressor"> <VTKFile type="RectilinearGrid" version="0.1" byte_order="LittleEndian" header_type="UInt32" compressor="vtkZLibDataCompressor">
<RectilinearGrid WholeExtent="0 20 0 18 0 8"> <RectilinearGrid WholeExtent="0 8 0 5 0 4">
<Piece Extent="0 20 0 18 0 8"> <Piece Extent="0 8 0 5 0 4">
<PointData> <PointData>
</PointData> </PointData>
<CellData> <CellData>
<DataArray type="Int32" Name="materialpoint" format="binary" RangeMin="1" RangeMax="2"> <DataArray type="Int64" Name="materialpoint" format="binary" RangeMin="1" RangeMax="41">
AQAAAACAAAAALQAANQAAAA==eF7t1CECACAMxLBj/380fhYwIyK2spWkmnWgt6b3AF65/avfegAAAAAAAAAAAMy0AfYtC2k= AQAAAACAAAAABQAAYwAAAA==eF7t0scBgkAAAEHBgBEwgDmBsf8GfTANCN/bzzSwUa8pCrYyZp8DDjliwjEnnHLGORdMmTHnkiuuuWHBklvuuOeBR5545oVX3nhnxZoPPvnimx9+GQc7GT5sqvjvhz+ZtAcJ
</DataArray> </DataArray>
</CellData> </CellData>
<Coordinates> <Coordinates>
<DataArray type="Float64" Name="x" format="binary" RangeMin="0" RangeMax="1"> <DataArray type="Float64" Name="x" format="binary" RangeMin="0" RangeMax="0.000008">
AQAAAACAAACoAAAAVQAAAA==eF5jYICAWTNBYKU9hN5pb2IMAoeh/JP2EFUXoOKX7dPTQOAaVP6m/dkzIHAHqu4BVPwhVP1jqPwTqL5nUHUvoOpeQtW9hqp7A1X3Dqrugz0ASSZF3Q== AQAAAACAAABIAAAAOgAAAA==eF5jYICA3rdbF3w/tsEOQh+wC3kiUFisdRLKv2D3IeNxx9YfV6DiN+22x9tFGsbchco/sAMA/fQl6g==
</DataArray> </DataArray>
<DataArray type="Float64" Name="y" format="binary" RangeMin="0" RangeMax="1"> <DataArray type="Float64" Name="y" format="binary" RangeMin="0" RangeMax="0.000005">
AQAAAACAAACYAAAAVgAAAA==eF5jYIAAmeOFQLTGHkLvsQ8Fg6NQ/hn7IjDjIlT8qr1F32MgugGVv2MPMeUBVN1D+8cQBVD1T+3BymSeQ/W9sF8FBq+g+t/Yg4Ut3kHN+WAPAAVdQE4= AQAAAACAAAAwAAAAKwAAAA==eF5jYICAvrdbF3w/tsEOQh+wC30iUFisdRLKv2D3MeNxx9YfV+wAD5wZgw==
</DataArray> </DataArray>
<DataArray type="Float64" Name="z" format="binary" RangeMin="0" RangeMax="1"> <DataArray type="Float64" Name="z" format="binary" RangeMin="0" RangeMax="0.000004">
AQAAAACAAABIAAAAIgAAAA==eF5jYEAGB+wh9AUofQNKP4DST6D0Cyj9Bkp/sAcAAU8I6Q== AQAAAACAAAAoAAAAIwAAAA==eF5jYICA3rdbF3w/tsEOQh+wC3kiUFisdRLKv2AHAFVBE/w=
</DataArray> </DataArray>
</Coordinates> </Coordinates>
</Piece> </Piece>

View File

@ -1,23 +1,23 @@
<?xml version="1.0"?> <?xml version="1.0"?>
<VTKFile type="RectilinearGrid" version="0.1" byte_order="LittleEndian" header_type="UInt32" compressor="vtkZLibDataCompressor"> <VTKFile type="RectilinearGrid" version="0.1" byte_order="LittleEndian" header_type="UInt32" compressor="vtkZLibDataCompressor">
<RectilinearGrid WholeExtent="0 20 0 18 0 8"> <RectilinearGrid WholeExtent="0 8 0 5 0 4">
<Piece Extent="0 20 0 18 0 8"> <Piece Extent="0 8 0 5 0 4">
<PointData> <PointData>
</PointData> </PointData>
<CellData> <CellData>
<DataArray type="Int32" Name="materialpoint" format="binary" RangeMin="1" RangeMax="2"> <DataArray type="Int64" Name="materialpoint" format="binary" RangeMin="1" RangeMax="2">
AQAAAACAAAAALQAANQAAAA==eF7t1CECACAMxLBj/380fhYwIyK2spWkmnWgt6b3AF65/avfegAAAAAAAAAAAMy0AfYtC2k= AQAAAACAAAAABQAAGwAAAA==eF5jZIAAxlF6lB4AmmmUpogeDUfKaAD7jwDw
</DataArray> </DataArray>
</CellData> </CellData>
<Coordinates> <Coordinates>
<DataArray type="Float64" Name="x" format="binary" RangeMin="0" RangeMax="1"> <DataArray type="Float64" Name="x" format="binary" RangeMin="0" RangeMax="0.000008">
AQAAAACAAACoAAAAVQAAAA==eF5jYICAWTNBYKU9hN5pb2IMAoeh/JP2EFUXoOKX7dPTQOAaVP6m/dkzIHAHqu4BVPwhVP1jqPwTqL5nUHUvoOpeQtW9hqp7A1X3Dqrugz0ASSZF3Q== AQAAAACAAABIAAAAOgAAAA==eF5jYICA3rdbF3w/tsEOQh+wC3kiUFisdRLKv2D3IeNxx9YfV6DiN+22x9tFGsbchco/sAMA/fQl6g==
</DataArray> </DataArray>
<DataArray type="Float64" Name="y" format="binary" RangeMin="0" RangeMax="1"> <DataArray type="Float64" Name="y" format="binary" RangeMin="0" RangeMax="0.000005">
AQAAAACAAACYAAAAVgAAAA==eF5jYIAAmeOFQLTGHkLvsQ8Fg6NQ/hn7IjDjIlT8qr1F32MgugGVv2MPMeUBVN1D+8cQBVD1T+3BymSeQ/W9sF8FBq+g+t/Yg4Ut3kHN+WAPAAVdQE4= AQAAAACAAAAwAAAAKwAAAA==eF5jYICAvrdbF3w/tsEOQh+wC30iUFisdRLKv2D3MeNxx9YfV+wAD5wZgw==
</DataArray> </DataArray>
<DataArray type="Float64" Name="z" format="binary" RangeMin="0" RangeMax="1"> <DataArray type="Float64" Name="z" format="binary" RangeMin="0" RangeMax="0.000004">
AQAAAACAAABIAAAAIgAAAA==eF5jYEAGB+wh9AUofQNKP4DST6D0Cyj9Bkp/sAcAAU8I6Q== AQAAAACAAAAoAAAAIwAAAA==eF5jYICA3rdbF3w/tsEOQh+wC3kiUFisdRLKv2AHAFVBE/w=
</DataArray> </DataArray>
</Coordinates> </Coordinates>
</Piece> </Piece>

View File

@ -1,23 +1,23 @@
<?xml version="1.0"?> <?xml version="1.0"?>
<VTKFile type="RectilinearGrid" version="0.1" byte_order="LittleEndian" header_type="UInt32" compressor="vtkZLibDataCompressor"> <VTKFile type="RectilinearGrid" version="0.1" byte_order="LittleEndian" header_type="UInt32" compressor="vtkZLibDataCompressor">
<RectilinearGrid WholeExtent="0 20 0 18 0 8"> <RectilinearGrid WholeExtent="0 8 0 5 0 4">
<Piece Extent="0 20 0 18 0 8"> <Piece Extent="0 8 0 5 0 4">
<PointData> <PointData>
</PointData> </PointData>
<CellData> <CellData>
<DataArray type="Int32" Name="materialpoint" format="binary" RangeMin="1" RangeMax="2"> <DataArray type="Int64" Name="materialpoint" format="binary" RangeMin="1" RangeMax="2">
AQAAAACAAAAALQAAMQAAAA==eF7tzCEOADAMxLDr/v/o8pLSaTMwi1JJCoAvnGHrN7f/AAAAAAAAAAAAeE8DQvkLTQ== AQAAAACAAAAABQAAGQAAAA==eF5jZIAAxlF6lB4AmmmUHqUHkAYA/M8A8Q==
</DataArray> </DataArray>
</CellData> </CellData>
<Coordinates> <Coordinates>
<DataArray type="Float64" Name="x" format="binary" RangeMin="0" RangeMax="1"> <DataArray type="Float64" Name="x" format="binary" RangeMin="0" RangeMax="0.000008">
AQAAAACAAACoAAAAVQAAAA==eF5jYICAWTNBYKU9hN5pb2IMAoeh/JP2EFUXoOKX7dPTQOAaVP6m/dkzIHAHqu4BVPwhVP1jqPwTqL5nUHUvoOpeQtW9hqp7A1X3Dqrugz0ASSZF3Q== AQAAAACAAABIAAAAOgAAAA==eF5jYICA3rdbF3w/tsEOQh+wC3kiUFisdRLKv2D3IeNxx9YfV6DiN+22x9tFGsbchco/sAMA/fQl6g==
</DataArray> </DataArray>
<DataArray type="Float64" Name="y" format="binary" RangeMin="0" RangeMax="1"> <DataArray type="Float64" Name="y" format="binary" RangeMin="0" RangeMax="0.000005">
AQAAAACAAACYAAAAVgAAAA==eF5jYIAAmeOFQLTGHkLvsQ8Fg6NQ/hn7IjDjIlT8qr1F32MgugGVv2MPMeUBVN1D+8cQBVD1T+3BymSeQ/W9sF8FBq+g+t/Yg4Ut3kHN+WAPAAVdQE4= AQAAAACAAAAwAAAAKwAAAA==eF5jYICAvrdbF3w/tsEOQh+wC30iUFisdRLKv2D3MeNxx9YfV+wAD5wZgw==
</DataArray> </DataArray>
<DataArray type="Float64" Name="z" format="binary" RangeMin="0" RangeMax="1"> <DataArray type="Float64" Name="z" format="binary" RangeMin="0" RangeMax="0.000004">
AQAAAACAAABIAAAAIgAAAA==eF5jYEAGB+wh9AUofQNKP4DST6D0Cyj9Bkp/sAcAAU8I6Q== AQAAAACAAAAoAAAAIwAAAA==eF5jYICA3rdbF3w/tsEOQh+wC3kiUFisdRLKv2AHAFVBE/w=
</DataArray> </DataArray>
</Coordinates> </Coordinates>
</Piece> </Piece>

View File

@ -0,0 +1,25 @@
<?xml version="1.0"?>
<VTKFile type="RectilinearGrid" version="0.1" byte_order="LittleEndian" header_type="UInt32" compressor="vtkZLibDataCompressor">
<RectilinearGrid WholeExtent="0 8 0 5 0 4">
<Piece Extent="0 8 0 5 0 4">
<PointData>
</PointData>
<CellData>
<DataArray type="Int64" Name="materialpoint" format="binary" RangeMin="1" RangeMax="41">
AQAAAACAAAAABQAAZwAAAA==eF7t0rcOgmAAhVEgNmyo2AuoWN//BR04EwsJcfzvcvabL47qxcFOJg177HPAIUdMOeaEU844Z8YFl1wx55obbrnjngceeeKZFxYseeWNd1Z88MkX3/zwy+Z/wf8YOqzX1uEPlgwHCA==
</DataArray>
</CellData>
<Coordinates>
<DataArray type="Float64" Name="x" format="binary" RangeMin="0" RangeMax="0.000008">
AQAAAACAAABIAAAAOgAAAA==eF5jYICA3rdbF3w/tsEOQh+wC3kiUFisdRLKv2D3IeNxx9YfV6DiN+22x9tFGsbchco/sAMA/fQl6g==
</DataArray>
<DataArray type="Float64" Name="y" format="binary" RangeMin="0" RangeMax="0.000005">
AQAAAACAAAAwAAAAKwAAAA==eF5jYICAvrdbF3w/tsEOQh+wC30iUFisdRLKv2D3MeNxx9YfV+wAD5wZgw==
</DataArray>
<DataArray type="Float64" Name="z" format="binary" RangeMin="0" RangeMax="0.000004">
AQAAAACAAAAoAAAAIwAAAA==eF5jYICA3rdbF3w/tsEOQh+wC3kiUFisdRLKv2AHAFVBE/w=
</DataArray>
</Coordinates>
</Piece>
</RectilinearGrid>
</VTKFile>

View File

@ -0,0 +1,25 @@
<?xml version="1.0"?>
<VTKFile type="RectilinearGrid" version="0.1" byte_order="LittleEndian" header_type="UInt32" compressor="vtkZLibDataCompressor">
<RectilinearGrid WholeExtent="0 8 0 5 0 4">
<Piece Extent="0 8 0 5 0 4">
<PointData>
</PointData>
<CellData>
<DataArray type="Int64" Name="materialpoint" format="binary" RangeMin="1" RangeMax="41">
AQAAAACAAAAABQAAagAAAA==eF7t0rkOglAARFExLrgCKuKuqLj8/w9acCoSY7B+05x+cqNOvSj4l92GPfY54JAxRxxzwilnnDNhyowLLrlizjULbrjljnseeOSJZ15Y8sob76z44JMvvtn8L9jObz2GDuv96vADk5QHBg==
</DataArray>
</CellData>
<Coordinates>
<DataArray type="Float64" Name="x" format="binary" RangeMin="0" RangeMax="0.000008">
AQAAAACAAABIAAAAOgAAAA==eF5jYICA3rdbF3w/tsEOQh+wC3kiUFisdRLKv2D3IeNxx9YfV6DiN+22x9tFGsbchco/sAMA/fQl6g==
</DataArray>
<DataArray type="Float64" Name="y" format="binary" RangeMin="0" RangeMax="0.000005">
AQAAAACAAAAwAAAAKwAAAA==eF5jYICAvrdbF3w/tsEOQh+wC30iUFisdRLKv2D3MeNxx9YfV+wAD5wZgw==
</DataArray>
<DataArray type="Float64" Name="z" format="binary" RangeMin="0" RangeMax="0.000004">
AQAAAACAAAAoAAAAIwAAAA==eF5jYICA3rdbF3w/tsEOQh+wC3kiUFisdRLKv2AHAFVBE/w=
</DataArray>
</Coordinates>
</Piece>
</RectilinearGrid>
</VTKFile>

View File

@ -1,23 +1,23 @@
<?xml version="1.0"?> <?xml version="1.0"?>
<VTKFile type="RectilinearGrid" version="0.1" byte_order="LittleEndian" header_type="UInt32" compressor="vtkZLibDataCompressor"> <VTKFile type="RectilinearGrid" version="0.1" byte_order="LittleEndian" header_type="UInt32" compressor="vtkZLibDataCompressor">
<RectilinearGrid WholeExtent="0 20 0 18 0 8"> <RectilinearGrid WholeExtent="0 8 0 5 0 4">
<Piece Extent="0 20 0 18 0 8"> <Piece Extent="0 8 0 5 0 4">
<PointData> <PointData>
</PointData> </PointData>
<CellData> <CellData>
<DataArray type="Int32" Name="materialpoint" format="binary" RangeMin="1" RangeMax="2"> <DataArray type="Int64" Name="materialpoint" format="binary" RangeMin="1" RangeMax="41">
AQAAAACAAAAALQAANQAAAA==eF7t1CECACAMxLBj/380fhYwIyK2spWkmnWgt6b3AF65/avfegAAAAAAAAAAAMy0AfYtC2k= AQAAAACAAAAABQAAZAAAAA==eF7t0scRglAAQEEBAyZUMCuomPtv0ANbgMNw/O+yDbyo1xQFWxkzYZ8DDjliyjEnnHLGOTMuuOSKOQuuueGWO+554JEnnlmy4oVX3ljzzgeffPHND7+Mg50aPmz698MfmvQHCg==
</DataArray> </DataArray>
</CellData> </CellData>
<Coordinates> <Coordinates>
<DataArray type="Float64" Name="x" format="binary" RangeMin="0" RangeMax="1"> <DataArray type="Float64" Name="x" format="binary" RangeMin="0" RangeMax="0.000008">
AQAAAACAAACoAAAAVQAAAA==eF5jYICAWTNBYKU9hN5pb2IMAoeh/JP2EFUXoOKX7dPTQOAaVP6m/dkzIHAHqu4BVPwhVP1jqPwTqL5nUHUvoOpeQtW9hqp7A1X3Dqrugz0ASSZF3Q== AQAAAACAAABIAAAAOgAAAA==eF5jYICA3rdbF3w/tsEOQh+wC3kiUFisdRLKv2D3IeNxx9YfV6DiN+22x9tFGsbchco/sAMA/fQl6g==
</DataArray> </DataArray>
<DataArray type="Float64" Name="y" format="binary" RangeMin="0" RangeMax="1"> <DataArray type="Float64" Name="y" format="binary" RangeMin="0" RangeMax="0.000005">
AQAAAACAAACYAAAAVgAAAA==eF5jYIAAmeOFQLTGHkLvsQ8Fg6NQ/hn7IjDjIlT8qr1F32MgugGVv2MPMeUBVN1D+8cQBVD1T+3BymSeQ/W9sF8FBq+g+t/Yg4Ut3kHN+WAPAAVdQE4= AQAAAACAAAAwAAAAKwAAAA==eF5jYICAvrdbF3w/tsEOQh+wC30iUFisdRLKv2D3MeNxx9YfV+wAD5wZgw==
</DataArray> </DataArray>
<DataArray type="Float64" Name="z" format="binary" RangeMin="0" RangeMax="1"> <DataArray type="Float64" Name="z" format="binary" RangeMin="0" RangeMax="0.000004">
AQAAAACAAABIAAAAIgAAAA==eF5jYEAGB+wh9AUofQNKP4DST6D0Cyj9Bkp/sAcAAU8I6Q== AQAAAACAAAAoAAAAIwAAAA==eF5jYICA3rdbF3w/tsEOQh+wC3kiUFisdRLKv2AHAFVBE/w=
</DataArray> </DataArray>
</Coordinates> </Coordinates>
</Piece> </Piece>

View File

@ -1,23 +1,23 @@
<?xml version="1.0"?> <?xml version="1.0"?>
<VTKFile type="RectilinearGrid" version="0.1" byte_order="LittleEndian" header_type="UInt32" compressor="vtkZLibDataCompressor"> <VTKFile type="RectilinearGrid" version="0.1" byte_order="LittleEndian" header_type="UInt32" compressor="vtkZLibDataCompressor">
<RectilinearGrid WholeExtent="0 20 0 18 0 8"> <RectilinearGrid WholeExtent="0 8 0 5 0 4">
<Piece Extent="0 20 0 18 0 8"> <Piece Extent="0 8 0 5 0 4">
<PointData> <PointData>
</PointData> </PointData>
<CellData> <CellData>
<DataArray type="Int32" Name="materialpoint" format="binary" RangeMin="1" RangeMax="2"> <DataArray type="Int64" Name="materialpoint" format="binary" RangeMin="1" RangeMax="41">
AQAAAACAAAAALQAANQAAAA==eF7t1CECACAMxLBj/380fhYwIyK2spWkmnWgt6b3AF65/avfegAAAAAAAAAAAMy0AfYtC2k= AQAAAACAAAAABQAAYwAAAA==eF7t0scBgkAAAEHBgBEwgDmBsf8GfTANCN/bzzSwUa8pCrYyZp8DDjliwjEnnHLGORdMmTHnkiuuuWHBklvuuOeBR5545oVX3nhnxZoPPvnimx9+GQc7GT5sqvjvhz+ZtAcJ
</DataArray> </DataArray>
</CellData> </CellData>
<Coordinates> <Coordinates>
<DataArray type="Float64" Name="x" format="binary" RangeMin="0" RangeMax="1"> <DataArray type="Float64" Name="x" format="binary" RangeMin="0" RangeMax="0.000008">
AQAAAACAAACoAAAAVQAAAA==eF5jYICAWTNBYKU9hN5pb2IMAoeh/JP2EFUXoOKX7dPTQOAaVP6m/dkzIHAHqu4BVPwhVP1jqPwTqL5nUHUvoOpeQtW9hqp7A1X3Dqrugz0ASSZF3Q== AQAAAACAAABIAAAAOgAAAA==eF5jYICA3rdbF3w/tsEOQh+wC3kiUFisdRLKv2D3IeNxx9YfV6DiN+22x9tFGsbchco/sAMA/fQl6g==
</DataArray> </DataArray>
<DataArray type="Float64" Name="y" format="binary" RangeMin="0" RangeMax="1"> <DataArray type="Float64" Name="y" format="binary" RangeMin="0" RangeMax="0.000005">
AQAAAACAAACYAAAAVgAAAA==eF5jYIAAmeOFQLTGHkLvsQ8Fg6NQ/hn7IjDjIlT8qr1F32MgugGVv2MPMeUBVN1D+8cQBVD1T+3BymSeQ/W9sF8FBq+g+t/Yg4Ut3kHN+WAPAAVdQE4= AQAAAACAAAAwAAAAKwAAAA==eF5jYICAvrdbF3w/tsEOQh+wC30iUFisdRLKv2D3MeNxx9YfV+wAD5wZgw==
</DataArray> </DataArray>
<DataArray type="Float64" Name="z" format="binary" RangeMin="0" RangeMax="1"> <DataArray type="Float64" Name="z" format="binary" RangeMin="0" RangeMax="0.000004">
AQAAAACAAABIAAAAIgAAAA==eF5jYEAGB+wh9AUofQNKP4DST6D0Cyj9Bkp/sAcAAU8I6Q== AQAAAACAAAAoAAAAIwAAAA==eF5jYICA3rdbF3w/tsEOQh+wC3kiUFisdRLKv2AHAFVBE/w=
</DataArray> </DataArray>
</Coordinates> </Coordinates>
</Piece> </Piece>

View File

@ -1,23 +1,23 @@
<?xml version="1.0"?> <?xml version="1.0"?>
<VTKFile type="RectilinearGrid" version="0.1" byte_order="LittleEndian" header_type="UInt32" compressor="vtkZLibDataCompressor"> <VTKFile type="RectilinearGrid" version="0.1" byte_order="LittleEndian" header_type="UInt32" compressor="vtkZLibDataCompressor">
<RectilinearGrid WholeExtent="0 20 0 18 0 8"> <RectilinearGrid WholeExtent="0 8 0 5 0 4">
<Piece Extent="0 20 0 18 0 8"> <Piece Extent="0 8 0 5 0 4">
<PointData> <PointData>
</PointData> </PointData>
<CellData> <CellData>
<DataArray type="Int32" Name="materialpoint" format="binary" RangeMin="1" RangeMax="2"> <DataArray type="Int64" Name="materialpoint" format="binary" RangeMin="1" RangeMax="2">
AQAAAACAAAAALQAAOgAAAA==eF7t1CEOACAMBMHS/z8aXwNJSagYMe6y8jIislgNtTW9d9oD/PL6r6b3AAAAAAAAAAAA4MYGlRYLYA== AQAAAACAAAAABQAAIgAAAA==eF5jZIAAxlGaLJoJjSakntr6hzqN7v9RepSmJw0AC04A9Q==
</DataArray> </DataArray>
</CellData> </CellData>
<Coordinates> <Coordinates>
<DataArray type="Float64" Name="x" format="binary" RangeMin="0" RangeMax="1"> <DataArray type="Float64" Name="x" format="binary" RangeMin="0" RangeMax="0.000008">
AQAAAACAAACoAAAAVQAAAA==eF5jYICAWTNBYKU9hN5pb2IMAoeh/JP2EFUXoOKX7dPTQOAaVP6m/dkzIHAHqu4BVPwhVP1jqPwTqL5nUHUvoOpeQtW9hqp7A1X3Dqrugz0ASSZF3Q== AQAAAACAAABIAAAAOgAAAA==eF5jYICA3rdbF3w/tsEOQh+wC3kiUFisdRLKv2D3IeNxx9YfV6DiN+22x9tFGsbchco/sAMA/fQl6g==
</DataArray> </DataArray>
<DataArray type="Float64" Name="y" format="binary" RangeMin="0" RangeMax="1"> <DataArray type="Float64" Name="y" format="binary" RangeMin="0" RangeMax="0.000005">
AQAAAACAAACYAAAAVgAAAA==eF5jYIAAmeOFQLTGHkLvsQ8Fg6NQ/hn7IjDjIlT8qr1F32MgugGVv2MPMeUBVN1D+8cQBVD1T+3BymSeQ/W9sF8FBq+g+t/Yg4Ut3kHN+WAPAAVdQE4= AQAAAACAAAAwAAAAKwAAAA==eF5jYICAvrdbF3w/tsEOQh+wC30iUFisdRLKv2D3MeNxx9YfV+wAD5wZgw==
</DataArray> </DataArray>
<DataArray type="Float64" Name="z" format="binary" RangeMin="0" RangeMax="1"> <DataArray type="Float64" Name="z" format="binary" RangeMin="0" RangeMax="0.000004">
AQAAAACAAABIAAAAIgAAAA==eF5jYEAGB+wh9AUofQNKP4DST6D0Cyj9Bkp/sAcAAU8I6Q== AQAAAACAAAAoAAAAIwAAAA==eF5jYICA3rdbF3w/tsEOQh+wC3kiUFisdRLKv2AHAFVBE/w=
</DataArray> </DataArray>
</Coordinates> </Coordinates>
</Piece> </Piece>

View File

@ -1,23 +1,23 @@
<?xml version="1.0"?> <?xml version="1.0"?>
<VTKFile type="RectilinearGrid" version="0.1" byte_order="LittleEndian" header_type="UInt32" compressor="vtkZLibDataCompressor"> <VTKFile type="RectilinearGrid" version="0.1" byte_order="LittleEndian" header_type="UInt32" compressor="vtkZLibDataCompressor">
<RectilinearGrid WholeExtent="0 20 0 18 0 8"> <RectilinearGrid WholeExtent="0 8 0 5 0 4">
<Piece Extent="0 20 0 18 0 8"> <Piece Extent="0 8 0 5 0 4">
<PointData> <PointData>
</PointData> </PointData>
<CellData> <CellData>
<DataArray type="Int32" Name="materialpoint" format="binary" RangeMin="1" RangeMax="2"> <DataArray type="Int64" Name="materialpoint" format="binary" RangeMin="1" RangeMax="2">
AQAAAACAAAAALQAANwAAAA==eF7t1KERADAMA7Gk+w9dWpYCswiI+R66q6rDzmPa/kj3ALZK/2m6BwAAAAAAAAAAAJMLZrELTQ== AQAAAACAAAAABQAALwAAAA==eF5jZIAAxlGaLJoJjSakHpc+cvUTUkdrmlL3j9KU0dROF5TqH2iaVPcDAALOANU=
</DataArray> </DataArray>
</CellData> </CellData>
<Coordinates> <Coordinates>
<DataArray type="Float64" Name="x" format="binary" RangeMin="0" RangeMax="1"> <DataArray type="Float64" Name="x" format="binary" RangeMin="0" RangeMax="0.000008">
AQAAAACAAACoAAAAVQAAAA==eF5jYICAWTNBYKU9hN5pb2IMAoeh/JP2EFUXoOKX7dPTQOAaVP6m/dkzIHAHqu4BVPwhVP1jqPwTqL5nUHUvoOpeQtW9hqp7A1X3Dqrugz0ASSZF3Q== AQAAAACAAABIAAAAOgAAAA==eF5jYICA3rdbF3w/tsEOQh+wC3kiUFisdRLKv2D3IeNxx9YfV6DiN+22x9tFGsbchco/sAMA/fQl6g==
</DataArray> </DataArray>
<DataArray type="Float64" Name="y" format="binary" RangeMin="0" RangeMax="1"> <DataArray type="Float64" Name="y" format="binary" RangeMin="0" RangeMax="0.000005">
AQAAAACAAACYAAAAVgAAAA==eF5jYIAAmeOFQLTGHkLvsQ8Fg6NQ/hn7IjDjIlT8qr1F32MgugGVv2MPMeUBVN1D+8cQBVD1T+3BymSeQ/W9sF8FBq+g+t/Yg4Ut3kHN+WAPAAVdQE4= AQAAAACAAAAwAAAAKwAAAA==eF5jYICAvrdbF3w/tsEOQh+wC30iUFisdRLKv2D3MeNxx9YfV+wAD5wZgw==
</DataArray> </DataArray>
<DataArray type="Float64" Name="z" format="binary" RangeMin="0" RangeMax="1"> <DataArray type="Float64" Name="z" format="binary" RangeMin="0" RangeMax="0.000004">
AQAAAACAAABIAAAAIgAAAA==eF5jYEAGB+wh9AUofQNKP4DST6D0Cyj9Bkp/sAcAAU8I6Q== AQAAAACAAAAoAAAAIwAAAA==eF5jYICA3rdbF3w/tsEOQh+wC3kiUFisdRLKv2AHAFVBE/w=
</DataArray> </DataArray>
</Coordinates> </Coordinates>
</Piece> </Piece>

View File

@ -0,0 +1,25 @@
<?xml version="1.0"?>
<VTKFile type="RectilinearGrid" version="0.1" byte_order="LittleEndian" header_type="UInt32" compressor="vtkZLibDataCompressor">
<RectilinearGrid WholeExtent="0 8 0 5 0 4">
<Piece Extent="0 8 0 5 0 4">
<PointData>
</PointData>
<CellData>
<DataArray type="Int64" Name="materialpoint" format="binary" RangeMin="1" RangeMax="41">
AQAAAACAAAAABQAAcQAAAA==eF7t0rkOglAUBFAxKu6igvsKrv//gxYcm9fQGEPBNKe6yc1kolaZqPEndthljzH7HHDIEceccMoZE8654JIpM6645oZb7rjngUeeeOaFV+YseOOdDz754pthf+3Aqr7rdv9vw3+/NjssU7XDD0/8BuQ=
</DataArray>
</CellData>
<Coordinates>
<DataArray type="Float64" Name="x" format="binary" RangeMin="0" RangeMax="0.000008">
AQAAAACAAABIAAAAOgAAAA==eF5jYICA3rdbF3w/tsEOQh+wC3kiUFisdRLKv2D3IeNxx9YfV6DiN+22x9tFGsbchco/sAMA/fQl6g==
</DataArray>
<DataArray type="Float64" Name="y" format="binary" RangeMin="0" RangeMax="0.000005">
AQAAAACAAAAwAAAAKwAAAA==eF5jYICAvrdbF3w/tsEOQh+wC30iUFisdRLKv2D3MeNxx9YfV+wAD5wZgw==
</DataArray>
<DataArray type="Float64" Name="z" format="binary" RangeMin="0" RangeMax="0.000004">
AQAAAACAAAAoAAAAIwAAAA==eF5jYICA3rdbF3w/tsEOQh+wC3kiUFisdRLKv2AHAFVBE/w=
</DataArray>
</Coordinates>
</Piece>
</RectilinearGrid>
</VTKFile>

View File

@ -0,0 +1,25 @@
<?xml version="1.0"?>
<VTKFile type="RectilinearGrid" version="0.1" byte_order="LittleEndian" header_type="UInt32" compressor="vtkZLibDataCompressor">
<RectilinearGrid WholeExtent="0 8 0 5 0 4">
<Piece Extent="0 8 0 5 0 4">
<PointData>
</PointData>
<CellData>
<DataArray type="Int64" Name="materialpoint" format="binary" RangeMin="1" RangeMax="41">
AQAAAACAAAAABQAAYQAAAA==eF7t0scVglAAAEHgqZgBA2ZExdR/gx6YCpDj38s0sEnUlgR7ccAhR0w55oRTzjjngktmzFlwxTU33LLkjnseeOSJZ15Y8cqaN975YMMnX3zzwy/j4F+GD9u6fvgD+gwHCA==
</DataArray>
</CellData>
<Coordinates>
<DataArray type="Float64" Name="x" format="binary" RangeMin="0" RangeMax="0.000008">
AQAAAACAAABIAAAAOgAAAA==eF5jYICA3rdbF3w/tsEOQh+wC3kiUFisdRLKv2D3IeNxx9YfV6DiN+22x9tFGsbchco/sAMA/fQl6g==
</DataArray>
<DataArray type="Float64" Name="y" format="binary" RangeMin="0" RangeMax="0.000005">
AQAAAACAAAAwAAAAKwAAAA==eF5jYICAvrdbF3w/tsEOQh+wC30iUFisdRLKv2D3MeNxx9YfV+wAD5wZgw==
</DataArray>
<DataArray type="Float64" Name="z" format="binary" RangeMin="0" RangeMax="0.000004">
AQAAAACAAAAoAAAAIwAAAA==eF5jYICA3rdbF3w/tsEOQh+wC3kiUFisdRLKv2AHAFVBE/w=
</DataArray>
</Coordinates>
</Piece>
</RectilinearGrid>
</VTKFile>

View File

@ -1,23 +1,23 @@
<?xml version="1.0"?> <?xml version="1.0"?>
<VTKFile type="RectilinearGrid" version="0.1" byte_order="LittleEndian" header_type="UInt32" compressor="vtkZLibDataCompressor"> <VTKFile type="RectilinearGrid" version="0.1" byte_order="LittleEndian" header_type="UInt32" compressor="vtkZLibDataCompressor">
<RectilinearGrid WholeExtent="0 20 0 18 0 8"> <RectilinearGrid WholeExtent="0 8 0 5 0 4">
<Piece Extent="0 20 0 18 0 8"> <Piece Extent="0 8 0 5 0 4">
<PointData> <PointData>
</PointData> </PointData>
<CellData> <CellData>
<DataArray type="Int32" Name="materialpoint" format="binary" RangeMin="1" RangeMax="2"> <DataArray type="Int64" Name="materialpoint" format="binary" RangeMin="1" RangeMax="41">
AQAAAACAAAAALQAANQAAAA==eF7t1CECACAMxLBj/380fhYwIyK2spWkmnWgt6b3AF65/avfegAAAAAAAAAAAMy0AfYtC2k= AQAAAACAAAAABQAAZAAAAA==eF7t0scRglAAQEEBAyZUMCuomPtv0ANbgMNw/O+yDbyo1xQFWxkzYZ8DDjliyjEnnHLGOTMuuOSKOQuuueGWO+554JEnnlmy4oVX3ljzzgeffPHND7+Mg50aPmz698MfmvQHCg==
</DataArray> </DataArray>
</CellData> </CellData>
<Coordinates> <Coordinates>
<DataArray type="Float64" Name="x" format="binary" RangeMin="0" RangeMax="1"> <DataArray type="Float64" Name="x" format="binary" RangeMin="0" RangeMax="0.000008">
AQAAAACAAACoAAAAVQAAAA==eF5jYICAWTNBYKU9hN5pb2IMAoeh/JP2EFUXoOKX7dPTQOAaVP6m/dkzIHAHqu4BVPwhVP1jqPwTqL5nUHUvoOpeQtW9hqp7A1X3Dqrugz0ASSZF3Q== AQAAAACAAABIAAAAOgAAAA==eF5jYICA3rdbF3w/tsEOQh+wC3kiUFisdRLKv2D3IeNxx9YfV6DiN+22x9tFGsbchco/sAMA/fQl6g==
</DataArray> </DataArray>
<DataArray type="Float64" Name="y" format="binary" RangeMin="0" RangeMax="1"> <DataArray type="Float64" Name="y" format="binary" RangeMin="0" RangeMax="0.000005">
AQAAAACAAACYAAAAVgAAAA==eF5jYIAAmeOFQLTGHkLvsQ8Fg6NQ/hn7IjDjIlT8qr1F32MgugGVv2MPMeUBVN1D+8cQBVD1T+3BymSeQ/W9sF8FBq+g+t/Yg4Ut3kHN+WAPAAVdQE4= AQAAAACAAAAwAAAAKwAAAA==eF5jYICAvrdbF3w/tsEOQh+wC30iUFisdRLKv2D3MeNxx9YfV+wAD5wZgw==
</DataArray> </DataArray>
<DataArray type="Float64" Name="z" format="binary" RangeMin="0" RangeMax="1"> <DataArray type="Float64" Name="z" format="binary" RangeMin="0" RangeMax="0.000004">
AQAAAACAAABIAAAAIgAAAA==eF5jYEAGB+wh9AUofQNKP4DST6D0Cyj9Bkp/sAcAAU8I6Q== AQAAAACAAAAoAAAAIwAAAA==eF5jYICA3rdbF3w/tsEOQh+wC3kiUFisdRLKv2AHAFVBE/w=
</DataArray> </DataArray>
</Coordinates> </Coordinates>
</Piece> </Piece>

View File

@ -1,23 +1,23 @@
<?xml version="1.0"?> <?xml version="1.0"?>
<VTKFile type="RectilinearGrid" version="0.1" byte_order="LittleEndian" header_type="UInt32" compressor="vtkZLibDataCompressor"> <VTKFile type="RectilinearGrid" version="0.1" byte_order="LittleEndian" header_type="UInt32" compressor="vtkZLibDataCompressor">
<RectilinearGrid WholeExtent="0 20 0 18 0 8"> <RectilinearGrid WholeExtent="0 8 0 5 0 4">
<Piece Extent="0 20 0 18 0 8"> <Piece Extent="0 8 0 5 0 4">
<PointData> <PointData>
</PointData> </PointData>
<CellData> <CellData>
<DataArray type="Int32" Name="materialpoint" format="binary" RangeMin="1" RangeMax="2"> <DataArray type="Int64" Name="materialpoint" format="binary" RangeMin="2" RangeMax="41">
AQAAAACAAAAALQAANQAAAA==eF7t1CECACAMxLBj/380fhYwIyK2spWkmnWgt6b3AF65/avfegAAAAAAAAAAAMy0AfYtC2k= AQAAAACAAAAABQAAZAAAAA==eF7t0rcSglAARFEHE0bAgBkE8///oAWnF8b2bXP6nRv1mkXBv+xzwCFHHDPmhFPOOOeCSyZMmXHFNTfcMueOex545IlnXliw5JUVa95454NPvvjmh79+DXYzdNisbYdfSqMHMg==
</DataArray> </DataArray>
</CellData> </CellData>
<Coordinates> <Coordinates>
<DataArray type="Float64" Name="x" format="binary" RangeMin="0" RangeMax="1"> <DataArray type="Float64" Name="x" format="binary" RangeMin="0" RangeMax="0.000008">
AQAAAACAAACoAAAAVQAAAA==eF5jYICAWTNBYKU9hN5pb2IMAoeh/JP2EFUXoOKX7dPTQOAaVP6m/dkzIHAHqu4BVPwhVP1jqPwTqL5nUHUvoOpeQtW9hqp7A1X3Dqrugz0ASSZF3Q== AQAAAACAAABIAAAAOgAAAA==eF5jYICA3rdbF3w/tsEOQh+wC3kiUFisdRLKv2D3IeNxx9YfV6DiN+22x9tFGsbchco/sAMA/fQl6g==
</DataArray> </DataArray>
<DataArray type="Float64" Name="y" format="binary" RangeMin="0" RangeMax="1"> <DataArray type="Float64" Name="y" format="binary" RangeMin="0" RangeMax="0.000005">
AQAAAACAAACYAAAAVgAAAA==eF5jYIAAmeOFQLTGHkLvsQ8Fg6NQ/hn7IjDjIlT8qr1F32MgugGVv2MPMeUBVN1D+8cQBVD1T+3BymSeQ/W9sF8FBq+g+t/Yg4Ut3kHN+WAPAAVdQE4= AQAAAACAAAAwAAAAKwAAAA==eF5jYICAvrdbF3w/tsEOQh+wC30iUFisdRLKv2D3MeNxx9YfV+wAD5wZgw==
</DataArray> </DataArray>
<DataArray type="Float64" Name="z" format="binary" RangeMin="0" RangeMax="1"> <DataArray type="Float64" Name="z" format="binary" RangeMin="0" RangeMax="0.000004">
AQAAAACAAABIAAAAIgAAAA==eF5jYEAGB+wh9AUofQNKP4DST6D0Cyj9Bkp/sAcAAU8I6Q== AQAAAACAAAAoAAAAIwAAAA==eF5jYICA3rdbF3w/tsEOQh+wC3kiUFisdRLKv2AHAFVBE/w=
</DataArray> </DataArray>
</Coordinates> </Coordinates>
</Piece> </Piece>

View File

@ -1,23 +1,23 @@
<?xml version="1.0"?> <?xml version="1.0"?>
<VTKFile type="RectilinearGrid" version="0.1" byte_order="LittleEndian" header_type="UInt32" compressor="vtkZLibDataCompressor"> <VTKFile type="RectilinearGrid" version="0.1" byte_order="LittleEndian" header_type="UInt32" compressor="vtkZLibDataCompressor">
<RectilinearGrid WholeExtent="0 20 0 18 0 8"> <RectilinearGrid WholeExtent="0 8 0 5 0 4">
<Piece Extent="0 20 0 18 0 8"> <Piece Extent="0 8 0 5 0 4">
<PointData> <PointData>
</PointData> </PointData>
<CellData> <CellData>
<DataArray type="Int32" Name="materialpoint" format="binary" RangeMin="1" RangeMax="2"> <DataArray type="Int64" Name="materialpoint" format="binary" RangeMin="1" RangeMax="2">
AQAAAACAAAAALQAAOQAAAA==eF7t1CESACAMA8HS/z8aX4OgCGDFuszJZERkMTbU1us9gFO6/+q23moPAAAAAAAAAADAnybPzQto AQAAAACAAAAABQAAIAAAAA==eF5jZIAAxlF6lB4AmokAPdj1DzRNyP2jNH4aAMufANU=
</DataArray> </DataArray>
</CellData> </CellData>
<Coordinates> <Coordinates>
<DataArray type="Float64" Name="x" format="binary" RangeMin="0" RangeMax="1"> <DataArray type="Float64" Name="x" format="binary" RangeMin="0" RangeMax="0.000008">
AQAAAACAAACoAAAAVQAAAA==eF5jYICAWTNBYKU9hN5pb2IMAoeh/JP2EFUXoOKX7dPTQOAaVP6m/dkzIHAHqu4BVPwhVP1jqPwTqL5nUHUvoOpeQtW9hqp7A1X3Dqrugz0ASSZF3Q== AQAAAACAAABIAAAAOgAAAA==eF5jYICA3rdbF3w/tsEOQh+wC3kiUFisdRLKv2D3IeNxx9YfV6DiN+22x9tFGsbchco/sAMA/fQl6g==
</DataArray> </DataArray>
<DataArray type="Float64" Name="y" format="binary" RangeMin="0" RangeMax="1"> <DataArray type="Float64" Name="y" format="binary" RangeMin="0" RangeMax="0.000005">
AQAAAACAAACYAAAAVgAAAA==eF5jYIAAmeOFQLTGHkLvsQ8Fg6NQ/hn7IjDjIlT8qr1F32MgugGVv2MPMeUBVN1D+8cQBVD1T+3BymSeQ/W9sF8FBq+g+t/Yg4Ut3kHN+WAPAAVdQE4= AQAAAACAAAAwAAAAKwAAAA==eF5jYICAvrdbF3w/tsEOQh+wC30iUFisdRLKv2D3MeNxx9YfV+wAD5wZgw==
</DataArray> </DataArray>
<DataArray type="Float64" Name="z" format="binary" RangeMin="0" RangeMax="1"> <DataArray type="Float64" Name="z" format="binary" RangeMin="0" RangeMax="0.000004">
AQAAAACAAABIAAAAIgAAAA==eF5jYEAGB+wh9AUofQNKP4DST6D0Cyj9Bkp/sAcAAU8I6Q== AQAAAACAAAAoAAAAIwAAAA==eF5jYICA3rdbF3w/tsEOQh+wC3kiUFisdRLKv2AHAFVBE/w=
</DataArray> </DataArray>
</Coordinates> </Coordinates>
</Piece> </Piece>

View File

@ -1,23 +1,23 @@
<?xml version="1.0"?> <?xml version="1.0"?>
<VTKFile type="RectilinearGrid" version="0.1" byte_order="LittleEndian" header_type="UInt32" compressor="vtkZLibDataCompressor"> <VTKFile type="RectilinearGrid" version="0.1" byte_order="LittleEndian" header_type="UInt32" compressor="vtkZLibDataCompressor">
<RectilinearGrid WholeExtent="0 20 0 18 0 8"> <RectilinearGrid WholeExtent="0 8 0 5 0 4">
<Piece Extent="0 20 0 18 0 8"> <Piece Extent="0 8 0 5 0 4">
<PointData> <PointData>
</PointData> </PointData>
<CellData> <CellData>
<DataArray type="Int32" Name="materialpoint" format="binary" RangeMin="1" RangeMax="1"> <DataArray type="Int64" Name="materialpoint" format="binary" RangeMin="1" RangeMax="2">
AQAAAACAAAAALQAAJAAAAA==eF7twwEJAAAMBKH7/qWXY6DgqqmqqqqqqqqqqqqqPnhyUwtB AQAAAACAAAAABQAAMAAAAA==eF5jYoAAJhw0IwEalz566aeUptT+oa6fUppS+4e6fkppSu0f6voppSm1HwBAngDh
</DataArray> </DataArray>
</CellData> </CellData>
<Coordinates> <Coordinates>
<DataArray type="Float64" Name="x" format="binary" RangeMin="0" RangeMax="1"> <DataArray type="Float64" Name="x" format="binary" RangeMin="0" RangeMax="0.000008">
AQAAAACAAACoAAAAVQAAAA==eF5jYICAWTNBYKU9hN5pb2IMAoeh/JP2EFUXoOKX7dPTQOAaVP6m/dkzIHAHqu4BVPwhVP1jqPwTqL5nUHUvoOpeQtW9hqp7A1X3Dqrugz0ASSZF3Q== AQAAAACAAABIAAAAOgAAAA==eF5jYICA3rdbF3w/tsEOQh+wC3kiUFisdRLKv2D3IeNxx9YfV6DiN+22x9tFGsbchco/sAMA/fQl6g==
</DataArray> </DataArray>
<DataArray type="Float64" Name="y" format="binary" RangeMin="0" RangeMax="1"> <DataArray type="Float64" Name="y" format="binary" RangeMin="0" RangeMax="0.000005">
AQAAAACAAACYAAAAVgAAAA==eF5jYIAAmeOFQLTGHkLvsQ8Fg6NQ/hn7IjDjIlT8qr1F32MgugGVv2MPMeUBVN1D+8cQBVD1T+3BymSeQ/W9sF8FBq+g+t/Yg4Ut3kHN+WAPAAVdQE4= AQAAAACAAAAwAAAAKwAAAA==eF5jYICAvrdbF3w/tsEOQh+wC30iUFisdRLKv2D3MeNxx9YfV+wAD5wZgw==
</DataArray> </DataArray>
<DataArray type="Float64" Name="z" format="binary" RangeMin="0" RangeMax="1"> <DataArray type="Float64" Name="z" format="binary" RangeMin="0" RangeMax="0.000004">
AQAAAACAAABIAAAAIgAAAA==eF5jYEAGB+wh9AUofQNKP4DST6D0Cyj9Bkp/sAcAAU8I6Q== AQAAAACAAAAoAAAAIwAAAA==eF5jYICA3rdbF3w/tsEOQh+wC3kiUFisdRLKv2AHAFVBE/w=
</DataArray> </DataArray>
</Coordinates> </Coordinates>
</Piece> </Piece>

View File

@ -0,0 +1,25 @@
4 header
grid a 8 b 5 c 4
size x 8e-06 y 5e-06 z 4e-06
origin x 0.0 y 0.0 z 0.0
homogenization 1
40 39 38 37 36 35 34 33
32 31 30 29 28 27 26 25
24 23 22 21 20 19 18 17
16 15 14 13 12 11 10 9
8 7 6 5 4 3 2 1
2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2
41 40 39 38 37 36 35 34
33 32 31 30 29 28 27 26
25 24 23 22 21 20 19 18
17 16 15 14 13 12 11 10
9 8 7 6 5 4 3 2
1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1

View File

@ -0,0 +1,25 @@
4 header
grid a 8 b 5 c 4
size x 8e-06 y 5e-06 z 4e-06
origin x 0.0 y 0.0 z 0.0
homogenization 1
1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1
9 8 7 6 5 4 3 2
17 16 15 14 13 12 11 10
25 24 23 22 21 20 19 18
33 32 31 30 29 28 27 26
41 40 39 38 37 36 35 34
2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2
8 7 6 5 4 3 2 1
16 15 14 13 12 11 10 9
24 23 22 21 20 19 18 17
32 31 30 29 28 27 26 25
40 39 38 37 36 35 34 33

View File

@ -0,0 +1,25 @@
4 header
grid a 8 b 5 c 4
size x 8e-06 y 5e-06 z 4e-06
origin x 0.0 y 0.0 z 0.0
homogenization 1
33 34 35 36 37 38 39 40
25 26 27 28 29 30 31 32
17 18 19 20 21 22 23 24
9 10 11 12 13 14 15 16
1 2 3 4 5 6 7 8
2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2
34 35 36 37 38 39 40 41
26 27 28 29 30 31 32 33
18 19 20 21 22 23 24 25
10 11 12 13 14 15 16 17
2 3 4 5 6 7 8 9
1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1

View File

@ -0,0 +1,25 @@
4 header
grid a 8 b 5 c 4
size x 8e-06 y 5e-06 z 4e-06
origin x 0.0 y 0.0 z 0.0
homogenization 1
40 39 38 37 36 35 34 33
32 31 30 29 28 27 26 25
24 23 22 21 20 19 18 17
16 15 14 13 12 11 10 9
8 7 6 5 4 3 2 1
2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2
41 40 39 38 37 36 35 34
33 32 31 30 29 28 27 26
25 24 23 22 21 20 19 18
17 16 15 14 13 12 11 10
9 8 7 6 5 4 3 2
1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1

View File

@ -17,8 +17,8 @@ def reference_dir(reference_dir_base):
class TestColormap: class TestColormap:
@pytest.fixture(autouse=True) @pytest.fixture(autouse=True)
def _version_date(self, version_date): def _execution_stamp(self, execution_stamp):
print('patched damask.util.version_date') print('patched damask.util.execution_stamp')
def test_conversion(self): def test_conversion(self):
specials = np.array([[0.,0.,0.], specials = np.array([[0.,0.,0.],

View File

@ -13,7 +13,8 @@ from damask import util
def geom_equal(a,b): def geom_equal(a,b):
return np.all(a.get_microstructure() == b.get_microstructure()) and \ return np.all(a.get_microstructure() == b.get_microstructure()) and \
np.all(a.get_grid() == b.get_grid()) and \ np.all(a.get_grid() == b.get_grid()) and \
np.allclose(a.get_size(), b.get_size()) np.allclose(a.get_size(), b.get_size()) and \
str(a.diff(b)) == str(b.diff(a))
@pytest.fixture @pytest.fixture
def default(): def default():
@ -32,15 +33,26 @@ def reference_dir(reference_dir_base):
class TestGeom: class TestGeom:
def test_update(self,default): @pytest.mark.parametrize('flavor',['plain','explicit'])
modified = default.copy() def test_duplicate(self,default,flavor):
modified.update( if flavor == 'plain':
modified = default.duplicate()
elif flavor == 'explicit':
modified = default.duplicate(
default.get_microstructure(), default.get_microstructure(),
default.get_size(), default.get_size(),
default.get_origin() default.get_origin()
) )
print(modified) print(modified)
assert geom_equal(modified,default) assert geom_equal(default,modified)
def test_diff_equal(self,default):
assert str(default.diff(default)) == ''
def test_diff_not_equal(self,default):
new = Geom(default.microstructure[1:,1:,1:]+1,default.size*.9,np.ones(3)-default.origin,comments=['modified'])
assert str(default.diff(new)) != ''
@pytest.mark.parametrize('masked',[True,False]) @pytest.mark.parametrize('masked',[True,False])
def test_set_microstructure(self,default,masked): def test_set_microstructure(self,default,masked):
@ -53,24 +65,25 @@ class TestGeom:
def test_write_read_str(self,default,tmpdir): def test_write_read_str(self,default,tmpdir):
default.to_file(str(tmpdir/'default.geom')) default.to_file(str(tmpdir/'default.geom'))
new = Geom.from_file(str(tmpdir/'default.geom')) new = Geom.from_file(str(tmpdir/'default.geom'))
assert geom_equal(new,default) assert geom_equal(default,new)
def test_write_read_file(self,default,tmpdir): def test_write_read_file(self,default,tmpdir):
with open(tmpdir/'default.geom','w') as f: with open(tmpdir/'default.geom','w') as f:
default.to_file(f) default.to_file(f,pack=True)
with open(tmpdir/'default.geom') as f: with open(tmpdir/'default.geom') as f:
new = Geom.from_file(f) new = Geom.from_file(f)
assert geom_equal(new,default) assert geom_equal(default,new)
def test_write_show(self,default,tmpdir): def test_write_as_ASCII(self,default,tmpdir):
with open(tmpdir/'str.geom','w') as f: with open(tmpdir/'str.geom','w') as f:
f.write(default.show()) f.write(default.as_ASCII())
with open(tmpdir/'str.geom') as f: with open(tmpdir/'str.geom') as f:
new = Geom.from_file(f) new = Geom.from_file(f)
assert geom_equal(new,default) assert geom_equal(default,new)
def test_read_write_vtr(self,default,tmpdir): def test_read_write_vtr(self,default,tmpdir):
default.to_vtr(tmpdir/'default') default.to_vtr(tmpdir/'default')
print(default.to_vtr())
for _ in range(10): for _ in range(10):
time.sleep(.2) time.sleep(.2)
if os.path.exists(tmpdir/'default.vtr'): break if os.path.exists(tmpdir/'default.vtr'): break
@ -78,6 +91,13 @@ class TestGeom:
new = Geom.from_vtr(tmpdir/'default.vtr') new = Geom.from_vtr(tmpdir/'default.vtr')
assert geom_equal(new,default) assert geom_equal(new,default)
def test_invalid_geom(self,tmpdir):
with open('invalid_file','w') as f:
f.write('this is not a valid header')
with open('invalid_file','r') as f:
with pytest.raises(TypeError):
Geom.from_file(f)
def test_invalid_vtr(self,tmpdir): def test_invalid_vtr(self,tmpdir):
v = VTK.from_rectilinearGrid(np.random.randint(5,10,3)*2,np.random.random(3) + 1.0) v = VTK.from_rectilinearGrid(np.random.randint(5,10,3)*2,np.random.random(3) + 1.0)
v.to_file(tmpdir/'no_materialpoint.vtr') v.to_file(tmpdir/'no_materialpoint.vtr')
@ -96,25 +116,25 @@ class TestGeom:
def test_invalid_combination(self,default): def test_invalid_combination(self,default):
with pytest.raises(ValueError): with pytest.raises(ValueError):
default.update(default.microstructure[1:,1:,1:],size=np.ones(3), rescale=True) default.duplicate(default.microstructure[1:,1:,1:],size=np.ones(3), autosize=True)
def test_invalid_size(self,default): def test_invalid_size(self,default):
with pytest.raises(ValueError): with pytest.raises(ValueError):
default.update(default.microstructure[1:,1:,1:],size=np.ones(2)) default.duplicate(default.microstructure[1:,1:,1:],size=np.ones(2))
def test_invalid_origin(self,default): def test_invalid_origin(self,default):
with pytest.raises(ValueError): with pytest.raises(ValueError):
default.update(default.microstructure[1:,1:,1:],origin=np.ones(4)) default.duplicate(default.microstructure[1:,1:,1:],origin=np.ones(4))
def test_invalid_microstructure_size(self,default): def test_invalid_microstructure_size(self,default):
microstructure = np.ones((3,3)) microstructure = np.ones((3,3))
with pytest.raises(ValueError): with pytest.raises(ValueError):
default.update(microstructure) default.duplicate(microstructure)
def test_invalid_microstructure_type(self,default): def test_invalid_microstructure_type(self,default):
microstructure = np.random.randint(1,300,(3,4,5))==1 microstructure = np.random.randint(1,300,(3,4,5))==1
with pytest.raises(TypeError): with pytest.raises(TypeError):
default.update(microstructure) default.duplicate(microstructure)
def test_invalid_homogenization(self,default): def test_invalid_homogenization(self,default):
with pytest.raises(TypeError): with pytest.raises(TypeError):
@ -128,31 +148,61 @@ class TestGeom:
] ]
) )
def test_mirror(self,default,update,reference_dir,directions,reflect): def test_mirror(self,default,update,reference_dir,directions,reflect):
modified = default.copy() modified = default.mirror(directions,reflect)
modified.mirror(directions,reflect)
tag = f'directions={"-".join(directions)}_reflect={reflect}' tag = f'directions={"-".join(directions)}_reflect={reflect}'
reference = reference_dir/f'mirror_{tag}.geom' reference = reference_dir/f'mirror_{tag}.geom'
if update: modified.to_file(reference) if update: modified.to_file(reference)
assert geom_equal(modified,Geom.from_file(reference)) assert geom_equal(Geom.from_file(reference),
modified)
@pytest.mark.parametrize('directions',[(1,2,'y'),('a','b','x'),[1]]) @pytest.mark.parametrize('directions',[(1,2,'y'),('a','b','x'),[1]])
def test_mirror_invalid(self,default,directions): def test_mirror_invalid(self,default,directions):
with pytest.raises(ValueError): with pytest.raises(ValueError):
default.mirror(directions) default.mirror(directions)
@pytest.mark.parametrize('directions',[
['x'],
['x','y','z'],
['z','x','y'],
['y','z'],
]
)
def test_flip(self,default,update,reference_dir,directions):
modified = default.flip(directions)
tag = f'directions={"-".join(directions)}'
reference = reference_dir/f'flip_{tag}.geom'
if update: modified.to_file(reference)
assert geom_equal(Geom.from_file(reference),
modified)
def test_flip_invariant(self,default):
assert geom_equal(default,default.flip([]))
@pytest.mark.parametrize('direction',[['x'],['x','y']])
def test_flip_double(self,default,direction):
assert geom_equal(default,default.flip(direction).flip(direction))
@pytest.mark.parametrize('directions',[(1,2,'y'),('a','b','x'),[1]])
def test_flip_invalid(self,default,directions):
with pytest.raises(ValueError):
default.flip(directions)
@pytest.mark.parametrize('stencil',[1,2,3,4]) @pytest.mark.parametrize('stencil',[1,2,3,4])
@pytest.mark.parametrize('selection',[None,1,2]) @pytest.mark.parametrize('selection',[None,[1],[1,2,3]])
@pytest.mark.parametrize('periodic',[True,False]) @pytest.mark.parametrize('periodic',[True,False])
def test_clean(self,update,reference_dir,stencil,selection,periodic): def test_clean(self,default,update,reference_dir,stencil,selection,periodic):
current = Geom.from_vtr((reference_dir/'clean').with_suffix('.vtr')) current = default.clean(stencil,selection,periodic)
current.clean(stencil,None if selection is None else [selection],periodic) reference = reference_dir/f'clean_{stencil}_{"+".join(map(str,[None] if selection is None else selection))}_{periodic}'
reference = reference_dir/f'clean_{stencil}_{selection}_{periodic}' if update and stencil > 1:
if update and stencil !=1:
current.to_vtr(reference) current.to_vtr(reference)
for _ in range(10): for _ in range(10):
time.sleep(.2) time.sleep(.2)
if os.path.exists(reference.with_suffix('.vtr')): break if os.path.exists(reference.with_suffix('.vtr')): break
assert geom_equal(current,Geom.from_vtr(reference if stencil !=1 else reference_dir/'clean')) assert geom_equal(Geom.from_vtr(reference) if stencil > 1 else default,
current
)
@pytest.mark.parametrize('grid',[ @pytest.mark.parametrize('grid',[
(10,11,10), (10,11,10),
@ -164,33 +214,29 @@ class TestGeom:
] ]
) )
def test_scale(self,default,update,reference_dir,grid): def test_scale(self,default,update,reference_dir,grid):
modified = default.copy() modified = default.scale(grid)
modified.scale(grid)
tag = f'grid={util.srepr(grid,"-")}' tag = f'grid={util.srepr(grid,"-")}'
reference = reference_dir/f'scale_{tag}.geom' reference = reference_dir/f'scale_{tag}.geom'
if update: modified.to_file(reference) if update: modified.to_file(reference)
assert geom_equal(modified,Geom.from_file(reference)) assert geom_equal(Geom.from_file(reference),
modified)
def test_renumber(self,default): def test_renumber(self,default):
modified = default.copy() microstructure = default.get_microstructure()
microstructure = modified.get_microstructure()
for m in np.unique(microstructure): for m in np.unique(microstructure):
microstructure[microstructure==m] = microstructure.max() + np.random.randint(1,30) microstructure[microstructure==m] = microstructure.max() + np.random.randint(1,30)
modified.update(microstructure) modified = default.duplicate(microstructure)
assert not geom_equal(modified,default) assert not geom_equal(modified,default)
modified.renumber() assert geom_equal(default,
assert geom_equal(modified,default) modified.renumber())
def test_substitute(self,default): def test_substitute(self,default):
modified = default.copy()
microstructure = modified.get_microstructure()
offset = np.random.randint(1,500) offset = np.random.randint(1,500)
microstructure += offset modified = default.duplicate(default.get_microstructure() + offset)
modified.update(microstructure)
assert not geom_equal(modified,default) assert not geom_equal(modified,default)
assert geom_equal(default,
modified.substitute(np.arange(default.microstructure.max())+1+offset, modified.substitute(np.arange(default.microstructure.max())+1+offset,
np.arange(default.microstructure.max())+1) np.arange(default.microstructure.max())+1))
assert geom_equal(modified,default)
@pytest.mark.parametrize('axis_angle',[np.array([1,0,0,86.7]), np.array([0,1,0,90.4]), np.array([0,0,1,90]), @pytest.mark.parametrize('axis_angle',[np.array([1,0,0,86.7]), np.array([0,1,0,90.4]), np.array([0,0,1,90]),
np.array([1,0,0,175]),np.array([0,-1,0,178]),np.array([0,0,1,180])]) np.array([1,0,0,175]),np.array([0,-1,0,178]),np.array([0,0,1,180])])
@ -198,40 +244,58 @@ class TestGeom:
modified = default.copy() modified = default.copy()
for i in range(np.rint(360/axis_angle[3]).astype(int)): for i in range(np.rint(360/axis_angle[3]).astype(int)):
modified.rotate(Rotation.from_axis_angle(axis_angle,degrees=True)) modified.rotate(Rotation.from_axis_angle(axis_angle,degrees=True))
assert geom_equal(modified,default) assert geom_equal(default,modified)
@pytest.mark.parametrize('Eulers',[[32.0,68.0,21.0], @pytest.mark.parametrize('Eulers',[[32.0,68.0,21.0],
[0.0,32.0,240.0]]) [0.0,32.0,240.0]])
def test_rotate(self,default,update,reference_dir,Eulers): def test_rotate(self,default,update,reference_dir,Eulers):
modified = default.copy() modified = default.rotate(Rotation.from_Eulers(Eulers,degrees=True))
modified.rotate(Rotation.from_Eulers(Eulers,degrees=True))
tag = f'Eulers={util.srepr(Eulers,"-")}' tag = f'Eulers={util.srepr(Eulers,"-")}'
reference = reference_dir/f'rotate_{tag}.geom' reference = reference_dir/f'rotate_{tag}.geom'
if update: modified.to_file(reference) if update: modified.to_file(reference)
assert geom_equal(modified,Geom.from_file(reference)) assert geom_equal(Geom.from_file(reference),
modified)
def test_canvas(self,default): def test_canvas(self,default):
grid = default.grid
grid_add = np.random.randint(0,30,(3)) grid_add = np.random.randint(0,30,(3))
modified = default.copy() modified = default.canvas(grid + grid_add)
modified.canvas(modified.grid + grid_add) assert np.all(modified.microstructure[:grid[0],:grid[1],:grid[2]] == default.microstructure)
e = default.grid
assert np.all(modified.microstructure[:e[0],:e[1],:e[2]] == default.microstructure)
@pytest.mark.parametrize('center1,center2',[(np.random.random(3)*.5,np.random.random(3)), @pytest.mark.parametrize('center1,center2',[(np.random.random(3)*.5,np.random.random()*8),
(np.random.randint(4,8,(3)),np.random.randint(9,12,(3)))]) (np.random.randint(4,8,(3)),np.random.randint(9,12,(3)))])
@pytest.mark.parametrize('diameter',[np.random.random(3)*.5, @pytest.mark.parametrize('diameter',[np.random.random(3)*.5,
np.random.randint(4,10,(3))]) np.random.randint(4,10,(3)),
def test_add_primitive(self,diameter,center1,center2): np.random.rand(),
np.random.randint(30)])
@pytest.mark.parametrize('exponent',[np.random.random(3)*.5,
np.random.randint(4,10,(3)),
np.random.rand()*4,
np.random.randint(20)])
def test_add_primitive_shift(self,center1,center2,diameter,exponent):
"""Same volume fraction for periodic microstructures and different center.""" """Same volume fraction for periodic microstructures and different center."""
o = np.random.random(3)-.5 o = np.random.random(3)-.5
g = np.random.randint(8,32,(3)) g = np.random.randint(8,32,(3))
s = np.random.random(3)+.5 s = np.random.random(3)+.5
G_1 = Geom(np.ones(g,'i'),s,o) G_1 = Geom(np.ones(g,'i'),s,o).add_primitive(diameter,center1,exponent)
G_2 = Geom(np.ones(g,'i'),s,o) G_2 = Geom(np.ones(g,'i'),s,o).add_primitive(diameter,center2,exponent)
G_1.add_primitive(diameter,center1,1)
G_2.add_primitive(diameter,center2,1)
assert np.count_nonzero(G_1.microstructure!=2) == np.count_nonzero(G_2.microstructure!=2) assert np.count_nonzero(G_1.microstructure!=2) == np.count_nonzero(G_2.microstructure!=2)
@pytest.mark.parametrize('center',[np.random.randint(4,10,(3)),
np.random.randint(2,10),
np.random.rand()*4,
np.random.rand(3)*10])
@pytest.mark.parametrize('inverse',[True,False])
@pytest.mark.parametrize('periodic',[True,False])
def test_add_primitive_rotation(self,center,inverse,periodic):
"""Rotation should not change result for sphere (except for discretization errors)."""
g = np.array([32,32,32])
fill = np.random.randint(10)+2
eu=np.array([np.random.randint(4),np.random.randint(2),np.random.randint(4)])*.5*np.pi
G_1 = Geom(np.ones(g,'i'),[1.,1.,1.]).add_primitive(.3,center,1,fill,inverse=inverse,periodic=periodic)
G_2 = Geom(np.ones(g,'i'),[1.,1.,1.]).add_primitive(.3,center,1,fill,Rotation.from_Eulers(eu),inverse,periodic=periodic)
assert geom_equal(G_1,G_2)
@pytest.mark.parametrize('trigger',[[1],[]]) @pytest.mark.parametrize('trigger',[[1],[]])
def test_vicinity_offset(self,trigger): def test_vicinity_offset(self,trigger):
offset = np.random.randint(2,4) offset = np.random.randint(2,4)
@ -248,8 +312,7 @@ class TestGeom:
if len(trigger) > 0: if len(trigger) > 0:
m2[m==1] = 1 m2[m==1] = 1
geom = Geom(m,np.random.rand(3)) geom = Geom(m,np.random.rand(3)).vicinity_offset(vicinity,offset,trigger=trigger)
geom.vicinity_offset(vicinity,offset,trigger=trigger)
assert np.all(m2==geom.microstructure) assert np.all(m2==geom.microstructure)

View File

@ -13,8 +13,19 @@ def reference_dir(reference_dir_base):
"""Directory containing reference results.""" """Directory containing reference results."""
return reference_dir_base/'VTK' return reference_dir_base/'VTK'
@pytest.fixture
def default():
"""Simple VTK."""
grid = np.array([5,6,7],int)
size = np.array([.6,1.,.5])
return VTK.from_rectilinearGrid(grid,size)
class TestVTK: class TestVTK:
@pytest.fixture(autouse=True)
def _execution_stamp(self, execution_stamp):
print('patched damask.util.execution_stamp')
def test_rectilinearGrid(self,tmp_path): def test_rectilinearGrid(self,tmp_path):
grid = np.random.randint(5,10,3)*2 grid = np.random.randint(5,10,3)*2
size = np.random.random(3) + 1.0 size = np.random.random(3) + 1.0
@ -77,10 +88,36 @@ class TestVTK:
@pytest.mark.parametrize('name,dataset_type',[('this_file_does_not_exist.vtk', None), @pytest.mark.parametrize('name,dataset_type',[('this_file_does_not_exist.vtk', None),
('this_file_does_not_exist.vtk','vtk'), ('this_file_does_not_exist.vtk','vtk'),
('this_file_does_not_exist.vtx', None)]) ('this_file_does_not_exist.vtx', None)])
def test_invalid_dataset_type(self,dataset_type,name): def test_invalid_dataset_type(self,name,dataset_type):
with pytest.raises(TypeError): with pytest.raises(TypeError):
VTK.from_file('this_file_does_not_exist.vtk',dataset_type) VTK.from_file(name,dataset_type)
def test_invalid_extension_write(self,default):
with pytest.raises(ValueError):
default.write('default.txt')
def test_invalid_get(self,default):
with pytest.raises(ValueError):
default.get('does_not_exist')
def test_invalid_add_shape(self,default):
with pytest.raises(ValueError):
default.add(np.ones(3),'valid')
def test_invalid_add_missing_label(self,default):
data = np.random.randint(9,size=np.prod(np.array(default.vtk_data.GetDimensions())-1))
with pytest.raises(ValueError):
default.add(data)
def test_invalid_add_type(self,default):
with pytest.raises(TypeError):
default.add('invalid_type','valid')
def test_comments(self,tmp_path,default):
default.add_comments(['this is a comment'])
default.write(tmp_path/'with_comments',parallel=False)
new = VTK.from_file(tmp_path/'with_comments.vtr')
assert new.get_comments() == ['this is a comment']
def test_compare_reference_polyData(self,update,reference_dir,tmp_path): def test_compare_reference_polyData(self,update,reference_dir,tmp_path):
points=np.dstack((np.linspace(0.,1.,10),np.linspace(0.,2.,10),np.linspace(-1.,1.,10))).squeeze() points=np.dstack((np.linspace(0.,1.,10),np.linspace(0.,2.,10),np.linspace(-1.,1.,10))).squeeze()
@ -90,7 +127,8 @@ class TestVTK:
polyData.write(reference_dir/'polyData') polyData.write(reference_dir/'polyData')
else: else:
reference = VTK.from_file(reference_dir/'polyData.vtp') reference = VTK.from_file(reference_dir/'polyData.vtp')
assert polyData.__repr__() == reference.__repr__() assert polyData.__repr__() == reference.__repr__() and \
np.allclose(polyData.get('coordinates'),points)
def test_compare_reference_rectilinearGrid(self,update,reference_dir,tmp_path): def test_compare_reference_rectilinearGrid(self,update,reference_dir,tmp_path):
grid = np.array([5,6,7],int) grid = np.array([5,6,7],int)
@ -104,4 +142,5 @@ class TestVTK:
rectilinearGrid.write(reference_dir/'rectilinearGrid') rectilinearGrid.write(reference_dir/'rectilinearGrid')
else: else:
reference = VTK.from_file(reference_dir/'rectilinearGrid.vtr') reference = VTK.from_file(reference_dir/'rectilinearGrid.vtr')
assert rectilinearGrid.__repr__() == reference.__repr__() assert rectilinearGrid.__repr__() == reference.__repr__() and \
np.allclose(rectilinearGrid.get('cell'),c)

View File

@ -15,7 +15,6 @@ module discretization
discretization_nElem discretization_nElem
integer, public, protected, dimension(:), allocatable :: & integer, public, protected, dimension(:), allocatable :: &
discretization_homogenizationAt, &
discretization_microstructureAt discretization_microstructureAt
real(pReal), public, protected, dimension(:,:), allocatable :: & real(pReal), public, protected, dimension(:,:), allocatable :: &
@ -38,12 +37,11 @@ contains
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
!> @brief stores the relevant information in globally accesible variables !> @brief stores the relevant information in globally accesible variables
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
subroutine discretization_init(homogenizationAt,microstructureAt,& subroutine discretization_init(microstructureAt,&
IPcoords0,NodeCoords0,& IPcoords0,NodeCoords0,&
sharedNodesBegin) sharedNodesBegin)
integer, dimension(:), intent(in) :: & integer, dimension(:), intent(in) :: &
homogenizationAt, &
microstructureAt microstructureAt
real(pReal), dimension(:,:), intent(in) :: & real(pReal), dimension(:,:), intent(in) :: &
IPcoords0, & IPcoords0, &
@ -56,7 +54,6 @@ subroutine discretization_init(homogenizationAt,microstructureAt,&
discretization_nElem = size(microstructureAt,1) discretization_nElem = size(microstructureAt,1)
discretization_nIP = size(IPcoords0,2)/discretization_nElem discretization_nIP = size(IPcoords0,2)/discretization_nElem
discretization_homogenizationAt = homogenizationAt
discretization_microstructureAt = microstructureAt discretization_microstructureAt = microstructureAt
discretization_IPcoords0 = IPcoords0 discretization_IPcoords0 = IPcoords0

View File

@ -53,8 +53,7 @@ subroutine discretization_grid_init(restart)
myGrid !< domain grid of this process myGrid !< domain grid of this process
integer, dimension(:), allocatable :: & integer, dimension(:), allocatable :: &
microstructureAt, & microstructureAt
homogenizationAt
integer :: & integer :: &
j, & j, &
@ -65,7 +64,7 @@ subroutine discretization_grid_init(restart)
write(6,'(/,a)') ' <<<+- discretization_grid init -+>>>'; flush(6) write(6,'(/,a)') ' <<<+- discretization_grid init -+>>>'; flush(6)
call readGeom(grid,geomSize,origin,microstructureAt,homogenizationAt) call readGeom(grid,geomSize,origin,microstructureAt)
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
! grid solver specific quantities ! grid solver specific quantities
@ -94,10 +93,8 @@ subroutine discretization_grid_init(restart)
! general discretization ! general discretization
microstructureAt = microstructureAt(product(grid(1:2))*grid3Offset+1: & microstructureAt = microstructureAt(product(grid(1:2))*grid3Offset+1: &
product(grid(1:2))*(grid3Offset+grid3)) ! reallocate/shrink in case of MPI product(grid(1:2))*(grid3Offset+grid3)) ! reallocate/shrink in case of MPI
homogenizationAt = homogenizationAt(product(grid(1:2))*grid3Offset+1: &
product(grid(1:2))*(grid3Offset+grid3)) ! reallocate/shrink in case of MPI
call discretization_init(homogenizationAt,microstructureAt, & call discretization_init(microstructureAt, &
IPcoordinates0(myGrid,mySize,grid3Offset), & IPcoordinates0(myGrid,mySize,grid3Offset), &
Nodes0(myGrid,mySize,grid3Offset),& Nodes0(myGrid,mySize,grid3Offset),&
merge((grid(1)+1) * (grid(2)+1) * (grid3+1),& ! write bottom layer merge((grid(1)+1) * (grid(2)+1) * (grid3+1),& ! write bottom layer
@ -139,7 +136,7 @@ end subroutine discretization_grid_init
!> @details important variables have an implicit "save" attribute. Therefore, this function is !> @details important variables have an implicit "save" attribute. Therefore, this function is
! supposed to be called only once! ! supposed to be called only once!
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
subroutine readGeom(grid,geomSize,origin,microstructure,homogenization) subroutine readGeom(grid,geomSize,origin,microstructure)
integer, dimension(3), intent(out) :: & integer, dimension(3), intent(out) :: &
grid ! grid (for all processes!) grid ! grid (for all processes!)
@ -147,8 +144,7 @@ subroutine readGeom(grid,geomSize,origin,microstructure,homogenization)
geomSize, & ! size (for all processes!) geomSize, & ! size (for all processes!)
origin ! origin (for all processes!) origin ! origin (for all processes!)
integer, dimension(:), intent(out), allocatable :: & integer, dimension(:), intent(out), allocatable :: &
microstructure, & microstructure
homogenization
character(len=:), allocatable :: rawData character(len=:), allocatable :: rawData
character(len=65536) :: line character(len=65536) :: line
@ -249,24 +245,18 @@ subroutine readGeom(grid,geomSize,origin,microstructure,homogenization)
enddo enddo
endif endif
case ('homogenization')
if (chunkPos(1) > 1) h = IO_intValue(line,chunkPos,2)
end select end select
enddo enddo
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
! sanity checks ! sanity checks
if(h < 1) &
call IO_error(error_ID = 842, ext_msg='homogenization (readGeom)')
if(any(grid < 1)) & if(any(grid < 1)) &
call IO_error(error_ID = 842, ext_msg='grid (readGeom)') call IO_error(error_ID = 842, ext_msg='grid (readGeom)')
if(any(geomSize < 0.0_pReal)) & if(any(geomSize < 0.0_pReal)) &
call IO_error(error_ID = 842, ext_msg='size (readGeom)') call IO_error(error_ID = 842, ext_msg='size (readGeom)')
allocate(microstructure(product(grid)), source = -1) ! too large in case of MPI (shrink later, not very elegant) allocate(microstructure(product(grid)), source = -1) ! too large in case of MPI (shrink later, not very elegant)
allocate(homogenization(product(grid)), source = h) ! too large in case of MPI (shrink later, not very elegant)
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
! read and interpret content ! read and interpret content

View File

@ -52,8 +52,7 @@ subroutine discretization_marc_init
type(tElement) :: elem type(tElement) :: elem
integer, dimension(:), allocatable :: & integer, dimension(:), allocatable :: &
microstructureAt, & microstructureAt
homogenizationAt
integer:: & integer:: &
Nnodes, & !< total number of nodes in the mesh Nnodes, & !< total number of nodes in the mesh
Nelems, & !< total number of elements in the mesh Nelems, & !< total number of elements in the mesh
@ -84,7 +83,7 @@ subroutine discretization_marc_init
mesh_unitlength = num_commercialFEM%get_asFloat('unitlength',defaultVal=1.0_pReal) ! set physical extent of a length unit in mesh mesh_unitlength = num_commercialFEM%get_asFloat('unitlength',defaultVal=1.0_pReal) ! set physical extent of a length unit in mesh
if (mesh_unitlength <= 0.0_pReal) call IO_error(301,ext_msg='unitlength') if (mesh_unitlength <= 0.0_pReal) call IO_error(301,ext_msg='unitlength')
call inputRead(elem,node0_elem,connectivity_elem,microstructureAt,homogenizationAt) call inputRead(elem,node0_elem,connectivity_elem,microstructureAt)
nElems = size(connectivity_elem,2) nElems = size(connectivity_elem,2)
if (debug_e < 1 .or. debug_e > nElems) call IO_error(602,ext_msg='element') if (debug_e < 1 .or. debug_e > nElems) call IO_error(602,ext_msg='element')
@ -104,7 +103,7 @@ subroutine discretization_marc_init
call buildIPcoordinates(IP_reshaped,reshape(connectivity_cell,[elem%NcellNodesPerCell,& call buildIPcoordinates(IP_reshaped,reshape(connectivity_cell,[elem%NcellNodesPerCell,&
elem%nIPs*nElems]),node0_cell) elem%nIPs*nElems]),node0_cell)
call discretization_init(microstructureAt,homogenizationAt,& call discretization_init(microstructureAt,&
IP_reshaped,& IP_reshaped,&
node0_cell) node0_cell)
@ -173,7 +172,7 @@ end subroutine writeGeometry
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
!> @brief Read mesh from marc input file !> @brief Read mesh from marc input file
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
subroutine inputRead(elem,node0_elem,connectivity_elem,microstructureAt,homogenizationAt) subroutine inputRead(elem,node0_elem,connectivity_elem,microstructureAt)
type(tElement), intent(out) :: elem type(tElement), intent(out) :: elem
real(pReal), dimension(:,:), allocatable, intent(out) :: & real(pReal), dimension(:,:), allocatable, intent(out) :: &
@ -181,8 +180,7 @@ subroutine inputRead(elem,node0_elem,connectivity_elem,microstructureAt,homogeni
integer, dimension(:,:), allocatable, intent(out) :: & integer, dimension(:,:), allocatable, intent(out) :: &
connectivity_elem connectivity_elem
integer, dimension(:), allocatable, intent(out) :: & integer, dimension(:), allocatable, intent(out) :: &
microstructureAt, & microstructureAt
homogenizationAt
integer :: & integer :: &
fileFormatVersion, & fileFormatVersion, &
@ -228,7 +226,7 @@ subroutine inputRead(elem,node0_elem,connectivity_elem,microstructureAt,homogeni
connectivity_elem = inputRead_connectivityElem(nElems,elem%nNodes,inputFile) connectivity_elem = inputRead_connectivityElem(nElems,elem%nNodes,inputFile)
call inputRead_microstructureAndHomogenization(microstructureAt,homogenizationAt, & call inputRead_microstructure(microstructureAt, &
nElems,elem%nNodes,nameElemSet,mapElemSet,& nElems,elem%nNodes,nameElemSet,mapElemSet,&
initialcondTableStyle,inputFile) initialcondTableStyle,inputFile)
end subroutine inputRead end subroutine inputRead
@ -677,14 +675,13 @@ end function inputRead_connectivityElem
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
!> @brief Stores homogenization and microstructure ID !> @brief Store microstructure ID
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
subroutine inputRead_microstructureAndHomogenization(microstructureAt,homogenizationAt, & subroutine inputRead_microstructure(microstructureAt,&
nElem,nNodes,nameElemSet,mapElemSet,initialcondTableStyle,fileContent) nElem,nNodes,nameElemSet,mapElemSet,initialcondTableStyle,fileContent)
integer, dimension(:), allocatable, intent(out) :: & integer, dimension(:), allocatable, intent(out) :: &
microstructureAt, & microstructureAt
homogenizationAt
integer, intent(in) :: & integer, intent(in) :: &
nElem, & nElem, &
nNodes, & !< number of nodes per element nNodes, & !< number of nodes per element
@ -700,7 +697,6 @@ subroutine inputRead_microstructureAndHomogenization(microstructureAt,homogeniza
allocate(microstructureAt(nElem),source=0) allocate(microstructureAt(nElem),source=0)
allocate(homogenizationAt(nElem),source=0)
do l = 1, size(fileContent) do l = 1, size(fileContent)
chunkPos = IO_stringPos(fileContent(l)) chunkPos = IO_stringPos(fileContent(l))
@ -719,8 +715,7 @@ subroutine inputRead_microstructureAndHomogenization(microstructureAt,homogeniza
contInts = continuousIntValues(fileContent(l+k+m+1:),nElem,nameElemSet,mapElemSet,size(nameElemSet)) ! get affected elements contInts = continuousIntValues(fileContent(l+k+m+1:),nElem,nameElemSet,mapElemSet,size(nameElemSet)) ! get affected elements
do i = 1,contInts(1) do i = 1,contInts(1)
e = mesh_FEM2DAMASK_elem(contInts(1+i)) e = mesh_FEM2DAMASK_elem(contInts(1+i))
if (sv == 2) microstructureAt(e) = myVal if (sv == 3) microstructureAt(e) = myVal
if (sv == 3) homogenizationAt(e) = myVal
enddo enddo
if (initialcondTableStyle == 0) m = m + 1 if (initialcondTableStyle == 0) m = m + 1
enddo enddo
@ -728,7 +723,7 @@ subroutine inputRead_microstructureAndHomogenization(microstructureAt,homogeniza
endif endif
enddo enddo
end subroutine inputRead_microstructureAndHomogenization end subroutine inputRead_microstructure
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------

View File

@ -80,7 +80,7 @@ module material
damage_initialPhi !< initial damage per each homogenization damage_initialPhi !< initial damage per each homogenization
integer, dimension(:), allocatable, public, protected :: & ! (elem) integer, dimension(:), allocatable, public, protected :: & ! (elem)
material_homogenizationAt !< homogenization ID of each element (copy of discretization_homogenizationAt) material_homogenizationAt !< homogenization ID of each element
integer, dimension(:,:), allocatable, public, target :: & ! (ip,elem) ToDo: ugly target for mapping hack integer, dimension(:,:), allocatable, public, target :: & ! (ip,elem) ToDo: ugly target for mapping hack
material_homogenizationMemberAt !< position of the element within its homogenization instance material_homogenizationMemberAt !< position of the element within its homogenization instance
integer, dimension(:,:), allocatable, public, protected :: & ! (constituent,elem) integer, dimension(:,:), allocatable, public, protected :: & ! (constituent,elem)
@ -241,7 +241,6 @@ subroutine material_parseHomogenization
homogDamage homogDamage
integer :: h integer :: h
logical, dimension(:), allocatable :: homogenization_active
material_homogenization => material_root%get('homogenization') material_homogenization => material_root%get('homogenization')
material_Nhomogenization = material_homogenization%length material_Nhomogenization = material_homogenization%length
@ -253,13 +252,9 @@ subroutine material_parseHomogenization
allocate(thermal_typeInstance(material_Nhomogenization), source=0) allocate(thermal_typeInstance(material_Nhomogenization), source=0)
allocate(damage_typeInstance(material_Nhomogenization), source=0) allocate(damage_typeInstance(material_Nhomogenization), source=0)
allocate(homogenization_Ngrains(material_Nhomogenization), source=0) allocate(homogenization_Ngrains(material_Nhomogenization), source=0)
allocate(homogenization_active(material_Nhomogenization), source=.false.) !!!!!!!!!!!!!!!
allocate(thermal_initialT(material_Nhomogenization), source=300.0_pReal) allocate(thermal_initialT(material_Nhomogenization), source=300.0_pReal)
allocate(damage_initialPhi(material_Nhomogenization), source=1.0_pReal) allocate(damage_initialPhi(material_Nhomogenization), source=1.0_pReal)
forall (h = 1:material_Nhomogenization) &
homogenization_active(h) = any(discretization_homogenizationAt == h) !ToDo: SR: needed??
do h=1, material_Nhomogenization do h=1, material_Nhomogenization
homog => material_homogenization%get(h) homog => material_homogenization%get(h)
homogMech => homog%get('mech') homogMech => homog%get('mech')
@ -317,7 +312,7 @@ subroutine material_parseHomogenization
damage_typeInstance(h) = count(damage_type (1:h) == damage_type (h)) damage_typeInstance(h) = count(damage_type (1:h) == damage_type (h))
enddo enddo
homogenization_maxNgrains = maxval(homogenization_Ngrains,homogenization_active) homogenization_maxNgrains = maxval(homogenization_Ngrains)
end subroutine material_parseHomogenization end subroutine material_parseHomogenization

View File

@ -77,7 +77,6 @@ subroutine discretization_mesh_init(restart)
IS :: faceSetIS IS :: faceSetIS
PetscErrorCode :: ierr PetscErrorCode :: ierr
integer, dimension(:), allocatable :: & integer, dimension(:), allocatable :: &
homogenizationAt, &
microstructureAt microstructureAt
class(tNode), pointer :: & class(tNode), pointer :: &
num_mesh num_mesh
@ -165,7 +164,6 @@ subroutine discretization_mesh_init(restart)
call mesh_FEM_build_ipVolumes(dimPlex) call mesh_FEM_build_ipVolumes(dimPlex)
allocate(microstructureAt(mesh_NcpElems)) allocate(microstructureAt(mesh_NcpElems))
allocate(homogenizationAt(mesh_NcpElems),source=1)
do j = 1, mesh_NcpElems do j = 1, mesh_NcpElems
call DMGetLabelValue(geomMesh,'material',j-1,microstructureAt(j),ierr) call DMGetLabelValue(geomMesh,'material',j-1,microstructureAt(j),ierr)
CHKERRQ(ierr) CHKERRQ(ierr)
@ -179,7 +177,7 @@ subroutine discretization_mesh_init(restart)
allocate(mesh_node0(3,mesh_Nnodes),source=0.0_pReal) allocate(mesh_node0(3,mesh_Nnodes),source=0.0_pReal)
call discretization_init(microstructureAt,homogenizationAt,& call discretization_init(microstructureAt,&
reshape(mesh_ipCoordinates,[3,mesh_maxNips*mesh_NcpElems]), & reshape(mesh_ipCoordinates,[3,mesh_maxNips*mesh_NcpElems]), &
mesh_node0) mesh_node0)