0% found this document useful (0 votes)
2K views

BDG Tutorial

This document provides a tutorial for performing Bogoliubov-de Gennes (BdG) calculations with the KKRhost code using AiiDA. The tutorial involves several steps: 1) Performing a normal state self-consistent field calculation for bulk niobium. 2) Changing the energy contour to a semi-circle to better resolve electronic structure near the Fermi level. 3) Constructing an initial pairing potential and converging the BdG calculation by iterating different coupling constant values to match the experimental gap size. The tutorial demonstrates how to perform s-wave superconducting BdG calculations and notes limitations such as only s-wave coupling currently being supported.

Uploaded by

yassine
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
2K views

BDG Tutorial

This document provides a tutorial for performing Bogoliubov-de Gennes (BdG) calculations with the KKRhost code using AiiDA. The tutorial involves several steps: 1) Performing a normal state self-consistent field calculation for bulk niobium. 2) Changing the energy contour to a semi-circle to better resolve electronic structure near the Fermi level. 3) Constructing an initial pairing potential and converging the BdG calculation by iterating different coupling constant values to match the experimental gap size. The tutorial demonstrates how to perform s-wave superconducting BdG calculations and notes limitations such as only s-wave coupling currently being supported.

Uploaded by

yassine
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 11

BdG-tutorial.

md 9/30/2021

Tutorial for Bogoliubov-de Gennes calculations with


AiiDA-KKR
This example illustrates how BdG calculations can be done with KKRhost. The example is shown for bulk
Nb.
Theory
For an overview of the KKR-BdG theory take a look, for example, at this iterature
BdG theory in general
KKR-BdG theory
KKR-BdG with discussion on numerical details
Overview of this example
The KKR-BdG calculations are done in several steps:
. they start from a converged normal state calcualtion
. Superconductivity relies on a more accurate description at the Fermi level. This is done with a special
energy contour that describes a semi circle between EMIN and the Fermi energy (which we can fix for
this calculation).
. We then construct a starting value for the superconducting pairing potential. This is done in a one-
shot calculation that uses a large value for Delta_BdG in the input. The output is an anomalous
density (called den_lm_ir.001.1.dat) which is then read and updated in the following steps.
. Then we converge the BdG calculation. This then preoduces a new output potential and updates the
anomalous density den_lm_ir.*.
. Finally, the DOS in the superconducting state is computed.
In practice the steps 3 and 4 are iterated with different values of the coupling constant LAMBDA_BdG to find
a gap size that matches the experiment.
Limitations
So far we can only do s-wave coupling.
With SOC the calculation takes much longer because of the required larged k-mesh and the lower
symmetries in the BZ.
Non-collinear magnetism does not work with BdG, make sure to fix the directions of the angles using the
<FIX_NONCO_ANGLES>= True input.

Requirements
In the setup of this tutorial we used the following versions of AiiDA-KKR and its dependencies:
https://github.com/JuDFTteam/aiida-kkr, commit:
1261e8b5bd263d647258b8235b3dbb9c84b85ab9
1 / 11
BdG-tutorial.md 9/30/2021

https://github.com/aiidateam/aiida-core, commit:
ec97fcf4e4022ed3d099a0e8ecc8f7477d1f468d
https://github.com/JuDFTteam/masci-tools, commit:
3083e19d991737598eb68044206b55b584236f4d
You need to install KKRhost from the BdG branch to be able to run this.
To load the nodes (and have the BdG code in the database) import the export file for this tutorial:

verdi import export-BdG-tutorial.aiida

Step by step tutorial


Preparation: Import modules and global settings
%load_ext autoreload
%autoreload 2
%matplotlib inline

from aiida import load_profile


profile = load_profile()

import numpy as np
import matplotlib.pyplot as plt
from aiida.orm import load_node, Dict, StructureData, Code
from aiida.engine import submit
from masci_tools.io.common_functions import get_aBohr2Ang
from masci_tools.io.common_functions import search_string
from aiida_kkr import __version__ as aiida_kkr_version
from aiida_kkr.tools import plot_kkr, kkrparams
from aiida_kkr.workflows import kkr_scf_wc, kkr_dos_wc

print('Version of AiiDA-KKR:', aiida_kkr_version, '(needs to be from BdG


branch!)')

def load_or_submit(builder, uuid=None):


"""Utility to submit a calculation or load it it the uuid is given"""
if uuid is None:
calc = submit(builder)
print('submitted', calc)
else:
calc = load_node(uuid)
return calc

