【问题标题】:Call different interpreter for Tcl in python在 python 中为 Tcl 调用不同的解释器
【发布时间】:2016-05-09 11:32:14
【问题描述】:

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

for-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 并运行以下例程:

elastic-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

【问题讨论】:

  • 我不知道你在这里问的是什么,你需要更清楚地说明你想做什么,并包含显示你已经尝试过的最少代码。跨度>
  • @Jackson 我已经相应地编辑了我的答案。
  • 一个提示brace your expr。编写 [expr {$counter + 2}] 而不是 [expr $counter + 2] 会快得多,因为表达式可以进行字节编译并且不会每次都重新解析。它也更安全。

标签: python tcl interpreter


【解决方案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 进程中(可能很难)。

【讨论】:

    【解决方案2】:

    用oneliner解决它:

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

    【讨论】:

    • 那是我的版本 2。),而您的通信协议只是“将脚本写入名为 elastic-1dof-spectrum.tcl 的文件”;-)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-17
    • 1970-01-01
    • 2017-12-16
    • 1970-01-01
    相关资源
    最近更新 更多