parent
0da39b0c69
commit
c8dfba89e5
|
@ -1,11 +1,14 @@
|
|||
#!/usr/bin/env python3
|
||||
# -*- coding: UTF-8 no BOM -*-
|
||||
|
||||
import os,sys,math
|
||||
import numpy as np
|
||||
import os
|
||||
import sys
|
||||
import multiprocessing
|
||||
from io import StringIO
|
||||
from optparse import OptionParser,OptionGroup
|
||||
from scipy import spatial
|
||||
|
||||
import numpy as np
|
||||
from scipy import spatial
|
||||
|
||||
import damask
|
||||
|
||||
scriptName = os.path.splitext(os.path.basename(__file__))[0]
|
||||
|
@ -29,74 +32,74 @@ def meshgrid2(*arrs):
|
|||
ans.insert(0,arr2)
|
||||
return tuple(ans)
|
||||
|
||||
def findClosestSeed(fargs):
|
||||
|
||||
def laguerreTessellation(undeformed, coords, weights, grains, periodic = True, cpus = 2):
|
||||
|
||||
def findClosestSeed(fargs):
|
||||
point, seeds, myWeights = fargs
|
||||
tmp = np.repeat(point.reshape(3,1), len(seeds), axis=1).T
|
||||
dist = np.sum((tmp - seeds)**2,axis=1) -myWeights
|
||||
return np.argmin(dist) # seed point closest to point
|
||||
|
||||
copies = \
|
||||
np.array([
|
||||
[ -1,-1,-1 ],
|
||||
[ 0,-1,-1 ],
|
||||
[ 1,-1,-1 ],
|
||||
[ -1, 0,-1 ],
|
||||
[ 0, 0,-1 ],
|
||||
[ 1, 0,-1 ],
|
||||
[ -1, 1,-1 ],
|
||||
[ 0, 1,-1 ],
|
||||
[ 1, 1,-1 ],
|
||||
[ -1,-1, 0 ],
|
||||
[ 0,-1, 0 ],
|
||||
[ 1,-1, 0 ],
|
||||
[ -1, 0, 0 ],
|
||||
[ 0, 0, 0 ],
|
||||
[ 1, 0, 0 ],
|
||||
[ -1, 1, 0 ],
|
||||
[ 0, 1, 0 ],
|
||||
[ 1, 1, 0 ],
|
||||
[ -1,-1, 1 ],
|
||||
[ 0,-1, 1 ],
|
||||
[ 1,-1, 1 ],
|
||||
[ -1, 0, 1 ],
|
||||
[ 0, 0, 1 ],
|
||||
[ 1, 0, 1 ],
|
||||
[ -1, 1, 1 ],
|
||||
[ 0, 1, 1 ],
|
||||
[ 1, 1, 1 ],
|
||||
]).astype(float)*info['size'] if periodic else \
|
||||
np.array([
|
||||
[ 0, 0, 0 ],
|
||||
]).astype(float)
|
||||
|
||||
def laguerreTessellation(undeformed, coords, weights, grains, periodic = True, cpus = 2):
|
||||
repeatweights = np.tile(weights,len(copies)).flatten(order='F') # Laguerre weights (1,2,3,1,2,3,...,1,2,3)
|
||||
for i,vec in enumerate(copies): # periodic copies of seed points ...
|
||||
try: seeds = np.append(seeds, coords+vec, axis=0) # ... (1+a,2+a,3+a,...,1+z,2+z,3+z)
|
||||
except NameError: seeds = coords+vec
|
||||
|
||||
copies = \
|
||||
np.array([
|
||||
[ -1,-1,-1 ],
|
||||
[ 0,-1,-1 ],
|
||||
[ 1,-1,-1 ],
|
||||
[ -1, 0,-1 ],
|
||||
[ 0, 0,-1 ],
|
||||
[ 1, 0,-1 ],
|
||||
[ -1, 1,-1 ],
|
||||
[ 0, 1,-1 ],
|
||||
[ 1, 1,-1 ],
|
||||
[ -1,-1, 0 ],
|
||||
[ 0,-1, 0 ],
|
||||
[ 1,-1, 0 ],
|
||||
[ -1, 0, 0 ],
|
||||
[ 0, 0, 0 ],
|
||||
[ 1, 0, 0 ],
|
||||
[ -1, 1, 0 ],
|
||||
[ 0, 1, 0 ],
|
||||
[ 1, 1, 0 ],
|
||||
[ -1,-1, 1 ],
|
||||
[ 0,-1, 1 ],
|
||||
[ 1,-1, 1 ],
|
||||
[ -1, 0, 1 ],
|
||||
[ 0, 0, 1 ],
|
||||
[ 1, 0, 1 ],
|
||||
[ -1, 1, 1 ],
|
||||
[ 0, 1, 1 ],
|
||||
[ 1, 1, 1 ],
|
||||
]).astype(float)*info['size'] if periodic else \
|
||||
np.array([
|
||||
[ 0, 0, 0 ],
|
||||
]).astype(float)
|
||||
if (repeatweights == 0.0).all(): # standard Voronoi (no weights, KD tree)
|
||||
myKDTree = spatial.cKDTree(seeds)
|
||||
devNull,closestSeeds = myKDTree.query(undeformed)
|
||||
else:
|
||||
damask.util.croak('...using {} cpu{}'.format(options.cpus, 's' if options.cpus > 1 else ''))
|
||||
arguments = [[arg,seeds,repeatweights] for arg in list(undeformed)]
|
||||
|
||||
repeatweights = np.tile(weights,len(copies)).flatten(order='F') # Laguerre weights (1,2,3,1,2,3,...,1,2,3)
|
||||
for i,vec in enumerate(copies): # periodic copies of seed points ...
|
||||
try: seeds = np.append(seeds, coords+vec, axis=0) # ... (1+a,2+a,3+a,...,1+z,2+z,3+z)
|
||||
except NameError: seeds = coords+vec
|
||||
|
||||
if (repeatweights == 0.0).all(): # standard Voronoi (no weights, KD tree)
|
||||
myKDTree = spatial.cKDTree(seeds)
|
||||
devNull,closestSeeds = myKDTree.query(undeformed)
|
||||
if cpus > 1: # use multithreading
|
||||
pool = multiprocessing.Pool(processes = cpus) # initialize workers
|
||||
result = pool.map_async(findClosestSeed, arguments) # evaluate function in parallel
|
||||
pool.close()
|
||||
pool.join()
|
||||
closestSeeds = np.array(result.get()).flatten()
|
||||
else:
|
||||
damask.util.croak('...using {} cpu{}'.format(options.cpus, 's' if options.cpus > 1 else ''))
|
||||
arguments = [[arg,seeds,repeatweights] for arg in list(undeformed)]
|
||||
|
||||
if cpus > 1: # use multithreading
|
||||
pool = multiprocessing.Pool(processes = cpus) # initialize workers
|
||||
result = pool.map_async(findClosestSeed, arguments) # evaluate function in parallel
|
||||
pool.close()
|
||||
pool.join()
|
||||
closestSeeds = np.array(result.get()).flatten()
|
||||
else:
|
||||
closestSeeds = np.zeros(len(arguments),dtype='i')
|
||||
for i,arg in enumerate(arguments):
|
||||
closestSeeds[i] = findClosestSeed(arg)
|
||||
closestSeeds = np.zeros(len(arguments),dtype='i')
|
||||
for i,arg in enumerate(arguments):
|
||||
closestSeeds[i] = findClosestSeed(arg)
|
||||
|
||||
# closestSeed is modulo number of original seed points (i.e. excluding periodic copies)
|
||||
return grains[closestSeeds%coords.shape[0]]
|
||||
return grains[closestSeeds%coords.shape[0]]
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
# MAIN
|
||||
|
@ -220,10 +223,7 @@ parser.set_defaults(pos = 'pos',
|
|||
if filenames == []: filenames = [None]
|
||||
|
||||
for name in filenames:
|
||||
try: table = damask.ASCIItable(name = name,
|
||||
outname = os.path.splitext(name)[0]+'.geom' if name else name,
|
||||
buffered = False)
|
||||
except: continue
|
||||
table = damask.ASCIItable(name = name, readonly = True)
|
||||
damask.util.report(scriptName,name)
|
||||
|
||||
# --- read header ----------------------------------------------------------------------------
|
||||
|
@ -281,7 +281,7 @@ for name in filenames:
|
|||
else table.data[:,table.label_indexrange(options.pos)] - info['origin']
|
||||
eulers = table.data[:,table.label_indexrange(options.eulers)] if hasEulers \
|
||||
else np.zeros(3*len(coords))
|
||||
grains = table.data[:,table.label_indexrange(options.microstructure)].astype('i') if hasGrains \
|
||||
grains = table.data[:,table.label_indexrange(options.microstructure)].astype(int) if hasGrains \
|
||||
else 1+np.arange(len(coords))
|
||||
weights = table.data[:,table.label_indexrange(options.weight)] if hasWeights \
|
||||
else np.zeros(len(coords))
|
||||
|
@ -299,20 +299,8 @@ for name in filenames:
|
|||
grid = np.vstack(meshgrid2(x, y, z)).reshape(3,-1).T
|
||||
indices = laguerreTessellation(grid, coords, weights, grains, options.periodic, options.cpus)
|
||||
|
||||
# --- write header ------------------------------------------------------------------------
|
||||
|
||||
usedGrainIDs = np.intersect1d(grainIDs,indices)
|
||||
info['microstructures'] = len(usedGrainIDs)
|
||||
|
||||
if info['homogenization'] == 0: info['homogenization'] = options.homogenization
|
||||
|
||||
damask.util.report_geom(info,['grid','size','origin','homogenization',])
|
||||
damask.util.croak(['microstructures: {}{}'.format(info['microstructures'],
|
||||
(' out of {}'.format(NgrainIDs) if NgrainIDs != info['microstructures'] else '')),
|
||||
])
|
||||
|
||||
config_header = []
|
||||
formatwidth = 1+int(math.log10(NgrainIDs))
|
||||
formatwidth = 1+int(np.log10(NgrainIDs))
|
||||
|
||||
if options.config:
|
||||
config_header += ['<microstructure>']
|
||||
|
@ -331,24 +319,10 @@ for name in filenames:
|
|||
] + theAxes
|
||||
config_header += ['<!skip>']
|
||||
|
||||
table.labels_clear()
|
||||
table.info_clear()
|
||||
table.info_append([
|
||||
scriptID + ' ' + ' '.join(sys.argv[1:]),
|
||||
"grid\ta {}\tb {}\tc {}".format(*info['grid']),
|
||||
"size\tx {}\ty {}\tz {}".format(*info['size']),
|
||||
"origin\tx {}\ty {}\tz {}".format(*info['origin']),
|
||||
"homogenization\t{}".format(info['homogenization']),
|
||||
"microstructures\t{}".format(info['microstructures']),
|
||||
config_header,
|
||||
])
|
||||
table.head_write()
|
||||
geom = damask.Geom(indices.reshape(info['grid'],order='F'),info['size'],options.homogenization,comments=config_header)
|
||||
damask.util.croak(geom)
|
||||
|
||||
# --- write microstructure information ------------------------------------------------------------
|
||||
|
||||
table.data = indices.reshape(info['grid'][1]*info['grid'][2],info['grid'][0])
|
||||
table.data_writeArray('%%%ii'%(formatwidth),delimiter=' ')
|
||||
|
||||
#--- output finalization --------------------------------------------------------------------------
|
||||
|
||||
table.close()
|
||||
if name is None:
|
||||
sys.stdout.write(str(geom.show()))
|
||||
else:
|
||||
geom.to_file(os.path.splitext(name)[0]+'.geom')
|
||||
|
|
|
@ -12,7 +12,7 @@ class Geom():
|
|||
|
||||
if len(microstructure.shape) != 3:
|
||||
raise ValueError('Invalid microstructure shape {}'.format(*microstructure.shape))
|
||||
elif microstructure.dtype not in ['int','float']:
|
||||
elif microstructure.dtype not in [int,float]:
|
||||
raise TypeError('Invalid data type {} for microstructure'.format(microstructure.dtype))
|
||||
else:
|
||||
self.microstructure = microstructure
|
||||
|
|
Loading…
Reference in New Issue