switched "Geom.materials" to "Geom.material"

This commit is contained in:
Philip Eisenlohr 2020-09-23 17:27:15 -04:00
parent b995f34834
commit 8c8db5b99f
7 changed files with 182 additions and 180 deletions

View File

@ -66,13 +66,13 @@ for name in filenames:
grid_original = geom.grid
damask.util.croak(geom)
materials = np.tile(geom.materials,np.where(grid_original == 1, 2,1)) # make one copy along dimensions with grid == 1
grid = np.array(materials.shape)
material = np.tile(geom.material,np.where(grid_original == 1, 2,1)) # make one copy along dimensions with grid == 1
grid = np.array(material.shape)
# --- initialize support data ---------------------------------------------------------------------
# store a copy of the initial material indices to find locations of immutable indices
materials_original = np.copy(materials)
material_original = np.copy(material)
if not options.ndimage:
X,Y,Z = np.mgrid[0:grid[0],0:grid[1],0:grid[2]]
@ -88,14 +88,14 @@ for name in filenames:
for smoothIter in range(options.N):
interfaceEnergy = np.zeros(materials.shape,dtype=np.float32)
interfaceEnergy = np.zeros(material.shape,dtype=np.float32)
for i in (-1,0,1):
for j in (-1,0,1):
for k in (-1,0,1):
# assign interfacial energy to all voxels that have a differing neighbor (in Moore neighborhood)
interfaceEnergy = np.maximum(interfaceEnergy,
getInterfaceEnergy(materials,np.roll(np.roll(np.roll(
materials,i,axis=0), j,axis=1), k,axis=2)))
getInterfaceEnergy(material,np.roll(np.roll(np.roll(
material,i,axis=0), j,axis=1), k,axis=2)))
# periodically extend interfacial energy array by half a grid size in positive and negative directions
periodic_interfaceEnergy = np.tile(interfaceEnergy,(3,3,3))[grid[0]//2:-grid[0]//2,
@ -143,33 +143,33 @@ for name in filenames:
return_distances = False,
return_indices = True) # want index of closest bulk grain
periodic_materials = np.tile(materials,(3,3,3))[grid[0]//2:-grid[0]//2,
grid[1]//2:-grid[1]//2,
grid[2]//2:-grid[2]//2] # periodically extend the geometry
periodic_material = np.tile(material,(3,3,3))[grid[0]//2:-grid[0]//2,
grid[1]//2:-grid[1]//2,
grid[2]//2:-grid[2]//2] # periodically extend the geometry
materials = periodic_materials[index[0],
index[1],
index[2]].reshape(2*grid)[grid[0]//2:-grid[0]//2,
grid[1]//2:-grid[1]//2,
grid[2]//2:-grid[2]//2] # extent grains into interface region
material = periodic_material[index[0],
index[1],
index[2]].reshape(2*grid)[grid[0]//2:-grid[0]//2,
grid[1]//2:-grid[1]//2,
grid[2]//2:-grid[2]//2] # extent grains into interface region
# replace immutable materials with closest mutable ones
index = ndimage.morphology.distance_transform_edt(np.in1d(materials,options.immutable).reshape(grid),
index = ndimage.morphology.distance_transform_edt(np.in1d(material,options.immutable).reshape(grid),
return_distances = False,
return_indices = True)
materials = materials[index[0],
material = material[index[0],
index[1],
index[2]]
immutable = np.zeros(materials.shape, dtype=np.bool)
immutable = np.zeros(material.shape, dtype=np.bool)
# find locations where immutable materials have been in original structure
for micro in options.immutable:
immutable += materials_original == micro
immutable += material_original == micro
# undo any changes involving immutable materials
materials = np.where(immutable, materials_original,materials)
material = np.where(immutable, material_original,material)
damask.Geom(materials = materials[0:grid_original[0],0:grid_original[1],0:grid_original[2]],
damask.Geom(material = material[0:grid_original[0],0:grid_original[1],0:grid_original[2]],
size = geom.size,
origin = geom.origin,
comments = geom.comments + [scriptID + ' ' + ' '.join(sys.argv[1:])],

View File

@ -100,7 +100,7 @@ def mesh(r,d):
#-------------------------------------------------------------------------------------------------
def material():
def materials():
return [\
"*new_mater standard",
"*mater_option general:state:solid",
@ -130,10 +130,10 @@ def geometry():
#-------------------------------------------------------------------------------------------------
def initial_conditions(materials):
def initial_conditions(material):
elements = []
element = 0
for id in materials:
for id in material:
element += 1
if len(elements) < id:
for i in range(id-len(elements)):
@ -197,14 +197,14 @@ for name in filenames:
damask.util.report(scriptName,name)
geom = damask.Geom.load_ASCII(StringIO(''.join(sys.stdin.read())) if name is None else name)
materials = geom.materials.flatten(order='F')
material = geom.material.flatten(order='F')
cmds = [\
init(),
mesh(geom.grid,geom.size),
material(),
materials(),
geometry(),
initial_conditions(materials),
initial_conditions(material),
'*identify_sets',
'*show_model',
'*redraw',

View File

@ -101,8 +101,8 @@ class myThread (threading.Thread):
#--- evaluate current seeds file ------------------------------------------------------------------
perturbedGeom = damask.Geom.load_ASCII(perturbedGeomVFile)
myNmaterials = len(np.unique(perturbedGeom.materials))
currentData=np.bincount(perturbedGeom.materials.ravel())[1:]/points
myNmaterials = len(np.unique(perturbedGeom.material))
currentData = np.bincount(perturbedGeom.material.ravel())[1:]/points
currentError=[]
currentHist=[]
for i in range(nMaterials): # calculate the deviation in all bins per histogram
@ -217,8 +217,8 @@ points = np.array(options.grid).prod().astype('float')
# ----------- calculate target distribution and bin edges
targetGeom = damask.Geom.load_ASCII(os.path.splitext(os.path.basename(options.target))[0]+'.geom')
nMaterials = len(np.unique(targetGeom.materials))
targetVolFrac = np.bincount(targetGeom.materials.flatten())/targetGeom.grid.prod().astype(np.float)
nMaterials = len(np.unique(targetGeom.material))
targetVolFrac = np.bincount(targetGeom.material.flatten())/targetGeom.grid.prod().astype(np.float)
target = []
for i in range(1,nMaterials+1):
targetHist,targetBins = np.histogram(targetVolFrac,bins=i) #bin boundaries
@ -244,10 +244,10 @@ initialGeomVFile.write(damask.util.execute('geom_fromVoronoiTessellation '+
initialGeomVFile.seek(0)
initialGeom = damask.Geom.load_ASCII(initialGeomVFile)
if len(np.unique(targetGeom.materials)) != nMaterials:
if len(np.unique(targetGeom.material)) != nMaterials:
damask.util.croak('error. Material count mismatch')
initialData = np.bincount(initialGeom.materials.flatten())/points
initialData = np.bincount(initialGeom.material.flatten())/points
for i in range(nMaterials):
initialHist = np.histogram(initialData,bins=target[i]['bins'])[0]
target[i]['error']=np.sqrt(np.square(np.array(target[i]['histogram']-initialHist)).sum())
@ -263,7 +263,7 @@ for i in range(nMaterials):
if options.maxseeds < 1:
maxSeeds = len(np.unique(initialGeom.materials))
maxSeeds = len(np.unique(initialGeom.material))
else:
maxSeeds = options.maxseeds

View File

@ -47,11 +47,11 @@ for name in filenames:
damask.util.report(scriptName,name)
geom = damask.Geom.load_ASCII(StringIO(''.join(sys.stdin.read())) if name is None else name)
materials = geom.materials.reshape((-1,1),order='F')
material = geom.material.reshape((-1,1),order='F')
mask = np.logical_and(np.in1d(materials,options.whitelist,invert=False) if options.whitelist else \
mask = np.logical_and(np.in1d(material,options.whitelist,invert=False) if options.whitelist else \
np.full(geom.grid.prod(),True,dtype=bool),
np.in1d(materials,options.blacklist,invert=True) if options.blacklist else \
np.in1d(material,options.blacklist,invert=True) if options.blacklist else \
np.full(geom.grid.prod(),True,dtype=bool))
seeds = damask.grid_filters.cell_coord0(geom.grid,geom.size).reshape(-1,3,order='F')
@ -64,5 +64,5 @@ for name in filenames:
]
damask.Table(seeds[mask],{'pos':(3,)},comments)\
.add('material',materials[mask].astype(int))\
.add('material',material[mask].astype(int))\
.save(sys.stdout if name is None else os.path.splitext(name)[0]+'.seeds',legacy=True)

View File

@ -76,7 +76,7 @@ for name in filenames:
g[2] = k + offset[2]
g %= geom.grid
seeds[n,0:3] = (g+0.5)/geom.grid # normalize coordinates to box
seeds[n, 3] = geom.materials[g[0],g[1],g[2]]
seeds[n, 3] = geom.material[g[0],g[1],g[2]]
if options.x: g[0] += 1
if options.y: g[1] += 1
n += 1

View File

@ -15,13 +15,13 @@ from . import grid_filters
class Geom:
"""Geometry definition for grid solvers."""
def __init__(self,materials,size,origin=[0.0,0.0,0.0],comments=[]):
def __init__(self,material,size,origin=[0.0,0.0,0.0],comments=[]):
"""
New geometry definition from array of materials, size, and origin.
New geometry definition from array of material, size, and origin.
Parameters
----------
materials : numpy.ndarray
material : numpy.ndarray
Material index array (3D).
size : list or numpy.ndarray
Physical size of the geometry in meter.
@ -31,16 +31,16 @@ class Geom:
Comment lines.
"""
if len(materials.shape) != 3:
raise ValueError(f'Invalid materials shape {materials.shape}.')
elif materials.dtype not in np.sctypes['float'] + np.sctypes['int']:
raise TypeError(f'Invalid materials data type {materials.dtype}.')
if len(material.shape) != 3:
raise ValueError(f'Invalid material shape {material.shape}.')
elif material.dtype not in np.sctypes['float'] + np.sctypes['int']:
raise TypeError(f'Invalid material data type {material.dtype}.')
else:
self.materials = np.copy(materials)
self.material = np.copy(material)
if self.materials.dtype in np.sctypes['float'] and \
np.all(self.materials == self.materials.astype(int).astype(float)):
self.materials = self.materials.astype(int)
if self.material.dtype in np.sctypes['float'] and \
np.all(self.material == self.material.astype(int).astype(float)):
self.material = self.material.astype(int)
if len(size) != 3 or any(np.array(size) <= 0):
raise ValueError(f'Invalid size {size}.')
@ -62,7 +62,7 @@ class Geom:
f'size x y z: {util.srepr(self.size, " x ")}',
f'origin x y z: {util.srepr(self.origin," ")}',
f'# materials: {self.N_materials}',
f'max material: {np.nanmax(self.materials)}',
f'max material: {np.nanmax(self.material)}',
])
@ -103,21 +103,21 @@ class Geom:
message.append(util.delete(f'# materials: {other.N_materials}'))
message.append(util.emph( f'# materials: { self.N_materials}'))
if np.nanmax(other.materials) != np.nanmax(self.materials):
message.append(util.delete(f'max material: {np.nanmax(other.materials)}'))
message.append(util.emph( f'max material: {np.nanmax( self.materials)}'))
if np.nanmax(other.material) != np.nanmax(self.material):
message.append(util.delete(f'max material: {np.nanmax(other.material)}'))
message.append(util.emph( f'max material: {np.nanmax( self.material)}'))
return util.return_message(message)
@property
def grid(self):
return np.asarray(self.materials.shape)
return np.asarray(self.material.shape)
@property
def N_materials(self):
return np.unique(self.materials).size
return np.unique(self.material).size
@staticmethod
@ -160,7 +160,7 @@ class Geom:
else:
comments.append(line.strip())
materials = np.empty(grid.prod()) # initialize as flat array
material = np.empty(grid.prod()) # initialize as flat array
i = 0
for line in content[header_length:]:
items = line.split('#')[0].split()
@ -172,16 +172,16 @@ class Geom:
abs(int(items[2])-int(items[0]))+1,dtype=float)
else: items = list(map(float,items))
else: items = list(map(float,items))
materials[i:i+len(items)] = items
material[i:i+len(items)] = items
i += len(items)
if i != grid.prod():
raise TypeError(f'Invalid file: expected {grid.prod()} entries, found {i}')
if not np.any(np.mod(materials,1) != 0.0): # no float present
materials = materials.astype('int')
if not np.any(np.mod(material,1) != 0.0): # no float present
material = material.astype('int')
return Geom(materials.reshape(grid,order='F'),size,origin,comments)
return Geom(material.reshape(grid,order='F'),size,origin,comments)
@staticmethod
@ -200,9 +200,11 @@ class Geom:
comments = v.get_comments()
grid = np.array(v.vtk_data.GetDimensions())-1
bbox = np.array(v.vtk_data.GetBounds()).reshape(3,2).T
size = bbox[1] - bbox[0]
return Geom(v.get('material').reshape(grid,order='F'),size,bbox[0],comments=comments)
return Geom(material = v.get('material').reshape(grid,order='F'),
size = bbox[1] - bbox[0],
origin = bbox[0],
comments=comments)
@staticmethod
@ -243,17 +245,17 @@ class Geom:
result = pool.map_async(partial(Geom._find_closest_seed,seeds_p,weights_p), [coord for coord in coords])
pool.close()
pool.join()
materials = np.array(result.get())
material = np.array(result.get())
if periodic:
materials = materials.reshape(grid*3)
materials = materials[grid[0]:grid[0]*2,grid[1]:grid[1]*2,grid[2]:grid[2]*2]%seeds.shape[0]
material = material.reshape(grid*3)
material = material[grid[0]:grid[0]*2,grid[1]:grid[1]*2,grid[2]:grid[2]*2]%seeds.shape[0]
else:
materials = materials.reshape(grid)
material = material.reshape(grid)
return Geom(materials = materials+1,
size = size,
comments = util.execution_stamp('Geom','from_Laguerre_tessellation'),
return Geom(material = material+1,
size = size,
comments = util.execution_stamp('Geom','from_Laguerre_tessellation'),
)
@ -276,11 +278,11 @@ class Geom:
"""
coords = grid_filters.cell_coord0(grid,size).reshape(-1,3)
KDTree = spatial.cKDTree(seeds,boxsize=size) if periodic else spatial.cKDTree(seeds)
devNull,materials = KDTree.query(coords)
devNull,material = KDTree.query(coords)
return Geom(materials = materials.reshape(grid)+1,
size = size,
comments = util.execution_stamp('Geom','from_Voronoi_tessellation'),
return Geom(material = material.reshape(grid)+1,
size = size,
comments = util.execution_stamp('Geom','from_Voronoi_tessellation'),
)
@ -311,10 +313,10 @@ class Geom:
plain = not compress
if plain:
format_string = '%g' if self.materials.dtype in np.sctypes['float'] else \
'%{}i'.format(1+int(np.floor(np.log10(np.nanmax(self.materials)))))
format_string = '%g' if self.material.dtype in np.sctypes['float'] else \
'%{}i'.format(1+int(np.floor(np.log10(np.nanmax(self.material)))))
np.savetxt(fname,
self.materials.reshape([grid[0],np.prod(grid[1:])],order='F').T,
self.material.reshape([grid[0],np.prod(grid[1:])],order='F').T,
header='\n'.join(header), fmt=format_string, comments='')
else:
try:
@ -325,7 +327,7 @@ class Geom:
compressType = None
former = start = -1
reps = 0
for current in self.materials.flatten('F'):
for current in self.material.flatten('F'):
if abs(current - former) == 1 and (start - current) == reps*(former - current):
compressType = 'to'
reps += 1
@ -370,7 +372,7 @@ class Geom:
"""
v = VTK.from_rectilinearGrid(self.grid,self.size,self.origin)
v.add(self.materials.flatten(order='F'),'material')
v.add(self.material.flatten(order='F'),'material')
v.add_comments(self.comments)
v.save(fname if str(fname).endswith('.vtr') else str(fname)+'.vtr',parallel=False,compress=compress)
@ -402,7 +404,7 @@ class Geom:
0 gives octahedron (|x|^(2^0) + |y|^(2^0) + |z|^(2^0) < 1)
1 gives a sphere (|x|^(2^1) + |y|^(2^1) + |z|^(2^1) < 1)
fill : int, optional
Fill value for primitive. Defaults to materials.max() + 1.
Fill value for primitive. Defaults to material.max() + 1.
R : damask.Rotation, optional
Rotation of primitive. Defaults to no rotation.
inverse : Boolean, optional
@ -428,12 +430,12 @@ class Geom:
if periodic: # translate back to center
mask = np.roll(mask,((c-np.ones(3)*.5)*self.grid).astype(int),(0,1,2))
fill_ = np.full_like(self.materials,np.nanmax(self.materials)+1 if fill is None else fill)
fill_ = np.full_like(self.material,np.nanmax(self.material)+1 if fill is None else fill)
return Geom(materials = np.where(np.logical_not(mask) if inverse else mask, self.materials,fill_),
size = self.size,
origin = self.origin,
comments = self.comments+[util.execution_stamp('Geom','add_primitive')],
return Geom(material = np.where(np.logical_not(mask) if inverse else mask, self.material,fill_),
size = self.size,
origin = self.origin,
comments = self.comments+[util.execution_stamp('Geom','add_primitive')],
)
@ -455,19 +457,19 @@ class Geom:
raise ValueError(f'Invalid direction {set(directions).difference(valid)} specified.')
limits = [None,None] if reflect else [-2,0]
ms = self.materials.copy()
mat = self.material.copy()
if 'x' in directions:
ms = np.concatenate([ms,ms[limits[0]:limits[1]:-1,:,:]],0)
mat = np.concatenate([mat,mat[limits[0]:limits[1]:-1,:,:]],0)
if 'y' in directions:
ms = np.concatenate([ms,ms[:,limits[0]:limits[1]:-1,:]],1)
mat = np.concatenate([mat,mat[:,limits[0]:limits[1]:-1,:]],1)
if 'z' in directions:
ms = np.concatenate([ms,ms[:,:,limits[0]:limits[1]:-1]],2)
mat = np.concatenate([mat,mat[:,:,limits[0]:limits[1]:-1]],2)
return Geom(materials = ms,
size = self.size/self.grid*np.asarray(ms.shape),
origin = self.origin,
comments = self.comments+[util.execution_stamp('Geom','mirror')],
return Geom(material = mat,
size = self.size/self.grid*np.asarray(mat.shape),
origin = self.origin,
comments = self.comments+[util.execution_stamp('Geom','mirror')],
)
@ -486,12 +488,12 @@ class Geom:
if not set(directions).issubset(valid):
raise ValueError(f'Invalid direction {set(directions).difference(valid)} specified.')
ms = np.flip(self.materials, (valid.index(d) for d in directions if d in valid))
mat = np.flip(self.material, (valid.index(d) for d in directions if d in valid))
return Geom(materials = ms,
size = self.size,
origin = self.origin,
comments = self.comments+[util.execution_stamp('Geom','flip')],
return Geom(material = mat,
size = self.size,
origin = self.origin,
comments = self.comments+[util.execution_stamp('Geom','flip')],
)
@ -507,17 +509,17 @@ class Geom:
Assume geometry to be periodic. Defaults to True.
"""
return Geom(materials = ndimage.interpolation.zoom(
self.materials,
return Geom(material = ndimage.interpolation.zoom(
self.material,
grid/self.grid,
output=self.materials.dtype,
output=self.material.dtype,
order=0,
mode=('wrap' if periodic else 'nearest'),
prefilter=False
),
size = self.size,
origin = self.origin,
comments = self.comments+[util.execution_stamp('Geom','scale')],
size = self.size,
origin = self.origin,
comments = self.comments+[util.execution_stamp('Geom','scale')],
)
@ -543,29 +545,29 @@ class Geom:
else:
return me
return Geom(materials = ndimage.filters.generic_filter(
self.materials,
return Geom(material = ndimage.filters.generic_filter(
self.material,
mostFrequent,
size=(stencil if selection is None else stencil//2*2+1,)*3,
mode=('wrap' if periodic else 'nearest'),
extra_keywords=dict(selection=selection),
).astype(self.materials.dtype),
size = self.size,
origin = self.origin,
comments = self.comments+[util.execution_stamp('Geom','clean')],
).astype(self.material.dtype),
size = self.size,
origin = self.origin,
comments = self.comments+[util.execution_stamp('Geom','clean')],
)
def renumber(self):
"""Renumber sorted material indices to 1,...,N."""
renumbered = np.empty(self.grid,dtype=self.materials.dtype)
for i, oldID in enumerate(np.unique(self.materials)):
renumbered = np.where(self.materials == oldID, i+1, renumbered)
renumbered = np.empty(self.grid,dtype=self.material.dtype)
for i, oldID in enumerate(np.unique(self.material)):
renumbered = np.where(self.material == oldID, i+1, renumbered)
return Geom(materials = renumbered,
size = self.size,
origin = self.origin,
comments = self.comments+[util.execution_stamp('Geom','renumber')],
return Geom(material = renumbered,
size = self.size,
origin = self.origin,
comments = self.comments+[util.execution_stamp('Geom','renumber')],
)
@ -578,32 +580,32 @@ class Geom:
R : damask.Rotation
Rotation to apply to the geometry.
fill : int or float, optional
Material index to fill the corners. Defaults to materials.max() + 1.
Material index to fill the corners. Defaults to material.max() + 1.
"""
if fill is None: fill = np.nanmax(self.materials) + 1
dtype = float if np.isnan(fill) or int(fill) != fill or self.materials.dtype==np.float else int
if fill is None: fill = np.nanmax(self.material) + 1
dtype = float if np.isnan(fill) or int(fill) != fill or self.material.dtype==np.float else int
Eulers = R.as_Eulers(degrees=True)
materials_in = self.materials.copy()
material_in = self.material.copy()
# These rotations are always applied in the reference coordinate system, i.e. (z,x,z) not (z,x',z'')
# see https://www.cs.utexas.edu/~theshark/courses/cs354/lectures/cs354-14.pdf
for angle,axes in zip(Eulers[::-1], [(0,1),(1,2),(0,1)]):
materials_out = ndimage.rotate(materials_in,angle,axes,order=0,
material_out = ndimage.rotate(material_in,angle,axes,order=0,
prefilter=False,output=dtype,cval=fill)
if np.prod(materials_in.shape) == np.prod(materials_out.shape):
if np.prod(material_in.shape) == np.prod(material_out.shape):
# avoid scipy interpolation errors for rotations close to multiples of 90°
materials_in = np.rot90(materials_in,k=np.rint(angle/90.).astype(int),axes=axes)
material_in = np.rot90(material_in,k=np.rint(angle/90.).astype(int),axes=axes)
else:
materials_in = materials_out
material_in = material_out
origin = self.origin-(np.asarray(materials_in.shape)-self.grid)*.5 * self.size/self.grid
origin = self.origin-(np.asarray(material_in.shape)-self.grid)*.5 * self.size/self.grid
return Geom(materials = materials_in,
size = self.size/self.grid*np.asarray(materials_in.shape),
origin = origin,
comments = self.comments+[util.execution_stamp('Geom','rotate')],
return Geom(material = material_in,
size = self.size/self.grid*np.asarray(material_in.shape),
origin = origin,
comments = self.comments+[util.execution_stamp('Geom','rotate')],
)
@ -618,12 +620,12 @@ class Geom:
offset : numpy.ndarray of shape (3)
Offset (measured in grid points) from old to new geometry [0,0,0].
fill : int or float, optional
Material index to fill the background. Defaults to materials.max() + 1.
Material index to fill the background. Defaults to material.max() + 1.
"""
if offset is None: offset = 0
if fill is None: fill = np.nanmax(self.materials) + 1
dtype = float if int(fill) != fill or self.materials.dtype in np.sctypes['float'] else int
if fill is None: fill = np.nanmax(self.material) + 1
dtype = float if int(fill) != fill or self.material.dtype in np.sctypes['float'] else int
canvas = np.full(self.grid if grid is None else grid,fill,dtype)
@ -632,35 +634,35 @@ class Geom:
ll = np.clip(-offset, 0,np.minimum( grid,self.grid-offset))
ur = np.clip(-offset+self.grid,0,np.minimum( grid,self.grid-offset))
canvas[ll[0]:ur[0],ll[1]:ur[1],ll[2]:ur[2]] = self.materials[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.material[LL[0]:UR[0],LL[1]:UR[1],LL[2]:UR[2]]
return Geom(materials = canvas,
size = self.size/self.grid*np.asarray(canvas.shape),
origin = self.origin+offset*self.size/self.grid,
comments = self.comments+[util.execution_stamp('Geom','canvas')],
return Geom(material = canvas,
size = self.size/self.grid*np.asarray(canvas.shape),
origin = self.origin+offset*self.size/self.grid,
comments = self.comments+[util.execution_stamp('Geom','canvas')],
)
def substitute(self,from_materials,to_materials):
def substitute(self,from_material,to_material):
"""
Substitute material indices.
Parameters
----------
from_materials : iterable of ints
from_material : iterable of ints
Material indices to be substituted.
to_materials : iterable of ints
to_material : iterable of ints
New material indices.
"""
substituted = self.materials.copy()
for from_ms,to_ms in zip(from_materials,to_materials):
substituted[self.materials==from_ms] = to_ms
substituted = self.material.copy()
for from_ms,to_ms in zip(from_material,to_material):
substituted[self.material==from_ms] = to_ms
return Geom(materials = substituted,
size = self.size,
origin = self.origin,
comments = self.comments+[util.execution_stamp('Geom','substitute')],
return Geom(material = substituted,
size = self.size,
origin = self.origin,
comments = self.comments+[util.execution_stamp('Geom','substitute')],
)
@ -679,7 +681,7 @@ class Geom:
Defaults to 1.
offset : int, optional
Offset (positive or negative) to tag material indices,
defaults to materials.max() + 1.
defaults to material.max() + 1.
trigger : list of ints, optional
List of material indices that trigger a change.
Defaults to [], meaning that any different neighbor triggers a change.
@ -698,15 +700,15 @@ class Geom:
trigger = list(trigger)
return np.any(np.in1d(stencil,np.array(trigger)))
offset_ = np.nanmax(self.materials) if offset is None else offset
mask = ndimage.filters.generic_filter(self.materials,
offset_ = np.nanmax(self.material) if offset is None else offset
mask = ndimage.filters.generic_filter(self.material,
tainted_neighborhood,
size=1+2*vicinity,
mode='wrap' if periodic else 'nearest',
extra_keywords={'trigger':trigger})
return Geom(materials = np.where(mask, self.materials + offset_,self.materials),
size = self.size,
origin = self.origin,
comments = self.comments+[util.execution_stamp('Geom','vicinity_offset')],
return Geom(material = np.where(mask, self.material + offset_,self.material),
size = self.size,
origin = self.origin,
comments = self.comments+[util.execution_stamp('Geom','vicinity_offset')],
)

View File

@ -11,8 +11,8 @@ from damask import util
def geom_equal(a,b):
return np.all(a.materials == b.materials) and \
np.all(a.grid == b.grid) and \
return np.all(a.material == b.material) and \
np.all(a.grid == b.grid) and \
np.allclose(a.size, b.size) and \
str(a.diff(b)) == str(b.diff(a))
@ -38,7 +38,7 @@ class TestGeom:
def test_diff_not_equal(self,default):
new = Geom(default.materials[1:,1:,1:]+1,default.size*.9,np.ones(3)-default.origin,comments=['modified'])
new = Geom(default.material[1:,1:,1:]+1,default.size*.9,np.ones(3)-default.origin,comments=['modified'])
assert str(default.diff(new)) != ''
@ -93,28 +93,28 @@ class TestGeom:
def test_invalid_size(self,default):
with pytest.raises(ValueError):
Geom(default.materials[1:,1:,1:],
Geom(default.material[1:,1:,1:],
size=np.ones(2))
def test_invalid_origin(self,default):
with pytest.raises(ValueError):
Geom(default.materials[1:,1:,1:],
Geom(default.material[1:,1:,1:],
size=np.ones(3),
origin=np.ones(4))
def test_invalid_materials_shape(self,default):
materials = np.ones((3,3))
material = np.ones((3,3))
with pytest.raises(ValueError):
Geom(materials,
Geom(material,
size=np.ones(3))
def test_invalid_materials_type(self,default):
materials = np.random.randint(1,300,(3,4,5))==1
material = np.random.randint(1,300,(3,4,5))==1
with pytest.raises(TypeError):
Geom(materials)
Geom(material)
@pytest.mark.parametrize('directions,reflect',[
@ -205,10 +205,10 @@ class TestGeom:
def test_renumber(self,default):
materials = default.materials.copy()
for m in np.unique(materials):
materials[materials==m] = materials.max() + np.random.randint(1,30)
modified = Geom(materials,
material = default.material.copy()
for m in np.unique(material):
material[material==m] = material.max() + np.random.randint(1,30)
modified = Geom(material,
default.size,
default.origin)
assert not geom_equal(modified,default)
@ -218,13 +218,13 @@ class TestGeom:
def test_substitute(self,default):
offset = np.random.randint(1,500)
modified = Geom(default.materials + offset,
modified = Geom(default.material + offset,
default.size,
default.origin)
assert not geom_equal(modified,default)
assert geom_equal(default,
modified.substitute(np.arange(default.materials.max())+1+offset,
np.arange(default.materials.max())+1))
modified.substitute(np.arange(default.material.max())+1+offset,
np.arange(default.material.max())+1))
@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]),
@ -251,7 +251,7 @@ class TestGeom:
grid = default.grid
grid_add = np.random.randint(0,30,(3))
modified = default.canvas(grid + grid_add)
assert np.all(modified.materials[:grid[0],:grid[1],:grid[2]] == default.materials)
assert np.all(modified.material[:grid[0],:grid[1],:grid[2]] == default.material)
@pytest.mark.parametrize('center1,center2',[(np.random.random(3)*.5,np.random.random()*8),
@ -271,7 +271,7 @@ class TestGeom:
s = np.random.random(3)+.5
G_1 = Geom(np.ones(g,'i'),s,o).add_primitive(diameter,center1,exponent)
G_2 = Geom(np.ones(g,'i'),s,o).add_primitive(diameter,center2,exponent)
assert np.count_nonzero(G_1.materials!=2) == np.count_nonzero(G_2.materials!=2)
assert np.count_nonzero(G_1.material!=2) == np.count_nonzero(G_2.material!=2)
@pytest.mark.parametrize('center',[np.random.randint(4,10,(3)),
@ -308,14 +308,14 @@ class TestGeom:
geom = Geom(m,np.random.rand(3)).vicinity_offset(vicinity,offset,trigger=trigger)
assert np.all(m2==geom.materials)
assert np.all(m2==geom.material)
@pytest.mark.parametrize('periodic',[True,False])
def test_vicinity_offset_invariant(self,default,periodic):
offset = default.vicinity_offset(trigger=[default.materials.max()+1,
default.materials.min()-1])
assert np.all(offset.materials==default.materials)
offset = default.vicinity_offset(trigger=[default.material.max()+1,
default.material.min()-1])
assert np.all(offset.material==default.material)
@pytest.mark.parametrize('periodic',[True,False])
@ -338,7 +338,7 @@ class TestGeom:
ms = np.random.randint(1, N_seeds+1)
weights[ms-1] = np.random.random()
Laguerre = Geom.from_Laguerre_tessellation(grid,size,seeds,weights,np.random.random()>0.5)
assert np.all(Laguerre.materials == ms)
assert np.all(Laguerre.material == ms)
@pytest.mark.parametrize('approach',['Laguerre','Voronoi'])
@ -346,10 +346,10 @@ class TestGeom:
grid = np.random.randint(5,10,3)*2
size = grid.astype(np.float)
seeds = np.vstack((size*np.array([0.5,0.25,0.5]),size*np.array([0.5,0.75,0.5])))
materials = np.ones(grid)
materials[:,grid[1]//2:,:] = 2
material = np.ones(grid)
material[:,grid[1]//2:,:] = 2
if approach == 'Laguerre':
geom = Geom.from_Laguerre_tessellation(grid,size,seeds,np.ones(2),np.random.random()>0.5)
elif approach == 'Voronoi':
geom = Geom.from_Voronoi_tessellation(grid,size,seeds, np.random.random()>0.5)
assert np.all(geom.materials == materials)
assert np.all(geom.material == material)