Band structure and density of states#

In this example we will perform band structure and DOS calculation for silicon using VASP. We will use the VaspBandWorkChain from the aiida-vasp plugin.

It is recommended to go through the single point calculation tutorial first before proceeding with this example.

Setting up the environment#

The code block below configures the environment for this example. Please see the single point example for more details.

from aiida_vasp.utils.temp_profile import *
from subprocess import check_output
print(load_temp_profile())


# Uncomment the below line to create a localhost Computer if you have not done so
comp = orm.Computer('localhost', 'localhost', transport_type='core.local', scheduler_type='core.direct')
comp.store()


# Some configuration may be needed for first-time user
import os
from pathlib import Path
comp.set_workdir('/tmp/aiida_run/')
comp.configure()
vasp_path = check_output(['which', 'mock-vasp'], universal_newlines=True).strip()

vasp_code = orm.InstalledCode(comp, vasp_path, default_calc_job_plugin='vasp.vasp')
vasp_code.label ='mock-vasp'
vasp_code.store()
os.environ['MOCK_VASP_REG_BASE'] = str((Path() / 'mock_registry').absolute())
os.environ['MOCK_VASP_UPLOAD_PREFIX'] = 'band'

# Upload the POTCAR files
from aiida_vasp.data.potcar import PotcarData, PotcarFileData
from pathlib import Path

print(PotcarData.upload_potcar_family(str(Path('potcars').absolute()), "PBE.EXAMPLE", "PBE.EXAMPLE"))

# Setting up the silicon structure
from ase.build import bulk
si = bulk('Si', 'diamond', 5.4)
si_node = orm.StructureData(ase=si)
Profile<uuid='a02330cdecdd4d4bb3a431878a0c6826' name='myprofile'>
(1, 1, 1)

Setting up the band structure and DOS calculation#

Similar to the single point calculation tutorial, we will use a BuilderUpdater to setup the inputs for the VaspBandsWorkChain:

from aiida_vasp.workchains.v2.bands import BandOptions
from aiida_vasp.workchains.v2 import VaspBandUpdater

upd = VaspBandUpdater().apply_preset(si_node, code='mock-vasp@localhost')
upd.builder.scf.potential_family = 'PBE.EXAMPLE'

The workchain can be modified with several options. These options are stored in the the band_settings input node which of the type orm.Dict. The available options can be printed using the aiida_description() method.

opt = BandOptions()
print(opt.aiida_description())
                              symprec:  float      
                                        Default: Precision of the symmetry determination
                            band_mode:  str        
                                        Default: Mode for generating the band path. Choose from: bradcrack, pymatgen,seekpath-aiida and latimer-munro.
                band_kpoints_distance:  float      
                                        Default: Spacing for band distances for automatic kpoints generation, used by seekpath-aiida mode.
                         line_density:  float      
                                        Default: Density of the point along the path, used by the sumo interface.
                 dos_kpoints_distance:  float      
                                        Default: Kpoints for running DOS calculations in A^-1 * 2pi. Will perform non-SCF DOS calculation is supplied.
                             only_dos:  bool       
                                        Default: Flag for running only DOS calculations
                              run_dos:  bool       
                                        Default: Flag for running DOS calculations
  additional_band_analysis_parameters:  dict       
                                        Default: Additional keyword arguments for the seekpath/ interface, available keys are:  ['with_time_reversal', 'reference_distance', 'recipe', 'threshold', 'symprec', 'angle_tolerance']
                    kpoints_per_split:  int        
                                        Default: Number of kpoints per split for the band structure calculation
                 hybrid_reuse_wavecar:  bool       
                                        Default: Whether to reuse the WAVECAR from the previous relax/singlepoint calculation

Hint

This can also be done for other Option classes such as relax_settings for the VaspRelaxWorkChain which uses the RelaxOptions class.

Run and inspect the results#

We can now run the workchain and get the returned WorkChainNode object.

band_out = upd.run_get_node().node
/home/docs/checkouts/readthedocs.org/user_builds/aiida-vasp-plugin/envs/v4.1.0/lib/python3.11/site-packages/seekpath/hpkot/__init__.py:172: DeprecationWarning: dict interface is deprecated. Use attribute interface instead
  conv_lattice = dataset["std_lattice"]
