Skip to content

Dealing with slabs for first principles calculations of surfaces


Notifications You must be signed in to change notification settings


Repository files navigation

Build status Documentation Status DOI

surfaxe logo header

Calculating the surface properties of crystals from first principles typically introduces several extra parameters including slab thickness, vacuum size, Miller index, surface termination and more. These factors all influence key properties of interest, making it a challenge to carry out simulations repeatably and draw reliable conclusions. Surfaxe is a Python package for automating and simplifying density functional theory (DFT) calculations of surface properties, as well as providing analytical tools for bulk and surface calculations.

The code is organised according to the best-practice workflow below:


The main features include:

  1. Slab generation: Automated generation of surface slabs from command line.
  • All unique zero-dipole symmetric terminations of slabs are cleaved from a bulk structure.
  • Slabs can be organised into separate folders, optionally with all the required input files to run each calculation.
  1. Raw data processing: Extracting data from convergence tests.
  • Parsing the convergence testing folders created using the slab generation scripts.
  • Producing dataframes and csv files of summary data.
  • Plotting scripts visualising convergence with respect to slab and vacuum thickness.
  1. Analysis: Various scripts for surface and bulk calculations.
  • Calculation of planar and macroscopic average of the electrostatic potential through the slab to determine absolute electron energies (ionisation potential, electron affinity).
  • Nearest neighbour atom determination and bond distance analysis (useful for geometry relaxation convergence checks).

Surfaxe primarily supports the VASP DFT code, however most of the generation module is code-agnostic. In the future we would like to add support for more periodic codes in the other modules.

Example outputs

Analysis of average bond lengths as a function of slab thickness Bond analysis example

Surface energy convergence checks with respect to vacuum and slab thickness Surface energy convergence example

See the tutorials directory for more examples.


Surfaxe is a Python 3 package and requires pymatgen and other standard scientific Python packages.

Recommended installation is to git clone and install with pip in a stable virtual environment:

git clone
cd surfaxe
pip install -e .

The -e option creates links to the source folder so any changes to the code are reflected on the path.

For the code to generate VASP input files along with the surface slabs, POTCARs need to be set up with pymatgen.


Quick start

Surfaxe can be used via the command line and via Python API. The docs include information on both, and the built-in -h option is available in the command line interface for each of the scripts.

We recommend starting off by looking at the dedicated tutorials. These Jupyter notebooks will guide you through most of the functionality of the package.

The tutorials can also be run interactively on Binder: Binder

Command line interface

The scripts can be separated into four modules that follow a typical surfaces workflow; these are generation, convergence, analysis and data, with added plotting functionality. The vast majority of surfaxe functionality is available via the command line interface, but the python API allows for more flexibility.


  • surfaxe-generate: Generates all unique symmetric zero-dipole surface slabs for one or more specified Miller indices or up to a maximum Miller index specified, in any format supported by pymatgen. Optionally provides all VASP input files.


  • surfaxe-parse-energies: Extracts the relevant data from the convergence folders set up with surfaxe-generate where calculations were run with VASP. Plots convergence graphs of the variation of surface energy with respect to slab and vacuum thickness. Can optionally parse core atom and vacuum energies as well.
  • surfaxe-parse-structures: Collects the structures' metadata into a json file and optionally performs bond analysis as in surfaxe-bonds.


  • surfaxe-bonds: Parses the structure, looking for bonds between specified atoms.
  • surfaxe-simplenn: Predicts the coordination environment of atoms for simple structures.
  • surfaxe-complexnn: Predcts the coordination environment of atoms in more complex structures where the default prediction algorithm fails.
  • surfaxe-potential: Calculates the planar potential of the slab along c-axis, the gradient of the planar potential and optionally macroscopic potential.
  • surfaxe-surface-dipole: Returns the surface dipole needed for macroscopic ionisation potential calculation
  • surfaxe-cartdisp: Calculates the Cartesian displacements of atoms during relaxation from intial and final structures.


  • surfaxe-plot-surfen and surfaxe-plot-enatom: Plot the surface energy and energy per atom based on data from surfaxe-parsefols with individual customisability
  • surfaxe-plot-bonds: Plots the bond distance with respect to fractional coordinate, based on surfaxe-bonds
  • surfaxe-plot-potential: Plots the planar (and macroscopic) potential based on data already analysed with surfaxe-potential


  • surfaxe-core: Collects the core energy level from the middle of a surface slab, based on supplied bulk core atom and the list of its nearest neighbours.
  • surfaxe-vacuum: Collects the vacuum potential level from a VASP LOCPOT file.

Pymatgen issues warnings whenever the hash in a VASP POTCAR present does not match the one in their library. Only one warning of the same type will be issued by default. All warnings can be suppressed completely by adding the following to your script:

import warnings

Development notes

Bugs, features and questions

Please use the Issue Tracker to report bugs or request features in the first instance.

Contributions to interface with this package are most welcome. Please use the "Fork and Pull" workflow to make contributions and stick as closely as possible to the following:

  • Code style should comply with PEP8 where possible. Google's house style is also helpful, including a good model for docstrings.
  • Please use comments liberally!
  • Add tests wherever possible, and use the test suite to check if everything still works.


Unit tests are in the tests directory and can be run from the top directory using pytest. Please run these tests whenever submitting bug fix pull requests and include new tests for new features as appropriate.

We also use CI build and testing using GitHub Actions.

License and how to cite

Surfaxe is free to use under the MIT License. If you use it in your research, please cite

K. Brlec, D. W. Davies and D. O. Scanlon, Surfaxe: Systematic surface calculations. Journal of Open Source Software, 6(61), 3171, (2021) DOI: 10.21105/joss.03171


Surfaxe relies primarily on Pymatgen for manipulating crystal structures and interfacing with the DFT codes.

Detailed requirements

Surfaxe is compatible with python 3.7+ and requires the following packages:


List of contributors:

  • Katarina Brlec (@brlec)
  • Daniel Davies (@dandavies99)
  • David Scanlon (@scanlond)


  • Surfaxe has benefited from useful discussions with Adam Jackson (@ajjackson), Seán Kavanagh (@kavanase), Graeme Watson (@wantsong), Luisa Herring-Rodriguez (@zccalgh), Christopher Savory (@cnsavory), Bonan Zhu (@zhubonan) and Maud Einhorn (@maudeinhorn).
  • Thanks to Keith Butler (@keeeto) for providing a starting point and validation examples for calculating the planar average electrostatic potential via the macrodensity package.
  • We thank @eihernan, @pzarabadip and @danielskatz for taking the time to review the code and offering valuable suggestions for improvements.