A Short Guide

Table of contents

Introduction

What is PWTK

PWTK stands for PWscf ToolKit.

PWTK is a Tcl scripting interface for Quantum ESPRESSO (QE), aiming at providing a flexible and productive framework. With PWTK, one can automate calculations and glue together different computational tasks, where outputs of preceding calculations serve as inputs for subsequent calculations.

(PWTK, standing for PWscf ToolKit, got its name from the consideration that it initially supported only the PWscf subset of Quantum ESPRESSO programs. Moreover, the name “Quantum ESPRESSO” did not yet exist at the time the PWTK project was initiated.)

PWTK features

Among the PWTK features are:

Simple example

Here is a comparison between the pw.x input file and the corresponding PWTK script:

pw.x input file: scf.Si.in PWTK script file: Si.pwtk
 &CONTROL
  calculation = 'scf'
       outdir = 'Si_example/'
   pseudo_dir = '/opt/espresso/pseudo'
 /

 &SYSTEM
        ibrav = 2
    celldm(1) = 10.2
          nat = 2
         ntyp = 1
      ecutwfc = 18.0
      ecutrho = 72.0
 /

 &ELECTRONS
     conv_thr = 1d-7
 /

ATOMIC_SPECIES
   Si  1.00  Si.vbc 

ATOMIC_POSITIONS alat 
   Si    0.00  0.00  0.00    
   Si    0.25  0.25  0.25    

K_POINTS automatic 
   4 4 4   1 1 1 
CONTROL {
  calculation = 'scf' 
       outdir = 'Si_example/'
   pseudo_dir = '/opt/espresso/pseudo'
} 
 
SYSTEM {
        ibrav = 2
    celldm(1) = 10.2
          nat = 2
         ntyp = 1
      ecutwfc = 18.0 
      ecutrho = 4*18.0 
}

ELECTRONS {
      conv_thr = 1d-7
}

ATOMIC_SPECIES {
   Si  1.00  Si.vbc 
}
ATOMIC_POSITIONS alat {
   Si    0.0   0.0   0.0
   Si    1/4   1/4   1/4
}
K_POINTS automatic {
   4 4 4   1 1 1 
}

runPW scf.Si.in
This calculation is run as: This calculation is run as:
pw.x < scf.Si.in > scf.Si.out &
pwtk Si.pwtk > Si.log &

The syntax of the PWTK scripts is similar to QE input files, but notice that both Fortran namelists (e.g. &CONTROL) and cards (e.g. ATOMIC_SPECIES) are enclosed with curly braces (e.g. CONTROL { ... }).

The last line of the above PWTK script, runPW scf.Si.in, requests the pw.x calculation. Upon execution, PWTK will:

At a simplistic level of the above example, there is no advantage of using PWTK, but the advantage becomes evident once multiple calculations are performed (see the example below).

Syntax of the PWTK scripts

The main syntactic attributes of PWTK scripts are:

Example: running multiple calculations

PWTK allows (re)assigning namelist variables or the content of cards on the fly, which is useful when performing multiple calculations, where only a few parameters per calculation change.

As an example, let us perform a few tests on Si bulk. To this end, we will use the above scf.Si.si input file. Below is the PWTK script that scans the energy cutoff (ecutwfc), k-point mesh (K_POINTS), and lattice parameter (celldm(1)):

# the "load_fromPWI" command loads the pw.x input file
load_fromPWI scf.Si.in

#------------------------
# scan the energy-cuttofs
#------------------------
# the "scanpar" command loops over a parameter; 
# it is similar to a one-parameter Tcl "foreach" command

scanpar e {10.0 14.0 18.0 22.0} {
   # load the new energy cuttofs
   SYSTEM "ecutwfc = $e, ecutrho = 4*$e"

   # perform the pw.x calculation (I/O files: scf.Si_e$e.in & scf.Si_e$e.out)
   runPW scf.Si_e$e

   # store $e and total energy in the 'ecut.dat' file 
   write ecut.dat [pwo_totene scf.Si_e$e.out]
}
# plot the result
plot -xl "ecutwfc (Ry)" -yl "Total energy (Ry)" ecut.dat


#-----------------
# scan the k-points
#-----------------

scanpar k {2 4 6} {
   # load new k-points
   K_POINTS automatic "$k $k $k   1 1 1"

   # perform the pw.x calculation (I/O files: scf.Si_k$k.in & scf.Si_k$k.out)
   runPW scf.Si_k$k

   # store $k and total energy into the 'k.dat' file 
   write k.dat [pwo_totene scf.Si_k$k.out]
}
# plot the result
plot -xl "K of the (KxKxK) k-point mesh" -yl "Total energy (Ry)" k.dat


#---------------------------
# scan the lattice-parameter
#---------------------------

# here we use the "seq" command, which behaves just like the Unix "seq" command
scanpar a [seq 9.2 0.2 10.8] {
   # load new celldm(1)
   SYSTEM " celldm(1) = $a "

   # perform the calculation (I/O files: scf.Si_alat$a.in & scf.Si_alat$a.out)
   runPW scf.Si_alat$a

   # store $a and total energy into the 'alat.dat' file
   write alat.dat [pwo_totene scf.Si_alat$a.out]
}
# plot the result
plot -xl "A lattice paramater (bohr)" -yl "Total energy (Ry)" alat.dat

