Beginner’s Tutorial

Table of contents

Once PWTK is installed and configured (see Installation and Configuration Tutorial), we are ready to start using PWTK. It can be used interactively, but more often, it is used to execute scripts. Among the first things to learn is how to specify QE input data and how to run QE programs in PWTK scripts.

Specifying input data

There are two ways to specify input data for QE executables in PWTK scripts.

  1. Input data can be loaded into PWTK from existing QE input files using the load_from command. For example, an existing pw.x input file (say pw.Si.in) can be loaded as:

    load_from pw.x pw.Si.in

    Hence, the usage of the load_from command is:

    load_from program inputFile

    where program is the name of the QE executable (e.g. pw.x, ph.x, pp.x) and inputFile is the name of the input file.

    Alternatively, the pw.x input file can be loaded with the load_fromPWI command as:

    load_fromPWI pw.Si.in

    where PWI stands for PW.x Input. For other executables, analogous commands exist (e.g., load_fromPHI, load_fromPPI, load_fromNEBI). The load_fromXXI (XXI = PWI, PHI, PPI, NEBI…) commands exist for all explicitly supported QE programs in PWTK. Likewise, only the inputs for the explicitly supported QE programs can be loaded into PWTK with the load_from command. To get the list of explicitly supported programs, enter the PWTK interactive prompt (by typing pwtk in the terminal) and type report programs.

  2. The second way of specifying input data is by entering them directly. The syntax is analogous to that of QE with the difference that namelists and cards are encapsulated in curly braces (or double quotes), e.g.:

    pw.x input file

    PWTK script

    &CONTROL
       calculation = 'scf'
    /
    &SYSTEM
         ibrav = 2
             A = 5.4
           nat = 2
          ntyp = 1
       ecutwfc = 18.0
     /
    &ELECTRONS
       conv_thr = 1d-7
    /
    
    ATOMIC_SPECIES
       Si  1.00  Si.pz-vbc.UPF 
    
    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'
    }
    SYSTEM {
         ibrav = 2
             A = 5.4
           nat = 2
          ntyp = 1
       ecutwfc = 18.0
    }
    ELECTRONS {
       conv_thr = 1d-7
    }
    ATOMIC_SPECIES {
       Si  1.00  Si.pz-vbc.UPF 
    }
    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
    }   

    BEWARE: PWTK scripts are case-sensitive, implying that namelists, namelist variables, and cards are also case-sensitive. Namelists and cards usually have the same names as in QE but are written in uppercase. Among exceptions are the generic namelists used by several QE programs (e.g., INPUT and INPUTPP), which are renamed because PWTK requires unique names. To list all exceptions, enter the PWTK interactive prompt (by typing pwtk in the terminal) and type:

    report exceptions

    which lists all the namelist and card naming exceptions in PWTK, looking like:

     -------------------------------------------------------------------------------
      executable      type       QE-name                             PWTK-name        
     -------------------------------------------------------------------------------
      cp.x            supercard  AUTOPILOT/ENDRULES                  AUTOPILOT        
    
      cppp.x          namelist   INPUTPP                             CPPP             
    
      d3hess.x        namelist   INPUT                               D3HESS           
    
      dynmat.x        namelist   INPUT                               DYNMAT           
    
      ...             ...        ...                                 ...

For further info about input data specs in PWTK, see section 2.2 Specifying Input Data.

Modifying and deleting namelist variables

In PWTK, input data can be changed on the fly. For example, consider the following snippet:

SYSTEM {
   nspin = 2
   tot_magnetization = 1
}

SYSTEM {
   nspin = 1
   tot_magnetization = 0
}   

The current value of variables is now nspin = 1 and tot_magnetization = 0. But for nspin=1, we do not need to specify tot_magnetization. In PWTK, a defined namelist variable can be deleted as follows:

SYSTEM {
   tot_magnetization =
}

Inheritance of namelist variables

