{ "cells": [ { "cell_type": "markdown", "id": "76be1310", "metadata": {}, "source": [ "# 1.1.3 Post-processing Qbox Outputs to compute dynamical matrix.\n", "Here we would learn how to post-process the qbox outputs after all the jobs regarding the displaced coordinates have finished. Here the qbox output files are fd-1.r and fd-2.r.\n", "\n", "For that purpose we need to import the following objects from pyepfd." ] }, { "cell_type": "code", "execution_count": 1, "id": "9452fb5a", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " \n", " ███████████ \n", " ░░███░░░░░███ \n", " ░███ ░███ █████ ████ \n", " ░██████████ ░░███ ░███ \n", " ░███░░░░░░ ░███ ░███ \n", " ░███ ░███ ░███ \n", " █████ ░░███████ \n", " ░░░░░ ░░░░░███ \n", " ███ ░███ \n", " ░░██████ \n", " ░░░░░░ \n", " ██████████ ███████████ ███████████ ██████████ \n", "░░███░░░░░█░░███░░░░░███░░███░░░░░░█░░███░░░░███ \n", " ░███ █ ░ ░███ ░███ ░███ █ ░ ░███ ░░███\n", " ░██████ ░██████████ ░███████ ░███ ░███\n", " ░███░░█ ░███░░░░░░ ░███░░░█ ░███ ░███\n", " ░███ ░ █ ░███ ░███ ░ ░███ ███ \n", " ██████████ █████ █████ ██████████ \n", "░░░░░░░░░░ ░░░░░ ░░░░░ ░░░░░░░░░░ \n", "PyEPFD version : 1.1\n", "Author : Arpan Kundu\n", "Author Email : arpan.kundu@gmail.com\n", "Today : 2024-12-18 17:11:40.952385\n", "*************************************************\n", " CITATIONS \n", "=================================================\n", "Please cite the following 3 references: \n", "(1) A. Kundu et al, Phys. Rev. Mater (2021), 5, \n", "L070801, \n", "(2) A. Kundu and G Galli, \n", "J. Chem. Theory. Comput. (2023), 19, 4011\n", "(3) https://pyepfd.readthedocs.io/en/latest/\n", "*************************************************\n" ] } ], "source": [ "from pyepfd.coord_util import *\n", "from pyepfd.elph_classes import *\n", "from pyepfd.pyepfd_io import *" ] }, { "cell_type": "markdown", "id": "a9f28f37", "metadata": {}, "source": [ "First, we would read the qbox outputs and store them within a list object. Let us first initialize the list object named qbouts." ] }, { "cell_type": "code", "execution_count": 2, "id": "1379bbfd", "metadata": {}, "outputs": [], "source": [ "qbouts = []" ] }, { "cell_type": "markdown", "id": "41a59d72", "metadata": {}, "source": [ "Now we would read the qbox outputs using the qbox class available within coord_utils." ] }, { "cell_type": "code", "execution_count": 3, "id": "1fb4bc37", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Time spent on qbox class: 0.02070307731628418 s.\n", "Time spent on qbox class: 0.018831729888916016 s.\n" ] } ], "source": [ "for i in range(2):\n", " qbouts.append(qbox(file_path = 'fd-'+str(i+1)+'.r',io = 'r'))" ] }, { "cell_type": "markdown", "id": "557f5bb5", "metadata": {}, "source": [ "We are running the loop twice as we have only two outputs. Change it according to your needs. qbox class have objects that stores coordinates (coords), atoms, mass, forces etc. Now we would store them into separate variables from the list of qbox objects. For that purpose first we initialize these objects with the first element of the qbouts. " ] }, { "cell_type": "code", "execution_count": 4, "id": "d279c77b", "metadata": {}, "outputs": [], "source": [ "coords = qbouts[0].coords\n", "atoms = qbouts[0].atoms\n", "mass = qbouts[0].mass\n", "forces = qbouts[0].forces" ] }, { "cell_type": "markdown", "id": "41c79b03", "metadata": {}, "source": [ "Next we will append other elements upto the length of the qbouts." ] }, { "cell_type": "code", "execution_count": 5, "id": "9ec5bf4a", "metadata": {}, "outputs": [], "source": [ "for i in range(1,len(qbouts)):\n", " coords = np.vstack((coords,qbouts[i].coords))\n", " forces = np.vstack((forces,qbouts[i].forces))" ] }, { "cell_type": "markdown", "id": "286b338e", "metadata": {}, "source": [ "The optimized geometry is the first set of coordinates. So we define it accordingly," ] }, { "cell_type": "code", "execution_count": 6, "id": "5e4f1865", "metadata": {}, "outputs": [], "source": [ "opt_coord = coords[0]" ] }, { "cell_type": "markdown", "id": "8b96173c", "metadata": {}, "source": [ "The cell parameters are fixed. Therefore we can take the first cell_parameters and conver them into vectors using abc2h function available within pyepfd.coord_utils." ] }, { "cell_type": "code", "execution_count": 7, "id": "2b48506e", "metadata": {}, "outputs": [], "source": [ "cell_v = abc2h(qbouts[0].cell)" ] }, { "cell_type": "markdown", "id": "3f5f3bca", "metadata": {}, "source": [ "Now we compute the force constant matrix and diagonaliz it to obtained normal-modes and its frequencies. This is done using the phonon_calculator class available within elph_classes." ] }, { "cell_type": "code", "execution_count": 8, "id": "79d81c09", "metadata": {}, "outputs": [], "source": [ "phonon = phonon_calculator(forces = forces,\\\n", " mass = mass,\\\n", " mode = 'FD',\\\n", " deltax = 0.005)" ] }, { "cell_type": "markdown", "id": "3137f515", "metadata": {}, "source": [ "Please remember to use the same mode and deltax that was used to prepare the input files, i.e., on tutorial cart_phonon_1. \n", "\n", "Next, we would take the computed dynamical matrix and instantiate a dynamica matrix (dm) class available in elph_classes. This class has the methods to refine the dynamical matrix using the suitable acoustic sum rule (asr). Here we have a linear molecule so we will choose asr = 'lin'. For a non-linear polyatomic molecule and crystal, one should use asr = 'lin' & asr = 'crystal', respectively." ] }, { "cell_type": "code", "execution_count": 9, "id": "b2696803", "metadata": {}, "outputs": [], "source": [ "dm = dm(dynmat = phonon.dynmat, mass = mass)\n", "dm.apply_asr(opt_coord = opt_coord, asr = 'lin')" ] }, { "cell_type": "markdown", "id": "51fb397e", "metadata": {}, "source": [ "Now it is time to write all information into a checkpoint/restart file that can be used for future reference. This file would be the starting point for calculating a normal-mode finite difference method, stochastic method, etc." ] }, { "cell_type": "code", "execution_count": 10, "id": "5a80e55e", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Time spent at write_info 0.0004 s\n" ] } ], "source": [ "restart_file = write_pyepfd_info(inp_dynmat = None,\\\n", " dynmat = dm.dynmatrix,\\\n", " ref_dynmat = dm.refdynmatrix,\\\n", " mass = mass,atoms = atoms,\\\n", " opt_coord = opt_coord,\\\n", " cell = qbouts[0].cell,\\\n", " file_name='fdphonon.xml',\\\n", " mode='fd',\\\n", " deltax=0.005,\\\n", " asr = 'lin')\n", "# deleting the restart file object to finish writing \n", "del restart_file" ] }, { "cell_type": "markdown", "id": "d654ec75", "metadata": {}, "source": [ "Let us have a look at the restart file fdphonon.xml." ] }, { "cell_type": "code", "execution_count": 11, "id": "d8f2f2b9", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", " \n", " 1 \n", " 0.005 \n", " 0.001 \n", " lin \n", " \n", "[ 2.12445535e-07, 3.42875298e-11, 1.71437649e-11, 1.33933949e-06, 0.00000000e+00, \n", " -1.71437649e-11, -3.07800297e-06, 1.97867238e-11, 3.95734476e-11, 3.42875298e-11, \n", " 2.12445535e-07, 1.71437649e-11, 3.42875298e-11, 1.33932235e-06, -1.71437649e-11, \n", " 1.97867238e-11, -3.07800297e-06, 1.97867238e-11, 1.71437649e-11, 1.71437649e-11, \n", " 3.45437948e-05, 0.00000000e+00, 0.00000000e+00, -3.07092832e-06, 0.00000000e+00, \n", " 0.00000000e+00, -3.67259006e-05, 1.33933949e-06, 3.42875298e-11, 0.00000000e+00, \n", " 2.12274097e-07, 0.00000000e+00, -3.42875298e-11, -3.07790403e-06, 1.97867238e-11, \n", " -3.95734476e-11, 0.00000000e+00, 1.33932235e-06, 0.00000000e+00, 0.00000000e+00, \n", " 2.12342672e-07, 1.71437649e-11, 0.00000000e+00, -3.07788425e-06, -1.97867238e-11, \n", " -1.71437649e-11, -1.71437649e-11, -3.07092832e-06, -3.42875298e-11, 1.71437649e-11, \n", " 3.45451663e-05, 0.00000000e+00, 0.00000000e+00, -3.67272857e-05, -3.07800297e-06, \n", " 1.97867238e-11, 0.00000000e+00, -3.07790403e-06, 0.00000000e+00, 0.00000000e+00, \n", " 5.83324319e-06, 0.00000000e+00, -2.28371329e-11, 1.97867238e-11, -3.07800297e-06, \n", " 0.00000000e+00, 1.97867238e-11, -3.07788425e-06, 0.00000000e+00, 0.00000000e+00, \n", " 5.83328886e-06, 0.00000000e+00, 3.95734476e-11, 1.97867238e-11, -3.67259006e-05, \n", " -3.95734476e-11, -1.97867238e-11, -3.67272857e-05, -2.28371329e-11, 0.00000000e+00, \n", " 8.22001133e-05 ]\n", " \n", " \n", "[ 1.16570877e-06, -1.27450455e-12, 1.77449774e-12, 1.16571357e-06, -1.27450979e-12, \n", " -7.58294525e-12, -2.69084475e-06, 2.94198171e-12, 6.70390356e-12, -1.27450455e-12, \n", " 1.16571224e-06, 1.48889657e-12, -1.27450979e-12, 1.16571704e-06, -8.50449734e-13, \n", " 2.94198171e-12, -2.69085276e-06, -7.36872634e-13, 1.77449774e-12, 1.48889657e-12, \n", " 3.44489401e-05, 1.77450504e-12, 1.48890270e-12, -3.16584535e-06, -4.09613279e-12, \n", " -3.43687002e-12, -3.61058355e-05, 1.16571357e-06, -1.27450979e-12, 1.77450504e-12, \n", " 1.16571837e-06, -1.27451504e-12, -7.58297646e-12, -2.69085583e-06, 2.94199381e-12, \n", " 6.70393115e-12, -1.27450979e-12, 1.16571704e-06, 1.48890270e-12, -1.27451504e-12, \n", " 1.16572184e-06, -8.50453234e-13, 2.94199381e-12, -2.69086383e-06, -7.36875666e-13, \n", " -7.58294525e-12, -8.50449734e-13, -3.16584535e-06, -7.58297646e-12, -8.50453234e-13, \n", " 3.44501870e-05, 1.75039675e-11, 1.96312172e-12, -3.61072746e-05, -2.69084475e-06, \n", " 2.94198171e-12, -4.09613279e-12, -2.69085583e-06, 2.94199381e-12, 1.75039675e-11, \n", " 6.21136742e-06, -6.79107529e-12, -1.54748460e-11, 2.94198171e-12, -2.69085276e-06, \n", " -3.43687002e-12, 2.94199381e-12, -2.69086383e-06, 1.96312172e-12, -6.79107529e-12, \n", " 6.21138590e-06, 1.70094788e-12, 6.70390356e-12, -7.36872634e-13, -3.61058355e-05, \n", " 6.70393115e-12, -7.36875666e-13, -3.61072746e-05, -1.54748460e-11, 1.70094788e-12, \n", " 8.33458035e-05 ]\n", " \n", " \n", " \n", "[ 2.00000000e+01, 2.00000000e+01, 2.00000000e+01, 9.00000000e+01, 9.00000000e+01, \n", " 9.00000000e+01 ]\n", " \n", " \n", "[ 2.91651223e+04, 2.91651223e+04, 2.91651223e+04, 2.91651223e+04, 2.91651223e+04, \n", " 2.91651223e+04, 2.18941669e+04, 2.18941669e+04, 2.18941669e+04 ]\n", " \n", " \n", "[ 0.00000000e+00, 0.00000000e+00, 2.18666400e+00, 0.00000000e+00, 0.00000000e+00, \n", " -2.18666100e+00, 0.00000000e+00, 0.00000000e+00, -3.00000000e-06 ]\n", " \n", " \n", "[ O, O, C ]\n", " \n", "" ] } ], "source": [ "%%bash\n", "cat fdphonon.xml" ] }, { "cell_type": "markdown", "id": "c8444e03", "metadata": {}, "source": [ "\n", "\n", "We see this is an xml file.It can be used to gather all information for further pyEPFD calculations, for example a normal-mode Hessian calculation or stochastic electron-phonon calculation.\n", "\n", "Sometime we would like to visualize the normal modes. For that purpose common visualization codes can be used and pyEPFD has methods to write normal-modes into an 'axsf', 'nmd' or 'molden' files that can be visualized with XCRYSDEN, VMD or MOLDEN programs, respectively. The below example shows how to do it using XCRYSDEN file as an example. \n" ] }, { "cell_type": "code", "execution_count": 12, "id": "eeaa7813", "metadata": {}, "outputs": [], "source": [ "nmodes = write_nmode(atoms = atoms, \n", " cell_v = cell_v, \n", " opt_coord = opt_coord, \n", " mode_v = dm.refV, # refined normal mode vectors after ASR \n", " mode_freq = dm.refomega, #refined frequencies \n", " fmt='axsf', #Options are: 'axsf','nmd','molden'\n", " file_path='refdynmat')\n", "# Deleting the nmodes object to finish printing the information into the file\n", "del nmodes" ] }, { "cell_type": "code", "execution_count": 13, "id": "c5d37d68", "metadata": { "scrolled": true }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "ANIMSTEPS 9\n", " CRYSTAL\n", " PRIMVEC\n", " 10.583544980 0.000000000 0.000000000\n", " 0.000000000 10.583544980 0.000000000\n", " 0.000000000 0.000000000 10.583544980\n", "PRIMCOORD 1\n", " 3 1\n", " O 0 0 1.15713 0.00543872 -0.000154545 -7.63158e-07\n", " O 0 0 -1.15713 -0.00078962 9.78154e-06 -7.63158e-07\n", " C 0 0 -1.58753e-06 0.00232455 -7.23814e-05 -7.63158e-07\n", "PRIMCOORD 2\n", " 3 1\n", " O 0 0 1.15713 -1.5501e-05 0.00180638 -0.000434643\n", " O 0 0 -1.15713 0.00502252 -0.000506981 -0.000434643\n", " C 0 0 -1.58753e-06 0.00250351 0.000649697 -0.000434643\n", "PRIMCOORD 3\n", " 3 1\n", " O 0 0 1.15713 0.000169877 0.00511544 1.96058e-05\n", " O 0 0 -1.15713 -0.00179793 -0.000373095 1.96058e-05\n", " C 0 0 -1.58753e-06 -0.000814027 0.00237117 1.96058e-05\n", "PRIMCOORD 4\n", " 3 1\n", " O 0 0 1.15713 -4.82234e-07 0.000348649 0.000149111\n", " O 0 0 -1.15713 -0.00032832 -0.0054022 0.000149111\n", " C 0 0 -1.58753e-06 -0.000164401 -0.00252678 0.000149111\n", "PRIMCOORD 5\n", " 3 1\n", " O 0 0 1.15713 1.6699e-06 -0.000180755 -0.0035005\n", " O 0 0 -1.15713 -0.000647508 -0.00016926 -0.0035005\n", " C 0 0 -1.58753e-06 -0.00032292 -0.000175007 -0.0035005\n", "PRIMCOORD 6\n", " 3 1\n", " O 0 0 1.15713 0.00205537 0.000673933 -2.22525e-09\n", " O 0 0 -1.15713 0.00205537 0.000673936 3.0202e-09\n", " C 0 0 -1.58753e-06 -0.0054759 -0.00179549 -1.05895e-09\n", "PRIMCOORD 7\n", " 3 1\n", " O 0 0 1.15713 0.000673933 -0.00205537 -8.26929e-12\n", " O 0 0 -1.15713 0.000673936 -0.00205537 3.69328e-10\n", " C 0 0 -1.58753e-06 -0.00179549 0.0054759 -4.80965e-10\n", "PRIMCOORD 8\n", " 3 1\n", " O 0 0 1.15713 1.33266e-09 3.33171e-10 0.00414054\n", " O 0 0 -1.15713 1.33266e-09 3.33172e-10 -0.00414047\n", " C 0 0 -1.58753e-06 -3.55046e-09 -8.87632e-10 -8.92961e-08\n", "PRIMCOORD 9\n", " 3 1\n", " O 0 0 1.15713 -4.33957e-10 4.76973e-11 0.00216297\n", " O 0 0 -1.15713 -4.33959e-10 4.76975e-11 0.0021631\n", " C 0 0 -1.58753e-06 1.15615e-09 -1.27075e-10 -0.00576275\n" ] } ], "source": [ "%%bash\n", "cat refdynmat.axsf" ] }, { "cell_type": "markdown", "id": "5da2b437", "metadata": {}, "source": [ "The refdynmat.axsf containes the normal modes after refining them applying acoustic sum rule. This file can be visualized with XCRYSDEN. If we choose fmt='nmd' / 'molden' that would create .nmd / .molden file respectively. They can be visualized with VMD and Molden, respectively. " ] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.8.10" } }, "nbformat": 4, "nbformat_minor": 5 }