2016-05-09 1 views
0

Je souhaite exécuter un script Tcl avec un interpréteur différent (OpenSees) de python lui-même, similaire à this question, quelle serait la manière la plus pratique? J'ai essayé les routines tkinter et subprocess mais pour autant que je sache, je cours le script en Tcl pur et rien ne se passe (les fonctions sont définies dans l'environnement OpenSees). J'ai essayé d'appeler mon script Tcl via tkinter et mais je ne peux pas pour la vie de me comprendre comment exécuter tcl avec un autre interprète, ce que j'ai essayé est:Appeler un interpréteur différent pour Tcl en python

pour-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]" 

fichier python

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

Ce que je veux faire est OpenSees d'appel à l'intérieur de python et exécuter la routine suivante:

élastique 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

Je ne peux pas travailler ce qu'il est votre demande ici, vous devez le rendre beaucoup plus clair quant à ce que vous essayez de faire et d'inclure un minimum de code que montre ce que vous avez déjà essayé. – Jackson

+0

@Jackson J'ai modifié ma réponse en conséquence. – Vyraj

+0

Une allusion 'accolade votre expr'. Il peut être beaucoup plus rapide d'écrire '[expr {$ counter + 2}]' au lieu de '[expr $ counter + 2]' car l'expression peut être compilée par octets et n'est pas réparée à chaque fois. C'est aussi beaucoup plus sûr. – schlenk

Répondre

1

Cela dépend de la façon dont OpenSees est construit et des options qu'il offre.

Généralement, les programmes qui intègrent Tcl ont deux options principales, comme Python. La variante 1 est d'avoir un programme principal C/C++ normal et un lien vers la bibliothèque Tcl, en fait la même chose que tclsh, un shell qui peut exécuter des commandes Tcl et fournir des commandes supplémentaires statiquement.

La variante 2 utilise un tclsh normal et il suffit de charger certains modules d'extension pour ajouter la fonctionnalité. Si tel est le cas, vous pouvez souvent simplement charger le paquet dans le shell tkinter s'ils sont assez similaires et terminés. OpenSees semble être un programme qui implémente la variante 1, un bigwish qui inclut des commandes supplémentaires non disponibles à l'extérieur. Vous ne pouvez donc pas charger le code directement dans un shell tkinter.

Vous avez trois options:

  1. Utilisez quelque chose comme le paquet tcllib comm pour communiquer entre Tkinter et la coquille de OpenSees (voir Running TCL code (on an existing TCL shell) from Python pour un exemple)
  2. de OpenSees Run via subprocess et mettre en œuvre une sorte de communication protocole pour envoyer vos commandes.
  3. Hack au code OpenSees pour le construire comme un paquet chargeable pour Tcl et le charger dans votre processus tkinter (peut être difficile).
0

a résolu le problème avec une oneliner:

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

Cest ma version 2.), et votre protocole de communication est juste 'écrire le script dans un fichier appelé élastique-1dof-spectre.tcl' ;-) – schlenk