quantum-espresso/GUI/PWgui/src/run.itcl

426 lines
12 KiB
Plaintext

#
# $RCSfile: run.itcl,v $ --
#
# This file contains ...
#
# Copyright (c) 2004 Anton Kokalj Email: tone.kokalj@ijs.si
#
#
# This file is distributed under the terms of the GNU General Public
# License. See the file `COPYING' in the root directory of the present
# distribution, or http://www.gnu.org/copyleft/gpl.txt .
#
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
# ANTON KOKALJ BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
#
# $Id: run.itcl,v 1.8 2009-07-16 16:58:45 kokalj Exp $
#
proc ::pwscf::run::run {guiObj {init 1} {use_defaults 1}} {
variable ::pwscf::settings
variable run
# initializing ...
if { $init == 1 } {
_init $guiObj
}
set moduleObj [$guiObj getSelected moduleObj]
set moduleIdent [$guiObj getSelected moduleIdent]
if { $use_defaults == 1 } {
# use default values
set _run(RUN.prefix,$moduleObj) $::pwscf::settings(RUN.prefix)
set _run(RUN.postfix,$moduleObj) $::pwscf::settings(RUN.postfix)
set _run(PW,$moduleObj) $::pwscf::settings(PW)
set _run(PH,$moduleObj) $::pwscf::settings(PH)
set _run(PP,$moduleObj) $::pwscf::settings(PP)
set _run(PROJWFC,$moduleObj) $::pwscf::settings(PROJWFC)
#set _run(D3,$moduleObj) $::pwscf::settings(D3)
set _run(LD1,$moduleObj) $::pwscf::settings(LD1)
} else {
# use values as specified in the current configuration
set _run(RUN.prefix,$moduleObj) $run(RUN.prefix,$moduleObj)
set _run(RUN.postfix,$moduleObj) $run(RUN.postfix,$moduleObj)
set _run(PW,$moduleObj) $run(PW,$moduleObj)
set _run(PH,$moduleObj) $run(PH,$moduleObj)
set _run(PP,$moduleObj) $run(PP,$moduleObj)
set _run(PROJWFC,$moduleObj) $run(PROJWFC,$moduleObj)
#set _run(D3,$moduleObj) $run(D3,$moduleObj)
set _run(LD1,$moduleObj) $run(LD1,$moduleObj)
}
#
# determine what program to run
#
switch -glob -- $moduleIdent {
*pw {
set runCmd "$_run(RUN.prefix,$moduleObj) $_run(PW,$moduleObj) $_run(RUN.postfix,$moduleObj)"
# find out the outdir and create it !!!
_mkdirOutdir $moduleObj
}
*ph {
set runCmd "$_run(RUN.prefix,$moduleObj) $_run(PH,$moduleObj) $_run(RUN.postfix,$moduleObj)"
# find out the outdir and create it !!!
_mkdirOutdir $moduleObj
}
*pp {
set runCmd "$_run(RUN.prefix,$moduleObj) $_run(PP,$moduleObj) $_run(RUN.postfix,$moduleObj)"
# find out the outdir and create it !!!
_mkdirOutdir $moduleObj
}
*pr {
set runCmd "$_run(RUN.prefix,$moduleObj) $_run(PROJWFC,$moduleObj) $_run(RUN.postfix,$moduleObj)"
# find out the outdir and create it !!!
_mkdirOutdir $moduleObj
}
*ld1 {
set runCmd "$_run(RUN.prefix,$moduleObj) $_run(LD1,$moduleObj) $_run(RUN.postfix,$moduleObj)"
# find out the outdir and create it !!!
_mkdirOutdir $moduleObj
}
default {
# module not yet supported ...
return 0
}
}
# *d3 {
# set runCmd "$_run(RUN.prefix,$moduleObj) $_run(D3,$moduleObj) $_run(RUN.postfix,$moduleObj)"
#
# # find out the outdir and create it !!!
# _mkdirOutdir $moduleObj
# }
#
# run the calculation
#
if { $run(mode,$moduleObj) == "nonblocking" } {
# run in non-blocking mode (i.e. on the fly)
set execID [::tclu::nonblocking open]
# display stdout into pager while calculating
::tclu::nonblocking stdout $execID "::pwscf::run::defaultStdOutPager [list $moduleObj]"
# run the calculation
set status [eval ::tclu::nonblocking exec $execID $runCmd < $run(inpFile,$moduleObj) 2> $run(errFile,$moduleObj)]
# CALCULATION is finished, hence ...
# save the stdout to outFile
::tclu::nonblocking save $execID $run(outFile,$moduleObj)
# we are done
::tclu::nonblocking unset $execID
return $status
} else {
# run in background and forget about it ...
eval exec $runCmd < $run(inpFile,$moduleObj) > $run(outFile,$moduleObj) 2> $run(errFile,$moduleObj) &
set run(run.done,$moduleObj) 1
return 1
}
}
proc ::pwscf::run::runAs {guiObj} {
variable run
# first configure and then run ...
set t [::tku::toplevelExists .pwgui_settings]
# initializing ...
_init $guiObj
set moduleObj [$guiObj getSelected moduleObj]
set moduleIdent [$guiObj getSelected moduleIdent]
set prog [getProg $moduleIdent]
# create a configure module
set obj [_configureModule $moduleObj $prog]
::guib::widgets::dialogshell $t -title "Configure calculation" -separator 1 -transient 0
$t add Cancel -text "Cancel" -command [list ::pwscf::run::_cancel $t $guiObj]
$t add Apply -text "Apply & Run" -command [list ::pwscf::run::_configApply $t $obj $guiObj]
$t default Apply
#
# build the config-GUI recursively
#
set cs [$t childsite]
$obj makeEmbedGUI $cs
::tku::centerWindow $t
}
proc ::pwscf::run::runAndXC {guiObj} {
variable run
# first run the calculation
set status [run $guiObj]
# now display with xcrysden if status is OK, and program is pw.x or pp.x
_displayXC $guiObj $status
}
proc ::pwscf::run::runAsAndXC {guiObj} {
variable run
# first run the calculation
runAs $guiObj
# wait for calculation to finish
set moduleObj [$guiObj getSelected moduleObj]
tkwait variable ::pwscf::run::run(run.done,$moduleObj)
# now display with xcrysden if status is OK, and program is pw.x or pp.x
_displayXC $guiObj $run(status,$moduleObj)
}
proc ::pwscf::run::defaultStdOutPager {moduleObj id newLine} {
variable run
set create 0
if { ! [info exists run(textWidget,$moduleObj)] } {
set create 1
} elseif { ! [winfo exists $run(textWidget,$moduleObj)] } {
set create 1
}
if { $create } {
# calling the pager for the first time: create the toplevel
# and text widgets ...
set t [::guib::widgets::dialogshell [::tku::widgetName] -title "Output file: $run(outFile,$moduleObj)" -separator 1 -transient 0]
$t add Close -text Close -command [list destroy $t]
$t default Close
set w [$t childsite]
set run(textWidget,$moduleObj) [::iwidgets::scrolledtext $w.text \
-labeltext "Output file:\n$run(outFile,$moduleObj)" \
-hscrollmode dynamic -vscrollmode dynamic \
-wrap none -state normal]
pack $run(textWidget,$moduleObj) -side top -fill both -expand 1
}
$run(textWidget,$moduleObj) configure -state normal
$run(textWidget,$moduleObj) insert end $newLine
$run(textWidget,$moduleObj) yview moveto 1
$run(textWidget,$moduleObj) configure -state disabled
}
proc ::pwscf::run::_init {guiObj} {
variable ::pwscf::settings
variable run
# initializing ...
set moduleObj [$guiObj getSelected moduleObj]
set moduleIdent [$guiObj getSelected moduleIdent]
::tclu::newset run(mode,$moduleObj) $run(mode)
::tclu::newset run(RUN.prefix,$moduleObj) $::pwscf::settings(RUN.prefix)
::tclu::newset run(RUN.postfix,$moduleObj) $::pwscf::settings(RUN.postfix)
::tclu::newset run(PW,$moduleObj) $::pwscf::settings(PW)
::tclu::newset run(PH,$moduleObj) $::pwscf::settings(PH)
::tclu::newset run(PP,$moduleObj) $::pwscf::settings(PP)
::tclu::newset run(PROJWFC,$moduleObj) $::pwscf::settings(PROJWFC)
#::tclu::newset run(D3,$moduleObj) $::pwscf::settings(D3)
::tclu::newset run(LD1,$moduleObj) $::pwscf::settings(LD1)
#
# determine what are the IO-files
#
set inpFile [$guiObj getSelected saveFile]
if { $inpFile == "" } {
# save the file
set inpFile [$guiObj saveAs]
if { $inpFile == "" } {
# Cancel button was pressed
return -code return 0
}
} else {
$guiObj save 1 ; # "1" here is for nocomplain. I am not sure if nocomplain is good idea ???
}
# get the output-file from the input-file; also the error file
#set head [regsub {\.(inp|in)$} $inpFile {}]
regsub {\.(inp|in)$} $inpFile {} head
set run(inpFile,$moduleObj) $inpFile
set run(outFile,$moduleObj) $head.out
set run(errFile,$moduleObj) $head.err
set run(status,$moduleObj) 1
set run(run.done,$moduleObj) 0
}
proc ::pwscf::run::getProg {moduleIdent} {
switch -glob -- $moduleIdent {
*pw { return pw.x }
*ph { return ph.x }
*pp { return pp.x }
*pr { return projwfc.x }
*atomic { return ld1.x }
default {
# module not yet supported ...
return ""
}
}
# *d3 { return d3.x }
}
proc ::pwscf::run::_configureModule {moduleObj prog} {
set var [string toupper [string trimright $prog .x]]
set script [subst -nocommands {
optionSetDefault line decor normal
optionSetDefault namelist decor normal
separator -label "--- PWscf settings ---\n\n The calculation will be executed as: prefix $prog postfix < input > output"
line pwscf_fix -name "Prefix & postfix (i.e. Prefix = mpirun -np 2 .AND. Postfix = -npool 2)" {
var RUN.prefix -variable ::pwscf::run::run(RUN.prefix,$moduleObj) -label "Prefix:"
var RUN.postfix -variable ::pwscf::run::run(RUN.postfix,$moduleObj) -label "Postfix:"
}
line pwscf_exe -name "Specify $prog executable (i.e. /usr/local/bin/$prog)" {
var $var -variable ::pwscf::run::run($var,$moduleObj) -label "Executable \\\"pw.x\\\":" -widget entryfileselect
}
line io_files -name "Input & Output files" {
var inFile -variable ::pwscf::run::run(inpFile,$moduleObj) -label "Input file:" -widget entryfileselect
var outFile -variable ::pwscf::run::run(outFile,$moduleObj) -label "Output file:" -widget entryfileselect
var errFile -variable ::pwscf::run::run(errFile,$moduleObj) -label "Error file:" -widget entryfileselect
}
line run_mode -name "Mode of calculation:" {
var mode {
-variable ::pwscf::run::run(mode,$moduleObj)
-label "Mode of calculation:"
-textvalue {
"on the fly (for short jobs)"
"in background (for longer jobs)"
}
-value {
nonblocking
background
}
-widget radiobox
}
}
postprocess {
loadFromVar
widgetconfigure inFile -width 60
}
}]
set obj [::guib::moduleObj settings\#auto -title "PWgui: settings" -script $script]
}
proc ::pwscf::run::_configApply {t configObj guiObj} {
variable run
if { [winfo exists $t] } {
destroy $t
}
# save "config" variables
$configObj saveToVar ::pwscf::run
# run the calculation
set status [run $guiObj no_init no_defaults]
# check the status of the run
set moduleObj [$guiObj getSelected moduleObj]
if { $status == 1 } {
set run(status,$moduleObj) 1
} else {
set run(status,$moduleObj) 0
}
set run(run.done,$moduleObj) 1
}
proc ::pwscf::run::_cancel {t guiObj} {
variable run
# destroy "config" toplevel
if { [winfo exists $t] } {
destroy $t
}
# set the status to zero
set moduleObj [$guiObj getSelected moduleObj]
set run(status,$moduleObj) 0
set run(run.done,$moduleObj) 1
}
proc ::pwscf::run::_mkdirOutdir {moduleObj} {
set outdir [string trim [namespace eval ::guib "$moduleObj varvalue outdir"] '\"]
if { $outdir != "" } {
if { ! [file isdirectory $outdir] } {
if { [catch {file mkdir $outdir} errMsg] } {
::tclu::warningDialog "cannot create temporary directory \"$outdir\". Aborting the calculation !!!\n\nERROR message: $errMsg"
return -code return 0
}
}
if { ! [file writable $outdir] } {
::tclu::warningDialog "temporary directory \"$outdir\" is not writable"
return -code return 0
}
}
}
proc ::pwscf::run::_displayXC {guiObj status} {
variable run
set moduleObj [$guiObj getSelected moduleObj]
set moduleIdent [$guiObj getSelected moduleIdent]
set prog [getProg $moduleIdent]
if { $status == 1 } {
if { $prog == "pw.x" } {
# launch XCRYSDEN in background mode and display the
# structure from output file
exec xcrysden --pwo $run(outFile,$moduleObj) &
} elseif { $prog == "pp.x" } {
# check if the output_format == 3 || output_format == 5, and display
# the structure/property from fileout
set output_format [namespace eval ::guib "$moduleObj vartextvalue output_format"]
set fileout [string trim [namespace eval ::guib "$moduleObj varvalue fileout"] '\"]
if { [string match *XSF* $output_format] } {
# it is an XSF format
exec xcrysden --xsf $fileout &
}
}
}
}