Thursday, June 22, 2006
Combining Fortran and Tcl in one program

Combining Fortran and Tcl in one program

Arjen Markus (7 november 2002) I have written an article on the use of Tcl in a Fortran program. (Fortran Forum, december 2002). Below you will find a fragment of that article, describing a small client-server system for on-line visualisation:

  • 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

It is meant to demonstrate how easy it is to combine Fortran and Tcl and do novel things with them.

Note: If you are interested in the library, just e-mail me.


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)

With this library I created a small demonstration program, an almost trivial simulation, that provides on-line visualisation of the results:

 ! 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
end

The 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.1

The 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

SetUp

The 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


Category Foreign Interfaces