2013-03-05 22:01:17 +05:30
#!/usr/bin/env python
2013-05-13 18:40:31 +05:30
# -*- coding: UTF-8 no BOM -*-
2013-03-05 22:01:17 +05:30
2014-10-10 14:24:48 +05:30
import os , sys , math , string
import numpy as np
from optparse import OptionParser
import damask
2013-07-18 18:58:54 +05:30
2014-11-17 03:14:46 +05:30
scriptID = string . replace ( ' $Id$ ' , ' \n ' , ' \\ n ' )
2014-11-18 21:01:39 +05:30
scriptName = os . path . splitext ( scriptID . split ( ) [ 1 ] ) [ 0 ]
2013-07-18 18:58:54 +05:30
2013-05-13 18:40:31 +05:30
#--------------------------------------------------------------------------------------------------
2013-03-05 22:01:17 +05:30
# MAIN
2013-05-13 18:40:31 +05:30
#--------------------------------------------------------------------------------------------------
2014-10-10 14:24:48 +05:30
parser = OptionParser ( option_class = damask . extendableOption , usage = ' % prog options [file[s]] ' , description = """
2015-04-10 18:27:25 +05:30
Generate geometry description and material configuration from input files used by R . A . Lebensohn .
2013-03-05 22:01:17 +05:30
2014-10-10 14:24:48 +05:30
""" , version = scriptID)
2013-03-05 22:01:17 +05:30
2015-04-10 18:27:25 +05:30
parser . add_option ( ' --column ' , dest = ' column ' , type = ' int ' , metavar = ' int ' ,
help = ' data column to discriminate between both phases [ %d efault] ' )
parser . add_option ( ' -t ' , ' --threshold ' , dest = ' threshold ' , type = ' float ' , metavar = ' float ' ,
help = ' threshold value for phase discrimination [ %d efault] ' )
parser . add_option ( ' --homogenization ' , dest = ' homogenization ' , type = ' int ' , metavar = ' int ' ,
help = ' homogenization index for <microstructure> configuration [ %d efault] ' )
parser . add_option ( ' --phase ' , dest = ' phase ' , type = ' int ' , nargs = 2 , metavar = ' int int ' ,
help = ' phase indices for <microstructure> configuration %d efault ' )
parser . add_option ( ' --crystallite ' , dest = ' crystallite ' , type = ' int ' , metavar = ' int ' ,
help = ' crystallite index for <microstructure> configuration [ %d efault] ' )
parser . add_option ( ' -c ' , ' --configuration ' , dest = ' config ' , action = ' store_true ' ,
2013-05-13 18:40:31 +05:30
help = ' output material configuration [ %d efault] ' )
2015-04-10 18:27:25 +05:30
parser . add_option ( ' --compress ' , dest = ' compress ' , action = ' store_true ' ,
help = ' lump identical microstructure and texture information [ %d efault] ' )
parser . add_option ( ' -p ' , ' --precision ' , dest = ' precision ' , choices = [ ' 0 ' , ' 1 ' , ' 2 ' , ' 3 ' ] , metavar = ' int ' ,
help = ' euler angles decimal places for output format and compressing (0,1,2,3) [2] ' )
2013-03-05 22:01:17 +05:30
2015-04-10 18:27:25 +05:30
parser . set_defaults ( column = 7 )
parser . set_defaults ( threshold = 1.0 )
2013-03-05 22:01:17 +05:30
parser . set_defaults ( homogenization = 1 )
parser . set_defaults ( phase = [ 1 , 2 ] )
parser . set_defaults ( crystallite = 1 )
2015-04-10 18:27:25 +05:30
parser . set_defaults ( config = False )
parser . set_defaults ( compress = False )
parser . set_defaults ( precision = ' 2 ' )
2013-03-05 22:01:17 +05:30
( options , filenames ) = parser . parse_args ( )
2013-05-14 23:21:53 +05:30
#--- setup file handles ---------------------------------------------------------------------------
2013-03-05 22:01:17 +05:30
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 ,
} )
2013-05-13 18:40:31 +05:30
#--- loop over input files ------------------------------------------------------------------------
2013-03-05 22:01:17 +05:30
for file in files :
2014-11-18 21:01:39 +05:30
file [ ' croak ' ] . write ( ' \033 [1m ' + scriptName + ' \033 [0m: ' + ( file [ ' name ' ] if file [ ' name ' ] != ' STDIN ' else ' ' ) + ' \n ' )
2013-03-05 22:01:17 +05:30
2013-05-13 18:40:31 +05:30
info = {
2014-10-10 14:24:48 +05:30
' grid ' : np . zeros ( 3 , ' i ' ) ,
' size ' : np . zeros ( 3 , ' d ' ) ,
' origin ' : np . zeros ( 3 , ' d ' ) ,
2013-05-13 18:40:31 +05:30
' microstructures ' : 0 ,
' homogenization ' : options . homogenization
}
2015-04-10 18:27:25 +05:30
phase = [ ]
eulerangles = [ ]
2013-05-13 18:40:31 +05:30
point = 0
2013-03-05 22:01:17 +05:30
for line in file [ ' input ' ] :
if line . strip ( ) :
words = line . split ( )
2013-05-13 18:40:31 +05:30
currPos = map ( float , words [ 3 : 6 ] )
for i in xrange ( 3 ) :
if currPos [ i ] > info [ ' grid ' ] [ i ] :
info [ ' size ' ] [ i ] = currPos [ i ]
info [ ' grid ' ] [ i ] + = 1
2015-04-10 18:27:25 +05:30
eulerangles . append ( map ( float , words [ : 3 ] ) )
phase . append ( options . phase [ int ( float ( words [ options . column - 1 ] ) > options . threshold ) ] )
eulerangles = np . array ( eulerangles , dtype = ' f ' ) . reshape ( info [ ' grid ' ] . prod ( ) , 3 )
phase = np . array ( phase , dtype = ' i ' ) . reshape ( info [ ' grid ' ] . prod ( ) )
2015-04-10 20:20:23 +05:30
limits = [ 360 , 180 , 360 ]
if any ( [ np . any ( eulerangles [ : , i ] > = limits [ i ] ) for i in [ 0 , 1 , 2 ] ] ) :
file [ ' croak ' ] . write ( ' Error: euler angles out of bound. Ang file might contain unidexed poins. \n ' )
for i , angle in enumerate ( [ ' phi1 ' , ' PHI ' , ' phi2 ' ] ) :
for n in np . nditer ( np . where ( eulerangles [ : , i ] > = limits [ i ] ) , [ ' zerosize_ok ' ] ) :
file [ ' croak ' ] . write ( ' %s in line %i ( %4.2f %4.2f %4.2f ) \n '
% ( angle , n , eulerangles [ n , 0 ] , eulerangles [ n , 1 ] , eulerangles [ n , 2 ] ) )
2015-04-10 18:27:25 +05:30
continue
2015-04-10 20:20:23 +05:30
eulerangles = np . around ( eulerangles , int ( options . precision ) ) # round to desired precision
for i , angle in enumerate ( [ ' phi1 ' , ' PHI ' , ' phi2 ' ] ) :
eulerangles [ : , i ] % = limits [ i ] # ensure, that rounded euler angles are not out of bounds (modulo by limits)
2015-04-10 18:27:25 +05:30
if options . compress :
formatString = ' { 0:0> ' + str ( int ( options . precision ) + 3 ) + ' } '
euleranglesRadInt = ( eulerangles * 10 * * int ( options . precision ) ) . astype ( ' int ' ) # scale by desired precision and convert to int
eulerKeys = np . array ( [ int ( ' ' . join ( map ( formatString . format , euleranglesRadInt [ i , : ] ) ) ) \
for i in xrange ( info [ ' grid ' ] . prod ( ) ) ] ) # create unique integer key from three euler angles by concatenating the string representation with leading zeros and store as integer
devNull , texture , eulerKeys_idx = np . unique ( eulerKeys , return_index = True , return_inverse = True ) # search unique euler angle keys. Texture IDs are the indices of the first occurence, the inverse is used to construct the microstructure
msFull = np . array ( [ [ eulerKeys_idx [ i ] , phase [ i ] ] for i in xrange ( info [ ' grid ' ] . prod ( ) ) ] , ' i8 ' ) # create a microstructure (texture/phase pair) for each point using unique texture IDs. Use longInt (64bit, i8) because the keys might be long
devNull , msUnique , matPoints = np . unique ( msFull . view ( ' c16 ' ) , True , True )
matPoints + = 1
microstructure = np . array ( [ msFull [ i ] for i in msUnique ] ) # pick only unique microstructures
else :
texture = np . arange ( info [ ' grid ' ] . prod ( ) )
microstructure = np . hstack ( zip ( texture , phase ) ) . reshape ( info [ ' grid ' ] . prod ( ) , 2 ) # create texture/phase pairs
formatOut = 1 + int ( math . log10 ( len ( texture ) ) )
textureOut = [ ' \n \n <texture> ' ]
eulerFormatOut = ' %% %i . %i f ' % ( int ( options . precision ) + 4 , int ( options . precision ) )
outStringAngles = ' (gauss) phi1 ' + eulerFormatOut + ' Phi ' + eulerFormatOut + ' phi2 ' + eulerFormatOut + ' scatter 0.0 fraction 1.0 \n '
for i in xrange ( len ( texture ) ) :
textureOut + = [ ' [Texture %s ] \n ' % str ( i + 1 ) . zfill ( formatOut ) +
outStringAngles % tuple ( eulerangles [ texture [ i ] , . . . ] )
]
formatOut = 1 + int ( math . log10 ( len ( microstructure ) ) )
microstructureOut = [ ' <microstructure> ' ]
for i in xrange ( len ( microstructure ) ) :
microstructureOut + = [ ' [Grain %s ] \n ' % str ( i + 1 ) . zfill ( formatOut ) +
' crystallite \t %i \n ' % options . crystallite +
' (constituent) \t phase %i \t texture %i \t fraction 1.0 \n ' % ( microstructure [ i , 1 ] , microstructure [ i , 0 ] + 1 )
]
info [ ' microstructures ' ] = len ( microstructure )
2013-05-13 18:40:31 +05:30
#--- report ---------------------------------------------------------------------------------------
2015-04-10 18:27:25 +05:30
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 ' ] +
2013-05-13 18:40:31 +05:30
' microstructures: %i \n \n ' % info [ ' microstructures ' ] )
2014-10-10 14:24:48 +05:30
if np . any ( info [ ' grid ' ] < 1 ) :
2013-05-17 22:14:03 +05:30
file [ ' croak ' ] . write ( ' invalid grid a b c. \n ' )
2015-04-10 18:27:25 +05:30
continue
2014-10-10 14:24:48 +05:30
if np . any ( info [ ' size ' ] < = 0.0 ) :
2013-05-17 22:14:03 +05:30
file [ ' croak ' ] . write ( ' invalid size x y z. \n ' )
2015-04-10 18:27:25 +05:30
continue
2013-05-15 02:39:37 +05:30
2013-05-13 18:40:31 +05:30
#--- write data -----------------------------------------------------------------------------------
2013-03-05 22:01:17 +05:30
if options . config :
2015-04-10 18:27:25 +05:30
file [ ' output ' ] . write ( ' \n ' . join ( microstructureOut + textureOut ) + ' \n ' )
2013-03-05 22:01:17 +05:30
else :
2015-04-10 18:27:25 +05:30
header = [ ' ' . join ( [ scriptID ] + sys . argv [ 1 : ] ) ,
" grid \t a %i \t b %i \t c %i " % ( info [ ' grid ' ] [ 0 ] , info [ ' grid ' ] [ 1 ] , info [ ' grid ' ] [ 2 ] , ) ,
" size \t x %f \t y %f \t z %f " % ( info [ ' size ' ] [ 0 ] , info [ ' size ' ] [ 1 ] , info [ ' size ' ] [ 2 ] , ) ,
" origin \t x %f \t y %f \t z %f " % ( info [ ' origin ' ] [ 0 ] , info [ ' origin ' ] [ 1 ] , info [ ' origin ' ] [ 2 ] , ) ,
" microstructures \t %i " % info [ ' microstructures ' ] ,
" homogenization \t %i " % info [ ' homogenization ' ] ,
]
file [ ' output ' ] . write ( ' \n ' . join ( [ ' %i \t header ' % ( len ( header ) ) ] + header ) + ' \n ' )
if options . compress :
matPoints = matPoints . reshape ( ( info [ ' grid ' ] [ 1 ] , info [ ' grid ' ] [ 0 ] ) )
np . savetxt ( file [ ' output ' ] , matPoints , fmt = ' % 0 ' + str ( 1 + int ( math . log10 ( np . amax ( matPoints ) ) ) ) + ' d ' )
else :
file [ ' output ' ] . write ( " 1 to %i \n " % ( info [ ' microstructures ' ] ) )
#--- output finalization --------------------------------------------------------------------------
2013-03-05 22:01:17 +05:30
if file [ ' name ' ] != ' STDIN ' :
2015-04-10 18:27:25 +05:30
file [ ' output ' ] . close ( )
os . rename ( file [ ' name ' ] + ' _tmp ' ,
os . path . splitext ( file [ ' name ' ] ) [ 0 ] + ' %s ' % ( ' _material.config ' if options . config else ' .geom ' ) )