GW tutorial. Convergence and approximations (BN): Difference between revisions

From The Yambo Project
Jump to navigation Jump to search
No edit summary
 
(50 intermediate revisions by 3 users not shown)
Line 1: Line 1:


We chosen hexagonal boron nitride to explain the use of yambopy. Along this tutorial we show how to use yambopy to make efficient convergence tests, to compare different approximations and to analyze the results.
We have selected 2D hexagonal boron nitride to explain the use of yambopy. Throughout this tutorial we show how to use yambopy to make efficient convergence tests, to compare different approximations and to analyse the results.


The initial step is the ground state calculation and the non self-consistent calculation using the <code>gs_bn.py</code> file:
=== Initial steps with Quantum Espresso ===


<source lang="bash">python gs_bn.py
Yambopy includes qepy, a module to handle QE-DFT calculations necessary to run Yambo.
python gs_bn.py -sn</source>
We have set 50 bands and the k-grid <code>12x12x1</code>.


=== GW convergence ===
The initial step consists of a self-consistent (scf) ground state calculation together with a non-self-consistent (nscf) calculation with QE using the <code>gs_bn.py</code> file:
 
python gs_bn.py
python gs_bn.py -sn
 
Here you will be using a predefined lattice parameter for the calculations. You can, however, run a geometry optimisation calculation with
 
python gs_bn.py -rsn
 
which at the end will update the input files for <code>pw.x</code> with the relaxed lattice parameters and atomic coordinates.
 
A quick note: almost all python scripts in this tutorial can be run without any options, but they will only print out the help message. In the case of <code>gs_bn.py</code> it will print:
 
python gs_bn.py
 
usage: gs_bn.py [-h] [-r] [-s] [-n] [-n2] [-b] [-l] [-o] [-p] [-d] [-t NTHREADS]
Test the yambopy script.
optional arguments:
  -h, --help            show this help message and exit
  -r, --relax          Structural relaxation
  -s, --scf            Self-consistent calculation
  -n, --nscf            Non-self consistent calculation
  -n2, --nscf_double    Non-self consistent calculation for the double grid
  -b, --bands          Calculate band-structure
  -l, --plot            Plot band-structure
  -o, --orbitals        Plot atomic orbital projected band-structure
  -p, --phonon          Phonon calculation
  -d, --dispersion      Phonon dispersion
  -t NTHREADS, --nthreads NTHREADS
                        Number of threads
 
We have set the non-self-consistent run with a wave-function cutoff of '''60 Ry, 70 bands and a k-grid of <code>12x12x1</code>''' for Yambo calculations.
 
In addition, we can check if we get a reasonable band structure for our many-body calculations. We can define a path, for instance, in an hexagonal Brillouin zone:
 
 
p = Path([ [[0.0, 0.0, 0.0],'$\Gamma$'],
            [[0.5, 0.0, 0.0],'M'],
            [[1./3,1./3,0.0],'K'],
            [[0.0, 0.0, 0.0],'$\Gamma$']], [int(10*2),int(10),int(sqrt(5)*10)])
 
 
We obtain the band structure by doing:
 
python gs_bn.py -b
 
[[File:Plot-bn-band.png|BN Band Structure|500px]]
 
The horizontal line marks the top of the valence band. The electronic bandgap has a value of 4.73 eV. In the next sections, we will show how to calculate the GW correction and the excitonic effects with BSE using Yambo in an automatic way.
 
=== GW convergence of the bandgap ===


'''(a) Calculations'''
'''(a) Calculations'''
We converge the main parameters of a GW calculation independently. We make use of the plasmon pole approximation for the dielectric function and the Newton solver to find the GW correction to the LDA eigenvalues. The quantity to converge is the band gap of the BN (conduction and valence band at the K point of the Brillouin zone). We can select this calculation by calling the <code>YamboIn</code> with the right arguments:


<source lang="python">y = YamboIn('yambo -d -g n -p p -V all',folder='gw_conv')</source>
We converge the main parameters of a GW calculation independently. In addition, we make use of the plasmon pole approximation for the dielectric function, and the Newton solver to find the GW correction to the LDA eigenvalues. We converge the band gap of BN (difference in energy of the bottom of the conduction and top of the valence band at the K point of the Brillouin zone). We have designed the script '''gw_conv_bn.py''' (folder ~/tutorial/bn) for this purpose.
The main variables are:
 
