TABLE OF CONTENTS
::pwtk::pwo::getStructData
SYNOPSIS
proc ::pwtk::pwo::getStructData {what args} {
USAGE
::pwtk::pwo::getStructData what [-k] pwoFile [index]
PURPOSE
The master structure retrieval routine for getting the index-th structure (CELL_PARAMETERS, ATOMIC_POSITIONS, ATOMIC_FORCES and their combination) from pw.x output file.
Not meant to be used directly, use the ::pwtk::pwo::getPrimVec, ::pwtk::pwo::getAtmPos, or ::pwtk::pwo::getStruct instead.
ARGUMENTS
- what -- what to extract (see below)
- -k -- (optional) option to request to include the ATOMIC_POSITIONS and/or CELL_PARAMETERS lines in the result
- pwoFile -- pw.x output file
- index -- (optional, default = end )sequential index of the structure to extract. The input structure has an index of 0, while for the last reported structure a string "end" can be used.
Possible values for the 'what' argument: * cell, vectors, CELL_PARAMETERS ==> returns CELL_PARAMETERS * atoms, coordinates, positions, ATOMIC_POSITIONS ==> returns ATOMIC_POSITIONS * atomforce, coorforce, posforce ==> returns ATOMIC_POSITIONS & ATOMIC_FORCES with the following lines "atmSymbol x y z fx fy fz" * both ==> returns CELL_PARAMETERS + ATOMIC_POSITIONS * all ==> implies cell + atomforce
SOURCE
# parse arguments ... set options { {k "include the keyword line in the result"} } set usage ": ::pwtk::pwo::getStructData what \[-k] pwoFile \[index]" array set opt [::cmdline::getoptions args $options $usage] set narg [llength $args] if { $narg < 1 || $narg > 2 } { ::pwtk::error "Usage $usage" 1 } set prependKeyword $opt(k) set pwoFile [lindex $args 0] set index [expr { $narg == 1 ? "end" : [lindex $args 1] }] # do the job ... set fid [open $pwoFile r] set l_vec {} set l_coor {} set l_force {} set nat 0 set l_first_vec 1 set l_first_coor 1 if { ! [string is boolean $prependKeyword] } { ::pwtk::error "prependKeyword must be of boolean type; assuming it is true" set prependKeyword 1 } while { ! [eof $fid] } { # gets $fid line # if { [string match {*number of atoms/cell*} $line] } { set nat [lindex $line end] } elseif { [string match {*crystal axes: \(cart. coord. in units of a*} $line] && $l_first_vec } { set l_first_vec 0 if { $prependKeyword} { set vec "CELL_PARAMETERS (alat)\n" } else { set vec "" } append vec [lrange [string map {( "" ) ""} [gets $fid]] 2 4]\n append vec [lrange [string map {( "" ) ""} [gets $fid]] 2 4]\n append vec [lrange [string map {( "" ) ""} [gets $fid]] 2 4]\n lappend l_vec $vec } elseif { [string match CELL_PARAMETERS* $line] } { if { $prependKeyword} { set vec $line\n } else { set vec "" } append vec [gets $fid]\n append vec [gets $fid]\n append vec [gets $fid]\n lappend l_vec $vec } elseif { [string match {*Cartesian axes*} $line] && $l_first_coor } { # # initial coordinates # set l_first_coor 0 gets $fid line; # empty line gets $fid line; # site n. atom positions (a_0 units) if { $prependKeyword} { set key "ATOMIC_POSITIONS (alat)\n" } else { set key "" } set coor "" for {set ia 0} {$ia < $nat} {incr ia} { set line [gets $fid] append coor [concat [lindex $line 1] [lrange [string map {( " " ) " "} $line] 5 7]]\n } # Try to transform coor to atmPos, but be cautious: # perhaps ATOMIC_POSITIONS card is empty or has a # different number of atoms; use transformation only if # the number-of-atoms matches set atmPos [::pwtk::pwi::coorToAtmPos $coor] if { [::pwtk::getNAtoms $coor] == [::pwtk::getNAtoms $atmPos] } { lappend l_coor ${key}$atmPos } else { lappend l_coor ${key}$coor } } elseif { [string match ATOMIC_POSITIONS* $line] } { if { $prependKeyword} { set coor $line\n } else { set coor "" } for {set ia 0} {$ia < $nat} {incr ia} { append coor [gets $fid]\n } lappend l_coor $coor } elseif { [string match {*Forces acting on atoms*} $line] } { if { $prependKeyword } { set force "ATOMIC_FORCES\n" } else { set force "" } gets $fid; # empty line for {set ia 0} {$ia < $nat} {incr ia} { append force [lrange [gets $fid] end-2 end]\n } lappend l_force $force } } close $fid proc atomforce_ {prependKeyword l_coor l_force index} { set coor [lindex $l_coor $index] set force [lindex $l_force $index] if { $prependKeyword } { # strip the keyword from $l_coor & $l_force append result [concat [lindex [split $coor \n] 0] [lindex [split $force \n] 0]]\n # set coor [join [lrange [split $coor \n] 1 end] \n] set force [join [lrange [split $force \n] 1 end] \n] } foreach {a x y z} $coor {fx fy fz} $force { append result [format $::pwtk::fmt_coor(7) $a $x $y $z $fx $fy $fz] } return $result } switch -nocase -glob -- $what { cell* - vec* { # vectors set result [lindex $l_vec $index] } both { # vectors + atoms set result [lindex $l_vec $index]\n[lindex $l_coor $index] } all { # vectors + atoms + forces set result [lindex $l_vec $index]\n append result [::pwtk::pwo::atomforce_ $prependKeyword $l_coor $l_force $index] } atomfor* - pos*for* - coor*for* { # atoms + forces set result [::pwtk::pwo::atomforce_ $prependKeyword $l_coor $l_force $index] } atom* - pos* - coor* { # atoms set result [lindex $l_coor $index] } for* { # forces set result [lindex $l_force $index] } default { ::pwtk::error "wrong type of data requested ($what), must be one of vectors, positions, forces, both, or all" 1 #set result [lindex $l_coor $index] } } return $result }