Elf Labeler: Bond Order
The ElfLabeler class can be used to automatically identify various chemical features in a system. This can be useful for a variety of automation task. Here we demonstrate its use for locating the covalent bonds in the the CO2 molecule. We also demonstrate how to calculate the exact and formal bond-order of the bond.
VASP¶
-
Create the CO2 POSCAR file.
CO2 in 10x10x10 cubic box 1.0 10.000000 0.000000 0.000000 0.000000 10.000000 0.000000 0.000000 0.000000 10.000000 C O 1 2 Direct 0.500000 0.500000 0.500000 0.500000 0.500000 0.616000 0.500000 0.500000 0.384000 -
Create your INCAR file. Below is a minimal example that writes the required CHGCAR, AECCAR, and ELFCAR files. In general, the grid density should be at least 10 pts/Å along each lattice vector for well converged Bader analysis.
Global Parameters LAECHG = True # Write AECCAR files LELF = True # Write ELFCAR file EDIFF = 1E-06 # SCF energy convergence, in eV ENCUT = 520 Grid Size # Moderately grid density NGX = 100 NGY = 100 NGZ = 100 "Fine" Grid Size # Must Match Standard Grid NGXF = 100 NGYF = 100 NGZF = 100 -
Create your
POTCAR. We cannot provide an example for this as the files are proprietary. -
Run VASP. Depending on your system how you do this may vary. On our system we use the following command.
mpirun -np 12 vasp_std
BaderKit¶
-
If you would like to follow along, open your preferred IDE in an environment with BaderKit installed. Alternatively, the complete python script from this tutorial is available at the end of this page.
-
Import the ElfLabeler class
from baderkit import Grid from baderkit.elf_analysis import ElfLabeler -
We recommend using the reconstructed total charge density as a reference for Bader partitioning when possible. In VASP we can construct this from the AECCAR files.
core_grid = Grid.from_vasp("AECCAR0") val_grid = Grid.from_vasp("AECCAR2") total = core_grid.linear_add(val_grid) total.write_vasp("CHGCAR_sum") -
Now create the ElfLabeler class instance.
labeler = ElfLabeler.from_vasp( charge_grid="CHGCAR", reference_grid="ELFCAR", total_charge_grid="CHGCAR_sum", pseudopotential_filename="POTCAR" ) -
label the basins in the ELF and get the charge in each.
features = labeler.basin_types charges = labeler.elf_bader.basin_charges -
Get the index corresponding to the first covalent bond between C and O and print the bond-order to the console.
covalent_idx = features.index("covalent bond") print(f"Bond Order: {charges[covalent_idx]/2}")You should see logging information as BaderKit runs, then outputs similar to the following:
Bond Order: 1.13237058575Note that the BO is lower than the formal value of 2. This is because the CO bond is partially ionic in nature, with Oxygen taking the dominant share.
-
If you are using an environment manager, load your baderkit environment. For conda:
conda activate baderkit -
We recommend using the reconstructed total charge density as a reference for Bader partitioning when possible. In VASP we can construct this from the AECCAR files.
baderkit sum AECCAR0 AECCAR2 -
Run the labeler analysis.
baderkit label CHGCAR ELFCAR -tot CHGCAR_sumYou should see logging information printed to the console and once complete a
labeler.jsonfile will be written which summarizes the results of the calculation.
And that's it! Try playing around with what else the ElfLabeler class offers.
Download Resources¶
Tutorial Script: bond_order.py
VASP Inputs/Outputs: CO2.zip