AiiDA-Fleur beyond the Command line interface: Calculating an equation of state

Objective

  • Revisiting the EOS workflow but use it directly from python.
  • Learning how to use FLEUR in python scripts.
  • Experiencing with some of the concepts AiiDA provides.

Introduction

This tutorial will walk you through an example of using the AiiDA workflow framework together with the FLEUR code to perform a very common task in DFT in calculating an equation of state for a given structure.

To achieve this, we need to run multiple self-consistent calculations of the total energy, while compressing/expanding the volume of the unit cell. In addition all relevant calculation parameters need to be kept consistent to ensure meaningful results.

!!! note In contrast to most other tutorials of we use here a python kernel, i.e. our commands will be executed by a python interpreter and not by bash.

We start with setting up the profile of AiiDA, this needed to ensure our script can work correctly using our settings.

from aiida import load_profile
load_profile();
!verdi status

If we want to work with AiiDA we have to create and load a profile, defining the different configurations. In this docker image we have preconfigured everything.

Defining the Structure

In this example we use bulk Si as an example. Below we see how a crystal structure can be defined in AiiDA. Of course more options for defining structures are also available, e.g. reading them from .cif files

from aiida.orm import StructureData

a = 5.43 #Lattice constant in Angstroem
cell = [[0     , a / 2., a / 2.],
        [a / 2., 0     , a / 2.],
        [a / 2., a / 2., 0     ]]
structure = StructureData(cell=cell)
structure.append_atom(position=(0., 0., 0.), symbols='Si')
structure.append_atom(position=(a / 4., a / 4., a / 4.), symbols='Si')
print(structure.cell)
print(structure.sites)

Setting up the calculation

In AiiDA we can submit individual calculations using a specific code or we can use a workflow, which can string multiple calculations together to perform more complex analysis. These are identified by strings and are loaded via the WorkflowFactory as shown below. In the case of the EOS calculation this string is 'fleur.eos'

from aiida.plugins import WorkflowFactory
FleurEOSWorkchain = WorkflowFactory('fleur.eos')

For Fleur the following other workflows are available

Name Description
fleur.scf Self-consistent calculations
fleur.relax Structural relaxations
fleur.banddos Calculate a density of states/band structure.
fleur.eos Calculate an equation of state
fleur.mae Calculate Magnetic Anisotropy Energies (force-theorem)
fleur.mae_conv Calculate Magnetic Anisotropy Energies (self-consistent)
fleur.ssdisp Calculate spin-spiral energy dispersions (force-theorem)
fleur.ssdisp_conv Calculate spin-spiral energy dispersion (self-consistent)
fleur.orbcontrol Find global minimum of DFT+U calculation using orbital occupation control
fleur.dmi Calculate Dzyaloshinskii–Moriya Interaction energy (force-theorem)
fleur.create_magnetic Create relaxed film structure for magnetic films on a substrate
fleur.initial_cls Calculate core-level shifts with resprect to elemental structures
fleur.corehole Calculate abcolute core-level binding energies
fleur.cfcoeff Calculate 4f crystal field coefficients
fleur.base Technical workflow resubmitting Fleur calculations in case of failures
fleur.base_relax Technical workflow handling structural relaxations and adjusting parameters in case of failures

In the following we need to set up the inputs for the EOS workflow. First we specify the structure to calculate and how many/which points on the equation of state we want to calculate

from aiida.orm import Dict

inputs = FleurEOSWorkchain.get_builder()

#Parameters for the EOS to calculate
inputs.structure = structure
inputs.wf_parameters = Dict({
    'points': 7,  #How many points to calculate
    'step': 0.01, #How much should the volume be compressed/expanded
    'guess': 1.03 # Guess for the equilibrium lattice constant
})

In addition we need to define, which executables we want to use and how we want to parallelize the calculations. In this tutorial we pre-configured the local fleur_MPI and inpgen executables and are not using any parallelization

Note: Of course the codes don't have to be on the same computer as the AiiDA environment you are using. This is the case here only for the tutorial. AiiDA has inbuilt support to talk to remote computers, e.g. via ssh and use schedulers like slurm, pbs, torgue, etc.

from aiida.orm import Dict, load_code

inputs.scf.fleur = load_code('fleur@localhost')
inputs.scf.inpgen = load_code('inpgen@localhost')
inputs.scf.options = Dict({
        'resources': {
            'num_machines': 1,
            'num_mpiprocs_per_machine': 1
        },
        'max_wallclock_seconds': 10 * 60,
        'withmpi': False,
    })

Now we submit our prepared inputs to the AiiDA engine and let it run our calculations. !!! note In more advanced use of AiiDA you probably want to use submit instead of run. Here, the script blocks until the workflow finishes, while in many situations you would probably prefer to just queue the job and continue, i.e. to submit further calculations. However, this requires the AiiDA installation to have the AiiDA demon enabled. In our tutorial this is not the case. Please see the AiiDA documentation for more details.

```python
from aiida.engine import run
eos_calculation = run(inputs)

Now that the calculation has successfully finished, we can look into the results.

We stored the return objects in the eos_calculation variable, which we will use to investigate the output.

All workchains in the AiiDA-Fleur plugin will have a python dictionary summarizing the results under a name like output_<workflow_abbreviation>_wc_para, which can be accessed like this

from pprint import pprint
pprint(eos_calculation["output_eos_wc_para"].get_dict())

As we can see the dictionary contains not only the total energies of all the different SCF calculations, in addition a fit of the energy curve was performed to determine

  • the equilibrium volume and it's corresponding volume scaling from the initial guess
  • The bulk modulus and derivative in GPa

This information you might recognize from the command line interface in which it was provided in the eos.json file.

We can also plot the results of the workchain, i.e. the equation of state code using the helper function below

from aiida_fleur.tools.plot import plot_fleur
plot_fleur(eos_calculation['output_eos_wc_para'])

In addition, the workchain also provides a structure with the fitted equilibrium lattice constant as an output

equilibrium_structure = eos_calculation["output_eos_wc_structure"]
print(equilibrium_structure.cell)
print(equilibrium_structure.sites)

Learn more

This of course only gave a short glimpse on how to use AiiDA-FLEUR in python scripts. For more details, we refer to

  • https://aiida.readthedocs.io/projects/aiida-core/en/latest/
  • https://aiida-fleur.readthedocs.io/en/develop/