From 41f1994569c6696ef55674ba2bd04d023f2bf235 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Mon, 26 Oct 2015 17:59:36 +0000 Subject: [PATCH] new style and test for grain growth --- processing/pre/geom_grainGrowth.py | 202 ++++++++++------------------- 1 file changed, 71 insertions(+), 131 deletions(-) diff --git a/processing/pre/geom_grainGrowth.py b/processing/pre/geom_grainGrowth.py index 6e528f7dd..a7674a15c 100755 --- a/processing/pre/geom_grainGrowth.py +++ b/processing/pre/geom_grainGrowth.py @@ -13,18 +13,6 @@ scriptName = os.path.splitext(scriptID.split()[1])[0] #-------------------------------------------------------------------------------------------------- # MAIN #-------------------------------------------------------------------------------------------------- -identifiers = { - 'grid': ['a','b','c'], - 'size': ['x','y','z'], - 'origin': ['x','y','z'], - } -mappings = { - 'grid': lambda x: int(x), - 'size': lambda x: float(x), - 'origin': lambda x: float(x), - 'homogenization': lambda x: int(x), - 'microstructures': lambda x: int(x), - } parser = OptionParser(option_class=damask.extendableOption, usage='%prog options [file[s]]', description = """ Smoothens out interface roughness by simulated curvature flow. @@ -52,98 +40,48 @@ parser.set_defaults(immutable = []) options.immutable = map(int,options.immutable) -#--- setup file handles -------------------------------------------------------------------------- -files = [] -if filenames == []: - files.append({'name':'STDIN', - 'input':sys.stdin, - 'output':sys.stdout, - 'croak':sys.stderr, - }) -else: - for name in filenames: - if os.path.exists(name): - files.append({'name':name, - 'input':open(name), - 'output':open(name+'_tmp','w'), - 'croak':sys.stdout, - }) +# --- loop over input files ------------------------------------------------------------------------- -#--- loop over input files ------------------------------------------------------------------------ -for file in files: - if file['name'] != 'STDIN': file['croak'].write('\033[1m'+scriptName+'\033[0m: '+file['name']+'\n') - else: file['croak'].write('\033[1m'+scriptName+'\033[0m\n') +if filenames == []: filenames = [None] - theTable = damask.ASCIItable(file['input'],file['output'],labeled = False,buffered = False) - theTable.head_read() +for name in filenames: + try: + table = damask.ASCIItable(name = name, + buffered = False, labeled = False) + except: continue + damask.util.report(scriptName,name) -#--- interpret header ---------------------------------------------------------------------------- - info = { - 'grid': np.zeros(3,'i'), - 'size': np.zeros(3,'d'), - 'origin': np.zeros(3,'d'), - 'homogenization': 0, - 'microstructures': 0, - } - newInfo = { - 'microstructures': 0, - } - extra_header = [] +# --- interpret header ---------------------------------------------------------------------------- - for header in theTable.info: - headitems = map(str.lower,header.split()) - if len(headitems) == 0: continue - if headitems[0] in mappings.keys(): - if headitems[0] in identifiers.keys(): - for i in xrange(len(identifiers[headitems[0]])): - info[headitems[0]][i] = \ - mappings[headitems[0]](headitems[headitems.index(identifiers[headitems[0]][i])+1]) - else: - info[headitems[0]] = mappings[headitems[0]](headitems[1]) - else: - extra_header.append(header) + table.head_read() + info,extra_header = table.head_getGeom() + + damask.util.croak(['grid a b c: %s'%(' x '.join(map(str,info['grid']))), + 'size x y z: %s'%(' x '.join(map(str,info['size']))), + 'origin x y z: %s'%(' : '.join(map(str,info['origin']))), + 'homogenization: %i'%info['homogenization'], + 'microstructures: %i'%info['microstructures'], + ]) - file['croak'].write('grid a b c: %s\n'%(' x '.join(map(str,info['grid']))) + \ - 'size x y z: %s\n'%(' x '.join(map(str,info['size']))) + \ - 'origin x y z: %s\n'%(' : '.join(map(str,info['origin']))) + \ - 'homogenization: %i\n'%info['homogenization'] + \ - 'microstructures: %i\n'%info['microstructures']) - - if np.any(info['grid'] < 1): - file['croak'].write('invalid grid a b c.\n') - continue - if np.any(info['size'] <= 0.0): - file['croak'].write('invalid size x y z.\n') + errors = [] + if np.any(info['grid'] < 1): errors.append('invalid grid a b c.') + if np.any(info['size'] <= 0.0): errors.append('invalid size x y z.') + if errors != []: + damask.util.croak(errors) + table.close(dismiss = True) continue -#--- read data ------------------------------------------------------------------------------------ - microstructure = np.zeros(np.prod(info['grid']),'i') # 2D structures do not work - i = 0 - - while theTable.data_read(): # read next data line of ASCII table - items = theTable.data - if len(items) > 2: - if items[1].lower() == 'of': items = [int(items[2])]*int(items[0]) - elif items[1].lower() == 'to': items = xrange(int(items[0]),1+int(items[2])) - else: items = map(int,items) - else: items = map(int,items) - - s = len(items) - microstructure[i:i+s] = items - i += s - -#--- reshape, if 2D make copy --------------------------------------------------------------------- - - microstructure = np.tile(microstructure.reshape(info['grid'],order='F'), - np.where(info['grid'] == 1, 2,1)) # make one copy along dimensions with grid == 1 +# --- read data ------------------------------------------------------------------------------------ + microstructure = np.tile(np.array(table.microstructure_read(info['grid']),'i').reshape(info['grid'],order='F'), + np.where(info['grid'] == 1, 2,1)) # make one copy along dimensions with grid == 1 grid = np.array(microstructure.shape) #--- initialize support data ----------------------------------------------------------------------- periodic_microstructure = np.tile(microstructure,(3,3,3))[grid[0]/2:-grid[0]/2, - grid[1]/2:-grid[1]/2, - grid[2]/2:-grid[2]/2] # periodically extend the microstructure - microstructure_original = np.copy(microstructure) # store a copy the initial microstructure to find locations of immutable indices + grid[1]/2:-grid[1]/2, + grid[2]/2:-grid[2]/2] # periodically extend the microstructure + microstructure_original = np.copy(microstructure) # store a copy the initial microstructure to find locations of immutable indices X,Y,Z = np.mgrid[0:grid[0],0:grid[1],0:grid[2]] gauss = np.exp(-(X*X + Y*Y + Z*Z)/(2.0*options.d*options.d))/math.pow(2.0*np.pi*options.d*options.d,1.5) @@ -153,7 +91,7 @@ for file in files: gauss = np.fft.rfftn(gauss) interfacialEnergy = lambda A,B: (A*B != 0)*(A != B)*1.0 - struc = ndimage.generate_binary_structure(3,1) # 3D von Neumann neighborhood + struc = ndimage.generate_binary_structure(3,1) # 3D von Neumann neighborhood for smoothIter in xrange(options.N): @@ -163,42 +101,42 @@ for file in files: for k in (-1,0,1): interfaceEnergy = np.maximum(boundary, interfacialEnergy(microstructure,np.roll(np.roll(np.roll( - microstructure,i,axis=0), j,axis=1), k,axis=2))) # assign interfacial energy to all voxels that have a differing neighbor (in Moore neighborhood) + microstructure,i,axis=0), j,axis=1), k,axis=2))) # assign interfacial energy to all voxels that have a differing neighbor (in Moore neighborhood) periodic_interfaceEnergy = np.tile(interfaceEnergy,(3,3,3))[grid[0]/2:-grid[0]/2, grid[1]/2:-grid[1]/2, - grid[2]/2:-grid[2]/2] # periodically extend interfacial energy array by half a grid size in positive and negative directions - index = ndimage.morphology.distance_transform_edt(periodic_interfaceEnergy == 0., # transform bulk volume (i.e. where interfacial energy is zero) + grid[2]/2:-grid[2]/2] # periodically extend interfacial energy array by half a grid size in positive and negative directions + index = ndimage.morphology.distance_transform_edt(periodic_interfaceEnergy == 0., # transform bulk volume (i.e. where interfacial energy is zero) return_distances = False, - return_indices = True) # want array index of nearest voxel on periodically extended boundary -# boundaryExt = boundaryExt[index[0].flatten(),index[1].flatten(),index[2].flatten()].reshape(boundaryExt.shape) # fill bulk with energy of nearest interface | question PE: what "flatten" for? + return_indices = True) # want array index of nearest voxel on periodically extended boundary +# boundaryExt = boundaryExt[index[0].flatten(),index[1].flatten(),index[2].flatten()].reshape(boundaryExt.shape) # fill bulk with energy of nearest interface | question PE: what "flatten" for? periodic_bulkEnergy = periodic_interfaceEnergy[index[0], index[1], - index[2]].reshape(2*grid) # fill bulk with energy of nearest interface + index[2]].reshape(2*grid) # fill bulk with energy of nearest interface diffusedEnergy = np.fft.irfftn(np.fft.rfftn(np.where(ndimage.morphology.binary_dilation(interfaceEnergy > 0., structure = struc, iterations = options.d/2 + 1), # fat boundary | question PE: why 2d - 1? I would argue for d/2 + 1 !! - periodic_bulkEnergy[grid[0]/2:-grid[0]/2, # retain filled energy on fat boundary... + periodic_bulkEnergy[grid[0]/2:-grid[0]/2, # retain filled energy on fat boundary... grid[1]/2:-grid[1]/2, - grid[2]/2:-grid[2]/2], # ...and zero everywhere else + grid[2]/2:-grid[2]/2], # ...and zero everywhere else 0.)\ )*gauss) periodic_diffusedEnergy = np.tile(diffusedEnergy,(3,3,3))[grid[0]/2:-grid[0]/2, grid[1]/2:-grid[1]/2, - grid[2]/2:-grid[2]/2] # periodically extend the smoothed bulk energy - index = ndimage.morphology.distance_transform_edt(periodic_diffusedEnergy >= 0.5, # transform voxels close to interface region | question PE: what motivates 1/2 (could be any small number, or)? + grid[2]/2:-grid[2]/2] # periodically extend the smoothed bulk energy + index = ndimage.morphology.distance_transform_edt(periodic_diffusedEnergy >= 0.5, # transform voxels close to interface region | question PE: what motivates 1/2 (could be any small number, or)? return_distances = False, - return_indices = True) # want index of closest bulk grain + return_indices = True) # want index of closest bulk grain microstructure = periodic_microstructure[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 + grid[2]/2:-grid[2]/2] # extent grains into interface region immutable = np.zeros(microstructure.shape, dtype=bool) for micro in options.immutable: - immutable += np.logical_or(microstructure == micro, microstructure_original == micro) # find locations where immutable microstructures have been or are now + immutable += np.logical_or(microstructure == micro, microstructure_original == micro) # find locations where immutable microstructures have been or are now - microstructure = np.where(immutable, microstructure_original,microstructure) # undo any changes involving immutable microstructures + microstructure = np.where(immutable, microstructure_original,microstructure) # undo any changes involving immutable microstructures # --- renumber to sequence 1...Ngrains if requested ------------------------------------------------ # http://stackoverflow.com/questions/10741346/np-frequency-counts-for-unique-values-in-an-array @@ -210,33 +148,35 @@ for file in files: newID += 1 microstructure = np.where(microstructure == microstructureID, newID, microstructure) -# --- assemble header ----------------------------------------------------------------------------- - newInfo['microstructures'] = microstructure[0:info['grid'][0],0:info['grid'][1],0:info['grid'][2]].max() + newInfo = {'microstructures': 0,} + newInfo['microstructures'] = microstructure.max() -#--- report --------------------------------------------------------------------------------------- - if (newInfo['microstructures'] != info['microstructures']): - file['croak'].write('--> microstructures: %i\n'%newInfo['microstructures']) +# --- report --------------------------------------------------------------------------------------- -#--- write header --------------------------------------------------------------------------------- - theTable.labels_clear() - theTable.info_clear() - theTable.info_append(extra_header+[ - scriptID+ ' ' + ' '.join(sys.argv[1:]), - "grid\ta %i\tb %i\tc %i"%(info['grid'][0],info['grid'][1],info['grid'][2],), - "size\tx %f\ty %f\tz %f"%(info['size'][0],info['size'][1],info['size'][2],), - "origin\tx %f\ty %f\tz %f"%(info['origin'][0],info['origin'][1],info['origin'][2],), - "homogenization\t%i"%info['homogenization'], - "microstructures\t%i"%(newInfo['microstructures']), + remarks = [] + if (newInfo['microstructures'] != info['microstructures']): remarks.append('--> microstructures: %i'%newInfo['microstructures']) + if remarks != []: damask.util.croak(remarks) + +# --- write header --------------------------------------------------------------------------------- + + table.labels_clear() + table.info_clear() + table.info_append(extra_header+[ + scriptID + ' ' + ' '.join(sys.argv[1:]), + "grid\ta {grid[0]}\tb {grid[1]}\tc {grid[2]}".format(grid=info['grid']), + "size\tx {size[0]}\ty {size[1]}\tz {size[2]}".format(size=info['size']), + "origin\tx {origin[0]}\ty {origin[1]}\tz {origin[2]}".format(origin=info['origin']), + "homogenization\t{homog}".format(homog=info['homogenization']), + "microstructures\t{microstructures}".format(microstructures=newInfo['microstructures']), ]) - theTable.head_write() + table.head_write() # --- write microstructure information ------------------------------------------------------------ - formatwidth = int(math.floor(math.log10(microstructure.max())+1)) - theTable.data = microstructure[0:info['grid'][0],0:info['grid'][1],0:info['grid'][2]].reshape(np.prod(info['grid']),order='F').transpose() # question PE: this assumes that only the Z dimension can be 1! - theTable.data_writeArray('%%%ii'%(formatwidth),delimiter=' ') -#--- output finalization -------------------------------------------------------------------------- - if file['name'] != 'STDIN': - theTable.input_close() - theTable.output_close() - os.rename(file['name']+'_tmp',file['name']) + formatwidth = int(math.floor(math.log10(microstructure.max())+1)) + table.data = microstructure.reshape((info['grid'][0],info['grid'][1]*info['grid'][2]),order='F').transpose() + table.data_writeArray('%%%ii'%(formatwidth),delimiter = ' ') + +# --- output finalization -------------------------------------------------------------------------- + + table.close()