2014-04-02 00:11:14 +05:30
# -*- coding: UTF-8 no BOM -*-
2011-12-22 16:00:25 +05:30
# $Id$
2012-02-02 01:14:36 +05:30
import re
2011-12-22 16:00:25 +05:30
2012-02-02 01:14:36 +05:30
class Section ( ) :
def __init__ ( self , data = { ' __order__ ' : [ ] } , part = ' ' ) :
classes = {
' homogenization ' : Homogenization ,
' microstructure ' : Microstructure ,
' crystallite ' : Crystallite ,
' phase ' : Phase ,
' texture ' : Texture ,
}
self . parameters = { }
for key in data :
if type ( data [ key ] ) is not list :
self . parameters [ key ] = [ data [ key ] ]
else :
self . parameters [ key ] = data [ key ]
if ' __order__ ' not in self . parameters :
self . parameters [ ' __order__ ' ] = 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 ]
if type ( data ) == list : self . parameters [ multiKey ] + = [ [ item ] for item in data ]
else : self . parameters [ multiKey ] + = [ [ data ] ]
def data ( self ) :
return self . parameters
class Homogenization ( Section ) :
def __init__ ( self , data = { ' __order__ ' : [ ] } ) :
Section . __init__ ( self , data )
class Crystallite ( Section ) :
def __init__ ( self , data = { ' __order__ ' : [ ] } ) :
Section . __init__ ( self , data )
class Phase ( Section ) :
def __init__ ( self , data = { ' __order__ ' : [ ] } ) :
Section . __init__ ( self , data )
class Microstructure ( Section ) :
def __init__ ( self , data = { ' __order__ ' : [ ] } ) :
Section . __init__ ( self , data )
class Texture ( Section ) :
def __init__ ( self , data = { ' __order__ ' : [ ] } ) :
Section . __init__ ( self , data )
def add_component ( self , theType , properties ) :
if ' scatter ' not in map ( str . lower , properties . keys ( ) ) :
2014-06-16 18:41:26 +05:30
scatter = 0.0
else :
scatter = properties [ ' scatter ' ]
2012-02-02 01:14:36 +05:30
if ' fraction ' not in map ( str . lower , properties . keys ( ) ) :
2014-06-16 18:41:26 +05:30
fraction = 1.0
else :
fraction = properties [ ' fraction ' ]
2012-02-02 01:14:36 +05:30
2014-06-17 14:23:37 +05:30
try :
multiKey = theType . lower ( )
except AttributeError :
pass
2012-02-02 01:14:36 +05:30
if multiKey == ' gauss ' :
self . add_multiKey ( multiKey , ' phi1 %g \t Phi %g \t phi2 %g \t scatter %g \t fraction %g ' % (
properties [ ' eulers ' ] [ 0 ] ,
properties [ ' eulers ' ] [ 1 ] ,
properties [ ' eulers ' ] [ 2 ] ,
scatter ,
fraction ,
)
)
if multiKey == ' fiber ' :
self . add_multiKey ( multiKey , ' alpha1 %g \t alpha2 %g \t beta1 %g \t beta2 %g \t scatter %g \t fraction %g ' % (
properties [ ' eulers ' ] [ 0 ] ,
properties [ ' eulers ' ] [ 1 ] ,
properties [ ' eulers ' ] [ 2 ] ,
properties [ ' eulers ' ] [ 3 ] ,
scatter ,
fraction ,
)
)
2011-12-14 01:32:26 +05:30
class Material ( ) :
2012-02-02 01:14:36 +05:30
2011-12-14 01:32:26 +05:30
'''
Reads , manipulates and writes material . config files
'''
__slots__ = [ ' data ' ]
2015-04-23 00:17:45 +05:30
def __init__ ( self , verbose = True ) :
2011-12-14 01:32:26 +05:30
self . parts = [
' homogenization ' ,
' microstructure ' ,
' crystallite ' ,
' phase ' ,
' texture ' ,
] # ordered (!) list of parts
self . data = { \
' homogenization ' : { ' __order__ ' : [ ] } ,
' microstructure ' : { ' __order__ ' : [ ] } ,
' crystallite ' : { ' __order__ ' : [ ] } ,
' phase ' : { ' __order__ ' : [ ] } ,
' texture ' : { ' __order__ ' : [ ] } ,
}
2015-04-23 00:17:45 +05:30
self . verbose = verbose
2011-12-14 01:32:26 +05:30
def __repr__ ( self ) :
me = [ ]
for part in self . parts :
2015-04-23 00:17:45 +05:30
if self . verbose : print ( ' doing ' + part )
2011-12-14 01:32:26 +05:30
me + = [ ' ' , ' #-----------------------------# ' , ' < %s > ' % part , ' #-----------------------------# ' , ]
for section in self . data [ part ] [ ' __order__ ' ] :
me + = [ ' ' , ' [ %s ] %s ' % ( section , ' - ' * max ( 0 , 27 - len ( section ) ) ) , ' ' , ]
for key in self . data [ part ] [ section ] [ ' __order__ ' ] :
if key . startswith ( ' ( ' ) and key . endswith ( ' ) ' ) : # multiple (key)
me + = [ ' %s \t %s ' % ( key , ' ' . join ( values ) ) for values in self . data [ part ] [ section ] [ key ] ]
else : # plain key
me + = [ ' %s \t %s ' % ( key , ' ' . join ( map ( str , self . data [ part ] [ section ] [ key ] ) ) ) ]
return ' \n ' . join ( me )
def parse_data ( self , part = None , sections = [ ] , content = None ) :
re_part = re . compile ( r ' ^<(.+)>$ ' ) # pattern for part
re_sec = re . compile ( r ' ^ \ [(.+) \ ]$ ' ) # pattern for section
name_section = ' '
idx_section = 0
active = False
for line in content :
2012-02-02 01:14:36 +05:30
line = line . split ( ' # ' ) [ 0 ] . strip ( ) # kill comments and extra whitespace
2015-03-15 20:54:45 +05:30
line = line . split ( ' /echo/ ' ) [ 0 ] . strip ( ) # remove '/echo/' tags
2014-06-16 18:41:26 +05:30
line = line . lower ( ) # be case insensitive
2011-12-14 01:32:26 +05:30
if line : # content survives...
2015-03-27 21:53:21 +05:30
match_part = re_part . match ( line . split ( ) [ 0 ] )
2011-12-14 01:32:26 +05:30
if match_part : # found <part> separator
active = ( match_part . group ( 1 ) == part ) # only active in <part>
continue
if active :
2015-03-27 21:53:21 +05:30
match_sec = re_sec . match ( line . split ( ) [ 0 ] )
2011-12-14 01:32:26 +05:30
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 : # respect 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 , file = None ) :
2012-02-02 01:14:36 +05:30
f = open ( file , ' r ' )
c = f . readlines ( )
f . close ( )
for p in self . parts :
self . parse_data ( part = p , content = c )
2011-12-14 01:32:26 +05:30
def write ( self , file = ' material.config ' , overwrite = False ) :
2012-02-02 01:14:36 +05:30
import os
i = 0
saveFile = file
while not overwrite and os . path . exists ( saveFile ) :
i + = 1
saveFile = file + ' _ %i ' % i
2015-04-23 00:17:45 +05:30
if self . verbose : print ( ' Writing material data to file %s ' % saveFile )
2012-02-02 01:14:36 +05:30
f = open ( saveFile , ' w ' )
2012-02-24 20:04:44 +05:30
f . write ( str ( self ) + ' \n ' ) #newline at end
2012-02-02 01:14:36 +05:30
f . close ( )
return saveFile
2014-06-16 18:41:26 +05:30
def add_section ( self , part = None , section = None , initialData = None , merge = False ) :
2012-02-02 01:14:36 +05:30
''' adding/updating '''
2014-06-16 18:41:26 +05:30
part = part . lower ( )
section = section . lower ( )
2011-12-14 01:32:26 +05:30
if part not in self . parts : raise Exception ( ' invalid part %s ' % part )
2012-02-02 01:14:36 +05:30
2014-06-16 18:41:26 +05:30
if type ( initialData ) is not dict :
initialData = initialData . data ( )
2012-02-02 01:14:36 +05:30
2011-12-14 01:32:26 +05:30
if section not in self . data [ part ] : self . data [ part ] [ ' __order__ ' ] + = [ section ]
2012-02-02 01:14:36 +05:30
if section in self . data [ part ] and merge :
2014-06-17 14:23:37 +05:30
for existing in self . data [ part ] [ section ] [ ' __order__ ' ] : # replace existing
2014-06-16 18:41:26 +05:30
if existing in initialData [ ' __order__ ' ] :
2014-06-17 14:23:37 +05:30
if existing . startswith ( ' ( ' ) and existing . endswith ( ' ) ' ) : # multiple (key)
2014-06-16 18:41:26 +05:30
self . data [ part ] [ section ] [ existing ] + = initialData [ existing ] # add new multiple entries to existing ones
2014-06-17 14:23:37 +05:30
else : # regular key
2014-06-16 18:41:26 +05:30
self . data [ part ] [ section ] [ existing ] = initialData [ existing ] # plain replice
for new in initialData [ ' __order__ ' ] : # merge new content
2012-02-02 01:14:36 +05:30
if new not in self . data [ part ] [ section ] [ ' __order__ ' ] :
2014-06-16 18:41:26 +05:30
self . data [ part ] [ section ] [ new ] = initialData [ new ]
2012-02-02 01:14:36 +05:30
self . data [ part ] [ section ] [ ' __order__ ' ] + = [ new ]
else :
2014-06-16 18:41:26 +05:30
self . data [ part ] [ section ] = initialData
2012-02-02 01:14:36 +05:30
2011-12-14 01:32:26 +05:30
2012-02-02 01:14:36 +05:30
def add_microstructure ( self , section = ' ' ,
components = { } , # dict of phase,texture, and fraction lists
) :
2011-12-14 01:32:26 +05:30
''' Experimental! Needs expansion to multi-constituent microstructures... '''
2012-02-02 01:14:36 +05:30
microstructure = Microstructure ( )
2014-06-17 14:23:37 +05:30
components = dict ( ( k . lower ( ) , v ) for k , v in components . iteritems ( ) ) # make keys lower case (http://stackoverflow.com/questions/764235/dictionary-to-lowercase-in-python)
for key in [ ' phase ' , ' texture ' , ' fraction ' , ' crystallite ' ] :
if type ( components [ key ] ) is not list :
try :
components [ key ] = [ components [ key ] . lower ( ) ]
except AttributeError :
components [ key ] = [ components [ key ] ]
else :
for i , x in enumerate ( components [ key ] ) :
try :
components [ key ] [ i ] = x . lower ( )
except AttributeError :
pass
2012-05-24 21:30:32 +05:30
for ( phase , texture , fraction , crystallite ) in zip ( components [ ' phase ' ] , components [ ' texture ' ] , components [ ' fraction ' ] , components [ ' crystallite ' ] ) :
microstructure . add_multiKey ( ' constituent ' , ' phase %i \t texture %i \t fraction %g \n crystallite %i ' % (
2012-02-02 01:14:36 +05:30
self . data [ ' phase ' ] [ ' __order__ ' ] . index ( phase ) + 1 ,
self . data [ ' texture ' ] [ ' __order__ ' ] . index ( texture ) + 1 ,
2012-05-24 21:30:32 +05:30
fraction ,
self . data [ ' crystallite ' ] [ ' __order__ ' ] . index ( crystallite ) + 1 ) )
2014-06-17 14:23:37 +05:30
2012-02-02 01:14:36 +05:30
self . add_section ( ' microstructure ' , section , microstructure )
2011-12-14 01:32:26 +05:30
def change_value ( self , part = None ,
section = None ,
key = None ,
value = None ) :
if type ( value ) is not type ( [ ] ) :
if type ( value ) is not type ( ' s ' ) :
value = ' %s ' % value
value = [ value ]
newlen = len ( value )
2014-06-16 18:41:26 +05:30
oldval = self . data [ part . lower ( ) ] [ section . lower ( ) ] [ key . lower ( ) ]
2011-12-14 01:32:26 +05:30
oldlen = len ( oldval )
2014-06-16 18:41:26 +05:30
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
2011-12-14 01:32:26 +05:30
if newlen is not oldlen :
print ( ' Length of value was changed from %i to %i ! ' % ( oldlen , newlen ) )
2012-02-02 01:14:36 +05:30
def ex1 ( ) :
mat = Material ( )
p = Phase ( { ' constitution ' : ' lump ' } )
t = Texture ( )
t . add_component ( ' gauss ' , { ' eulers ' : [ 1 , 2 , 3 ] } )
mat . add_section ( ' phase ' , ' phase1 ' , p )
mat . add_section ( ' texture ' , ' tex1 ' , t )
mat . add_microstructure ( ' mustruct1 ' , { ' phase ' : [ ' phase1 ' ] * 2 , ' texture ' : [ ' tex1 ' ] * 2 , ' fraction ' : [ 0.2 ] * 2 } )
2013-09-19 01:01:27 +05:30
print ( mat )
2012-02-02 01:14:36 +05:30
mat . write ( file = ' poop ' )
mat . write ( file = ' poop ' , overwrite = True )
2013-09-20 21:53:52 +05:30