{ "cells": [ { "cell_type": "markdown", "id": "1ae9ce3c", "metadata": {}, "source": [ "# Phonons and Born effective charges\n", "\n", "This lesson discusses how to compute phonon band structures, DOS\n", "and Born effective charges with Abinit and AbiPy.\n", "The discussion closely follows the [second lesson](https://docs.abinit.org/tutorial/rf2/index.html)\n", "on DFPT available on the Abinit web site.\n", "More specifically, we will discuss how to\n", "\n", " * Perform a convergence study for the phonon frequencies at $\\Gamma$ as function of `ecut`\n", " * Compute the full phonon band structure of `AlAs` with the inclusion of LO-TO splitting\n", " * Obtain thermodynamic properties within the harmonic approximation\n", "\n", "We assume that you have read the references mentioned in the\n", "[first Abinit lesson](https://docs.abinit.org/tutorial/rf1/index.html) on DFPT.\n", "You might find additional material, related to the present section, in the following references:\n", "\n", "* [Dynamical matrices, Born effective charges, dielectric permittivity tensors, and interatomic force constants from density-functional perturbation theory](https://journals.aps.org/prb/abstract/10.1103/PhysRevB.55.10355)\n", "* [Phonons and related crystal properties from density-functional perturbation theory](https://journals.aps.org/rmp/abstract/10.1103/RevModPhys.73.515)\n", "\n", "If you are already familiar with python and AbiPy-Abinit are already installed and configured,\n", "you may want to use directly the command line interface.\n", "See the README.md file in the directory of this lesson explaining how to analyze the data from the shell\n", "using ipython and matplotlib.\n", "\n", "```{include} ../snippets/plotly_matplotlib_note.md\n", "```\n", "\n", "## Phonon frequencies at $\\Gamma$ as function of ecut\n", "\n", "Before starting, we need to import the python modules and the functions we will need in the notebook:" ] }, { "cell_type": "code", "execution_count": 1, "id": "76d1d536", "metadata": {}, "outputs": [], "source": [ "import numpy as np\n", "import warnings\n", "\n", "warnings.filterwarnings(\"ignore\") # to get rid of deprecation warnings\n", "\n", "from abipy import abilab\n", "abilab.enable_notebook() # This line tells AbiPy we are running inside a notebook\n", "import abipy.flowtk as flowtk\n", "\n", "# This line configures matplotlib to show figures embedded in the notebook.\n", "# Replace `inline` with `notebook` in classic notebook\n", "%matplotlib inline\n", "\n", "# Option available in jupyterlab. See https://github.com/matplotlib/jupyter-matplotlib\n", "#%matplotlib widget" ] }, { "cell_type": "markdown", "id": "3ee52c8a", "metadata": {}, "source": [ "and an useful function from the `lesson_dfpt` module that will be used to generate our DFPT flows:" ] }, { "cell_type": "code", "execution_count": 2, "id": "48882f10", "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n", "\n", "
\n", "def make_scf_input(ecut=2, ngkpt=(4, 4, 4)):\n",
" """\n",
" This function constructs an `AbinitInput` to perform a GS-SCF calculation in crystalline AlAs.\n",
"\n",
" Args:\n",
" ecut: cutoff energy in Ha.\n",
" ngkpt: 3 integers specifying the k-mesh for the electrons.\n",
"\n",
" Return:\n",
" `AbinitInput` object\n",
" """\n",
" # Initialize the AlAs structure from an internal database. Use the pseudos shipped with AbiPy.\n",
" gs_inp = abilab.AbinitInput(structure=abidata.structure_from_ucell("AlAs"),\n",
" pseudos=abidata.pseudos("13al.981214.fhi", "33as.pspnc"))\n",
"\n",
" # Set the value of the Abinit variables needed for GS runs.\n",
" gs_inp.set_vars(\n",
" nband=4,\n",
" ecut=ecut,\n",
" ngkpt=ngkpt,\n",
" nshiftk=4,\n",
" shiftk=[0.0, 0.0, 0.5, # This gives the usual fcc Monkhorst-Pack grid\n",
" 0.0, 0.5, 0.0,\n",
" 0.5, 0.0, 0.0,\n",
" 0.5, 0.5, 0.5],\n",
" ixc=1,\n",
" nstep=25,\n",
" diemac=9.0,\n",
" tolvrs=1.0e-10,\n",
" #iomode=3,\n",
" )\n",
"\n",
" return gs_inp\n",
"
def build_flow_alas_ecut_conv(options):\n",
" """\n",
" Build and return Flow for convergence study of phonon frequencies at Gamma as function of ecut.\n",
" """\n",
" scf_input = make_scf_input()\n",
" return flowtk.phonon_conv_flow("flow_alas_ecut_conv", scf_input, qpoints=(0, 0, 0),\n",
" params=["ecut", [4, 6, 8]])\n",
"
\n", " | ecut | \n", "class | \n", "
---|---|---|
w0_t0 | \n", "4 | \n", "ScfTask | \n", "
w1_t0 | \n", "4 | \n", "PhononTask | \n", "
w1_t1 | \n", "4 | \n", "PhononTask | \n", "
w2_t0 | \n", "6 | \n", "ScfTask | \n", "
w3_t0 | \n", "6 | \n", "PhononTask | \n", "
w3_t1 | \n", "6 | \n", "PhononTask | \n", "
w4_t0 | \n", "8 | \n", "ScfTask | \n", "
w5_t0 | \n", "8 | \n", "PhononTask | \n", "
w5_t1 | \n", "8 | \n", "PhononTask | \n", "
\n", " | rfphon | \n", "rfatpol | \n", "rfdir | \n", "qpt | \n", "kptopt | \n", "class | \n", "
---|---|---|---|---|---|---|
w0_t0 | \n", "None | \n", "None | \n", "None | \n", "None | \n", "None | \n", "ScfTask | \n", "
w1_t0 | \n", "1 | \n", "[1, 1] | \n", "[1, 0, 0] | \n", "[0.0, 0.0, 0.0] | \n", "2 | \n", "PhononTask | \n", "
w1_t1 | \n", "1 | \n", "[2, 2] | \n", "[1, 0, 0] | \n", "[0.0, 0.0, 0.0] | \n", "2 | \n", "PhononTask | \n", "
w2_t0 | \n", "None | \n", "None | \n", "None | \n", "None | \n", "None | \n", "ScfTask | \n", "
w3_t0 | \n", "1 | \n", "[1, 1] | \n", "[1, 0, 0] | \n", "[0.0, 0.0, 0.0] | \n", "2 | \n", "PhononTask | \n", "
w3_t1 | \n", "1 | \n", "[2, 2] | \n", "[1, 0, 0] | \n", "[0.0, 0.0, 0.0] | \n", "2 | \n", "PhononTask | \n", "
w4_t0 | \n", "None | \n", "None | \n", "None | \n", "None | \n", "None | \n", "ScfTask | \n", "
w5_t0 | \n", "1 | \n", "[1, 1] | \n", "[1, 0, 0] | \n", "[0.0, 0.0, 0.0] | \n", "2 | \n", "PhononTask | \n", "
w5_t1 | \n", "1 | \n", "[2, 2] | \n", "[1, 0, 0] | \n", "[0.0, 0.0, 0.0] | \n", "2 | \n", "PhononTask | \n", "
\n", " | ecut | \n", "mode0 | \n", "mode1 | \n", "mode2 | \n", "mode3 | \n", "mode4 | \n", "mode5 | \n", "
---|---|---|---|---|---|---|---|
flow_alas_ecut_conv/w1/outdata/out_DDB | \n", "4.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "0.043641 | \n", "0.043641 | \n", "0.043641 | \n", "
flow_alas_ecut_conv/w3/outdata/out_DDB | \n", "6.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "0.044485 | \n", "0.044485 | \n", "0.044485 | \n", "
flow_alas_ecut_conv/w5/outdata/out_DDB | \n", "8.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "0.044625 | \n", "0.044625 | \n", "0.044625 | \n", "
\n", " | ecut | \n", "mode0 | \n", "mode1 | \n", "mode2 | \n", "mode3 | \n", "mode4 | \n", "mode5 | \n", "
---|---|---|---|---|---|---|---|
count | \n", "3.0 | \n", "3.0 | \n", "3.0 | \n", "3.0 | \n", "3.000000 | \n", "3.000000 | \n", "3.000000 | \n", "
mean | \n", "6.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "0.044250 | \n", "0.044250 | \n", "0.044250 | \n", "
std | \n", "2.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "0.000533 | \n", "0.000533 | \n", "0.000533 | \n", "
min | \n", "4.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "0.043641 | \n", "0.043641 | \n", "0.043641 | \n", "
25% | \n", "5.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "0.044063 | \n", "0.044063 | \n", "0.044063 | \n", "
50% | \n", "6.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "0.044485 | \n", "0.044485 | \n", "0.044485 | \n", "
75% | \n", "7.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "0.044555 | \n", "0.044555 | \n", "0.044555 | \n", "
max | \n", "8.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "0.044625 | \n", "0.044625 | \n", "0.044625 | \n", "
def build_flow_alas_phonons(options):\n",
" """\n",
" Build and return a Flow to compute the dynamical matrix on a (2, 2, 2) qmesh\n",
" as well as DDK and Born effective charges.\n",
" The final DDB with all perturbations will be merged automatically and placed\n",
" in the Flow `outdir` directory.\n",
" """\n",
" scf_input = make_scf_input(ecut=6, ngkpt=(4, 4, 4))\n",
" return flowtk.PhononFlow.from_scf_input("flow_alas_phonons", scf_input,\n",
" ph_ngqpt=(2, 2, 2), with_becs=True)\n",
"
\n", " | rfphon | \n", "rfatpol | \n", "rfdir | \n", "qpt | \n", "kptopt | \n", "class | \n", "
---|---|---|---|---|---|---|
w0_t0 | \n", "None | \n", "None | \n", "None | \n", "None | \n", "None | \n", "ScfTask | \n", "
w1_t0 | \n", "None | \n", "None | \n", "(1, 0, 0) | \n", "(0, 0, 0) | \n", "2 | \n", "DdkTask | \n", "
w1_t1 | \n", "None | \n", "None | \n", "(0, 1, 0) | \n", "(0, 0, 0) | \n", "2 | \n", "DdkTask | \n", "
w1_t2 | \n", "None | \n", "None | \n", "(0, 0, 1) | \n", "(0, 0, 0) | \n", "2 | \n", "DdkTask | \n", "
w1_t3 | \n", "1 | \n", "[1, 1] | \n", "[1, 0, 0] | \n", "(0, 0, 0) | \n", "2 | \n", "BecTask | \n", "
w1_t4 | \n", "1 | \n", "[2, 2] | \n", "[1, 0, 0] | \n", "(0, 0, 0) | \n", "2 | \n", "BecTask | \n", "
w1_t5 | \n", "1 | \n", "[1, 1] | \n", "[1, 0, 0] | \n", "[0.5, 0.0, 0.0] | \n", "3 | \n", "PhononTask | \n", "
w1_t6 | \n", "1 | \n", "[1, 1] | \n", "[0, 1, 0] | \n", "[0.5, 0.0, 0.0] | \n", "3 | \n", "PhononTask | \n", "
w1_t7 | \n", "1 | \n", "[2, 2] | \n", "[1, 0, 0] | \n", "[0.5, 0.0, 0.0] | \n", "3 | \n", "PhononTask | \n", "
w1_t8 | \n", "1 | \n", "[2, 2] | \n", "[0, 1, 0] | \n", "[0.5, 0.0, 0.0] | \n", "3 | \n", "PhononTask | \n", "
w1_t9 | \n", "1 | \n", "[1, 1] | \n", "[1, 0, 0] | \n", "[0.5, 0.5, 0.0] | \n", "3 | \n", "PhononTask | \n", "
w1_t10 | \n", "1 | \n", "[2, 2] | \n", "[1, 0, 0] | \n", "[0.5, 0.5, 0.0] | \n", "3 | \n", "PhononTask | \n", "
\n", " | x | \n", "y | \n", "z | \n", "
---|---|---|---|
x | \n", "10.396165 | \n", "0.000000 | \n", "0.000000 | \n", "
y | \n", "0.000000 | \n", "10.396165 | \n", "0.000000 | \n", "
z | \n", "0.000000 | \n", "0.000000 | \n", "10.396165 | \n", "
\n", " | element | \n", "site_index | \n", "frac_coords | \n", "cart_coords | \n", "wyckoff | \n", "xx | \n", "yy | \n", "zz | \n", "yz | \n", "xz | \n", "xy | \n", "
---|---|---|---|---|---|---|---|---|---|---|---|
0 | \n", "Al | \n", "0 | \n", "[0.0, 0.0, 0.0] | \n", "[0.0, 0.0, 0.0] | \n", "1a | \n", "2.168053 | \n", "2.168053 | \n", "2.168053 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "
1 | \n", "As | \n", "1 | \n", "[0.25, 0.25, 0.25] | \n", "[1.40364, 1.40364, 1.40364] | \n", "1d | \n", "-2.168053 | \n", "-2.168053 | \n", "-2.168053 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "