TABLE OF CONTENTS
::pwtk::scanpar
SYNOPSIS
proc ::pwtk::scanpar {paramName values script} {
USAGE
::pwtk::scanpar paramName values script
ARGUMENTS
- paramName --- name of the parameter to scan
- values --- list of parameter values to scan
- script --- script to execute for each value of the parameter
DESCRIPTION
The 'scanpar' command is analogous to a one-parameter Tcl "foreach" command and has a similar syntax, but (1) it keeps track of the scanned parameter to make the creation of datafiles a bit easier, and (2) uses input data stacking (::pwtk::input::push_pop) to restore the input data after the completion of the scan.
Below are two examples using the "foreach" and "scanpar" commands that are analogous.
EXAMPLES
# to illustrate what "scanpar" does, we first do an example # using the "foreach" Tcl command, and then repeat the same # example using "scanpar" # 1. using "foreach" write ecut.dat "# columns are: ecut data" input_pushpop { foreach ecut {10 14 18 22} { SYSTEM "ecutwfc = $ecut" runPW scf.ecut$ecut write ecut.dat "$k [pwo_totene scf.ecut$ecut.out]" } } plot -xl "ecutwfc (Ry)" -yl "Total energy (Ry)" ecut.dat # 2. the same example using "scanpar" scanpar ecut {10 14 18 22} { SYSTEM "ecutwfc = $ecut" runPW scf.ecut$ecut write ecut.dat [pwo_totene scf.ecut$ecut.out] } plot -xl "ecutwfc (Ry)" -yl "Total energy (Ry)" ecut.dat
EXPLANATION
In both examples above, identical "ecut.dat" datafile is created, but with "scanpar", the 1st-line comment is automatically created and the parameter $k is not specified in the "write" command because "write" adds $k automatically as it knows which parameter(s) is (are) being scanned with "scanpar".
SOURCE
variable scanpar variable scanparList upvar $paramName par if { [info exists scanparList] && ($paramName in $scanparList) } { ::pwtk::error "scanpar already scans the \"$paramName\" parameter, name of the parameter must be unique" 1 } ifnotempty scanparList { set d_ "" foreach p $scanparList { upvar $p p_ append pt "${d_}$p = ${p_}" set d_ {, } } print "${pt}: scanning the paramater \"$paramName\" for values: [join $values {, }]\n" } else { print "Scanning the paramater \"$paramName\" for values: [join $values {, }]\n" } lappend scanparList $paramName input_pushpop { foreach par $values { # save the current value of the parameter (used by "write" if # called within the script) set scanpar($paramName) $par set code [catch {uplevel 1 $script} result] if {($code != 0) && ($code != 4)} { break } } } set scanparList [lrange $scanparList 0 end-1] if { $scanparList eq {} } { unset scanparList unset scanpar($paramName) } if { ($code == 0) || ($code == 3) || ($code == 4) } { return $result } return -code $code $result }