我希望从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
答案 0 :(得分:1)
这取决于OpenSees的构建方式以及它提供的选项。
通常嵌入Tcl的程序有两个主要选项,与Python非常相似。
变体一是拥有一个普通的C / C ++主程序并链接到Tcl库,实际上是tclsh
所做的一样,一个可以执行Tcl命令并静态提供额外命令的shell。
变体二使用普通tclsh
并只加载一些扩展模块来添加功能。如果是这种情况,您通常可以简单地在tkinter
shell中加载包,如果它们足够相似,那么就完成了。
OpenSees似乎是一个实现变体的程序,一个包含一些外部无法获得的额外命令的程序。因此,您无法直接在tkinter
shell中加载代码。
您有三种选择:
comm
包之类的东西在Tkinter和OpenSees shell之间进行通信(参见Running TCL code (on an existing TCL shell) from Python示例)subprocess
运行opensees并实现某种通信协议来发送命令。答案 1 :(得分:0)
用oneliner解决了它:
subprocess.call('Opensees elastic-1dof-spectrum.tcl', shell=True)