We can select the GW calculation by calling the <code>YamboIn</code> with the corresponding arguments:


<blockquote><code>EXXRLvcs</code>: Exchange self-energy cutoff
python gw_conv_gw.py -c
 
y = YamboIn.from_runlevel('yambo -d -p p -g n -V all',folder='gw_conv')
 
The main variables of a GW calculation are:
 
<blockquote>
 
<code>EXXRLvcs</code>: Exchange self-energy cutoff
 
<code>NGsBlkXp</code>: Cutoff of the dielectric function.


<code>BndsRnXp</code>: Number of bands in the calculation of the dielectric function (PPA).
<code>BndsRnXp</code>: Number of bands in the calculation of the dielectric function (PPA).


<code>NGsBlkXp</code>: Cutoff of the dielectric function.
<code>GbndRnge</code>: Self-energy. The number of bands.


<code>GbndRnge</code>: Self-energy. Number of bands.
</blockquote>
</blockquote>
The convergence with the k-grid is done after these variables are converged and in principle is also independent of them. The convergence is set with a dictionary in which we choose the parameter and the values. Be aware of setting the right units and format for each parameter.


<source lang="python">conv = { 'EXXRLvcs': [[1,20,40,60,80,100],'Ry'],
We define a dictionary with all the parameters that we want to converge. Be aware of setting the right units and format for each parameter.
         'NGsBlkXp': [[0,1,2,3,4], 'Ry'],
 
         'BndsRnXp': [[[1,5],[1,10],[1,20],[1,30],[1,40]]],''] ,
conv = { 'EXXRLvcs': [[10,10,20,30,40,50,60,70,80,90,100],'Ry'],
         'GbndRnge': [[[1,5],[1,10],[1,20],[1,30],[1,40]],''] }</source>
         'NGsBlkXp': [[0,0,1,2,3,4,5,6], 'Ry'],
         'BndsRnXp': [[[1,10],[1,10],[1,20],[1,30],[1,40],[1,50],[1,60],[1,70]],''] ,
         'GbndRnge': [[[1,10],[1,10],[1,20],[1,30],[1,40],[1,50],[1,60],[1,70]],''] }
 
The class <code>YamboIn</code> includes the function <code>optimize</code>, which is called here:
The class <code>YamboIn</code> includes the function <code>optimize</code>, which is called here:


<source lang="python">y.optimize(conv,run=run,ref_run=False)</source>
y.optimize(conv,folder='gw_conv',run=run,ref_run=False)
This optimization function just needs the convergence dictionary and the run instructions, given by the function:
 
The function <code>optimize</code> has two main arguments: the convergence dictionary, and a function '''run''' with the instructions to run
the calculation, defined in our case like:
 
    def run(filename):
        """ Function to be called by the optimize function """
        folder = filename.split('.')[0]
        print(filename,folder)
        shell = bash()
        shell.add_command('cd gw_conv')
        shell.add_command('rm -f *.json %s/o-*'%folder) #cleanup
        shell.add_command('%s -F %s -J %s -C %s 2> %s.log'%(yambo,filename,folder,folder,folder))
        shell.run()
        shell.clean()


<source lang="python">def run(filename):
We have defined interactive run, in the folder <code>gw_conv</code>. We have also defined the name for each job, associated with the variable and its value.
    &quot;&quot;&quot; Function to be called by the optimize function &quot;&quot;&quot;
    folder = filename.split('.')[0]
    print(filename,folder)
    shell = bash()
    shell.add_command('cd gw_conv; %s -F %s -J %s -C %s 2&gt; %s.log'%(yambo,filename,folder,folder,folder))
    shell.run()
    shell.clean()</source>
We set an interactive run, in the folder <code>gw_conv</code>. All the calculations will be made there with the corresponding jobname.


'''(b) Analysis'''
'''(b) Analysis'''


Once all the calculations are finished it's time to pack all the files in the <code>json</code> format for posterior analysis. For this use the <code>YamboOut()</code> class:
Once all the calculations are finished it's time to analyse them. At this point yambopy will facilitate the analysis. Besides
the python module, <code>yambopy</code> can also be called in the terminal to perform some post-analysis tasks:
 
    $ yambopy
    analysebse ->    Using ypp, you can study the convergence of BSE calculations in 2 ways:
      plotem1s ->    Plot em1s calculation
      analysegw ->    Study the convergence of GW calculations by looking at the change in bandgap value.
        mergeqp ->    Merge QP databases
          test ->    Run yambopy tests
  plotexcitons ->    Plot excitons calculation
 