def get_delta(node, verbose=False):


"""Plot convergence of BdG pairing potential"""
from aiida_kkr.tools.plot_kkr import get_rms_kkrcalc_from_remote
try:
_, _, _, _, res = get_rms_kkrcalc_from_remote(node, **{'l-

2 / 11
BdG-tutorial.md 9/30/2021

independent delta:': None})


d = np.array(res['l-independent delta:'])
except:# ValueError:
from masci_tools.io.common_functions import search_string
d = []
if node.is_finished:
with node.outputs.retrieved.open('out_kkr') as f:
txt = f.readlines()
itmp = search_string('l-independent delta:', txt)
while itmp>=0:
d.append(float(txt.pop(itmp).split()[-1]))
itmp = search_string('l-independent delta:', txt)
d = np.array(d)
if verbose:
print('Delta=', d)
if len(d)==0:
print('no Delta values')
d = []
return d

# code that uses AMD nodes and has the BdG functionality
kkr_BdG = Code.get_from_string('kkrhost_BdG_AMD@iffslurm')
options_AMD = {
'withmpi': True,
'resources': {'num_machines': 1, 'tot_num_mpiprocs': 32},
'queue_name': 'th1-2020-32', # select AMD nodes that match the AMD
codes (see above)
'max_wallclock_seconds': 3600*4 # 4 hours max runtime
}

Version of AiiDA-KKR: 1.1.11-dev5-BdG (needs to be from BdG branch!)

0. Normal state scf


First prepare the structure for bulk Nb (bcc)

struc = StructureData(cell=np.array([[0.5, 0.5, -0.5], [0.5, -0.5, 0.5],


[-0.5, 0.5, 0.5]])*3.3)
struc.append_atom(position=[0,0,0], symbols='Nb')
struc.label = 'Nb_bulk'
struc.description = 'bcc Nb bulk structure'
struc = load_node('95fdec5c-17bf-4894-9867-d3031531e11e')

# plot_kkr(struc, silent=True)

Then run the normal state self-consistency:


3 / 11
BdG-tutorial.md 9/30/2021

scf_settings = kkr_scf_wc.get_wf_defaults(silent=True)[0]
scf_settings['mag_init'] = False
scf_settings['check_dos'] = False
scf_settings['nsteps'] = 100
scf_settings.convergence_setting_coarse =
scf_settings.convergence_setting_fine
para = kkrparams(NSPIN=1, LMAX=2, RMAX=10, GMAX=100)

builder = kkr_scf_wc.get_builder()
builder.kkr = kkr_BdG # BdG code on AMD nodes
builder.voronoi = Code.get_from_string('voronoi_3.5_AMD@iffslurm')
builder.calc_parameters = Dict(dict=para)
builder.wf_parameters = Dict(dict=scf_settings)
builder.metadata.label = 'Nb_bulk_scf'
builder.structure = struc
builder.options = Dict(dict=options_AMD)

Nb_scf = load_or_submit(builder, '5a473096-caad-4521-ab03-4c4e38b7e745')


# plot_kkr(Nb_scf, silent=True)

1. Change energy contour to semi-circle


We need to use a different energy contour to be able to resolve the fine details of the electronic structure at
the Fermi level. This is required by the BdG calculation.
Use the converged calcualtion and rerun a KkrCalculation with the changed energy contour and increased
numerical parameters (number of k-points for the Brilouin zone integration, size of the screening cluster):

if not Nb_scf.is_finished_ok:
raise ValueError('Wait for scf to finish!')

# get the parameters that were used in the scf step


para_kkr = kkrparams(**{k:v for k,v in
Nb_scf.inputs.calc_parameters.get_dict().items() if v is not None})

# update parameters to use a semi-circle contour


para_kkr.set_multiple_values(
use_semi_circle_contour=True, # use semi-circle energy contour
IM_E_CIRC_MIN= 5e-5, # minimal energy for semi-circle contour
NPT1=32, # number of points on semi-circle contour
MAX_NUM_KMESH=4, # limit the number of k-meshes to avoid undersampling
in the BZ integration
DISABLE_CHARGE_NEUTRALITY=True, # fix the Fermi level (otherwise the
Fermi energy can jump a lot, this make the calculation stable)
BZDIVIDE= [100, 100, 100], # larger k-mesh is needed since last energy
points is close to real axis (see IM_E_CIRC_MIN)
RCLUSTZ= 3.5, # increase cluster radius (larger screening cluster is
necessary because of last energy point)
NSTEPS= 200,
IMIX= 4,

4 / 11
BdG-tutorial.md 9/30/2021

# this is for the use of the Chebychev solver (required to run BdG
mode)
RUNOPT=['NEWSOSOL'],
R_LOG= 0.6,
NPAN_EQ= 7,
NPAN_LOG= 18,
NCHEB= 12,
DECOUPLE_SPIN_CHEBY=True, # use the Chebychev solver without SOC to
speed everything up
)

# create a process builder for the KKR calculation and submit


builder = kkr_BdG.get_builder()
builder.metadata.label = Nb_scf.label + '_semi_circ'
builder.metadata.options = options_AMD
builder.parameters = Dict(dict=para_kkr)
builder.parent_folder = Nb_scf.outputs.last_RemoteData
Nb_semi_circ = load_or_submit(builder, '5a57de5b-02d3-4aaf-9875-
25dafab076fb')
# plot_kkr(Nb_semi_circ, silent=True)

print('Finished with semi-circle contour?', Nb_semi_circ.is_finished_ok)

Finished with semi-circle contour? True

This is the energy contour we used (the color indicates the k-mesh):

with Nb_semi_circ.outputs.retrieved.open('output.000.txt') as _f:


txt = _f.readlines()

ec = []

# read RMS values for pairing potential


iline = search_string('ENERGY =', txt)
while (iline>=0):
l = txt.pop(iline).split()
ec.append([l[6], l[7], l[-1]])
iline = search_string('ENERGY =', txt)

ec = np.array(ec, dtype=float)

plt.figure(figsize=(12,6))
plt.scatter(ec[:,0], ec[:,1], c=ec[:,2], )
plt.xlabel('Re(E) (Ry)')
plt.ylabel('Im(E) (Ry)')
cb = plt.colorbar()
plt.title('Energy contour')
plt.ylim(0)
plt.show()

5 / 11
BdG-tutorial.md 9/30/2021

2. Initialize BdG calculation


We now initialize the BdG mode with a one-shot calcualtion that uses a guess for the size of the pairing
potential (here we use 0.5 mRy). This calculation produces a starting point for the pairing potential
$\Delta(r)$ that is used in the BdG self-consistency.

if not Nb_semi_circ.is_finished_ok:
raise ValueError('Wait for semi-circle calculation to finish!')

# activate BdG mode and change settings for one-shot calculation


# this reuses the settings from the semi-circle calculation (i.e. we reuse
the same energy contour etc.)
para_BdG = kkrparams(**{k:v for k,v in
Nb_semi_circ.inputs.parameters.get_dict().items() if v is not None})
para_BdG.set_multiple_values(
# run 1 iteration for the one-shot calcualtion
NSTEPS= 1,

# activate BdG mode


use_BdG=True,

# 'big' starting value (improves convergence)


Delta_BdG=5e-4,

# use e/h symmetry (uses only half of the mirrored contour, makes
everything faster)
use_e_symm_BdG= True,

# same Delta on all atoms (useful if non-superconducting atoms are in

6 / 11
BdG-tutorial.md 9/30/2021

the structure)
at_scale_BdG = [1.0 for i in range(len(struc.sites))],
)

# create calculation and run it


builder = kkr_BdG.get_builder() # reuse BdG code on AMD node
builder.parameters = Dict(dict=para_BdG)
builder.metadata.label = Nb_semi_circ.label + f'_BdG_start'
builder.metadata.options = options_AMD
# start from scf on the semi-circle contour
builder.parent_folder = Nb_semi_circ.outputs.remote_folder
BdG_scf_start = load_or_submit(builder, 'c4a2f6f8-b863-4f86-ba0c-
da7fb8c51c70')

print('Finished with BdG initialization?', BdG_scf_start.is_finished_ok)

Finished with BdG initialization? True

3. BdG scf
if not BdG_scf_start.is_finished_ok:
raise ValueError('Wait for BdG init to finish!')

# update parmeters for self-consistency of BdG mode


para_BdG_scf = kkrparams(**{k:v for k,v in
BdG_scf_start.inputs.parameters.get_dict().items() if v is not None})
para_BdG_scf.set_multiple_values(
# run many iteration until self-consistency
NSTEPS= 200,

# coupling constant, this needs to be scaled for the different systems


(trial and error) to reproduce the correct gap size
lambda_BdG= 0.025,

# BdG mixing:
mixfac_BdG = 0.3, # mixing factor for BdG Broyden mixing
Ninit_Broyden_BdG = 5, # number of BdG simple mixing steps (should be
between 5 and 50 for stability)

# control potential mixing


IMIX = 4, # use Broyden mixing in the potential
NSIMPLEMIXFIRST = 25, # for the first 25 iterations we just do simple
mixing in the potential to first converge the pairing potential and then
let the (electronic) potential follow
)

# create new calculation and run it


builder = BdG_scf_start.get_builder_restart() # reuse BdG code on AMD node
builder.parameters = Dict(dict=para_BdG_scf)

7 / 11
BdG-tutorial.md 9/30/2021

builder.metadata.label = Nb_semi_circ.label + f'_BdG_scf'


builder.metadata.options = options_AMD
# start from BdG init (i.e. this uses the output anomalous density from
the previous step
builder.parent_folder = BdG_scf_start.outputs.remote_folder
BdG_scf = load_or_submit(builder, '41285105-9951-47a7-86e4-65c5df5448ed')

print('Finished with BdG scf?', BdG_scf.is_finished_ok)

Finished with BdG scf? True

plot BdG convergence

# plot convergence
plot_kkr(BdG_scf, silent=True)

# plot the convergence of the pairing potential


delta = get_delta(BdG_scf)
plt.figure()
plt.plot(delta, 'o-')
plt.ylabel('$\Delta$ (a.u.)')
plt.xlabel('iteration')
# add lines to indicate where mixing changes
plt.axvline(para_BdG_scf.get_value('NSIMPLEMIXFIRST')+0.5, ls=':',
color='red', label='start Broyden for potential')
plt.axvline(para_BdG_scf.get_value('<NINIT_BROYDEN_BDG>')+0.5, ls=':',
color='blue', label='start Broyden for $\Delta$')
plt.legend(fontsize='large')
plt.show()

8 / 11
BdG-tutorial.md 9/30/2021

4. BdG DOS
Finally we can look at the density of states in the superconducting state. The overview in an energy range of
-3 to +1 eV around EF does not show a lot of differences to the normal state.

if not BdG_scf.is_finished_ok:
raise ValueError('Wait for BdG scf to finish!')

dos_settings = {'nepts': 32*4, 'tempr': 100, 'emin': -3.0, 'emax': 1.0,


'kmesh': [100, 100, 100]}

builder = kkr_dos_wc.get_builder()
builder.kkr = kkr_BdG
builder.options = Dict(dict=options_AMD)
builder.remote_data = BdG_scf.outputs.remote_folder
builder.wf_parameters = Dict(dict=dos_settings)
builder.metadata.label = BdG_scf.label + '_DOS_overview'

BdG_DOS_overview = load_or_submit(builder, '1cf7a898-4f48-4061-ae2b-


b15792d7601e')
plot_kkr(BdG_DOS_overview, silent=True, noshow=True)
plt.title('BdG-DOS in large range around Fermi level')
plt.xlim(-3,1)
plt.show()

9 / 11
BdG-tutorial.md 9/30/2021

To see the superconducting gap we have to focus closely around the Fermi level (+/-10meV around EF):

if not BdG_scf.is_finished_ok:
raise ValueError('Wait for BdG scf to finish!')

# needs small temperature and large k-mesh!


dos_settings = {'nepts': 32*4, 'tempr': 0.5, 'emin': -0.01, 'emax': 0.01,
'kmesh': [300, 300, 300], 'KPOIBZ': 600000} # KPOIBZ needs to be big
enough to fit the irreducable BZ

builder = kkr_dos_wc.get_builder()
builder.kkr = kkr_BdG
builder.options = Dict(dict={
'withmpi': True,
'resources': {'num_machines': 1, 'tot_num_mpiprocs': 64},
'queue_name': 'th1-2020-64',
'max_wallclock_seconds': 14400}
)
builder.remote_data = BdG_scf.outputs.remote_folder
builder.wf_parameters = Dict(dict=dos_settings)
builder.metadata.label = BdG_scf.label + '_DOS_zoom'

BdG_DOS_zoom = load_or_submit(builder, '63658dd6-88d2-49ee-bdf0-


a5005dfaf6df')
plot_kkr(BdG_DOS_zoom, silent=True, xscale=1000, noshow=True, ptitle='SC
gap in BdG-DOS')
plt.xlabel('$E-E_{\mathrm{F}}$ (meV)')
plt.xlim(-10,10)
plt.show()

10 / 11
BdG-tutorial.md 9/30/2021

11 / 11

You might also like