In PWTK, a few namelist variables are inherited from a “parent” namelist to “descendant” namelists. Examples of such variables are the prefix and outdir variables of the CONTROL namelist, INPUTPH’s fildyn, and flfrc of the q2r.x program. Hence, for example, if the prefix and outdir variables are set in the CONTROL namelist, their definition in the “descendant” namelists (INPUTPP, INPUTPH, PROJWFC…) can be omitted because PWTK automatically sets them. Here is an example:

CONTROL {
   prefix = 'example1'
   outdir = '.'
}

# 'outdir' and 'prefix' are inherited from the CONTROL namelist; 
# no need to set them here
PROJWFC {
   ngauss  = 0
   degauss = 0.01
   DeltaE  = 0.1
}

The ntyp-type namelist arrays: using atomic labels instead of indices

In PWTK, it is highly recommended to use atomic labels instead of numeric indices for the ntyp-type namelist arrays. For example:

  SYSTEM { 
     ntyp = 2
     starting_magnetization(Fe) = 0.8
  }
  ATOMIC_SPECIES {
     O  1.0 O.pbe-n-kjpaw_psl.1.0.0.UPF
     Fe 1.0 Fe.pbe-n-kjpaw_psl.1.0.0.UPF
  }

The qe2pwtk program

An easy way to learn how to specify input data in PWTK is by using its qe2pwtk program, which converts the QE input into the PWTK script. The usage is:

qe2pwtk ?-p program? inputFile

where the pair of question marks (?…?) indicates optional arguments, program is the name of QE executable and inputFile is the input file. For example, a neb.x input file (say, neb.H2+H.in) can be converted to PWTK syntax as:

qe2pwtk -p neb.x neb.H2+H.in

which gives:

PATH {
   CI_scheme     = 'auto'
   num_of_images = 7
   nstep_path    = 100
   string_method = 'neb'
}

CONTROL {
   prefix = 'H2+H'
}

SYSTEM {
   ecutwfc           = 20.0
   ibrav             = 0
   nat               = 3
   nspin             = 2
   ntyp              = 1
   tot_magnetization = 1.0
}

ELECTRONS {
   conv_thr    = 1.e-8
}

ATOMIC_SPECIES {
    H  1.00794  H.pbe-rrkjus.UPF
}

CELL_PARAMETERS bohr {
    12.000000000000000    0.000000000000000    0.000000000000000
     0.000000000000000    5.000000000000000    0.000000000000000
     0.000000000000000    0.000000000000000    5.000000000000000
}

K_POINTS gamma

POSITIONS {
FIRST_IMAGE
ATOMIC_POSITIONS bohr
  H       -5.274278671000   0.000000000000   0.000000000000   1  0  0
  H        0.000000000000   0.000000000000   0.000000000000   0  0  0
  H        1.490737029000   0.000000000000   0.000000000000   1  0  0
LAST_IMAGE
ATOMIC_POSITIONS bohr
  H       -1.490737127000   0.000000000000   0.000000000000
  H        0.000000000000   0.000000000000   0.000000000000
  H        5.274284748000   0.000000000000   0.000000000000
}

Note that for neb.x, the PWTK syntax is slightly simpler than the QE syntax because it omits the BEGIN- and END-type keywords.

Running QE executables