Calling <code>yambopy analysegw</code> will display the help of the function:
 
 
    Study the convergence of GW calculations by looking at the change in bandgap value.
    The script reads from <folder> all results from <variable> calculations and display them.
    Use the band and k-point options according to the size of your k-grid
    and the location of the band extrema.
 
        Mandatory arguments are:
            folder  -> Folder containing SAVE and convergence runs.
            var      -> Variable tested (e.g. FFTGvecs)
        Optional variables are:
            -bc, --bandc  (int)  -> Lowest conduction band number
            -kc, --kpointc (int)  -> k-point index for conduction band
            -bv, --bandv  (int)  -> Highest valence band number
            -kv, --kpointv (int)  -> k-point index for valence band
            -np, --nopack  (flag) -> Do not call 'pack_files_in_folder'
            -nt, --notext  (flag) -> Do not print a text file
            -nd, --nodraw  (flag) -> Do not draw (plot) the result
 
 
Running the function selecting the bands and k-points, together with the parameter of convergence we will obtain the convergence plot.
 
yambopy analysegw -bc 5 -kc 7 -bv 4 -kv 7 gw_conv EXXRLvcs
yambopy analysegw -bc 5 -kc 7 -bv 4 -kv 7 gw_conv NGsBlkXp
yambopy analysegw -bc 5 -kc 7 -bv 4 -kv 7 gw_conv BndsRnXp
yambopy analysegw -bc 5 -kc 7 -bv 4 -kv 7 gw_conv GbndRnge
 
From the convergence plots, we can choose the set of converged parameters and repeat the calculation for finer k-grids until we reach convergence with the k-points. We have
intentionally used non-converged parameters. Nevertheless, along this week
you should have gotten enough expertise to push the convergence of the parameters
and determine the correct convergence set of parameters.
We invite you to enter in the python script, increase the parameters and check
again the convergence for larger values!
 
 
[[File:EXXRLvcs.png|FFTGvecs|300px]]
 
[[File:NGsBlkXp.png|NGsBlkXp|300px]]
 
[[File:BndsRnXp.png|BndsRnXp|300px]]
 
[[File:GbndRnge2.png|GbndRnge|300px]]
 
In general, the convergence with the '''k-grid''' is done after these variables are converged and, in principle, it is also independent of them. We invite you to change the number of k-points in the file '''gs_bn.py''' using the variable '''kpoints_nscf'''.
 
=== GW calculation in regular k-grid ===
 
From the bandgap convergence study made above for a '''k-grid''' we can decide reasonable parameters. Another option is to decide a convergence threshold to establish
the accuracy of the convergence. In this tutorial, in order to make calculations lighter, we have chosen the following parameters:
 
EXXRLvcs = 60 Ry
BndsRnXp = 40 bands
NGsBlkXp =  3  Ry
GbndRnge = 30 bands
QPkrange = [1,19,2,6]
 
We can change the <code>gs_bn.py</code> scripts to calculate a non self-consistent run for a larger '''k-grid''' (12x12x1 will do the job). We can also change the number of bands to 40 in order to speed up a bit the QE calculation.
 
We can just simply run the code to calculate the GW corrections for all the points of the Brillouin zone by setting the converged parameters in the script <code>gw_bn.py</code>. If we enter in the script we can check that we define a scheduler (the default is bash):
 
scheduler = Scheduler.factory
 
We just need to define the run level and the variables we are going to change:
 
y = YamboIn.from_runlevel('%s -p p -g n -V all'%yambo,folder='gw')
   
y['EXXRLvcs'] = [60,'Ry']      # Self-energy. Exchange
y['BndsRnXp'] = [1,40]          # Screening. Number of bands
y['NGsBlkXp'] = [3,'Ry']        # Cutoff Screening
y['GbndRnge'] = [1,30]          # Self-energy. Number of bands
y['QPkrange'] = [kpoint_start,kpoint_end,2,6]
 


<source lang="python">#pack the files in .json files
We can now run the script and obtain the GW in the full '''k-grid'''.
for dirpath,dirnames,filenames in os.walk('gw_conv'):
  #check if there are some output files in the folder
  if ([ f for f in filenames if 'o-' in f ]):
      y = YamboOut(dirpath,save_folder=dirpath)
      y.pack()</source>