09/13/2025 06:23:18 AM <663> aiida.orm.nodes.process.workflow.workchain.WorkChainNode: [REPORT] [17|VaspBandsWorkChain|run_scf]: Correction: setting LCHARG to True
09/13/2025 06:23:18 AM <663> aiida.orm.nodes.process.workflow.workchain.WorkChainNode: [REPORT] [17|VaspBandsWorkChain|run_scf]: Running SCF calculation uuid: 17e9da40-1f4d-46cc-8088-1ecc1249c921 (pk: 26) (aiida.workflows:vasp.v2.vasp)
09/13/2025 06:23:19 AM <663> aiida.orm.nodes.process.workflow.workchain.WorkChainNode: [REPORT] [26|VaspWorkChain|run_process]: launching VaspCalculation<29> iteration #1
09/13/2025 06:23:21 AM <663> aiida.orm.nodes.process.workflow.workchain.WorkChainNode: [REPORT] [26|VaspWorkChain|results]: work chain completed after 1 iterations
09/13/2025 06:23:21 AM <663> aiida.orm.nodes.process.workflow.workchain.WorkChainNode: [ERROR] Failed to delete checkpoint: attributes of a sealed node are immutable
Traceback (most recent call last):
  File "/home/docs/checkouts/readthedocs.org/user_builds/aiida-vasp-plugin/envs/v4.1.0/lib/python3.11/site-packages/plumpy/base/state_machine.py", line 351, in transition_to
    call_with_super_check(self.on_terminated)
  File "/home/docs/checkouts/readthedocs.org/user_builds/aiida-vasp-plugin/envs/v4.1.0/lib/python3.11/site-packages/plumpy/base/utils.py", line 31, in call_with_super_check
    wrapped(*args, **kwargs)
  File "/home/docs/checkouts/readthedocs.org/user_builds/aiida-vasp-plugin/envs/v4.1.0/lib/python3.11/site-packages/aiida_vasp/workchains/v2/vasp.py", line 660, in on_terminated
    out_remote_pk = self.outputs.remote_folder.pk
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^
AttributeError: 'dict' object has no attribute 'remote_folder'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/docs/checkouts/readthedocs.org/user_builds/aiida-vasp-plugin/envs/v4.1.0/lib/python3.11/site-packages/aiida/engine/processes/process.py", line 502, in on_terminated
    self.runner.persister.delete_checkpoint(self.pid)
  File "/home/docs/checkouts/readthedocs.org/user_builds/aiida-vasp-plugin/envs/v4.1.0/lib/python3.11/site-packages/aiida/engine/persistence.py", line 150, in delete_checkpoint
    calc.delete_checkpoint()
  File "/home/docs/checkouts/readthedocs.org/user_builds/aiida-vasp-plugin/envs/v4.1.0/lib/python3.11/site-packages/aiida/orm/nodes/process/process.py", line 543, in delete_checkpoint
    self.base.attributes.delete(self.CHECKPOINT_KEY)
  File "/home/docs/checkouts/readthedocs.org/user_builds/aiida-vasp-plugin/envs/v4.1.0/lib/python3.11/site-packages/aiida/orm/nodes/attributes.py", line 152, in delete
    self._node._check_mutability_attributes([key])
  File "/home/docs/checkouts/readthedocs.org/user_builds/aiida-vasp-plugin/envs/v4.1.0/lib/python3.11/site-packages/aiida/orm/utils/mixins.py", line 218, in _check_mutability_attributes
    raise exceptions.ModificationNotAllowed('attributes of a sealed node are immutable')