There are two ways how to run QE executables in PWTK.

  1. They can be run by using the existing QE input files with the run command, i.e.:

    run pw.x pw.Si.in

    which is equivalent to the following shell command:

    $PREFIX pw.x $POSTFIX < pw.Si.in > pw.Si.out

    where pw.Si.in is an existing pw.x input file and the value of PREFIX and POSTFIX is, e.g., mpirun -np 4 and -npool 2, respectively. The run command is similar to the Tcl exec command but takes into account the PWTK specs, such as bin_dir, prefix, postfix

  2. The second way to run QE executables is by loading the input data into PWTK and then using the runXX command. The advantage of loading the input data into PWTK is that one can change them on the fly. For example:

    load_from pw.x pw.Si.in
    SYSTEM { ecutwfc = 25.0 } 
    runXX pw.x pw.Si-e25.in 

    Alternatively, the pw.x program can be run with the runPW command as: runPW pw.Si-e25.in Analogous commands exist for other QE programs (e.g., runPH, runPP, runNEB).

    BEWARE: load_from and runXX commands are available only for the explicitly supported QE programs in PWTK. To list them, enter the PWTK interactive prompt (by typing pwtk in the terminal) and type:

    report programs

    which gives:

     -------------------------------------------------------------------------------
      executable             runCmd                rerunCmd      input namespace     
     -------------------------------------------------------------------------------
      all_currents.x         runALL_CURRENTS                     ::pwtk::all_curri   
      band_interpolation.x   runBAND_INTERPOLATION               ::pwtk::band_inti   
      bands.x                runBANDS                            ::pwtk::bi          
      bgw2pw.x               runBGW2PW                           ::pwtk::bgw2pwi     
      cp.x                   runCP                 rerunCP       ::pwtk::cpi         
      cppp.x                 runCPPP                             ::pwtk::cpppi       
      d3hess.x               runD3HESS                           ::pwtk::d3hessi     
      dos.x                  runDOS                              ::pwtk::di          
      dynmat.x               runDYNMAT                           ::pwtk::dmi         
      hp.x                   runHP                               ::pwtk::hpi         
      kcw.x                  runKCW                              ::pwtk::kcwi        
      ld1.x                  runLD1                              ::pwtk::ld1i        
      matdyn.x               runMATDYN                           ::pwtk::mdi         
      molecularpdos.x        runMOPDOS                           ::pwtk::mpdi        
      neb.x                  runNEB                rerunNEB      ::pwtk::nebi        
      oscdft_et.x            runOSCDFT_ET                        ::pwtk::oscdft_eti  
      oscdft_pp.x            runOSCDFT_PP                        ::pwtk::oscdft_ppi  
      ph.x                   runPH                 rerunPH       ::pwtk::phi         
      postahc.x              runPOSTAHC                          ::pwtk::postahci    
      pp.x                   runPP                               ::pwtk::ppi         
      ppacf.x                runPPACF                            ::pwtk::ppacfi      
      pprism.x               runPPRISM                           ::pwtk::pprismi     
      projwfc.x              runPROJWFC                          ::pwtk::pri         
      pw.x                   runPW                 rerunPW       ::pwtk::pwi         
      pw2bgw.x               runPW2BGW                           ::pwtk::pw2bgwi     
      pw2gw.x                runPW2GW                            ::pwtk::pw2gwi      
      pw2wannier90.x         runPW2WANNIER90                     ::pwtk::pw2wan90i   
      pwcond.x               runPWCOND             rerunPWCOND   ::pwtk::pwcondi     
      q2r.x                  runQ2R                              ::pwtk::q2ri        
      turbo_davidson.x       runDAVIDSON           rerunDAVIDSON ::pwtk::davi        
      turbo_eels.x           runEELS               rerunEELS     ::pwtk::eelsi       
      turbo_lanczos.x        runLANCZOS            rerunLANCZOS  ::pwtk::lani        
      turbo_magnon.x         runMAGNON             rerunMAGNON   ::pwtk::magi        
      turbo_spectrum.x       runSPECTRUM                         ::pwtk::speci
     -------------------------------------------------------------------------------

Simple script: a parameter scan

As seen above, loading input data into PWTK allows for changing them on the fly, which is a handy feature that, among others, makes parameter-scan calculations relatively easy to script. For example, the following script loads the pw.Si.in input files and makes a series of pw.x calculations where the value of the ecutwfc variable (i.e., kinetic energy wavefunction cutoff) is scanned:

load_fromPWI pw.Si.in

scanpar ecut [seq 12 4 40] {
    SYSTEM " ecutwfc = $ecut "
    write ecutwfc.dat [pwo_totene [runPW pw.Si-e$ecut.in]]
}

