2016-05-09 10 views
0

Ich möchte ein Tcl-Skript mit einem anderen Interpreter (OpenSees) von Python selbst, ähnlich wie this question, was wäre der praktischste Weg? Ich habe versucht, tkinter und Subprozessroutinen, aber soweit ich verstehe, ich führe das Skript in reinem Tcl und nichts passiert (Funktionen sind in der OpenSees-Umgebung definiert). Ich habe versucht, meinen Tcl-Skript über tkinter Aufruf und aber ich kann für das Leben von mir nicht vorstellen, wie tcl mit einem anderen Interpreter ausführen kann, was ich habe versucht, ist:Aufruf verschiedener Interpreter für Tcl in Python

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

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

Was ich will ist Aufruf Opensees innerhalb python zu tun, und führen Sie das folgende Programm:

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

ich nicht herausfinden können, was es ist, hier zu fragen, müssen Sie es viel klarer, was Ihr versucht zu tun und sind minimal Code zu machen, die zeigt, was Sie bereits versucht haben. – Jackson

+0

@Jackson Ich habe meine Antwort entsprechend bearbeitet. – Vyraj

+0

Ein Hinweis 'Klammer deinen Ausdruck'. Es kann viel schneller sein, '[expr {$ counter + 2}]' anstelle von '[expr $ counter + 2]' zu schreiben, da der Ausdruck bytekompiliert sein kann und nicht jedes Mal neu parasiert wird. Es ist auch viel sicherer. – schlenk

Antwort

1

Es hängt davon ab, wie OpenSees aufgebaut ist und welche Optionen es bietet.

In der Regel Programme, die Tcl einbetten, haben zwei Hauptoptionen, wie es zu tun, ganz ähnlich wie Python.

Variante 1 ist ein normales C/C++ Hauptprogramm und Link zur Tcl-Bibliothek, in der Tat die gleiche Sache tclsh tut, eine Shell, die Tcl-Befehle ausführen und zusätzliche Befehle statisch bereitstellen kann.

Variante zwei verwendet eine normale tclsh und nur einige Erweiterungsmodule laden, um die Funktionalität hinzuzufügen. Wenn dies der Fall ist, können Sie das Paket oft einfach in die Shell tkinter laden, wenn sie ähnlich genug sind und fertig sind.

OpenSees scheint ein Programm zu sein, das Variante 1 implementiert, eine Bigwish, die einige zusätzliche Befehle enthält, die außerhalb nicht verfügbar sind. Sie können also den Code nicht direkt in eine tkinter Shell laden.

Sie haben drei Möglichkeiten:

  1. Verwendung so etwas wie das tcllib comm Paket zwischen Tkinter und die OpenSees Schale (siehe Running TCL code (on an existing TCL shell) from Python für ein Beispiel)
  2. Run opensees über subprocess und implementieren eine Art von Kommunikation zu kommunizieren Protokoll, um Ihre Befehle zu senden.
  3. Hack am OpenSees-Code, um es als ein ladbares Paket für Tcl zu bauen und es in Ihren tkinter-Prozess zu laden (könnte schwierig sein).
0

Gelöst es mit einem Einzeiler:

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

Das ist meine Version 2.), und dein comm-Protokoll ist nur 'schreibe das Skript in eine Datei namens elastic-1dof-spectrum.tcl' ;-) – schlenk