Tcl as a Front End for Python

I know I’m not the only one who enjoys converting between scripting languages or between structural analysis programs. I’ve had fun writing bespoke Tcl middleware between OpenSees and MATLAB, but now OpenSeesPy makes all of that obsolete.

But, let’s say you have an OpenSees Tcl script that you’d like to run in OpenSeesPy. There’s a line-by-line converter available on GitHub, but it does not handle variables, conditionals, loops, or procedures. This line-by-line approach is great for converting the Tcl files exported by OpenSees Navigator or other front ends that pump out Tcl files to run OpenSees.

But what do you do when there’s Tcl variables, conditionals, loops, and procedures? Consider this snippet of OpenSees Tcl code I received a couple weeks ago and wanted to convert to OpenSees Python.

for {set i 1} {$i <= $nyweb} {incr i 1} {
    for {set j 1} {$j <= $nxweb} {incr j 1} {
        set e [expr $e+1]
        set n1 [expr ($nxweb+1)*(($i-1)+1)-($nxweb-($j-1))]
        set n2 [expr ($nxweb+1)*(($i-1)+1)-($nxweb-$j)]
        set n3 [expr ($nxweb+1)*($i+1)-($nxweb-$j)]
        element ShellNLDKGT $e $n1 $n2 $n3 $websection
    }
}

Converting the loops from Tcl to Python would be relatively easy–use range(1,nyweb+1). However, converting the expressions in the loop body would be ripe for error.

But, all I wanted was to analyze the model with OpenSeesPy, not keep the variables, loops, etc. from the Tcl script. So, I took an approach from my bespoke middleware days–use a Tcl filestream.

set python [open model.py w]

puts $python "import openseespy.opensees as ops"
puts $python "ops.wipe()"
puts $python "ops.model('basic','-ndm',3,'-ndf',6)"

#
# Do some stuff
#

for {set i 1} {$i <= $nyweb} {incr i 1} {
    for {set j 1} {$j <= $nxweb} {incr j 1} {
        set e [expr $e+1]
        set n1 [expr ($nxweb+1)*(($i-1)+1)-($nxweb-($j-1))]
        set n2 [expr ($nxweb+1)*(($i-1)+1)-($nxweb-$j)]
        set n3 [expr ($nxweb+1)*($i+1)-($nxweb-$j)]
        element ShellNLDKGT $e $n1 $n2 $n3 $websection
        # Write to .py file
        puts $python "ops.element('ShellNLDKGT',$e,$n1,$n2,$n3,$secTag)"
    }
}

#
# Do some more stuff
#

close $python

The output in model.py is line-by-line element definitions.

ops.element('ShellNLDKGT',207,161,162,164,2)
ops.element('ShellNLDKGT',208,162,165,164,2)
ops.element('ShellNLDKGT',209,163,164,166,2)
ops.element('ShellNLDKGT',210,164,167,166,2)
ops.element('ShellNLDKGT',211,164,165,167,2)
ops.element('ShellNLDKGT',212,165,168,167,2)

With this approach, any changes you make to the Tcl script will appear in the output Python script, i.e., the Tcl script is a front end for the OpenSeesPy analysis.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.