This snippet of code can be called using the function:


<source lang="python">pack_files_in_folder('gw_conv',save_folder='gw_conv')</source>
python gw_bn.py
Yambopy provides the function <code>yambopy analysegw</code> to perform the analysis of the <code>json</code> files in an automatic way. By running the script selecting the bands and kpoints, together with the parameter we will obtain the convergence plot.


<source lang="python">yambopy analysegw -bc 5 -kc 19 -bv 4 -kv 19 gw_conv EXXRLvcs
If everything has worked fine now we will have inside the folder <code>gw/yambo</code> the netCDF file <code>ndb.QP</code> with the results of the GW calculation. We can analyze the results and/or use them in BSE calculations.
yambopy analysegw -bc 5 -kc 19 -bv 4 -kv 19 gw_conv NGsBlkXp
yambopy analysegw -bc 5 -kc 19 -bv 4 -kv 19 gw_conv BndsRnXp
yambopy analysegw -bc 5 -kc 19 -bv 4 -kv 19 gw_conv GbndRnge</source>


[[File:GW CONV EXXRLvcs.png|FFTGvecs|300px]]
=== Plotting GW calculations. Scissor operator and GW band structure  ===


[[File:GW CONV BndsRnXp.png|BndsRnXp|300px]]
If everything has worked fine now we can start using the yambopy analysis tools. For this purpose, we have created the script <code>plot-qp.py</code>. Using this
script we will be able to read the Yambo databases and plot the results. Notice that we use matplotlib to make the plots. For all the plots we define a figure and axis by
doing:


[[File:GW CONV NGsBlkXp.png|NGsBlkXp|300px]]
fig = plt.figure(figsize=(6,4))
ax  = fig.add_axes( [ 0.20, 0.20, 0.70, 0.70 ])


[[File:GW CONV GbndRnge.png|GbndRnge|300px]]
The file is structured as follows:


From the convergence plot we can choose now a set of parameters and repeat the calculation for finer k-grids until we reach convergence with the k-points. The convergence criteria are left to the user.
'''A. Define a path'''. Using qepy we can define a path to plot the band structure.


=== GW calculation in a regular grid and plot in a path in the Brillouin zone ===
npoints = 10
path = Path([ [[  0.0,  0.0,  0.0],'$\Gamma$'],
              [[  0.5,  0.0,  0.0],'M'],
              [[1./3.,1./3.,  0.0],'K'],
              [[  0.0,  0.0,  0.0],'$\Gamma$']], [int(npoints*2),int(npoints),int(sqrt(5)*npoints)] )


We will work in the PPA for the screening. We have chosen the following parameters:
'''B. Read Yambo lattice and QP databases.'''


<source lang="bash">FFTGvecs = 20 Ha
lat  = YamboSaveDB.from_db_file(folder='gw/SAVE',filename='ns.db1')
BndsRnXp = 24 bands
ydb  = YamboQPDB.from_db(filename='ndb.QP',folder='gw/yambo')
NGsBlkXp = 500 mHa
GbndRnge = 20 bands
EXXRLvcs = 20 Ha
QPkrange = [1,19,2,6]</source>
We can just simply run the code to calculate the GW corrections for all the points of the Brillouin zone by setting the convergence parameters in the function gw of the script and doing:


<source lang="bash">python gw_conv_bn.py -g</source>
The first image show all the GW energies along all the k-points of the Brillouin zone. A clearer picture can be obtained by plotting the band structure along the symmetry points GMKG by using the analyser:


<source lang="bash">python gw_conv_bn.py -r</source>
'''C. Plot all QP eigenvalues.''' A very typical plot when analyzing GW calculations is the plot of the GW eigenvalues versus LDA eigenvalues. You just need to indicate which band index corresponds to the
We first pack the results in a json file and subsequently we use the analyser to create the object which contains all the information.
top of the valence band.


<source lang="bash">pack_files_in_folder('gw')
n_top_vb = 4
ya = YamboAnalyser('gw')</source>
ydb.plot_scissor_ax(ax,n_top_vb)
The object <code>ya</code> contains all the results written in the output. We can plot any output variable. In yambopy we provide a function to plot the band structure along a given path. The BN band structure is shown below. The GW correction opens the LDA bandgap as expected.