Let us save this script into the scan.pwtk file. The script is run from the terminal as:

pwtk scan.pwtk

List of supported Quantum ESPRESSO programs

PWTK explicitly supports all QE executables, which are documented with the INPUT_*.html documentation. To get the list of these executables, enter the PWTK interactive prompt by typing pwtk in the terminal. Then type:

report programs

which returns the alphabetically sorted list of supported QE executables and the respective commands for running them (e.g. runPW for pw.x, runCP for cp.x, runPH for ph.x…), i.e.:

----------------------------------------------
 executable             runCmd                 
----------------------------------------------
 all_currents.x         runALL_CURRENTS        
 band_interpolation.x   runBAND_INTERPOLATION  
 bands.x                runBANDS               
 bgw2pw.x               runBGW2PW              
 cp.x                   runCP                 
 cppp.x                 runCPPP               
 d3hess.x               runD3HESS             
 dos.x                  runDOS                
 dynmat.x               runDYNMAT             
 hp.x                   runHP                 
 kcw.x                  runKCW                
 ld1.x                  runLD1                
 matdyn.x               runMATDYN             
 molecularpdos.x        runMOPDOS             
 neb.x                  runNEB                
 oscdft_et.x            runOSCDFT_ET          
 oscdft_pp.x            runOSCDFT_PP          
 ph.x                   runPH                 
 postahc.x              runPOSTAHC            
 pp.x                   runPP                 
 ppacf.x                runPPACF              
 pprism.x               runPPRISM             
 projwfc.x              runPROJWFC            
 pw.x                   runPW                 
 pw2bgw.x               runPW2BGW             
 pw2gw.x                runPW2GW              
 pw2wannier90.x         runPW2WANNIER90       
 pwcond.x               runPWCOND             
 q2r.x                  runQ2R                
 turbo_davidson.x       runDAVIDSON           
 turbo_eels.x           runEELS               
 turbo_lanczos.x        runLANCZOS            
 turbo_magnon.x         runMAGNON             
 turbo_spectrum.x       runSPECTRUM
----------------------------------------------

Because there are many runCmd commands, which may be hard to remember, there is also an alternative runXX command, whose usage is:

runXX program inputName

where program is the name of the QE executable. For example, runXX ph.x is equivalent to runPH. In the first example above, we used:

runPW scf.Si.in

which is equivalent to:

runXX pw.x scf.Si.in

How to run unsupported programs with PWTK

It is also possible to run other QE programs that are not directly supported by PWTK, using the run command. But in this case, the input file needs to exist before the run command is called. It can be created in a PWTK script with the writeFile command. Here is an example of how to run the ev.x executable:

# create the 'ev.murnaghan.in' file
writeFile ev.murnaghan.in {
   au
   fcc
   4
   Etot-vs-alat.dat
   Etot-vs-alat.out
}

# run the ev.x code; the -serial option requests running in a serial mode
run -serial ev.x ev.murnaghan.in

Input data stacking

PWTK has an input data stacking mechanism, which is useful when performing multiple calculations. For example, say that we have a set of default parameters for all calculations, but each calculation requires some input data modification. We do not want a change of input data for a given calculation to affect the input data for subsequent calculations. This can be elegantly achieved using the input data stacking mechanism, and for this purpose, PWTK provides the input_pushpop command. The concept is illustrated below:

# import a default set of parameters (#0)
import input-data.pwtk

