在python中为Tcl调用不同的解释器

时间:2016-05-09 11:32:14

标签: python tcl interpreter

我希望从python本身运行一个带有不同解释器(OpenSees)的Tcl脚本,类似于this question,最实用的方法是什么?我已经尝试过tkinter和subprocess例程,但据我所知,我在纯Tcl中运行脚本并且没有任何反应(函数在OpenSees环境中定义)。 我试过通过tkinter调用我的Tcl脚本但是我不能为我的生活弄清楚如何用另一个解释器运行tcl,我试过的是:

换test.tcl

proc fractional_while {j float_increment upper_limit} {
    while {$j < $upper_limit} {
        set j [expr $j + $float_increment]
    }
}
puts "time it took: [time {fractional_while 1 0.001 500} 1]"

python文件

import tkinter
r = tkinter.Tk()
r.eval('source {for-test.tcl}')

我想要做的是在python中调用Opensees并运行以下例程:

弹性1DOF-spectrum.tcl

model BasicBuilder -ndm 2 -ndf 3

set time_zero [clock clicks -millisec]

set node_restraint 1
set node_spring 2

...

set load_dir $x_direction
set x_mass 1
set elastic_modulus 2e6
set rotation_z 6

node $node_restraint 0 0 -mass 0 0 0
node $node_spring 0 0 -mass 0 0 0
fix $node_restraint 1 1 1

equalDOF $master_node $slave_node 1 2
geomTransf Linear $transf_tag

uniaxialMaterial Elastic $linear_elastic_mat_tag $elastic_modulus
element zeroLength 0 $node_restraint $node_spring -mat $linear_elastic_mat_tag -dir $rotation_z

set accel_series "Path -filePath acelerograma_85_ii.191 -dt $ground_motion_time_step -factor 1"
pattern UniformExcitation $load_tag $load_dir -accel $accel_series

set oscillator_length 1
set node_mass 3
set counter 1

while {$oscillator_length < 1000} {

set oscillator_length [expr $counter*0.1]
set node_mass [expr $counter + 2]

node $node_mass 0 $oscillator_length 
mass $node_mass $x_mass 0 0

element elasticBeamColumn $node_mass $node_spring $node_mass $area_column $elastic_modulus $inertia_column $transf_tag

set eigenvalue [eigen -fullGenLapack 1]
set period [expr 2*$pi/sqrt($eigenvalue)]

recorder EnvelopeNode -file results/acceleration-envelope-period-$period.out -time -node $node_mass -dof $x_direction accel
...

rayleigh [expr 2*$damping_ratio*$x_mass*$eigenvalue] 0 0 0
constraints Transformation 
# determines how dof constraits are treated and assigned
numberer Plain 
# numbering schemes are tied directly to the efficiency of numerical solvers
system BandGeneral
# defines the matricial numerical solving method based on the form of the stiffness matrix
test NormDispIncr 1e-5 10 0
integrator Newmark $gamma $beta
# defines the integrator for the differential movement equation
algorithm Newton
# solve nonlinear residual equation
analysis Transient
# for uniform timesteps in excitations
analyze [expr int($duration_motion/$time_step)] $time_step

incr counter
}

puts stderr "[expr {([clock clicks -millisec]-$time_zero)/1000.}] sec" ;# RS
wipe

2 个答案:

答案 0 :(得分:1)

这取决于OpenSees的构建方式以及它提供的选项。

通常嵌入Tcl的程序有两个主要选项,与Python非常相似。

变体一是拥有一个普通的C / C ++主程序并链接到Tcl库,实际上是tclsh所做的一样,一个可以执行Tcl命令并静态提供额外命令的shell。

变体二使用普通tclsh并只加载一些扩展模块来添加功能。如果是这种情况,您通常可以简单地在tkinter shell中加载包,如果它们足够相似,那么就完成了。

OpenSees似乎是一个实现变体的程序,一个包含一些外部无法获得的额外命令的程序。因此,您无法直接在tkinter shell中加载代码。

您有三种选择:

  1. 使用Tcllib comm包之类的东西在Tkinter和OpenSees shell之间进行通信(参见Running TCL code (on an existing TCL shell) from Python示例)
  2. 通过subprocess运行opensees并实现某种通信协议来发送命令。
  3. 破解OpenSees代码,将其构建为Tcl的可加载包并将其加载到tkinter进程中(可能很难)。

答案 1 :(得分:0)

用oneliner解决了它:

subprocess.call('Opensees elastic-1dof-spectrum.tcl', shell=True)