{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "Back to the main [Index](../index.ipynb) " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
Carbon in diamond structure
\n", "\n", "In this lesson, we discuss how to compute the electron-phonon (e-ph) self-energy and the renormalization of the electronic states due to the e-ph interaction. We start with a very brief discussion of the basic equations and some technical details about the Abinit implementation of the EPH code. \n", "Then we show how to build an AbiPy flow to automate the multiple steps required by this calculation.\n", "
\n", "\n", "In the second part, we use the AbiPy objects to analyze the results. We start from the simplest case of a single EPH calculation whose most important results are stored in the SIGEPH.nc file. Then we show how to use SigEPhRobot to handle multiple netcdf files and perform convergence studies. \n", "Finally, we present a possible approach to interpolate the QP corrections to obtain temperature-dependent band structures along an arbitrary high-symmetry k-path.\n", "
\n", "def build_flow(options):\n",
" """\n",
" C in diamond structure. Very rough q-point mesh, low ecut, completely unconverged.\n",
" The flow computes the ground state density and a WFK file on a 8x8x8 k-mesh including\n",
" empty states needed for the self-energy. Then all the independent atomic perturbations\n",
" for the irreducible qpoints in a 4x4x4 grid are obtained with DFPT.\n",
" Finally, we enter the EPH driver to compute the EPH self-energy.\n",
" """\n",
" workdir = options.workdir if (options and options.workdir) else "flow_diamond"\n",
"\n",
" # Define structure explicitly.\n",
" structure = abilab.Structure.from_abivars(\n",
" acell=3*[6.70346805],\n",
" rprim=[0.0, 0.5, 0.5,\n",
" 0.5, 0.0, 0.5,\n",
" 0.5, 0.5, 0.0],\n",
" typat=[1, 1],\n",
" xred=[0.0, 0.0, 0.0, 0.25, 0.25, 0.25],\n",
" ntypat=1,\n",
" znucl=6,\n",
" )\n",
"\n",
" # Initialize input from structure and norm-conserving pseudo provided by AbiPy.\n",
" gs_inp = abilab.AbinitInput(structure, pseudos="6c.pspnc")\n",
"\n",
" # Set basic variables for GS part.\n",
" gs_inp.set_vars(\n",
" ecut=25.0, # Too low, shout be ~30\n",
" nband=4,\n",
" tolvrs=1e-8,\n",
" )\n",
"\n",
" # The kpoint grid is minimalistic to keep the calculation manageable.\n",
" # The q-mesh for phonons must be a submesh of this one.\n",
" gs_inp.set_kmesh(\n",
" ngkpt=[8, 8, 8],\n",
" shiftk=[0.0, 0.0, 0.0],\n",
" )\n",
"\n",
" # Build new input for NSCF calculation with k-path (automatically selected by AbiPy)\n",
" # Used to plot the KS band structure and interpolate the QP corrections.\n",
" nscf_kpath_inp = gs_inp.new_with_vars(\n",
" nband=8,\n",
" tolwfr=1e-16,\n",
" iscf=-2,\n",
" )\n",
" nscf_kpath_inp.set_kpath(ndivsm=10)\n",
"\n",
" # Build another NSCF input with k-mesh and empty states.\n",
" # This step generates the WFK file used to build the EPH self-energy.\n",
" nscf_empty_kmesh_inp = gs_inp.new_with_vars(\n",
" nband=210, # Too low. ~300\n",
" nbdbuf=10, # Reduces considerably the time needed to converge empty states!\n",
" tolwfr=1e-16,\n",
" iscf=-2,\n",
" )\n",
"\n",
" # Create empty flow.\n",
" flow = flowtk.Flow(workdir=workdir)\n",
"\n",
" # Register GS + band structure parts in the first work\n",
" work0 = flowtk.BandStructureWork(gs_inp, nscf_kpath_inp, dos_inputs=[nscf_empty_kmesh_inp])\n",
" flow.register_work(work0)\n",
"\n",
" # Generate Phonon work with 4x4x4 q-mesh\n",
" # Reuse variables from GS input and let AbiPy handle the generation of the input files\n",
" # Note that the q-point grid is a sub-grid of the k-point grid (here 8x8x8)\n",
" ddb_ngqpt = [4, 4, 4]\n",
" ph_work = flowtk.PhononWork.from_scf_task(work0[0], ddb_ngqpt, is_ngqpt=True,\n",
" tolerance={"tolvrs": 1e-6}) # This to speedup DFPT\n",
" flow.register_work(ph_work)\n",
"\n",
" # Build template for self-energy calculation. See also v8/Input/t44.in\n",
" # The k-points must be in the WFK file\n",
" #\n",
" eph_inp = gs_inp.new_with_vars(\n",
" optdriver=7, # Enter EPH driver.\n",
" eph_task=4, # Activate computation of EPH self-energy.\n",
" ddb_ngqpt=ddb_ngqpt, # q-mesh used to produce the DDB file (must be consistent with DDB data)\n",
" nkptgw=1,\n",
" kptgw=[0, 0, 0],\n",
" bdgw=[1, 8],\n",
" # For more k-points...\n",
" #nkptgw=2,\n",
" #kptgw=[0, 0, 0, 0.5, 0, 0],\n",
" #bdgw=[1, 8, 1, 8],\n",
" tmesh=[0, 200, 5], # (start, step, num)\n",
" zcut="0.2 eV", # Too large. needed to get reasonable results due to coarse q-mesh.\n",
" nfreqsp=301, # Compute A(w)\n",
" )\n",
"\n",
" # Set q-path for Fourier interpolation of phonons.\n",
" eph_inp.set_qpath(10)\n",
"\n",
" # Set q-mesh for phonons DOS.\n",
" eph_inp.set_phdos_qmesh(nqsmall=16, method="tetra")\n",
"\n",
" # EPH part requires the GS WFK, the DDB file with all perturbations\n",
" # and the database of DFPT potentials (already merged by PhononWork)\n",
" deps = {work0[2]: "WFK", ph_work: ["DDB", "DVDB"]}\n",
"\n",
" # Now we use the EPH template to perform a convergence study in which\n",
" # we change the q-mesh used to integrate the self-energy and the number of bands.\n",
" # The code will activate the Fourier interpolation of the DFPT potentials if eph_ngqpt_fine != ddb_ngqpt\n",
"\n",
" for eph_ngqpt_fine in [[4, 4, 4], [8, 8, 8]]:\n",
" # Create empty work to contain EPH tasks with this value of eph_ngqpt_fine\n",
" eph_work = flow.register_work(flowtk.Work())\n",
" for nband in [100, 150, 200]:\n",
" new_inp = eph_inp.new_with_vars(eph_ngqpt_fine=eph_ngqpt_fine, nband=nband)\n",
" eph_work.register_eph_task(new_inp, deps=deps)\n",
"\n",
" flow.allocate()\n",
"\n",
" return flow\n",
"
\n", " | nband | \n", "eph_ngqpt_fine | \n", "class | \n", "
---|---|---|---|
w3_t0 | \n", "100 | \n", "[8, 8, 8] | \n", "EphTask | \n", "
w3_t1 | \n", "150 | \n", "[8, 8, 8] | \n", "EphTask | \n", "
w3_t2 | \n", "200 | \n", "[8, 8, 8] | \n", "EphTask | \n", "
\n", " | nband | \n", "eph_ngqpt_fine | \n", "class | \n", "
---|---|---|---|
w2_t0 | \n", "100 | \n", "[4, 4, 4] | \n", "EphTask | \n", "
w2_t1 | \n", "150 | \n", "[4, 4, 4] | \n", "EphTask | \n", "
w2_t2 | \n", "200 | \n", "[4, 4, 4] | \n", "EphTask | \n", "
\n", " | band | \n", "e0 | \n", "re_qpe | \n", "qpeme0 | \n", "re_sig0 | \n", "imag_sig0 | \n", "ze0 | \n", "re_fan0 | \n", "dw | \n", "tmesh | \n", "
---|---|---|---|---|---|---|---|---|---|---|
0 | \n", "0 | \n", "-8.796107 | \n", "-8.857742 | \n", "-0.061635 | \n", "-0.062745 | \n", "0.0 | \n", "0.982315 | \n", "-0.121061 | \n", "0.058316 | \n", "0.0 | \n", "
0 | \n", "1 | \n", "12.743474 | \n", "12.866324 | \n", "0.122850 | \n", "0.131324 | \n", "0.0 | \n", "0.935473 | \n", "-0.936921 | \n", "1.068245 | \n", "0.0 | \n", "
0 | \n", "2 | \n", "12.743474 | \n", "12.866324 | \n", "0.122850 | \n", "0.131324 | \n", "0.0 | \n", "0.935473 | \n", "-0.936921 | \n", "1.068245 | \n", "0.0 | \n", "
0 | \n", "3 | \n", "12.743474 | \n", "12.866324 | \n", "0.122850 | \n", "0.131324 | \n", "0.0 | \n", "0.935473 | \n", "-0.936921 | \n", "1.068245 | \n", "0.0 | \n", "
0 | \n", "4 | \n", "18.360583 | \n", "18.188235 | \n", "-0.172348 | \n", "-0.222156 | \n", "0.0 | \n", "0.775797 | \n", "-1.166413 | \n", "0.944257 | \n", "0.0 | \n", "
0 | \n", "5 | \n", "18.360583 | \n", "18.188235 | \n", "-0.172348 | \n", "-0.222156 | \n", "0.0 | \n", "0.775797 | \n", "-1.166413 | \n", "0.944257 | \n", "0.0 | \n", "
0 | \n", "6 | \n", "18.360583 | \n", "18.188235 | \n", "-0.172348 | \n", "-0.222156 | \n", "0.0 | \n", "0.775797 | \n", "-1.166413 | \n", "0.944257 | \n", "0.0 | \n", "
0 | \n", "7 | \n", "26.672500 | \n", "26.675328 | \n", "0.002828 | \n", "0.004461 | \n", "0.0 | \n", "0.633845 | \n", "-0.080522 | \n", "0.084983 | \n", "0.0 | \n", "
\n", " | nbsum | \n", "zcut | \n", "symsigma | \n", "nqbz | \n", "nqibz | \n", "ddb_nqbz | \n", "eph_nqbz_fine | \n", "ph_nqbz | \n", "eph_intmeth | \n", "eph_fsewin | \n", "eph_fsmear | \n", "eph_extrael | \n", "eph_fermie | \n", "
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
nbsum: 200 | \n", "200 | \n", "0.007349865079592465 | \n", "1 | \n", "64 | \n", "8 | \n", "64 | \n", "64 | \n", "4096 | \n", "1 | \n", "0.04 | \n", "0.01 | \n", "0.0 | \n", "0.0 | \n", "
nbsum: 150 | \n", "150 | \n", "0.007349865079592465 | \n", "1 | \n", "64 | \n", "8 | \n", "64 | \n", "64 | \n", "4096 | \n", "1 | \n", "0.04 | \n", "0.01 | \n", "0.0 | \n", "0.0 | \n", "
nbsum: 100 | \n", "100 | \n", "0.007349865079592465 | \n", "1 | \n", "64 | \n", "8 | \n", "64 | \n", "64 | \n", "4096 | \n", "1 | \n", "0.04 | \n", "0.01 | \n", "0.0 | \n", "0.0 | \n", "
\n", " | nbsum | \n", "zcut | \n", "symsigma | \n", "nqbz | \n", "nqibz | \n", "ddb_nqbz | \n", "eph_nqbz_fine | \n", "ph_nqbz | \n", "eph_intmeth | \n", "eph_fsewin | \n", "eph_fsmear | \n", "eph_extrael | \n", "eph_fermie | \n", "
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
nbsum: 200, nqibz: 29 | \n", "200 | \n", "0.007349865079592465 | \n", "1 | \n", "512 | \n", "29 | \n", "64 | \n", "512 | \n", "4096 | \n", "1 | \n", "0.04 | \n", "0.01 | \n", "0.0 | \n", "0.0 | \n", "
nbsum: 150, nqibz: 29 | \n", "150 | \n", "0.007349865079592465 | \n", "1 | \n", "512 | \n", "29 | \n", "64 | \n", "512 | \n", "4096 | \n", "1 | \n", "0.04 | \n", "0.01 | \n", "0.0 | \n", "0.0 | \n", "
nbsum: 100, nqibz: 29 | \n", "100 | \n", "0.007349865079592465 | \n", "1 | \n", "512 | \n", "29 | \n", "64 | \n", "512 | \n", "4096 | \n", "1 | \n", "0.04 | \n", "0.01 | \n", "0.0 | \n", "0.0 | \n", "
nbsum: 200, nqibz: 8 | \n", "200 | \n", "0.007349865079592465 | \n", "1 | \n", "64 | \n", "8 | \n", "64 | \n", "64 | \n", "4096 | \n", "1 | \n", "0.04 | \n", "0.01 | \n", "0.0 | \n", "0.0 | \n", "
nbsum: 150, nqibz: 8 | \n", "150 | \n", "0.007349865079592465 | \n", "1 | \n", "64 | \n", "8 | \n", "64 | \n", "64 | \n", "4096 | \n", "1 | \n", "0.04 | \n", "0.01 | \n", "0.0 | \n", "0.0 | \n", "
nbsum: 100, nqibz: 8 | \n", "100 | \n", "0.007349865079592465 | \n", "1 | \n", "64 | \n", "8 | \n", "64 | \n", "64 | \n", "4096 | \n", "1 | \n", "0.04 | \n", "0.01 | \n", "0.0 | \n", "0.0 | \n", "