Documents/NamdSample/namd210b/lib/abf/distance-com.tcl (67 lines of code) (raw):
#########################################################
# ABF procedures for a distance between two atom groups #
#########################################################
set ABFcoordID "Distance between COM of two atom groups"
# Define coordinate-specific optional parameters with default values
array set ABFoptions {
temp 300.0
dxi 0.1
dSmooth 0.2
}
###############################################################
# ABFstartup : declares atoms whose coordinates are requested #
###############################################################
proc ABFstartup {} {
namespace eval ABFcoord {
set abf1 $::ABF::abf1
set abf2 $::ABF::abf2
# we need this for 'loadtotalforces'
foreach a $abf1 {addatom $a}
foreach a $abf2 {addatom $a}
# this one is convenient for 'loadcoords' and 'addforce'
set group1 [ addgroup $abf1 ]
set group2 [ addgroup $abf2 ]
}
}
################################################################
# ABFcoord : reads coord, returns value of reaction coordinate #
################################################################
proc ABFcoord {} {
namespace eval ABFcoord {
loadcoords coords
set r [veclength [vecsub $coords($group2) $coords($group1)]]
return $r
}
}
############################################################
# ABForce : returns force along reaction coordinate #
############################################################
proc ABForce {} {
namespace eval ABFcoord {
set dr [vecsub $coords($group2) $coords($group1)]
set nv [vecnorm $dr] ;# unity vector
loadtotalforces forces
set f1 0.0
foreach a $abf1 { set f1 [expr {$f1 + [vecdot $forces($a) $nv]}]}
set f2 0.0
foreach a $abf2 { set f2 [expr {$f2 + [vecdot $forces($a) $nv]}]}
return [expr {($f2 - $f1) / 2.0}]
}
}
###############################################################################
# ABFapply : applies the force given as a parameter along reaction coordinate #
###############################################################################
proc ABFapply {force} {
set ABFcoord::force $force
namespace eval ABFcoord {
set dr [vecsub $coords($group2) $coords($group1)]
set r [veclength $dr]
set nv [vecnorm $dr] ;# unity vector group1 -> group2
# compensate for the Jacobian term 2kT/r
set force [expr {$force - 2.0 * 0.001986 * $::ABF::temp / $r}]
set F2 [vecscale $force $nv]
addforce $group1 [vecinvert $F2]
addforce $group2 $F2
return $force
}
}