Version 0 of PDEs and the Tensor package

Updated 2008-10-22 06:47:18 by arjen

Arjen Markus (22 october 2008) Recently Neil McKay announced version 4.0a1 of his Tensor package on c.l.t. I thought it might be a good idea to see if this package that deals with vectors, matrices and their higher-dimensional cousins, could be used for solving partial differential equations (PDEs) and what kind of code that would produce.

The program below is just a quick-and-dirty attempt to get some feeling for the package. Some remarks:

  • Tensors that you create are commands and therefore persistent. This means that you will have to clean them up explicitly
  • The assignments do not create new tensors, they merely set the values contained in the tensors.
  • The tensor::expr command does not like to deal with Tcl variables directly, so I used double quotes (") instead of the more usual {} around my expressions.
  • The tensor package seems to lack some functionality still, notably a convenient way to get the data

But apart from that, the experiment, as far as I am concerned, was a success. This package does hold some promises in this area ...

(Note: The package is available for Tcl 8.5 via Teapot and the source code is at http://www.eecs.umich.edu:~mckay/computer/tensor4.0a1.tar.gz )


# tensors.tcl --
#     Use the Tensor package to solve a simple diffusion problem
#
package require Tensor

# initialise --
#     Create the tensors
#
# Arguments:
#     value           Value at cell x=0, t=0
#     noCells         Number of cells
#
# Result:
#     None
#
# Side effects:
#     Creates the tensors solution, work and deriv
#
proc initialise {value noCells} {

    ::tensor::create solution -type double -size [expr {$noCells+2}]
    ::tensor::create deriv    -type double -size [expr {$noCells+2}]
    ::tensor::create work     -type double -size [expr {$noCells+2}]

    set zero [expr {$noCells/2}]
    solution = scalar 0.0
    solution section $zero = scalar $value

    work  = scalar 0.0
    deriv = scalar 0.0
}

# nextTime --
#     Compute the solution for the next time
#
# Arguments:
#     diff            Diffusion coefficient (m2/s)
#     dx              Size of a grid cell
#     dt              Time step (s)
#
# Result:
#     None
#
# Side effects:
#     An updated solution
#
proc nextTime {diff dx dt} {

    set maxCell   [expr {[solution dimensions] - 1}]
    set maxCellM1 [expr {$maxCell - 1}]
    set maxCellM2 [expr {$maxCell - 2}]

    ::tensor::expr "work(i=1:$maxCellM1) = -2.0 * solution(i=1:$maxCellM1)
                                                  + solution(i=0:$maxCellM2)
                                                  + solution(i=2:$maxCell)"
    deriv = scalar 0.0
    ::tensor::expr "deriv(i) = $diff * work(i) / $dx / $dx"
    ::tensor::expr "solution(i) = solution(i) + $dt * deriv(i)"
}

# main --
#     Run it
#
initialise 1.0 10

set dx   0.1
set dt   0.01
set diff 0.1

for { set i 0 } { $i < 10 } { incr i } {
   nextTime $diff $dx $dt
}

#solution writechannel stdout text ;# Did not print anything useful ...

solution put into a
parray a 

enter categories here