From: Artem Mamonov (artem_at_mercury.chem.pitt.edu)
Date: Wed Apr 14 2004 - 21:34:20 CDT

Hello,

I wrote a tcl script to unwrap coordinates of oxygen atoms for diffusion
calculations using msd method. I found that "moveby" command used inside a
loop caused VMD to grow in memory until it eventually uses up all virtual
and physical memory and causes the system to crash. Below is the scrip
that I am using. Please, let me know what you find.

set box 48.2949
puts "box: $box"
set half_box [expr 48.2949/2]
puts "half_box: $half_box"

mol delete all
mol load psf oxy_0-100.psf dcd O_100.dcd

set num_of_frames [molinfo top get numframes]
puts "num_of_frames: $num_of_frames"
set total_num_of_atoms [molinfo top get numatoms]
puts "total_num_of_atoms: $total_num_of_atoms"

unwrap $total_num_of_atoms $num_of_frames

animate write dcd unwrap100.dcd beg 0 waitfor all
puts "all done !!!"

proc unwrap {num_of_atoms num_of_frames} {
        global box
        global half_box

# puts "num_of_atoms: $num_of_atoms"
# puts "num_of_frames: $num_of_frames"

        for { set i 0 } { $i < $num_of_atoms } { incr i } {
                        puts "index: $i"
                        set sel [atomselect top "index $i"]
                        set selOld [atomselect top "index $i"]

                        for { set frame 1 } { $frame < $num_of_frames } { incr frame } {

                                $sel frame $frame
                                $selOld frame [expr $frame - 1]

                                set deltaXYZ [vecsub "[lindex [$sel get {x y z}] 0]
[lindex [$sel get {x y z}] 1] [lindex [$sel get {x y z}]
2]" "[lindex [$selOld get {x y z}] 0] [lindex [$selOld
get {x y z}] 1] [lindex [$selOld get {x y z}] 2]"]
                                if { abs([lindex $deltaXYZ 0]) > $half_box } {
                                        $sel moveby "[expr -$box*round([lindex
$deltaXYZ 0]/$box)] 0 0"
                                }
                                if { abs([lindex $deltaXYZ 1]) > $half_box } {
                                        $sel moveby "0 [expr -$box*round(abs([lindex $deltaXYZ 1]/$box))] 0"
                                }
                                if { abs([lindex $deltaXYZ 2]) > $half_box } {
                                        $sel moveby "0 0 [expr
-$box*round(abs([lindex $deltaXYZ
2]/$box))] "
                                }

                                unset deltaXYZ
                        }
        }
        unset frame
        $sel delete
        $selOld delete
        unset sel
        unset selOld

        return 0
}

thanks,
artem