- 1 Introduction
- 1.1 The purpose of PWTK
- 1.2 PWTK features
- 1.3 Simple example
- 1.4 Syntax of the PWTK scripts
- 1.5 Example: running multiple calculations
- 1.6 List of supported QUANTUM ESPRESSO programs

- 2 Input data stacking
- 3 Customizing the PWTK
- 3.1 Main configuration file: $HOME/.pwtk/pwtk.tcl
- 3.2 (Incomplete) list of configuration files
- 3.3 PWTK's batch queuing support

- 4 Math parser

- About this document ...

The **PWTK** stands for **PW**SCF **T**OOL** K**IT.

Technically, **PWTK** is a Tcl scripting interface for
**QUANTUM ESPRESSO**. The aim of
the **PWTK** package is to make the use of
**QUANTUM ESPRESSO**
easier and
to provide a more productive framework. (The name of the **PWTK** originates from the fact that in its early versions, **PWTK** supported
only a subset of **PWSCF** programs contained in the
**QUANTUM ESPRESSO**
distribution.)

**Why PWTK?** Imagine that you want to perform a set of calculations where only a
few of parameters are varied. Such set of calculations requires a set
of input files, one input per each run. Hence we have two choices:
(i) to make a new input for each calculation, or (ii) to generate the
files in some automate way. For simple cases automation can be
achieved by shell scripts, but such scripts get quickly too
elaborate. With the

- assignment of input data (e.g., namelist variables) on the fly
- stacking of input data
- math-parser: real numbers can be input as math expressions
- data retrieval functions (i.e., either loading the data from pre-existing input files or retrieving the data from output files)
- a few predefined high-level tasks (e.g. lattice parameter search, charge density difference)
- control flow (loops, conditionals, ...)
- support for batch queuing
- possibility to assign default values of namelist variables on a project basis
- extensible and hierarchical configuration (global,
project-based, local) including specification of
**QUANTUM ESPRESSO**'s binaries, batch script configurations ...)

Here is a simple example--a comparison between the **pw.x** input file for
Si bulk and the corresponding **PWTK** script.

pw.x input file: si.scf.in |
PWTK script file: si.pwtk |

&CONTROL title = 'Si bulk' calculation = 'scf' , restart_mode = 'from_scratch' , outdir = 'Si_example/' , pseudo_dir = '/home/tone/pw/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 { title = 'Si bulk' calculation = 'scf' , restart_mode = 'from_scratch' , outdir = 'Si_example/' , pseudo_dir = '/home/tone/pw/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 si.scf.in |

This calculation is run as: | This calculation is run as: |

pw.x < si.scf.in > si.scf.out & |
pwtk si.pwtk |

