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:
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
NDM (07 January 2009) Just a couple of comments. First, the line
::tensor::expr "solution(i) = solution(i) + $dt * deriv(i)"
could be written as
::tensor::expr "solution(i) += $dt * deriv(i)"
Second, to get a tensor value as a nested Tcl list, just use the tensor's name as a command, for example
puts [solution]