# 1st calculation 
input_pushpop {
   # input data was pushed on the stack;
   # at this point the input data is the same as in (#0)
 
   ... modify input data for this calculation (#1)
   ... perform the 1st calculation
}
# the input data modifications (#1) were popped away;
# at this point the input data is the same as in (#0)

# 2nd calculation
input_pushpop {
   # input data still the same as in (#0)
 
   ... modify input data for this calculation (#2)
   ... perform the 2nd calculation
}
# at this point the input data is again the same as in (#0)

Customizing PWTK

The PWTK user configuration files are stored in the ~/.pwtk/ directory. The main configuration file therein is pwtk.tcl. In this file, the following items are typically defined (actually their default values):

The system configuration files are stored in the $PWTK/config/ directory and the PWTK first reads the system configuration files and then the user configuration files, which implies that user configuration has priority over the system configuration.

The main configuration file: ~/.pwtk/pwtk.tcl

Here is an example of the ~/.pwtk/pwtk.tcl file:

# ------------------------------------------------------------------------
# 
# File: pwtk.tcl -- PWTK main configuration file
#
# This is a main configuration file for PWTK. It contains some custom
# definitions, such as Quantum ESPRESSO executables and alike.
# ------------------------------------------------------------------------

#
# LOCATION OF QUANTUM ESPRESSO EXECUTABLES AND
# HOW TO RUN THEM ...
# 
# executables are run as: container prefix bin_dir/program postfix

prefix  mpirun -np 32
bin_dir $env(HOME)/bin/espresso

# for containers, one may use:

container apptainer exec /path/to/container.sif
bin_query false

#
# DEFAULT DIRECTORIES ...
#
# N.B. outdir == outdir_prefix/outdir_postfix
#      wfcdir == wfcdir_prefix/wfcdir_postfix

outdir_prefix /scratch/$env(USER)/QE
wfcdir_prefix /scratch/$env(USER)/QE

outdir_postfix [pid]
wfcdir_postfix [pid]

# directory for pseudopotential files (aka pseudo_dir)

pseudo_dir    $env(HOME)/espresso/pseudo

In this file, the following data are typically specified:

Here is a snippet that automatically determines the number of available processors that can be used in ~/.pwtk/pwtk.tcl:

set np [exec nproc]
while { [catch {exec mpirun -n $np echo yes}] } {
    set np [expr { $np > 2 ? $np / 2 : 1 }]
}
if { $np > 1 } {
    prefix mpirun -n $np
}

Incomplete list of configuration files

The configuration files that a user should usually copy from the $PWTK/config/ to ~/.pwtk/ directory and edit are:

The following configuration files typically do not need any user attention and relying on system configurations in $PWTK/config/ directory is just fine.

PWTK support for HPC schedulers

HPC machines use job schedulers. Hence, one needs to provide some batch-queuing system-specific instructions (directives) in shell script files, such as the name of the queue, number of processors, and some other resources. Instead of putting such instructions inside each shell script (or PWTK script, if one is using PWTK), the specific queuing directives can be stored in the corresponding PWTK configuration file (e.g. ~/.pwtk/slurm.tcl, ~/.pwtk/lsf.tcl, ~/.pwtk/pbs.tcl). Templates for these configuration files are available in the $PWTK/config/ directory.

Once such configuration file is properly set, a user needs to instuct PWTK that the script is to be submitted to the batch queuing system. For Slurm, this can be achieved by encapsulating the whole script with the SLURM { ... } command (for the other supported job schedulers, analogous commands are LSF, PBS, LL). For example:

SLURM {
    ... here comes the whole script ...
}

Alternatively, the name of the PWTK script file can be supplied to the SLURM command, i.e.:

SLURM job.pwtk

or the pwtk can be called with the --slurm option from the terminal:

pwtk --slurm job.pwtk

Note that the --slurm option is configurable, i.e.:

pwtk --slurm=profile job.pwtk

or

pwtk --slurm="profile options" job.pwtk

where profile is the name of the user-defined Slurm profile (see below), and options are the Slurm sbatch command-line options.

Likewise, also the SLURM command is analogously configurable; its usage is:

where script is either the PWTK script file or the script code and profile is the name of the profile as defined in the user ~/.pwtk/slurm.tcl file that contains the Slurm specific directives. If the profile is omitted the default profile is used, which is guaranteed to exist, because it is defined in the $PWTK/config/slurm.tcl file.

One can define different profiles in the configuration file (e.g., ~/.pwtk/slurm.tcl). Here is an example with two defined Slurm profiles, named default and long:

# ------------------------------------------------------------------------
# This is a configuration file for PWTK's SLURM utility
# ------------------------------------------------------------------------

slurm_profile default {
    #!/bin/sh
    #SBATCH --nodes=1
    #SBATCH --ntasks=8
    #SBATCH --time=6:00:00
} {
    prefix mpirun -np 8
}

slurm_profile long {
    #!/bin/sh
    #SBATCH --partition=long
    #SBATCH --ntasks=64
    #SBATCH --time=2-00:00:00
} {
    prefix mpirun -np 64
}

The usage of the slurm_profile command is (for other supported job schedulers, analogous commands are lsf_profile, pbs_profile, etc.):

slurm_profile name slurmDirectives ?pwtkDirectives?

where the last pwtkDirectives argument is optional (hence, denotated with the pair of question marks). The purpose of the optional pwtkDirectives argument is to provide to PWTK a default way of how to run executables. For example, the long profile request 64 tasks, hence it is reasonable to run executables with mpirun -np 64.

The long profile can then be utilized in a PWTK script as:

SLURM long job.pwtk

or from the terminal as:

pwtk --slurm=long job.pwtk

Math parser

Within namelists and cards, numbers can be specified as mathematical expressions, e.g.: 1/4*exp(2*log(0.23)). Here is an example of how mathematical expressions can be used in namelists and cards:

SYSTEM { celldm(1) = 7.5*sqrt(2)*$angs2bohr }
ATOMIC_POSITIONS alat {
   Si    0.0   0.0   0.0
   Si    1/4   1/4   1/4
}

Notice the use of the $angs2bohr variable in the example above. This is a predefined constant (a conversion factor from Å to bohr units).

IMPORTANT: mathematical expression should be written without any whitespace. For example, the 1/4 * sqrt(2) expression contains two whitespaces; hence, it is treated as three separate input-fields and the parser returns .25000000000000000000 * 1.41421356237309504880.

List of predefined constants

Here is a list of predefined constants that can be used in PWTK scripts and in mathematical expressions of input data specs. Physical constants correspond to CODATA Internationally Recommended 2018 Values.