The syntax of the input data in **PWTK**'s scripts is similar to that of
**PWSCF**'s input file, but notice that both Fortran namelists
(e.g. **&CONTROL .... /**) and cards (e.g. **ATOMIC_SPECIES**)
are enclosed with curly braces (e.g. **CONTROL { ... }**). The
curly braces are due to the fact that the **PWTK** package is written in
TCL scripting language.

The last line of the above **PWTK** script (i.e. **runPW si.scf**)
requests the **pw.x** calculation. Upon execution the **PWTK** will:

- construct the
**si.scf.in**input file from the provided data (the pw.x output will be written to a file**si.scf.out**), - automatically create the temporary directory as specified by the
**outdir**variable if the directory does not exist yet, and - run the
**pw.x**calculation.

Here are the main **syntactic attributes** of the **PWTK** scripts:

**PWTK**scripts are**case-sensitive**! The names of namelists and cards are written in uppercase; e.g. to use**control**instead of**CONTROL**will produce the error:**invalid command name "control" ...**- Beware that also the names of namelist
variables are case-sensitive in
**PWTK**. This implies that, e.g.,**ibrav**and**IBRAV**are too different namelist variables. - Namelists and cards are bracketed with curly braces or double-quotes,
e.g.
**CONTROL { ... }**or**CONTROL " ... "**(note that “#” is used for comments):# either with curly braces SYSTEM { celldm(1) = 10.2 ! this is also a comment, but only inside the namelist } # or with double-quotes SYSTEM " celldm(1) = $a "

- The difference between curly braces { } and
double-quotes " " is that inside the double-quotes the
variable
**$a**is substituted by its value, whereas inside curly braces the**$a**would be treated literally (i.e. no substitution). - Once a given namelist variable is set, it can be unset by
assigning it an “empty” value as follows:
# a namelist variable is unset as follows: SYSTEM { celldm(3) = }

- Namelists and cards can be cleared (unset) via the
**input_clear**command, for example:input_clear SYSTEM ATOMIC_POSITIONS

will clear the**SYSTEM**namelist and the**ATOMIC_POSITIONS**card. - Numbers can be specified as mathematical expressions:
math-parsing is enabled for all cards and all (majority) real type namelist
variables. Here is an example:
SYSTEM { ecutrho = 12*30.0 }

- Indices of
*ntyp*-type array variables, such as**starting_magnetization**, can be specified with atomic labels:SYSTEM { starting_magnetization(Fe) = -0.8 }

where species Fe is one among atomic species defined by**ATOMIC_SPECIES**card. - the
**PWTK**scripts are actually Tcl scripts, which means that one can use all standard Tcl commands.

One of the strengths of **PWTK** is the possibility to (re)assign the
value of namelist's variable or the content of a given card at
will. This comes handy when performing multiple calculations, where
only a few parameters change per run, while the majority of the input
data is common to all runs.

Let us perform a few tests on Si bulk example. We will first construct
a common script that will be used by all calculations. Let us call it
**Si_common.pwtk**:

CONTROL { title = 'Si bulk' calculation = 'scf' , restart_mode = 'from_scratch' , outdir = 'Si_example/' , pseudo_dir = '/home/tone/pw/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 }

Now let's make a script that will scan the energy-cutoff
(**ecutwfc**), k-point mesh (**K_POINTS)**, and lattice parameter
(**celldm(1)**). Let's call this file **scan.pwtk**.

# load the common definitions source Si_common.pwtk #------------------------ # scan the energy-cuttofs #------------------------ foreach e {10.0 14.0 18.0 22.0} { # load the new energy-cuttofs SYSTEM "ecutwfc = $e, ecutrho = 4*$e" # perform the calculation (io files: Si_e$e.scf.in|out) runPW Si_e$e.scf } #----------------- # scan the kpoints #----------------- # say that we want to perform this at 18.0 Ry SYSTEM "ecutwfc = 18.0, ecutrho = 4*18.0" foreach k {2 4 6} { # load new k-points K_POINTS automatic "$k $k $k 1 1 1" # perform the calculation (io files: Si_k$k.scf.in|out) runPW Si_k$k.scf } #--------------------------- # scan the lattice-parameter #--------------------------- # say that we want to perform this at the following k-mesh K_POINTS automatic "4 4 4 1 1 1" # here we use the "seq" command, which behaves just like the Unix seq foreach a [seq 9.2 0.2 10.8] { # load new celldm(1) SYSTEM " celldm(1) = $a " # perform the calculation (io files: Si_a$a.scf.in|out) runPW Si_a$a.scf }

We run this script by executing: **pwtk scan.pwtk**. Notice from
this example that the namelist variables and cards can be reassigned
at will.

The following **QUANTUM ESPRESSO** programs are explicitly supported by **PWTK**. The
below list lists the supported programs and the corresponding **PWTK** routines for running them in the form: program ->
runCommand.

**pw.x -> runPW****cp.x -> runCP****neb.x -> runNEB****pp.x -> runPP****dos.x -> runDOS****bands.x -> runBANDS****projwfc.x -> runPROJWFC****molecularpdos.x -> runMOLECULARPDOS****ph.x -> runPH****dynmat.x -> runDYNMAT****matdyn.x -> runMATDYN****q2r.x -> runQ2R****hp.x -> runHP****turbo_davidson.x -> runDAVIDSON****turbo_lanczos.x -> runLANCSOZ****turbo_eels.x -> runEELS****turbo_spectrum.x -> runSPECTRUM**

Note that it is possible to run also other **QUANTUM ESPRESSO** programs that are not
directly supported by **PWTK**, using the **run** command or even the
generic Tcl **exec** command. As an example, see the end of the file
**Si.pwtk**.

**PWTK** allows for input data stacking, which is useful when performing
multiple calculations. For example, we want a set of default
parameters for all calculations, but each individual calculation
require some modification of input data. We don't want that a change
of input data for a given calculation affects the input data for other
calculations. This can be done by organizing input data into a stack,
and for this purpose **PWTK** provide **input_push** and
**input_pop** commands. The concept is illustrated below:

... define default set of parameters (#0) # 1st calculation input_push # input data has been pushed on the stack; # at this point the input data is the same as in (#0) ... modify input data for this calculation (#1) ... perform 1st calculation input_pop # the "input_pop" has removed the input data modification (#1), # i.e. input data (#1) has been popped from the stack; # at this point the input data is the same as in (#0) # 2nd calculation input_push # input data still the same as in (#0) ... modify input data for this calculation (#2) ... perform 2nd calculation input_pop # at this point the input data is again the same as in (#0)

As a convenience, there is also the **input_pushpop { ... }**
command, which behaves as the **input_push ... input_pop** pair,
i.e.:

# example of input_push/input_pop pair input_push ... modify input data ... perform calculation input_pop # the same example using the input_pushpop { ... } command input_pushpop { ... modify input data ... perform calculation }

**PWTK** customization (configuration) files are stored in
**$HOME/.pwtk/** directory and the main customization file
therein is **pwtk.tcl**. In this file the following items are
defined (actually default values for those items):

- how
**QUANTUM ESPRESSO**executables are run: these include**prefix**,**postfix**, and the binary directory, where the executables are located. - directory where pseudo-potential files are located and temporary directories (outdir, wfcdir)
- extra user-defined stuff and extensions

The system configuration files are stored in **$PWTK/config/**
directory and the **PWTK** first reads the system configuration files
and then the user configuration files, which implies that user
definitions have precedence/priority over the system configuration
(i.e. user can overwrite system configuration).

Here is an example of the **$HOME/.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. # # (by default almost everything is commented) # ------------------------------------------------------------------------ # # HOW TO RUN QUANTUM ESPRESSO EXECUTABLES ... # # They are run as: prefix bin_dir/program postfix #prefix "" #postfix "" #bin_dir $env(HOME)/bin/espresso # For Singularity containers use: #prefix "singularity exec /path/to/container.simg mpirun -np 32" #serial_prefix "singularity exec /path/to/container.simg" #bin_query false # if you wish to define some individual executables explicitly, # uncomment appropriate lines below, and set the full-path name # accordingly. # pw /full/path/to/pw.x # neb /full/path/to/neb.x # ph /full/path/to/ph.x # cp /full/path/to/cp.x # # DEFAULT DIRECTORIES ... # # top (root) directory where the scatch files will be written # (i.e. outdir == outdir_prefix/outdir_postfix) # either: #outdir_prefix /scratch/$env(USER)/pw #wfcdir_prefix /scratch/$env(USER)/pw # or: #outdir /scratch/$env(USER)/pw/[pid] #wfcdir /scratch/$env(USER)/pw/[pid] # default pseudo_dir #pseudo_dir $env(HOME)/pw/pseudo

In this file, the following data are specified:

- location of the
**PWSCF**(or**QUANTUM ESPRESSO**) executables and how to run them in parallel - default directory of where the pseudo-potentials are located
- default locations for temporary directories, such as,
**outdir**and**wfcdir**(the**PWTK**will insert their values in the corresponding input files automatically, when those variables were not explicitly defined in the input data specification)

Among the configuration files that are usually copied by a user from
**$PWTK/config/** to **$HOME/.pwtk/** directory and edited
therein are:

**pwtk.tcl**-- main configuration file (it is typically edited by each user)**slurm.tcl**-- configuration file for specifying SLURM batch queuing directives**lsf.tcl**-- configuration file for Platform-LSF batch queuing directives**ll.tcl**-- configuration file for Load-Leveler batch queuing directives**eos.tcl**-- configuration file related to equation-of-state utility (i.e. lattice parameter and bulk modulus search)

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

**pwi.tcl**-- configuration file related to pw.x input data (e.g. definition of all namelists variables for math-parsing)**cpi.tcl**-- configuration file related to cp.x input data**nebi.tcl**-- configuration file related to neb.x input data**ppi.tcl**-- configuration file related to pp.x input data**bi.tcl**-- configuration file related to bands.x input data**di.tcl**-- configuration file related to dos.x input data**pri.tcl**-- configuration file related to projwfc.x input data**mpdi.tcl**-- configuration file related to molecularpdos.x input data**phi.tcl**-- configuration file related to ph.x input data**dmi.tcl**-- configuration file related to dynmat.x input data**mdi.tcl**-- configuration file related to matdyn.x input data**q2ri.tcl**-- configuration file related to matdyn.x input data**davi.tcl**-- configuration file related to turbo_davidson.x input data**lani.tcl**-- configuration file related to turbo_lancsoz.x input data**eelsi.tcl**-- configuration file related to turbo_eelsx input data**speci.tcl**-- configuration file related to trubo_spectrum.x input data

When running calculations via batch queuing system one needs to
provide some batch queuing system specific instructions within the
shell script files, such as the name of the queue, number of
processors, and some other resources. Instead of putting this
instructions inside each shell script (or **PWTK** script, if one is
using **PWTK** instead), the specific queuing system instructions can be
stored in the corresponding **PWTK**'s configuration file
(e.q. **$HOME/.pwtk/slurm.tcl**, **$HOME/.pwtk/lsf.tcl**, or
**$HOME/.pwtk/ll.tcl**).

Once such configuration file is properly set, we need to tell to
**PWTK** that the script is to be submitted to the batch queuing
system. For example, for SLURM this can be achieved by encapsulating
the whole script with the **SLURM { ... }** command, i.e.:

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

Alternatively, a plain **PWTK** script can be imported with the
**import** command, i.e:

SLURM { import job.pwtk }

Note that **SLURM** command is fully configurable; its usage is the
following:

- Either:
`SLURM script`

- Or:
`SLURM profile script`

- Or:
`SLURM profile --option1=value1 --option2=value2 ... script`

where **script** stands for the plain **PWTK** script to be submitted
to SLURM and **profile** is the name of the profile as defined in
the user **$HOME/.pwtk/slurm.tcl** file and contains 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. Here is an example where two different SLURM profiles, named as
parallel and longpar are defined in user
configuration file **$HOME/.pwtk/slurm.tcl**:

# ------------------------------------------------------------------------ # # SLURM # # This is a configuration file for PWTK's SLURM utility # # ------------------------------------------------------------------------ set profile(parallel) { #!/bin/sh #SBATCH --nodes=1 #SBATCH --ntasks=64 #SBATCH --time=6:00:00 #SBATCH --partition=parallel } set profile(longpar) { #!/bin/sh #SBATCH --nodes=1 #SBATCH --ntasks=64 #SBATCH --time=24:00:00 #SBATCH --partition=longpar }

For example, the longpar profile can then be utilized in
**PWTK** script via:

SLURM longpar { import job.pwtk }

As specified above floating-point numbers can be specified as
mathematical expressions, for example:
**1/4*exp(2*log(0.23))**. Here is an example of how mathematical
expressions can be used in specifying the input data:

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 **$angs2bohr** in the example above. This a
predefined constant (a conversion factor from Å to Bohr units).

**IMPORTANT:** mathematical expression should be written ** without any whitespace** or else it should be double-quoted. For
example, the **1/4 * sqrt(2)** expression contains two whitespaces
and it will be treated as three separate input-fields and the parser
will return **.25000000000000000000 * 1.41421356237309504880**,
whereas **"1/4 * sqrt(2)"** is evaluated to
**.35355339059327376220**.

Here is a list of predefined constant that can be used in mathematical
expressions, and their values (corresponding to *CODATA Internationally
recommended 2018 values*):

- bohr2angs = 0.529177210903
- angs2bohr = 1.0/$bohr2angs
- ry2ev = 13.605693122994017
- ha2ev = 2.0*$ry2ev
- ev2ry = 1.0/$ry2ev
- ev2ha = 1.0/$ha2ev
- ry2kjm = 1312.7498197399127
- ha2kjm = 2.0*$ry2kjm
- kjm2ry = 1.0/$ry2kjm
- kjm2ha = 1.0/$ha2kjm

Here is a list of supported mathematical functions (actually these are functions supported by the Tcl):

**abs**(*number*) -- returns the absolute value of*number*.*number*may be either integer or floating-point, and the result is returned in the same form;**acos**(*number*) -- returns the arc cosine of*number*, in the range [0,] radians.*number*should be in the range [-1,1];**asin**(*number*) -- returns the arc sine of*number*, in the range [-/2,/2] radians.*number*should be in the range [-1,1];**atan**(*number*) -- returns the arc tangent of*number*, in the range [-/2,/2] radians;**atan2**(*x*,*y*) -- returns the arc tangent of*y/x*, in the range [-,] radians.*x*and*y*cannot both be 0;**ceil**(*number*) -- returns the smallest integer value not less than*number*;**cos**(*number*) -- returns the cosine of*number*, measured in radians;**cosh**(*number*) -- returns the hyperbolic cosine of*number*. If the result would cause an overflow, an error is returned;**double**(*number*) -- if*number*is a floating value, returns*number*, otherwise converts*number*to floating and returns the converted value;**exp**(*number*) -- returns the exponential of*number*. If the result would cause an overflow, an error is returned;**floor**(*number*) -- returns the largest integral value not greater than*number*;**fmod**(*x*,*y*) -- returns the floating-point remainder of the division of*x*by*y*. If*y*is 0, an error is returned;**hypot**(*x*,*y*) -- computes the length of the hypotenuse of a right-angled triangle (*x*x*+*y*y*);**int**(*number*) -- if*number*is an integer value, returns*number*, otherwise converts*number*to integer by truncation and returns the converted value;**log**(*number*) -- returns the natural logarithm of*number*.*number*must be a positive value;**log10**(*number*) -- returns the base 10 logarithm of*number*.*number*must be a positive value;**pow**(*x*,*y*) -- computes the value of*x*raised to the power*y*. If*x*is negative,*y*must be an integer value;**rand**() -- returns a floating point number from zero to just less than one or, in mathematical terms, the range [0,1). The seed comes from the internal clock of the machine or may be set manual with the srand function;**round**(*number*) -- if*number*is an integer value, returns*number*, otherwise converts*number*to integer by rounding and returns the converted value;**sin**(*number*) -- returns the sine of*number*, measured in radians;**sinh**(*number*) -- returns the hyperbolic sine of*number*. If the result would cause an overflow, an error is returned;**sqrt**(*number*) -- returns the square root of*number*.*number*must be non-negative;**srand**(*number*) -- the*number*, which must be an integer, is used to reset the seed for the random number generator. Returns the first random number from that seed. Each interpreter has it's own seed;**tan**(*number*) -- returns the tangent of*number*, measured in radians;**tanh**(*number*) -- returns the hyperbolic tangent of*number*.

This document was generated using the LaTeX2HTML translator Version 2019 (Released January 1, 2019)

The command line arguments were:

`latex2html -split 1 -t 'PWTK: A Short Tutorial' -no_navigation -toc_stars -show_section_numbers -link 4 -toc_depth 4 tutorial.tex`

The translation was initiated on 2021-05-18