plot -xr 10:40 -yf %.3f -xl "ecutwfc (Ry)" -yl "Total energy (Ry)" ecutwfc.dat

In this script, the following new PWTK commands are used:

In addition to performing the scan, this script extracts the total energy from the pw.x output file and writes it to the ecutwfc.dat file, which is plotted at the end with the plot command. Let us save the above script into the ecut.pwtk file and run it from the terminal as:

pwtk ecut.pwtk

After the calculations are completed, we obtain the following plot:

Total energy vs. ecutwfc plot

Input-data stacking

Say we want to perform several calculations, each requiring specific input-data modification. It would be convenient if such modifications are local so that input-data modification for the preceding calculation does not affect the input data for subsequent calculations. This feature is implemented in PWTK with a stack. The concept is graphically presented here, with push and pop being the basic stack operations:

Note that the number of push/pop operations is not limited, e.g.:

In PWTK, the input-data stacking mechanism is implemented with the input_pushpop command (a combination of push and pop); the input_pushpop commands can be nested. Here is a simple scripting example (read the comments):

   load_fromPWI pw.Si.in
   
   
   # the value of 'ecutwfc' in 'pw.Si.in' is 18.0 Ry;
   # let's perform the calculation at higher 'ecutwfc'
   
   input_pushpop {
      SYSTEM { ecutrho = 30.0 }
      # now the value of ecutrho = 30.0 Ry
      runPW pw.Si-e30.0.in
   }

   # here, the value of ecutrho = 18.0 Ry again
   
   # K_POINTS specs in 'pw.Si.in' are 4x4x4;
   # let's perform the calculation with a denser K-grid
   input_pushpop {
      K_POINTS (automatic) {
         8 8 8   1 1 1
      }
      runPW pw.Si-k8x8x8.in
   }
   
   # here K_POINTS specs are 4x4x4 again 

Explanation of the “scanpar” command

To further illustrate the input-data stacking mechanism, let us explain the scanpar command used above. It is similar to a one-parameter Tcl foreach loop but, in addition, uses the input-data stacking mechanism and, in combination with the write command, keeps track of the scanned parameter. Here is a comparison between equivalent script snippets using the scanpar and foreach commands:

using scanpar using foreach
scanpar ecut [seq 12 4 40] {
   SYSTEM " ecutwfc = $ecut "
   write ecut.dat \
      [pwo_totene [runPW pw.Si-e$ecut.in]]
}

# the above modifications of 'ecutwfc' 
# have no effect here
input_pushpop {
   foreach ecut [seq 12 4 40] {
      SYSTEM " ecutwfc = $ecut "
      write ecut.dat \
        "$ecut  [pwo_totene [runPW pw.Si-e$ecut.in]]"
   }
}
# the above modifications of 'ecutwfc'
# have no effect here

The scanpar command internally uses input_pushpop, implying that all input data modifications performed inside the scanpar loop are removed after the loop finishes. Note also that within the scanpar loop, the $ecut variable is not specified on the write command line because write knows which parameters are being scanned and adds them automatically.

Project-based configuration: the “import” command

With the import command, it is possible to include a PWTK script into another script. This command can be exploited for a kind of project-based configuration, which helps systematize its calculations. The idea is to create a project common file (let us name it common.pwtk), where default input data for the project are stored, and then project scripts import it.

Say that we want to study the adsorption of small organic molecules (containing H, C, N, and O atoms) on low Miller index Rh surfaces. After performing the basic convergence tests calculations (to determine the energy cutoff, lattice parameter, k-point sampling…), we can create the project common.pwtk, which could look something like this:

# default pw.x input data
CONTROL {
   calculation = 'relax'
   nstep       = 400
}
SYSTEM {
   ibrav       = 0   
   ecutwfc     = 50.
   ecutrho     = 400.   
   occupations = 'smearing' 
   degauss     = 0.02 
   smearing    = 'm-v'
}
ELECTRONS {
   conv_thr    = 1d-8
   mixing_beta = 0.3
}
IONS {
   upscale = 100.
}
ATOMIC_SPECIES {
   H  1.0079   H.pbe-rrkjus_psl.1.0.0.UPF
   C  12.011   C.pbe-n-rrkjus_psl.1.0.0.UPF
   N  14.0067  N.pbe-n-rrkjus_psl.1.0.0.UPF
   O  15.9994  O.pbe-n-rrkjus_psl.1.0.0.UPF
   Rh 102.906  Rh.pbe-spn-rrkjus_psl.1.0.0.UPF
}
# default k-points for Rh(111)-2x2 & Rh(100)-2x2
K_POINTS (automatic) {
   6 6 1   1 1 1
}

# default ph.x input data
INPUTPH {
   tr2_ph       = 1e-16
   trans        = .true.
   nogg         = .true.
   alpha_mix(1) = 0.3
} {
   0.0  0.0  0.0
}

# default projwfc.x input data
PROJWFC {
   ngauss  = 0
   degauss = 0.01
   DeltaE  = 0.1
}

REMARK: Note that all the pseudopotentials used in the project are listed in the ATOMIC_SPECIES card, and the SYSTEM’s ntyp variable is not assigned. For specific cases, PWTK uses only pseudopotentials for atomic types present in the ATOMIC_POSITIONS card and sets the ntyp variable accordingly. It is for this reason, that the use of atomic labels instead of numeric indices is highly recommended in the ntyp-type namelist arrays.

Then, we can include this common.pwtk file from specific scripts. For example, let us perform some calculations in the Rh100-2x2-4L/ subdirectory. In particular, we scan the lateral position of CH3 over Rh(100)-2x2-4L slab (4L = four-layer). The script could look something like this:

# we are currently in the './Rh100-2x2-4L/' subdirectory;
# the project 'common.pwtk' file is the '../' directory 

import ../common.pwtk

# load the CH3 @ Rh(100)-2x2-4L structure (4L = 4-layers);
# the below command also assigns the 'nat' and 'ntyp' variables

CELL_PARAMETERS_and_ATOMIC_POSITIONS_fromXSF CH3-Rh100-2x2-4L.xsf

# fix the bottom-layer Rh atoms (i.e., atoms from 1 to 4)

fixAtoms 1-4 

# fix the C atom (atom 17) laterally

fixAtoms 17 "0 0 1"

# the Rh-Rh distance is 2.687 Å

set dRhRh 2.687

# scan the CH3 laterally

scanpar dx [seq 0 0.2 1] {
    scanpar dy [seq 0 0.2 1] {
        set name CH3-$dx,$dy@Rh100-2x2-4L
        outdir_postfix $name       
        CONTROL " prefix = '$name' "
       
        # convert dx,dy to Å
        set dxA [expr $dx*$dRhRh]
        set dyA [expr $dy*$dRhRh]
            
        input_pushpop {
            # CH3 atoms are atoms from 17 to 20
            displaceAtoms "$dxA $dyA 0.0" 17-20
            
            set E [pwo_totene [runPW relax.$name]]
            write CH3.dat $E
        }
        write CH3.dat ""
    }
}

# plot the result into the PNG image as a 3D surface plot
splot -pal rainbow -t png  \
    -xl "Δx/d_{RhRh}"  -yl "Δy/d_{RhRh}"  -zl "ΔE (eV)" \
    -xf %.1f  -yf %.1f  -zf %.2f  -cbf %.2f \
    -u 1:2:(\$3+$E)*$ry2ev  CH3.dat

In this script, we used the following new PWTK commands:

After the script finishes the calculations, splot creates the following splot-CH3.png image:

Further reading: online PWTK examples

To learn more about PWTK scripting, please check its collection of the online hyperlinked examples, which are documented with explanatory comments.

For further info, see also section 2. User Interface, which explains various aspects of PWTK. It is also worth checking the built-in workflows.