[[File:GW-LDA-BN-bands.png|LDA (dashed lines) and GW (solid lines) band structures]]
[[File:Scissor-gw.png|GW results (dots) and linear fitting (solid lines) |300px]]


=== Approximations of the dielectric function (COHSEX, PPA, Real axis integration) ===
'''D. Plot exact QP-GW eigenvalues in a path.''' We can also plot the band structure of calculated points (not interpolated). Yambopy
will find which k-points belong to a given path. We can add the LDA results for comparison.


We can use yambopy to examine different run levels. For instance, the approximations used to obtain the screening are the: (i) static screening or COHSEX, plasmon-pole approximations (PPA), or real axis integration. We have set the same parameters for each run, just changing the variable name for the number of bands and the cut-off of the screening.
ks_bs_0, qp_bs_0 = ydb.get_bs_path(lat,path)
ks_bs_0.plot_ax(ax,legend=True,color_bands='r',label='KS')
qp_bs_0.plot_ax(ax,legend=True,color_bands='b',label='QP-GW')
 
[[File:Bands-LDA-GW.png|GW and LDA band structures |300px]]
 
'''E. Plot interpolated QP-GW eigenvalues in a path.''' In order to obtain results ready for publication or presentation, we can interpolate the GW calculations.
 
[[File:Bands-LDA-GW-interpolated.png| Interpolated GW and LDA band structures |300px]]
 
'''F. Comparison non-interpolated and interpolated results.''' It is convenient to check how good is the interpolation of GW results.
 
[[File:Lda-gw-comparison.png| Exact and interpolated GW and LDA band structures |300px]]
 
=== GW convergence for all k-points ===
 
If we want to perform GW convergence in all the band states, we can check the
script <code>plot-gw-conv.py</code>. Here we plot the band structure for all the k-points. For this, we pack the results in json files and then use the analyzer:
 
<source lang="bash">
pack_files_in_folder('gw_conv')
ya = YamboAnalyser('gw_conv')
</source>
 
For the case of the variable NGsBlkXs, we have set:
 
<source lang="bash">
ya.plot_gw_all_kpoints_convergence(tag='NGsBlkXs')
</source>
 
[[File:Chi-cutoff-kpoints.png||500px]]
 
=== Approximations of the dielectric function (COHSEX, PPA) ===
 
We can use yambopy to examine different run levels. For instance, the approximations used to obtain the screening are the: (i) static screening or COHSEX, (ii) plasmon-pole approximations (PPA), or (iii) real axis integration. We have set the same parameters for the first two options, just changing the variable name for the number of bands and the cut-off of the screening.
 
COHSEX
EXXRLvcs = 60 Ry
BndsRnXs = 40 bands
NGsBlkXs = 3 Ry
PPA
EXXRLvcs = 60 Ry
BndsRnXp = 40 bands
NGsBlkXp = 3 Ry


<source lang="bash">COHSEX
BndsRnXs = 24 bands
NGsBlkXs = 500 mHa
PPA
BndsRnXp = 24 bands
NGsBlkXp = 500 mHa
RA
BndsRnXd = 24 bands
NGsBlkXd = 500 mHa</source>
We have set the converged parameters and the function works by running:
We have set the converged parameters and the function works by running:


<source lang="bash">python gw_conv_bn.py -x</source>
python gw_conv_bn.py -x
 
We plot the band structure using the analyzer explained above.
We plot the band structure using the analyzer explained above.


<source lang="bash">python gw_conv_bn.py -xp</source>
python gw_conv_bn.py -xp
The PPA and the RA results are basically on top of each other. On the contrary, the COHSEX (static screening) makes a poor job, overestimating the bandgap correction.
 
[[File:GW-cohsex-ppa-ra.png|Yambo tutorial image]]


