TABLE OF CONTENTS
::pwtk::runPW_remedy
SYNOPSIS
proc ::pwtk::runPW_remedy {args} {
USAGE
runPW_remedy [remedy-options] [runPW-options] input ?output?
Remedy-options are:
-restart -remedy1st -reduceconv <factor> -nsteps <value> -script <script> -max_thr <value> -nlevels <number>
RunPW-options are options of ::pwtk::runPW
PURPOSE
An ehanced version of ::pwtk::runPW with an automatic mechanism for dealing with SCF convergence problems.
OPTIONS
Remedy options are the following:
- -restart == run already the first calculation in restart mode, i.e., restart from previous calculation (aka rerunPW)
- -script <script> == how to change the pw.x input for the remedy calculation upon the SCF convergence failure
- -remedy1st == run first in remedy mode
- -reduceconv <factor> == if remedy calculation fails, further reduce the conv_thr by a "factor" and retry
- -nsteps <value> == how many ionic steps to perform in remedy mode calculation (note that sometimes it may help the SCF convergnece to move a bit the atoms)
- -loose_thr <value> == the loosest acceptable conv_thr (default value is 1d-4)
- -nlevels <number> == number of remedy trials before aborting (default value is 5)
ARGUMENTS
- input -- filename (or headname) to which the pw.x input file will be stored. The .in (.out) suffix will be added to headname for input (output) filename.
- output -- [optional] filename to which the pw.x output will be stored
DESCRIPTION
The ::pwtk::runPW_remedy behaves like ::pwtk::runPW with the exeption that if the SCF convergence fails, it will try to remedy it by making a calculation in "remedy" mode where the pw.x input will be changed by the instructions provided with -script option. If the SCF converges with the remedy calculation then the calculation is restarted in normal mode. If even the remedy calculation fails and -reduceconv option was specified then another remedy calculation is performed with the reduced conv_thr threshold.
The names of the I/O files of remedy calculations are prefixed by "__remedy-N__" string, where N is the sequential number of a given remedy calculation.
EXAMPLE
::pwtk::runPW_remedy -script {
CONTROL { calculation = 'scf' } SYSTEM { degauss = 0.05 } ::pwtk::pwi::disableDipoleCorr
} relax.in
SOURCE
variable error variable state variable remedy_level variable run_options variable runPW_extra_options variable run if { [remote_mode_] } { ::pwtk::warning "::pwtk::runPW_remedy may not run as expected in remote mode" } incr remedy_level if { $remedy_level == 1 } { printTitle REMEDY "Running pw.x in \"remedy\" mode" } set args_orig $args set extra_options { {restart 0 "run already the first calculation in restart mode, i.e., restart from scf-failed calculation"} {remedy1st 0 "run first in remedy mode"} {reduceconv.arg 0 "reduce the conv_thr if remedy calculation fails and make another trial"} {nsteps.arg 2 "how many ionic steps to run in remedy mode"} {script.arg ::pwtk::pwi::disableDipoleCorr "script to execute before runing the remedy calculation (the purpose of the script is to modify the pw.x input)"} {loose_thr.arg 1d-4 "the loosest acceptable conv_thr"} {nlevels.arg 5 "number of remedy trials before aborting"} } array set opt [::cmdline::getKnownOptions args $extra_options] set argums $args # ::cmdline::getoptions argums [concat $run_options $runPW_extra_options] "\n\nUsage: ::pwtk::runPW_remedy \[options\] input ?output?\n\nOptions are:" # set argums_len [llength $argums] set args_len [llength $args] if { $argums_len < 1 || $argums_len > 2 } { ::pwtk::error [::cmdline::usage [concat $run_options $runPW_extra_options] "\n\nUsage: ::pwtk::runPW_remedy \[options\] input ?output?"] 1 } else { set pw_options [lrange $args 0 [expr $args_len - $argums_len - 1]] } set input [lindex $argums 0] set output [lindex $argums 1] if { $output == {} } { set output [outputName_ $input] } set runPW runPW if { $opt(restart) } { set runPW rerunPW } set stopOnError_orig $state(stopOnError) set state(stopOnError) -1 if { ! $opt(remedy1st) } { # # NORMAL mode # ::pwtk::print REMEDY-#$remedy_level "Running calculation in normal mode in \$PWD directory:\n [pwd]" ::pwtk::print REMEDY-#$remedy_level " * current value of stopOnError = $state(stopOnError)\n" #------------------------------------- eval $runPW $pw_options $input $output #------------------------------------- set runPW rerunPW set output $run(output) } if { (! $opt(remedy1st) && $error(type) == "convergence failure") || $opt(remedy1st) } { # # REMEDY mode # set head [regsub "^relax.|^vc-relax.|^scf." [::pwtk::headname $input] {}] set head __remedy-${remedy_level}__.$head ::pwtk::print REMEDY-#$remedy_level "Trying to remedy SCF convergence problems using the following instructions:\n $opt(script)" input_push; #1 # remedy mode should make only $opt(nsteps) ionic steps runPW_remedy_fewSteps_ $output $opt(nsteps) # eval the REMEDY script eval $opt(script) #----------------------- if { $opt(reduceconv) <= 0.0} { # do not retry if the remedy calculation fails, hence # treat the stopOnError by original (default) way set state(stopOnError) $stopOnError_orig } ::pwtk::print REMEDY-#$remedy_level "Runing the remedy calculation ..." ::pwtk::print REMEDY-#$remedy_level " * current value of stopOnError = $state(stopOnError)\n" #---------------------------- eval $runPW $pw_options $head #---------------------------- set runPW rerunPW set state(stopOnError) $stopOnError_orig if { $error(type) == "convergence failure" && $opt(reduceconv) > 0.0} { # reduce the conv_thr and make another trial; but do not go beyond conv_thr = 1e-4 set conv_thr_old [f2c_number [::pwtk::input::namelistGetVarValue ELECTRONS conv_thr]] ::pwtk::print REMEDY-#$remedy_level "Apparently the remedy calculation failed !\n" input_push; #2 ::pwtk::pwi::reduceConvThr $opt(reduceconv) IONS { upscale = 1.0 } set conv_thr [f2c_number [::pwtk::input::namelistGetVarValue ELECTRONS conv_thr]] if { $conv_thr <= $opt(loose_thr) } { ::pwtk::print REMEDY-#$remedy_level "Temporarily reducing the SCF conv_thr and setting upscale = 1.0 ..." ::pwtk::print REMEDY-#$remedy_level " * previous value of conv_thr = [format %7.2e $conv_thr_old]" ::pwtk::print REMEDY-#$remedy_level " * reduced value of conv_thr = [format %7.2e $conv_thr]" ::pwtk::print REMEDY-#$remedy_level " * current value of stopOnError = $state(stopOnError)\n" # file copy -force $head.in $head.fail.in #------------------------------------ eval $runPW $pw_options -append $head #------------------------------------ } else { ::pwtk::print REMEDY-#$remedy_level "The SCF conv_thr is too low to be reduced further. Aborting." ::pwtk::print REMEDY-#$remedy_level " * current value of non reduced conv_thr = [format %7.2e $conv_thr_old]" ::pwtk::print REMEDY-#$remedy_level " * reduced value of conv_thr would be $conv_thr, which is lower then $opt(loose_thr)\n" } input_pop; #2 } input_pop; #1 # if we come thus far, the remedy calculation converged; # now restart a (normal) calculation via runPW_remedy set state(stopOnError) $stopOnError_orig # N.B.: use a maximum of $opt(nlevels) trials of runPW_remedy as to prevent too many trials if { $remedy_level < $opt(nlevels) } { # strip the restart & remedy1st options set ignored_options { {restart 0 "ignored option"} {remedy1st 0 "ignored option"} } array set opt [::cmdline::getKnownOptions args_orig $ignored_options] ::pwtk::print REMEDY-#$remedy_level "Reverting back to normal calculation mode." ::pwtk::print REMEDY-#$remedy_level " * current value of stopOnError = $state(stopOnError)\n" eval runPW_remedy -restart $args_orig } else { # too many levels - give up if { $stopOnError_orig } { ::pwtk::error "Too many trials of runPW_remedy tricks. Aborting ..." } else { ::pwtk::warning "Too many trials of runPW_remedy tricks. Giving up ..." } } }; # remedy-mode set state(stopOnError) $stopOnError_orig ::pwtk::print REMEDY-#$remedy_level "Leaving runPW_remedy #$remedy_level" if { $remedy_level == 1 } { ::pwtk::print "" } incr remedy_level -1 }