- The Fortran program does a calculation and uses Tcl to send the results to a server program
- The server program displays the results in a graphical form
- Make a friendlier build system that require less expertise from the user.
- Setting up extensions in Fortran should be very easy
- (In the longer run) support for derived types
To apply Tcl within a program you need to interact with the run-time system, the Tcl interpreter. This is actually a collection of variables and Tcl routines. Most commonly there is only one interpreter, but there are classes of applications where several are used at once, as each may act quite independently, for instance in client/server systems.I created a small library to facilitate the interaction:
- One routine, ftcl_start, to initialise the one interpreter that will remain active during the whole program run. It can optionally run a startup script from file.
- A set of routines to set the values of variables in the interpreter (one for each common data type, but via the interface mechanism in Fortran, they present themselves as a single routine, ftcl_set)
- A set of routines to get the values of variables in the interpreter (likewise, externally they are visible as a single routine, ftcl_get).
- One routine to evaluate Tcl scripts (one or more commands; ftcl_script)
! Simple program to show the Ftcl library ! program calc use FTCL implicit none integer :: i integer :: nosteps real :: x real :: y real :: dphi real :: phi ! ! Start the Tcl interpreter, and read the major parameters ! call ftcl_start( 'calc.tcl' ) call ftcl_get( 'dphi', dphi ) call ftcl_get( 'nosteps', nosteps ) ! ! Run the calculation and output the variables ! do i = 0,nosteps phi = real(i) * dphi x = cos( phi ) y = sin( phi ) call ftcl_put( 'x', x ) call ftcl_put( 'y', y ) call ftcl_script( 'transfer' ) enddo call ftcl_script( 'close_transfer' ) stop endThe interesting feature here is that the Fortran program does not need to know anything about the output mechanism - this is all put into the Tcl routine transfer.The script file that is run when initialising the interpreter looks like this:
# Define the routines to send data to the server # proc transfer { } { global channel global x global y puts $channel "$x $y" flush $channel } proc close_transfer { } { global channel close $channel } # # SetUp accepts zero or one arguments, if there is no argument, # use the local host. # proc SetUp { {host localhost} } { global channel set port 8085 set channel [ socket $host $port ] } SetUp # # Set the computational parameters # set nosteps 100 set dphi 0.1The routine SetUp sets up a socket connection to the local host (as there is no host name given). The routine transfer writes the values of the variables x and y to the channel and flushes it to make sure the output is available immediately on the receiving side.The receiving side is a somewhat less simple Tcl script that uses the graphical toolkit, Tk, to display the input (the x and y coordinates) graphically:
# # SetUp the server side (it needs to "listen" to the port) # proc SetUp { } { set port 8085 set timeout 60000 socket -server [list Accept $timeout] $port # We run in a graphical (Tk) shell, so an event loop is # already available: the next statement is not required. # vwait forever } # # Procedure that accepts the client and sets up the connection # proc Accept { timelimit socket ip args } { fconfigure $socket -block false fileevent $socket readable [list DrawInput $socket] } # # Draw the input graphically # proc DrawInput { socket } { global xprev yprev if { ! [eof $socket] } { gets $socket line set x [lindex $line 0] set y [lindex $line 1] if { $x != "" && $y != "" } { set xc [expr 100+80*$x] set yc [expr 100+80*$y] .c create line $xprev $yprev $xc $yc -fill black set xprev $xc set yprev $yc } } } # # Main code: create a window in which we can draw and start # the server . # global xprev yprev set xprev 0.0 set yprev 0.0 canvas .c -background white pack .c SetUpThe server's version of SetUp creates a so-called server socket and then enters an event loop (explicitly via the command vwait or automatically because the runtime environment is graphical). The other routines have to do with the handling of incoming requests and incoming data. The result is a very simple picture.
AM Thanks to Clif Flynt this little library is now capable of using Tk within a Fortran program. This means you can build a Fortran program with a very portable GUI ... Just thought to mention this, as the interest in this library has increased a lot over the past couple of months.AM (2 july 2004) One place to find the library is: http://www.digitalsmarties.com/tcl/ftcl.zip AM (1 september 2006) See above!