Computing Hubbard parameters self-consistently#
In this tutorial you will learn how to compute iteratively the Hubbard parameters through the SelfConsistentHubbardWorkChain.
The cycle#
To have a full ab-initio calculation of Hubbard parameters, an iterative procedure should be employed. This forsees the following steps, to do in a cyclic way till the parameters don’t differ from the previous ones by a certain threshold, i.e. self-consistently.
The steps to do in order are:
Perform a volume relaxation of the structure, starting from a zero value of Hubbard parameters (i.e. if it was a ‘non-Hubbard’ calculation).
Perform the ground-state calculation (SCF) of the relaxed structure.
Perform the linear response calculation to predict the new Hubbard values.
If all U (and V) are within the desired threshold, stop, otherwise restart with the new values from (1).
Note for SCF (step 2)
Tipically, as these are electronic responses, the gound-state SCF can be performed with looser energy cutoffs and k poit density, and still retain the same accuracy on the prediction of Hubbard parameters.
Important
Before any production run, you should make sure to have converged such parameters.
Note for thresholds
Threshold for U and V may depend on the final goal, or property, of your research. From our experience, good values are of the order of 0.1 eV for the onsite parameters (U) and 0.01 eV for the intersites (V).
Automating the cycle#
As we already learnt from the previous tutorials (1,2), we can simply fill the builder of the work chain using the get_builder_from_protocol to get to know what the workflow is doing, and how this can help and speed up our research.
Warning
In this tutorial we will compute only the U on Co, and not the V for Co-O. This is to speed up the simulation, which on only a handful of cores would take tens of minutes, if not more.
This workflow may take 5 minutes (or more) to complete depending on your local resources.
from aiida.engine import run_get_node
from aiida_hubbard.workflows.hubbard import SelfConsistentHubbardWorkChain
builder = SelfConsistentHubbardWorkChain.get_builder_from_protocol(
pw_code=data.pw_code,
hp_code=data.hp_code,
hubbard_structure=hubbard_structure,
protocol="fast",
overrides={
"clean_workdir": False,
"tolerance_onsite": 0.5,
"tolerance_intersite": 0.1,
"relax":{
"base_init_relax":{
"kpoints_distance":100.0,
"pw":{
"parameters":{
"SYSTEM":{
"ecutwfc": 60.0, # to speed up the tutorial
"ecutrho": 60.0 * 8,
},
},
},
},
"base_relax":{
"kpoints_distance":100.0,
"pw":{
"parameters":{
"SYSTEM":{
"ecutwfc": 60.0, # to speed up the tutorial
"ecutrho": 60.0 * 8,
},
},
},
}
}, # to speed up the tutorial
"scf":{
"kpoints_distance":100.0,
"pw":{
"parameters":{
"SYSTEM":{
"ecutwfc": 30.0, # to speed up the tutorial
"ecutrho": 30.0 * 8,
},
},
},
},
"hubbard":{"qpoints_distance":100.0, "parallelize_atoms":False, "parallelize_qpoints":False}}, # to speed up the tutorial
)
results, node = run_get_node(builder)
Let’s inspect the status of the work chain to see the full self-consistency on screen!
%verdi process status {node.pk}
SelfConsistentHubbardWorkChain<133> Finished [0] [2:run_results]
├── PwRelaxWorkChain<136> Finished [0] [3:results]
│ ├── PwBaseWorkChain<138> Finished [501] [2:while_(should_run_process)(2:inspect_process)]
│ │ ├── create_kpoints_from_distance<139> Finished [0]
│ │ └── PwCalculation<143> Finished [501]
│ └── PwBaseWorkChain<152> Finished [0] [3:results]
│ ├── create_kpoints_from_distance<153> Finished [0]
│ └── PwCalculation<157> Finished [0]
├── PwBaseWorkChain<166> Finished [0] [3:results]
│ ├── create_kpoints_from_distance<167> Finished [0]
│ └── PwCalculation<171> Finished [0]
├── PwBaseWorkChain<179> Finished [0] [3:results]
│ ├── create_kpoints_from_distance<180> Finished [0]
│ └── PwCalculation<184> Finished [0]
├── HpWorkChain<192> Finished [0] [3:results]
│ ├── create_kpoints_from_distance<194> Finished [0]
│ └── HpBaseWorkChain<198> Finished [0] [3:results]
│ └── HpCalculation<201> Finished [0]
├── PwRelaxWorkChain<211> Finished [0] [3:results]
│ ├── PwBaseWorkChain<213> Finished [0] [3:results]
│ │ ├── create_kpoints_from_distance<214> Finished [0]
│ │ └── PwCalculation<218> Finished [0]
│ └── PwBaseWorkChain<227> Finished [0] [3:results]
│ ├── create_kpoints_from_distance<228> Finished [0]
│ └── PwCalculation<232> Finished [0]
├── PwBaseWorkChain<241> Finished [0] [3:results]
│ ├── create_kpoints_from_distance<242> Finished [0]
│ └── PwCalculation<246> Finished [0]
├── PwBaseWorkChain<254> Finished [0] [3:results]
│ ├── create_kpoints_from_distance<255> Finished [0]
│ └── PwCalculation<259> Finished [0]
└── HpWorkChain<267> Finished [0] [3:results]
├── create_kpoints_from_distance<269> Finished [0]
└── HpBaseWorkChain<273> Finished [0] [3:results]
└── HpCalculation<276> Finished [0]
And of course, here you have the final relaxed structure with fully self-consistent ab-initio Hubbard parameters! 🎉
from aiida_quantumespresso.utils.hubbard import HubbardUtils
print(HubbardUtils(results['hubbard_structure']).get_hubbard_card())
HUBBARD ortho-atomic
U Co-3d 7.861
Final considerations#
We managed to compute the Hubbard parameters self-consistently with a series of relaxations, scfs, and hp calculations, all fully automated! 🎉
Learn more and in details
To learn the full sets of inputs, to use proficiently the get_builder_from_protocol and more, have a look at the following sections: