2010-08-17 02:17:27 +05:30
#!/usr/bin/env python
2014-04-02 00:11:14 +05:30
# -*- coding: UTF-8 no BOM -*-
2010-08-17 02:17:27 +05:30
2015-10-27 01:04:44 +05:30
import sys , os , string
2014-11-18 13:30:45 +05:30
import numpy as np
2010-08-17 02:17:27 +05:30
from optparse import OptionParser
2014-11-18 13:30:45 +05:30
import damask
2010-08-17 02:17:27 +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
2012-01-16 15:02:36 +05:30
sys . path . append ( damask . solver . Marc ( ) . libraryPath ( ' ../../ ' ) )
2010-08-17 23:51:22 +05:30
2015-10-27 01:04:44 +05:30
active = [ True , True , True ] # directions on which to add PBC
2010-08-17 02:17:27 +05:30
def outMentat ( cmd , locals ) :
if cmd [ 0 : 3 ] == ' (!) ' :
exec ( cmd [ 3 : ] )
elif cmd [ 0 : 3 ] == ' (?) ' :
cmd = eval ( cmd [ 3 : ] )
py_send ( cmd )
else :
py_send ( cmd )
return
2015-10-27 01:04:44 +05:30
#-------------------------------------------------------------------------------------------------
def outFile ( cmd , locals , dest ) :
#-------------------------------------------------------------------------------------------------
2010-08-17 02:17:27 +05:30
if cmd [ 0 : 3 ] == ' (!) ' :
exec ( cmd [ 3 : ] )
elif cmd [ 0 : 3 ] == ' (?) ' :
cmd = eval ( cmd [ 3 : ] )
2015-10-27 01:04:44 +05:30
dest . write ( cmd + ' \n ' )
2010-08-17 02:17:27 +05:30
else :
2015-10-27 01:04:44 +05:30
dest . write ( cmd + ' \n ' )
2010-08-17 02:17:27 +05:30
return
2015-10-27 01:04:44 +05:30
#-------------------------------------------------------------------------------------------------
2010-08-17 02:17:27 +05:30
def output ( cmds , locals , dest ) :
2015-10-27 01:04:44 +05:30
#-------------------------------------------------------------------------------------------------
2010-08-17 02:17:27 +05:30
for cmd in cmds :
if isinstance ( cmd , list ) :
output ( cmd , locals , dest )
else :
2015-10-27 01:04:44 +05:30
if dest == ' Mentat ' :
outMentat ( str ( cmd ) , locals )
else :
outFile ( str ( cmd ) , locals , dest )
2010-08-17 02:17:27 +05:30
return
def servoLink ( ) :
cmds = [ ]
base = [ ' x ' , ' y ' , ' z ' ]
2014-11-18 13:30:45 +05:30
box = { ' min ' : np . zeros ( 3 , dtype = ' d ' ) ,
' max ' : np . zeros ( 3 , dtype = ' d ' ) ,
' delta ' : np . zeros ( 3 , dtype = ' d ' ) ,
2010-08-17 02:17:27 +05:30
}
Nnodes = py_get_int ( " nnodes() " )
2014-11-18 13:30:45 +05:30
NodeCoords = np . zeros ( ( Nnodes , 3 ) , dtype = ' d ' )
2013-01-18 18:29:26 +05:30
for node in xrange ( Nnodes ) :
NodeCoords [ node , 0 ] = py_get_float ( " node_x( %i ) " % ( node + 1 ) )
NodeCoords [ node , 1 ] = py_get_float ( " node_y( %i ) " % ( node + 1 ) )
NodeCoords [ node , 2 ] = py_get_float ( " node_z( %i ) " % ( node + 1 ) )
box [ ' min ' ] = NodeCoords . min ( axis = 0 ) # find the bounding box
box [ ' max ' ] = NodeCoords . max ( axis = 0 )
box [ ' delta ' ] = box [ ' max ' ] - box [ ' min ' ]
for coord in xrange ( 3 ) : # calc the dimension of the bounding box
2012-03-14 19:10:22 +05:30
if box [ ' delta ' ] [ coord ] != 0.0 :
for extremum in [ ' min ' , ' max ' ] :
rounded = round ( box [ extremum ] [ coord ] * 1e+15 / box [ ' delta ' ] [ coord ] ) * \
2015-10-27 01:04:44 +05:30
1e-15 * box [ ' delta ' ] [ coord ] # rounding to 1e-15 of dimension
box [ extremum ] [ coord ] = 0.0 if rounded == 0.0 else rounded # get rid of -0.0 (negative zeros)
2010-08-17 02:17:27 +05:30
baseNode = { }
linkNodes = [ ]
2015-10-27 01:04:44 +05:30
#!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
# loop over all nodes
for node in xrange ( Nnodes ) :
2010-08-17 02:17:27 +05:30
pos = { }
key = { }
2013-01-18 18:29:26 +05:30
maxFlag = [ False , False , False ]
2010-08-17 02:17:27 +05:30
Nmax = 0
Nmin = 0
2013-01-18 18:29:26 +05:30
for coord in xrange ( 3 ) : # for each direction
2012-03-14 19:10:22 +05:30
if box [ ' delta ' ] [ coord ] != 0.0 :
2013-01-18 18:29:26 +05:30
rounded = round ( NodeCoords [ node , coord ] * 1e+15 / box [ ' delta ' ] [ coord ] ) * \
2015-10-27 01:04:44 +05:30
1e-15 * box [ ' delta ' ] [ coord ] # rounding to 1e-15 of dimension
NodeCoords [ node , coord ] = 0.0 if rounded == 0.0 else rounded # get rid of -0.0 (negative zeros)
key [ base [ coord ] ] = " %.8e " % NodeCoords [ node , coord ] # translate position to string
if ( key [ base [ coord ] ] == " %.8e " % box [ ' min ' ] [ coord ] ) : # compare to min of bounding box (i.e. is on outer face?)
Nmin + = 1 # count outer (back) face membership
elif ( key [ base [ coord ] ] == " %.8e " % box [ ' max ' ] [ coord ] ) : # compare to max of bounding box (i.e. is on outer face?)
Nmax + = 1 # count outer (front) face membership
maxFlag [ coord ] = True # remember face membership (for linked nodes)
if Nmin > 0 : # node is on a back face
2010-08-17 02:17:27 +05:30
# prepare for any non-existing entries in the data structure
if key [ ' x ' ] not in baseNode . keys ( ) :
baseNode [ key [ ' x ' ] ] = { }
if key [ ' y ' ] not in baseNode [ key [ ' x ' ] ] . keys ( ) :
baseNode [ key [ ' x ' ] ] [ key [ ' y ' ] ] = { }
if key [ ' z ' ] not in baseNode [ key [ ' x ' ] ] [ key [ ' y ' ] ] . keys ( ) :
baseNode [ key [ ' x ' ] ] [ key [ ' y ' ] ] [ key [ ' z ' ] ] = 0
baseNode [ key [ ' x ' ] ] [ key [ ' y ' ] ] [ key [ ' z ' ] ] = node + 1 # remember the base node id
2015-10-27 01:04:44 +05:30
if Nmax > 0 and Nmax > = Nmin : # node is on at least as many front than back faces
if any ( [ maxFlag [ i ] and active [ i ] for i in xrange ( 3 ) ] ) :
linkNodes . append ( { ' id ' : node + 1 , ' coord ' : NodeCoords [ node ] , ' faceMember ' : [ maxFlag [ i ] and active [ i ] for i in xrange ( 3 ) ] } )
2010-08-17 02:17:27 +05:30
2015-10-27 01:04:44 +05:30
baseCorner = baseNode [ " %.8e " % box [ ' min ' ] [ 0 ] ] [ " %.8e " % box [ ' min ' ] [ 1 ] ] [ " %.8e " % box [ ' min ' ] [ 2 ] ] # detect ultimate base node
2010-08-17 02:17:27 +05:30
2012-01-16 21:35:02 +05:30
2015-10-27 01:04:44 +05:30
for node in linkNodes : # loop over all linked nodes
linkCoord = [ node [ ' coord ' ] ] # start list of control node coords with my coords
for dir in xrange ( 3 ) : # check for each direction
if node [ ' faceMember ' ] [ dir ] : # me on this front face
linkCoord [ 0 ] [ dir ] = box [ ' min ' ] [ dir ] # project me onto rear face along dir
linkCoord . append ( np . array ( box [ ' min ' ] ) ) # append base corner
linkCoord [ - 1 ] [ dir ] = box [ ' max ' ] [ dir ] # stretch it to corresponding control leg of "dir"
2010-08-17 02:17:27 +05:30
nLinks = len ( linkCoord )
for dof in [ 1 , 2 , 3 ] :
cmds . append ( [
" *new_link *link_class servo " ,
" *link_class servo *tied_node %i " % node [ ' id ' ] ,
" *link_class servo *tied_dof %i " % dof ,
" *servo_nterms %i " % ( 1 + nLinks ) ,
] )
for i in range ( nLinks ) :
cmds . append ( [
2013-01-18 18:29:26 +05:30
" *link_class servo *servo_ret_node %i %i " % ( i + 1 , baseNode [ " %.8e " % linkCoord [ i ] [ 0 ] ] [ " %.8e " % linkCoord [ i ] [ 1 ] ] [ " %.8e " % linkCoord [ i ] [ 2 ] ] ) ,
2010-08-17 02:17:27 +05:30
" *link_class servo *servo_ret_dof %i %i " % ( i + 1 , dof ) ,
" *link_class servo *servo_ret_coef %i 1 " % ( i + 1 ) ,
] )
cmds . append ( [
" *link_class servo *servo_ret_node %i %i " % ( 1 + nLinks , baseCorner ) ,
" *link_class servo *servo_ret_dof %i %i " % ( 1 + nLinks , dof ) ,
" *link_class servo *servo_ret_coef %i - %i " % ( 1 + nLinks , nLinks - 1 ) ,
] )
return cmds
2013-05-13 16:57:59 +05:30
#--------------------------------------------------------------------------------------------------
# MAIN
#--------------------------------------------------------------------------------------------------
2014-11-18 13:30:45 +05:30
parser = OptionParser ( option_class = damask . extendableOption , usage = ' % prog [options] ' , description = """
2011-08-18 13:23:07 +05:30
Set up servo linking to achieve periodic boundary conditions for a regular hexahedral mesh presently opened in MSC . Mentat
2014-11-18 13:30:45 +05:30
""" , version = scriptID)
2011-08-18 13:23:07 +05:30
2015-04-23 00:27:44 +05:30
parser . add_option ( " -p " , " --port " , type = " int " , dest = " port " , metavar = ' int ' ,
2011-08-18 13:23:07 +05:30
help = " Mentat connection port [ %d efault] " )
2015-04-23 00:27:44 +05:30
parser . add_option ( " -v " , " --verbose " , action = " store_true " , dest = " verbose " ,
2011-08-18 13:23:07 +05:30
help = " write Mentat command stream also to stdout [ %d efault] " )
parser . set_defaults ( port = 40007 )
parser . set_defaults ( verbose = False )
2010-08-17 02:17:27 +05:30
( options , args ) = parser . parse_args ( )
2015-04-23 00:27:44 +05:30
if options . verbose :
file = { ' croak ' : sys . stderr }
else :
file = { ' croak ' : sys . stdout }
2015-10-27 01:04:44 +05:30
try :
from py_mentat import *
except :
file [ ' croak ' ] . write ( ' error: no valid Mentat release found ' )
sys . exit ( - 1 )
outputLocals = { }
2015-04-23 00:27:44 +05:30
file [ ' croak ' ] . write ( ' \033 [1m ' + scriptName + ' \033 [0m \n \n ' )
file [ ' croak ' ] . write ( ' waiting to connect... \n ' )
2015-10-27 01:04:44 +05:30
try :
py_connect ( ' ' , options . port )
output ( [ ' *draw_manual ' ] , outputLocals , ' Mentat ' ) # prevent redrawing in Mentat, should be much faster. Since py_connect has no return value, try this to determine if failed or not
except :
file [ ' croak ' ] . write ( ' Could not connect. Set Tools/Python/ " Run as Separate Process " & " Initiate " ... \n ' )
sys . exit ( )
file [ ' croak ' ] . write ( ' connected... \n ' )
output ( [ ' *remove_all_servos ' ,
2010-08-17 02:17:27 +05:30
' *sweep_all ' ,
2011-02-11 16:59:58 +05:30
' *renumber_nodes ' ,
' *set_links off ' ,
] , outputLocals , ' Mentat ' ) # script depends on consecutive numbering of nodes
2015-10-27 01:04:44 +05:30
2010-08-17 02:17:27 +05:30
cmds = servoLink ( )
output ( cmds , outputLocals , ' Mentat ' )
py_disconnect ( )
if options . verbose :
2015-10-27 01:04:44 +05:30
output ( cmds , outputLocals , sys . stdout )