aiida.common.exceptions.ModificationNotAllowed: attributes of a sealed node are immutable
Task exception was never retrieved
future: <Task finished name='Task-3' coro=<Process.step_until_terminated() done, defined at /home/docs/checkouts/readthedocs.org/user_builds/aiida-vasp-plugin/envs/v4.1.0/lib/python3.11/site-packages/plumpy/processes.py:1363> exception=AttributeError("'dict' object has no attribute 'remote_folder'")>
Traceback (most recent call last):
  File "/home/docs/checkouts/readthedocs.org/user_builds/aiida-vasp-plugin/envs/v4.1.0/lib/python3.11/site-packages/plumpy/base/state_machine.py", line 351, in transition_to
    call_with_super_check(self.on_terminated)
  File "/home/docs/checkouts/readthedocs.org/user_builds/aiida-vasp-plugin/envs/v4.1.0/lib/python3.11/site-packages/plumpy/base/utils.py", line 31, in call_with_super_check
    wrapped(*args, **kwargs)
  File "/home/docs/checkouts/readthedocs.org/user_builds/aiida-vasp-plugin/envs/v4.1.0/lib/python3.11/site-packages/aiida_vasp/workchains/v2/vasp.py", line 660, in on_terminated
    out_remote_pk = self.outputs.remote_folder.pk
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^
AttributeError: 'dict' object has no attribute 'remote_folder'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/docs/.asdf/installs/python/3.11.12/lib/python3.11/asyncio/tasks.py", line 277, in __step
    result = coro.send(None)
             ^^^^^^^^^^^^^^^
  File "/home/docs/checkouts/readthedocs.org/user_builds/aiida-vasp-plugin/envs/v4.1.0/lib/python3.11/site-packages/plumpy/processes.py", line 1371, in step_until_terminated
    await self.step()
  File "/home/docs/checkouts/readthedocs.org/user_builds/aiida-vasp-plugin/envs/v4.1.0/lib/python3.11/site-packages/plumpy/processes.py", line 1357, in step
    self.transition_to(next_state)
  File "/home/docs/checkouts/readthedocs.org/user_builds/aiida-vasp-plugin/envs/v4.1.0/lib/python3.11/site-packages/plumpy/base/state_machine.py", line 357, in transition_to
    self.transition_failed(initial_state_label, label, *sys.exc_info()[1:])
  File "/home/docs/checkouts/readthedocs.org/user_builds/aiida-vasp-plugin/envs/v4.1.0/lib/python3.11/site-packages/plumpy/processes.py", line 1100, in transition_failed
    self.transition_to(new_state)
  File "/home/docs/checkouts/readthedocs.org/user_builds/aiida-vasp-plugin/envs/v4.1.0/lib/python3.11/site-packages/plumpy/base/state_machine.py", line 351, in transition_to
    call_with_super_check(self.on_terminated)
  File "/home/docs/checkouts/readthedocs.org/user_builds/aiida-vasp-plugin/envs/v4.1.0/lib/python3.11/site-packages/plumpy/base/utils.py", line 31, in call_with_super_check
    wrapped(*args, **kwargs)
  File "/home/docs/checkouts/readthedocs.org/user_builds/aiida-vasp-plugin/envs/v4.1.0/lib/python3.11/site-packages/aiida_vasp/workchains/v2/vasp.py", line 660, in on_terminated
    out_remote_pk = self.outputs.remote_folder.pk
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^
AttributeError: 'dict' object has no attribute 'remote_folder'
09/13/2025 06:23:21 AM <663> aiida.orm.nodes.process.workflow.workchain.WorkChainNode: [REPORT] [17|VaspBandsWorkChain|verify_scf]: SCF calculation uuid: 17e9da40-1f4d-46cc-8088-1ecc1249c921 (pk: 26) (aiida.workflows:vasp.v2.vasp) completed
09/13/2025 06:23:22 AM <663> aiida.orm.nodes.process.workflow.workchain.WorkChainNode: [REPORT] [17|VaspBandsWorkChain|run_bands_dos]: Submitted workchain uuid: 0cdee689-add6-455c-95cb-6052cf7b7060 (pk: 35) (aiida.workflows:vasp.v2.vasp) for band structure
09/13/2025 06:23:22 AM <663> aiida.orm.nodes.process.workflow.workchain.WorkChainNode: [REPORT] [35|VaspWorkChain|run_process]: launching VaspCalculation<37> iteration #1
09/13/2025 06:23:22 AM <663> aiida.orm.nodes.process.calculation.calcjob.CalcJobNode: [REPORT] [37|VaspCalculation|remote_copy_restart_folder]: WARNING: Object WAVECAR does not exist in the restart folder.
09/13/2025 06:23:24 AM <663> aiida.orm.nodes.process.workflow.workchain.WorkChainNode: [REPORT] [35|VaspWorkChain|results]: work chain completed after 1 iterations
09/13/2025 06:23:25 AM <663> aiida.orm.nodes.process.workflow.workchain.WorkChainNode: [REPORT] [35|VaspWorkChain|on_terminated]: cleaned remote folders of calculations: 37

The computed band structure is stored as a BandsData object in the band_structure output port. We can plot the band structure using the show_mpl method provided.

band_out.outputs.band_structure.show_mpl()
../_images/a940c20b12e393d2a56d70c1d48db734cb5e7368db2fca54c5dfa19af95a46a8.png