{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Compute the phonons and the infrared spectrum\n", "\n", "MyBigDFT comes with some classes implementing particular workflows of calculations. These workflows define a queue of jobs, that can easily be run sequentially, without having to worry about the `Job` context manager. They also generally define a particular post-processing procedure, run after all the BigDFT calculations in order to extract some meaningful imformation.\n", "\n", "The example provided here shows how to obtain the phonons and the infrared spectrum of the CO molecule using the [Phonons](https://mmoriniere.gitlab.io/MyBigDFT/phonons.html#mybigdft.workflows.phonons.Phonons) and [InfraredSpectrum](https://mmoriniere.gitlab.io/MyBigDFT/infrared.html#mybigdft.workflows.infraredspectrum.InfraredSpectrum) class." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Initialization\n", "\n", "You first need to import some useful classes to define a ground state calculation as well as the `Phonons` and `InfraredSpectrum` classes:" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "from mybigdft import Job, Posinp, Atom, InputParams\n", "from mybigdft.workflows import Phonons, InfraredSpectrum" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## The [Phonons](https://mmoriniere.gitlab.io/MyBigDFT/phonons.html#mybigdft.workflows.phonons.Phonons) class" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let us first obtain the the normal modes of the CO molecule. \n", "\n", "To get the **energies** of the Raman spectrum, one needs to find the **eigenvalues of the dynamical matrix**, that is closely related to the Hessian matrix. To build these matrices, one must find the derivatives of the forces when the position of each atom is translated (along each coordinate) by a small amount around their equilibrium position. To get a better precision on the derivative, each coodinate is translated positively and negatively. The number of BigDFT calculations therefore amounts to $2 * 3 n_{at} = 6 n_{at}$, where $n_{at}$ is the number of atoms (3 for the coordinates ($x$, $y$ and $z$), 2 for the number of calculations per coordinates).\n", "\n", "**Be careful:** you must compute a geometry optimization of your system before actually computing the phonons, as you may get unphysical results. This part is not reproduced here. Similarly to the polarizability tensor calculation, you only need to provide a ground state job while default values are used to define the amplitude of the moves along each direction (you might want to set them via the `translation_amplitudes` argument).\n", "\n", "**Note**: you can select ``order=1`` when initializing the Phonons instance, so as to run only one calculation per coordinates (meaning $3 n_{at}$ calculations will be performed, instead of $6 n_{at}$)" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "CO_ref = \"\"\"2 angstroem \n", "free \n", "C -8.61468162115724335E-22 -5.85961390944064004E-22 -4.99273481690253648E-03 \n", "O 6.11054044310156593E-22 5.85961390944064004E-22 1.12999273481690232E+00\"\"\"\n", "pos = Posinp.from_string(CO_ref)\n", "inp = InputParams({\"dft\": {\"ixc\": 11, \"gnrm_cv\": 1.e-5, \"hgrids\": [0.35]*3, \"rmult\": [8, 10]}})\n", "gs = Job(posinp=pos, inputparams=inp, name='CO', run_dir='CO/phonons/')\n", "phonons = Phonons(gs)\n", "# The line above actually amounts to:\n", "# phonons = Phonons(gs, translation_amplitudes=[0.45/64]*3, order=2)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "To run the calculation, simply use the run method:" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "/Users/maximemoriniere/Documents/Python/MyBigDFT/doc/source/notebooks/CO/phonons/atom0000/x+\n", "Logfile log-CO.yaml already exists!\n", "\n", "/Users/maximemoriniere/Documents/Python/MyBigDFT/doc/source/notebooks/CO/phonons/atom0000/x-\n", "Logfile log-CO.yaml already exists!\n", "\n", "/Users/maximemoriniere/Documents/Python/MyBigDFT/doc/source/notebooks/CO/phonons/atom0000/y+\n", "Logfile log-CO.yaml already exists!\n", "\n", "/Users/maximemoriniere/Documents/Python/MyBigDFT/doc/source/notebooks/CO/phonons/atom0000/y-\n", "Logfile log-CO.yaml already exists!\n", "\n", "/Users/maximemoriniere/Documents/Python/MyBigDFT/doc/source/notebooks/CO/phonons/atom0000/z+\n", "Logfile log-CO.yaml already exists!\n", "\n", "/Users/maximemoriniere/Documents/Python/MyBigDFT/doc/source/notebooks/CO/phonons/atom0000/z-\n", "Logfile log-CO.yaml already exists!\n", "\n", "/Users/maximemoriniere/Documents/Python/MyBigDFT/doc/source/notebooks/CO/phonons/atom0001/x+\n", "Logfile log-CO.yaml already exists!\n", "\n", "/Users/maximemoriniere/Documents/Python/MyBigDFT/doc/source/notebooks/CO/phonons/atom0001/x-\n", "Logfile log-CO.yaml already exists!\n", "\n", "/Users/maximemoriniere/Documents/Python/MyBigDFT/doc/source/notebooks/CO/phonons/atom0001/y+\n", "Logfile log-CO.yaml already exists!\n", "\n", "/Users/maximemoriniere/Documents/Python/MyBigDFT/doc/source/notebooks/CO/phonons/atom0001/y-\n", "Logfile log-CO.yaml already exists!\n", "\n", "/Users/maximemoriniere/Documents/Python/MyBigDFT/doc/source/notebooks/CO/phonons/atom0001/z+\n", "Logfile log-CO.yaml already exists!\n", "\n", "/Users/maximemoriniere/Documents/Python/MyBigDFT/doc/source/notebooks/CO/phonons/atom0001/z-\n", "Logfile log-CO.yaml already exists!\n", "\n" ] } ], "source": [ "phonons.run(nmpi=2, nomp=2)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In the end, you can get the phonon energies via the `energies` attribute. They are stored in a dictionary whose keys are the units." ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([ 2.11205229e+03, 5.82170475e-06, -5.11175466e+00, -5.11174626e+00,\n", " 3.52753775e-06, -2.43602537e-03])" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "phonons.energies # in cm^-1" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## The [InfraredSpectrum](https://mmoriniere.gitlab.io/MyBigDFT/infrared.html#mybigdft.workflows.infrared.InfraredSpectrum) class\n", "\n", "To get the **intensities** of the infrared spectrum, one must compute the **derivative of the dipole moment along the normal modes**. To that end, no extra DFT calculation is required, since one already has access to the dipole moments for each diplaced geometry used to compute the phonons.\n", "\n", "An InfraredSpectrum instance is initialized by a Phonons instance. \n", "\n", "Here, the phonons instance defined above is re-used, hence the UserWarning below: the calculations for the phonons were already performed before, so we are said to set `force_run` to `True` if we wish to run them again (but this is not our case)." ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "/Users/maximemoriniere/Documents/Python/MyBigDFT/mybigdft/workflows/workflow.py:118: UserWarning: Calculations already performed; set the argument 'force_run' to True to re-run them.\n", " warnings.warn(warning_msg, UserWarning)\n" ] } ], "source": [ "ir = InfraredSpectrum(phonons)\n", "ir.run(nmpi=2, nomp=2)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In the end, we can check the phonon energies:" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([ 2.11205229e+03, 5.82170475e-06, -5.11175466e+00, -5.11174626e+00,\n", " 3.52753775e-06, -2.43602537e-03])" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "ir.energies # in cm^-1" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The intensities associated to each normal mode are obtained via the `intensities` attribute:" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([1.55251144e+00, 1.47776864e-22, 4.07193761e-03, 4.07018828e-03,\n", " 1.68939224e-22, 2.06873213e-12])" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "ir.intensities # in (D/A)^2/amu" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The carbon monoxyde molecule being linear, it has $3 n_{at} - 5 = 1$ normal mode. Its energy, found using the GGA exchange-correlation is around 2112 cm$^{-1}$. Following the statement of [B. G. Johnson *et al.*, *J. Chem. Phys.* **98**, 5612 (1993)](http://aip.scitation.org/doi/10.1063/1.464906), our result should be compared with the harmonic experimental value, which is reported to be 2170 cm$^{-1}$ in this same reference. There is a rather good agreement! Note that the actual experimental value (without neglecting anharmocity) is 2143 cm$^{-1}$.\n", "\n", "An intensity of 61.2 km.mol$^{-1}$ was reported in [D. Bishop and L. Cheung, *J. Phys. Chem. Ref. Data* **11**, 119 (1982)](https://aip.scitation.org/doi/abs/10.1063/1.555658). Our result, converted in the same units, is 65.6 km.mol$^{-1}$), again in rather good agreement. \n", "\n", "**Note:**\n", "1 $(\\text{D} / \\unicode[serif]{xc5})^2 \\text{amu}^{-1}$ = 42.255 km.mol$^{-1}$.\n", "\n", "Keep in mind that the present calculations cannot be considered as converged (the grid extension should be increased and the grid spacing decreased)." ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "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.7.2" } }, "nbformat": 4, "nbformat_minor": 2 }