Home / Tutorials

Tutorials

Three ways to use QEpy: as a drop-in QE executable, from Python scripts with MPI control, or interactively in Jupyter notebooks.

QEpy SCF density update animation
Iterative SCF: QEpy updates the electron density step by step from Python.

Run QEpy as QE (command line)

QEpy can replace standard QE executables. List supported packages:

python -m qepy -h

Options ending in .x mirror QE executables; options ending in .py are QEpy-specific tools.

Serial pw.x equivalent
python -m qepy --pw.x -i qe.in
MPI parallel (OpenMPI / Intel MPI)
mpirun -n 4 python -m qepy --pw.x -i qe.in

QEpy-specific example: analyze and convert pw.x output:

python -m qepy --pw2pp.py -h

HPC clusters (SLURM): on some systems (e.g. Rutgers Amarel) plain mpirun may fail. Use the site-recommended MPI launcher: often srun --mpi=pmi2 -n N python -m qepy .... Check your cluster documentation.

Use QEpy in Python code

The Driver class is the main entry point. Import qepy before mpi4py to avoid FFT allocation errors (see FAQ).

Serial execution

Pass comm=None (default) for a single-process run:

import qepy
from qepy import Driver

driver = Driver('si.scf.in', comm=None)
driver.scf()
energy = driver.get_energy()
driver.stop()

Parallel execution with mpi4py

Pass an MPI communicator so Python and Fortran share the same process layout. Only rank 0 (driver.is_root) should print or write files unless you gather data explicitly.

import qepy
from mpi4py import MPI
from qepy import Driver

comm = MPI.COMM_WORLD
driver = Driver('si.scf.in', comm=comm)

if driver.is_root:
    print(f"Running on {driver.nproc} MPI ranks")

driver.scf()
if driver.is_root:
    print("Total energy:", driver.get_energy())
driver.stop()

Launch with your MPI runner, e.g.:

# OpenMPI / Intel MPI
mpirun -n 4 python my_script.py

# SLURM (example)
srun --mpi=pmi2 -n 4 python my_script.py

Iterative SCF (step-by-step control)

Set iterative=True to run one SCF iteration at a time: useful for custom mixing, external potentials, or coupling to other models.

driver = Driver('si.scf.in', iterative=True, comm=comm)

while not driver.check_convergence():
    driver.diagonalize()
    driver.mix()
    rho = driver.get_density()
    # inspect or modify rho, set external potentials, etc.

driver.end_scf()
driver.stop()

External potentials & custom XC

# Add an external potential on the real-space grid (Ry units)
v_ext = driver.create_array(kind='rho')
# ... fill v_ext ...
driver.set_external_potential(v_ext)

# Swap XC functional (requires DFTpy integration)
driver.update_exchange_correlation(xc='PBE')

ASE calculator

from ase.build import bulk
from qepy.calculator import QEpyCalculator

atoms = bulk('Si')
calc = QEpyCalculator(inputfile='si.scf.in', comm=comm)
atoms.calc = calc
energy = atoms.get_potential_energy()

Note: ASE uses Å and eV; the Driver uses Bohr and Rydberg. The calculator handles unit conversion.

Jupyter notebooks

Interactive examples live in the QEpy repository under examples/jupyter/. Clone the repo and open them locally, or try the Google Colab notebooks. Notebooks marked with 👉 in the Beginners column are good starting points.

Beginners Notebook Description
👉 scf/qepy_scf Basic SCF with the Driver.
scf/qepy_scf_iterative Iterative SCF loop.
scf/qepy_iterative Advanced iterative workflows.
scf/qepy_qeinput Build QE input with QEInput.
scf/dftpy_mixer Custom density mixing with DFTpy.
👉 pseudos/kspp_pseudo_setup Automatic pseudopotentials with KSPP (ksppresolver=True).
👉 band/dos_band_silicon Band structure and DOS for silicon.
👉 band/dos_band_graphene Band structure and DOS for graphene.
👉 eos/test_eos_vc Equation of state.
👉 eos/test_eos_slow Detailed EOS workflow.
pp/qepy_potentials Extract potentials from a calculation.
pp/qepy_parse_output Parse QE output files.
pp/qepy_elf_rdg ELF and reduced density gradient.
ext/dirac_exchange Custom Dirac exchange functional.
ext/dftpy_xc User-defined XC with DFTpy.
👉 nvt/ase_nvt NVT MD with ASE.
colab/qepy_scf QEpy in Google Colab.
colab/qepy_colab Colab setup overview.
👉 testing/test_kpoints K-point convergence.
👉 testing/test_ecutwfc Cutoff convergence.
👉 testing/test_degauss Smearing convergence.

Running notebooks with MPI: start Jupyter under an MPI allocation (e.g. srun --mpi=pmi2 -n 4 jupyter notebook) and pass comm=MPI.COMM_WORLD to Driver. For serial exploration, omit comm or use the Colab notebooks.

Video tutorials

QEpy YouTube playlist ↗

These videos span 2021–2025. The current QEpy release (QE 7.2, dev branch) may differ slightly in installation steps, API details, or recommended workflows from what is shown in the older recordings. Use the written tutorials and install guide for up-to-date instructions.

Intro to QEpy June 13, 2021
QEpy for beginners October 10, 2022
Installation of QEpy October 10, 2022
QEpy with ASE October 10, 2022
QEpy on Google Colaboratory October 10, 2022
QEpy on Jupyter Notebooks October 10, 2022
Aniket Mandal, QEpy: Quantum ESPRESSO in Python September 7, 2025

For the full Python API, see The code.