=== Solvers (Newton, Secant, Green's function) ===
We observe a difference between COHSEX and PPA.


The solvers to find the QP correction from the self-energy can also be tested. We have included the Newton and the secant method. In the resulting band structures we do not appreciate big differences. In anycase it is worthy to test during the convergence procedure.
[[File:Gw-chi-s.png|GW bands calculated with the COHSEX and PPA|300px]]


[[File:GW-newton-secant.png|Yambo tutorial image]]
You are welcome to refine the calculations using better parameters and check how this difference changes. In the next tutorial,  [[Bethe-Salpeter equation tutorial. Optical absorption (BN)]], you can use the scissor operator computed in section [[#GW_calculation_in_regular_k-grid|GW calculation in regular k-grid]].

Latest revision as of 14:19, 31 March 2022

We have selected 2D hexagonal boron nitride to explain the use of yambopy. Throughout this tutorial we show how to use yambopy to make efficient convergence tests, to compare different approximations and to analyse the results.

Initial steps with Quantum Espresso

Yambopy includes qepy, a module to handle QE-DFT calculations necessary to run Yambo.

The initial step consists of a self-consistent (scf) ground state calculation together with a non-self-consistent (nscf) calculation with QE using the gs_bn.py file:

python gs_bn.py
python gs_bn.py -sn

Here you will be using a predefined lattice parameter for the calculations. You can, however, run a geometry optimisation calculation with

python gs_bn.py -rsn

which at the end will update the input files for pw.x with the relaxed lattice parameters and atomic coordinates.

A quick note: almost all python scripts in this tutorial can be run without any options, but they will only print out the help message. In the case of gs_bn.py it will print:

python gs_bn.py 
usage: gs_bn.py [-h] [-r] [-s] [-n] [-n2] [-b] [-l] [-o] [-p] [-d] [-t NTHREADS]
Test the yambopy script.
optional arguments:
  -h, --help            show this help message and exit
  -r, --relax           Structural relaxation
  -s, --scf             Self-consistent calculation
  -n, --nscf            Non-self consistent calculation
  -n2, --nscf_double    Non-self consistent calculation for the double grid
  -b, --bands           Calculate band-structure
  -l, --plot            Plot band-structure
  -o, --orbitals        Plot atomic orbital projected band-structure
  -p, --phonon          Phonon calculation
  -d, --dispersion      Phonon dispersion
  -t NTHREADS, --nthreads NTHREADS
                       Number of threads

We have set the non-self-consistent run with a wave-function cutoff of 60 Ry, 70 bands and a k-grid of 12x12x1 for Yambo calculations.

In addition, we can check if we get a reasonable band structure for our many-body calculations. We can define a path, for instance, in an hexagonal Brillouin zone:


p = Path([ [[0.0, 0.0, 0.0],'$\Gamma$'],
           [[0.5, 0.0, 0.0],'M'],
           [[1./3,1./3,0.0],'K'],
           [[0.0, 0.0, 0.0],'$\Gamma$']], [int(10*2),int(10),int(sqrt(5)*10)])


We obtain the band structure by doing:

python gs_bn.py -b

BN Band Structure

The horizontal line marks the top of the valence band. The electronic bandgap has a value of 4.73 eV. In the next sections, we will show how to calculate the GW correction and the excitonic effects with BSE using Yambo in an automatic way.

GW convergence of the bandgap

(a) Calculations

We converge the main parameters of a GW calculation independently. In addition, we make use of the plasmon pole approximation for the dielectric function, and the Newton solver to find the GW correction to the LDA eigenvalues. We converge the band gap of BN (difference in energy of the bottom of the conduction and top of the valence band at the K point of the Brillouin zone). We have designed the script gw_conv_bn.py (folder ~/tutorial/bn) for this purpose.

We can select the GW calculation by calling the YamboIn with the corresponding arguments:

python gw_conv_gw.py -c 
y = YamboIn.from_runlevel('yambo -d -p p -g n -V all',folder='gw_conv')

The main variables of a GW calculation are:

EXXRLvcs: Exchange self-energy cutoff

NGsBlkXp: Cutoff of the dielectric function.

BndsRnXp: Number of bands in the calculation of the dielectric function (PPA).

GbndRnge: Self-energy. The number of bands.

We define a dictionary with all the parameters that we want to converge. Be aware of setting the right units and format for each parameter.

conv = { 'EXXRLvcs': [[10,10,20,30,40,50,60,70,80,90,100],'Ry'],
        'NGsBlkXp': [[0,0,1,2,3,4,5,6], 'Ry'],
        'BndsRnXp': [[[1,10],[1,10],[1,20],[1,30],[1,40],[1,50],[1,60],[1,70]],] ,
        'GbndRnge': [[[1,10],[1,10],[1,20],[1,30],[1,40],[1,50],[1,60],[1,70]],] }

The class YamboIn includes the function optimize, which is called here:

y.optimize(conv,folder='gw_conv',run=run,ref_run=False)

The function optimize has two main arguments: the convergence dictionary, and a function run with the instructions to run the calculation, defined in our case like:

   def run(filename):
       """ Function to be called by the optimize function """
       folder = filename.split('.')[0]
       print(filename,folder)
       shell = bash() 
       shell.add_command('cd gw_conv')
       shell.add_command('rm -f *.json %s/o-*'%folder) #cleanup
       shell.add_command('%s -F %s -J %s -C %s 2> %s.log'%(yambo,filename,folder,folder,folder))
       shell.run()
       shell.clean()

We have defined interactive run, in the folder gw_conv. We have also defined the name for each job, associated with the variable and its value.

(b) Analysis

Once all the calculations are finished it's time to analyse them. At this point yambopy will facilitate the analysis. Besides the python module, yambopy can also be called in the terminal to perform some post-analysis tasks:

    $ yambopy
    analysebse ->     Using ypp, you can study the convergence of BSE calculations in 2 ways:
      plotem1s ->     Plot em1s calculation
     analysegw ->     Study the convergence of GW calculations by looking at the change in bandgap value.
       mergeqp ->     Merge QP databases
          test ->     Run yambopy tests
  plotexcitons ->     Plot excitons calculation

Calling yambopy analysegw will display the help of the function:


   Study the convergence of GW calculations by looking at the change in bandgap value.

   The script reads from <folder> all results from <variable> calculations and display them. 

   Use the band and k-point options according to the size of your k-grid
   and the location of the band extrema.
 
       Mandatory arguments are:
           folder   -> Folder containing SAVE and convergence runs.
           var      -> Variable tested (e.g. FFTGvecs)

       Optional variables are:
           -bc, --bandc   (int)  -> Lowest conduction band number
           -kc, --kpointc (int)  -> k-point index for conduction band
           -bv, --bandv   (int)  -> Highest valence band number
           -kv, --kpointv (int)  -> k-point index for valence band
           -np, --nopack  (flag) -> Do not call 'pack_files_in_folder'
           -nt, --notext  (flag) -> Do not print a text file
           -nd, --nodraw  (flag) -> Do not draw (plot) the result


Running the function selecting the bands and k-points, together with the parameter of convergence we will obtain the convergence plot.

yambopy analysegw -bc 5 -kc 7 -bv 4 -kv 7 gw_conv EXXRLvcs 
yambopy analysegw -bc 5 -kc 7 -bv 4 -kv 7 gw_conv NGsBlkXp
yambopy analysegw -bc 5 -kc 7 -bv 4 -kv 7 gw_conv BndsRnXp
yambopy analysegw -bc 5 -kc 7 -bv 4 -kv 7 gw_conv GbndRnge

From the convergence plots, we can choose the set of converged parameters and repeat the calculation for finer k-grids until we reach convergence with the k-points. We have intentionally used non-converged parameters. Nevertheless, along this week you should have gotten enough expertise to push the convergence of the parameters and determine the correct convergence set of parameters. We invite you to enter in the python script, increase the parameters and check again the convergence for larger values!


FFTGvecs

NGsBlkXp

BndsRnXp

GbndRnge

In general, the convergence with the k-grid is done after these variables are converged and, in principle, it is also independent of them. We invite you to change the number of k-points in the file gs_bn.py using the variable kpoints_nscf.

GW calculation in regular k-grid

From the bandgap convergence study made above for a k-grid we can decide reasonable parameters. Another option is to decide a convergence threshold to establish the accuracy of the convergence. In this tutorial, in order to make calculations lighter, we have chosen the following parameters:

EXXRLvcs = 60 Ry
BndsRnXp = 40 bands
NGsBlkXp =  3  Ry
GbndRnge = 30 bands
QPkrange = [1,19,2,6]

We can change the gs_bn.py scripts to calculate a non self-consistent run for a larger k-grid (12x12x1 will do the job). We can also change the number of bands to 40 in order to speed up a bit the QE calculation.

We can just simply run the code to calculate the GW corrections for all the points of the Brillouin zone by setting the converged parameters in the script gw_bn.py. If we enter in the script we can check that we define a scheduler (the default is bash):

scheduler = Scheduler.factory

We just need to define the run level and the variables we are going to change:

y = YamboIn.from_runlevel('%s -p p -g n -V all'%yambo,folder='gw')
    
y['EXXRLvcs'] = [60,'Ry']       # Self-energy. Exchange
y['BndsRnXp'] = [1,40]          # Screening. Number of bands
y['NGsBlkXp'] = [3,'Ry']        # Cutoff Screening
y['GbndRnge'] = [1,30]          # Self-energy. Number of bands
y['QPkrange'] = [kpoint_start,kpoint_end,2,6]


We can now run the script and obtain the GW in the full k-grid.

python gw_bn.py

If everything has worked fine now we will have inside the folder gw/yambo the netCDF file ndb.QP with the results of the GW calculation. We can analyze the results and/or use them in BSE calculations.

Plotting GW calculations. Scissor operator and GW band structure

If everything has worked fine now we can start using the yambopy analysis tools. For this purpose, we have created the script plot-qp.py. Using this script we will be able to read the Yambo databases and plot the results. Notice that we use matplotlib to make the plots. For all the plots we define a figure and axis by doing:

fig = plt.figure(figsize=(6,4))
ax  = fig.add_axes( [ 0.20, 0.20, 0.70, 0.70 ])

The file is structured as follows:

A. Define a path. Using qepy we can define a path to plot the band structure.

npoints = 10
path = Path([ [[  0.0,  0.0,  0.0],'$\Gamma$'],
              [[  0.5,  0.0,  0.0],'M'],
              [[1./3.,1./3.,  0.0],'K'],
              [[  0.0,  0.0,  0.0],'$\Gamma$']], [int(npoints*2),int(npoints),int(sqrt(5)*npoints)] )

B. Read Yambo lattice and QP databases.

lat  = YamboSaveDB.from_db_file(folder='gw/SAVE',filename='ns.db1')
ydb  = YamboQPDB.from_db(filename='ndb.QP',folder='gw/yambo')


C. Plot all QP eigenvalues. A very typical plot when analyzing GW calculations is the plot of the GW eigenvalues versus LDA eigenvalues. You just need to indicate which band index corresponds to the top of the valence band.

n_top_vb = 4
ydb.plot_scissor_ax(ax,n_top_vb)

GW results (dots) and linear fitting (solid lines)

D. Plot exact QP-GW eigenvalues in a path. We can also plot the band structure of calculated points (not interpolated). Yambopy will find which k-points belong to a given path. We can add the LDA results for comparison.

ks_bs_0, qp_bs_0 = ydb.get_bs_path(lat,path)
ks_bs_0.plot_ax(ax,legend=True,color_bands='r',label='KS')
qp_bs_0.plot_ax(ax,legend=True,color_bands='b',label='QP-GW')

GW and LDA band structures

E. Plot interpolated QP-GW eigenvalues in a path. In order to obtain results ready for publication or presentation, we can interpolate the GW calculations.

Interpolated GW and LDA band structures

F. Comparison non-interpolated and interpolated results. It is convenient to check how good is the interpolation of GW results.

Exact and interpolated GW and LDA band structures

GW convergence for all k-points

If we want to perform GW convergence in all the band states, we can check the script plot-gw-conv.py. Here we plot the band structure for all the k-points. For this, we pack the results in json files and then use the analyzer:

<source lang="bash"> pack_files_in_folder('gw_conv') ya = YamboAnalyser('gw_conv') </source>

For the case of the variable NGsBlkXs, we have set:

<source lang="bash"> ya.plot_gw_all_kpoints_convergence(tag='NGsBlkXs') </source>

Chi-cutoff-kpoints.png

Approximations of the dielectric function (COHSEX, PPA)

We can use yambopy to examine different run levels. For instance, the approximations used to obtain the screening are the: (i) static screening or COHSEX, (ii) plasmon-pole approximations (PPA), or (iii) real axis integration. We have set the same parameters for the first two options, just changing the variable name for the number of bands and the cut-off of the screening.

COHSEX
EXXRLvcs = 60 Ry 
BndsRnXs = 40 bands
NGsBlkXs = 3 Ry

PPA
EXXRLvcs = 60 Ry 
BndsRnXp = 40 bands
NGsBlkXp = 3 Ry

We have set the converged parameters and the function works by running:

python gw_conv_bn.py -x

We plot the band structure using the analyzer explained above.

python gw_conv_bn.py -xp

We observe a difference between COHSEX and PPA.

GW bands calculated with the COHSEX and PPA

You are welcome to refine the calculations using better parameters and check how this difference changes. In the next tutorial, Bethe-Salpeter equation tutorial. Optical absorption (BN), you can use the scissor operator computed in section GW calculation in regular k-grid.