TABLE OF CONTENTS


::pwtk::scanpar

SYNOPSIS

proc ::pwtk::scanpar {paramName values script} {

USAGE

   ::pwtk::scanpar paramName values script

ARGUMENTS

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
}