Example #1
0
    def test_plot_functions(self):
        """Testing plotting tools for phonons."""
        phbst_filename = abidata.ref_file("trf2_5.out_PHBST.nc")
        with abilab.abiopen(phbst_filename) as nc:
            phbands = nc.phbands

        phb_objects = [
            phbands,
            phbst_filename,
        ]

        phdos_filename = abidata.ref_file("trf2_5.out_PHDOS.nc")
        phdos = PhdosFile(phdos_filename)
        phdos_objects = [
            phdos,
            phdos_filename,
        ]

        if self.has_matplotlib():
            assert phbands_gridplot(phb_objects,
                                    titles=["phonons1", "phonons2"],
                                    phdos_objects=phdos_objects,
                                    units="meV",
                                    show=False)

        phdos.close()
Example #2
0
    def test_plot_functions(self):
        """Testing plotting tools for phonons."""
        if not self.has_matplotlib():
            raise unittest.SkipTest("matplotlib missing")

        phbst_filename = abidata.ref_file("trf2_5.out_PHBST.nc")
        from abipy import abilab
        with abilab.abiopen(phbst_filename) as nc:
            phbands = nc.phbands

        phb_objects = [
            phbands,
            phbst_filename,
        ]

        phdos_filename = abidata.ref_file("trf2_5.out_PHDOS.nc")
        phdos = PhdosFile(phdos_filename)
        phdos_objects = [
            phdos,
            phdos_filename,
        ]

        fig = phbands_gridplot(phb_objects,
                               titles=["phonons1", "phonons2"],
                               phdos_objects=phdos_objects,
                               show=False)
        assert fig is not None
        phdos.close()
Example #3
0
    def test_from_phdosfile(self):
        ncfile = PhdosFile(abidata.ref_file("trf2_5.out_PHDOS.nc"))
        assert hasattr(ncfile, "structure")

        phdos = ncfile.phdos

        # Thermodinamics in the Harmonic approximation
        #self.assert_almost_equal(phdos.zero_point_energy, )
        f = phdos.get_free_energy()
        #self.assert_almost_equal(f.values, )
        u = phdos.get_internal_energy()
        #self.assert_almost_equal(u.values, )
        s = phdos.get_entropy()
        #self.assert_almost_equal(s.values, )
        cv = phdos.get_cv()
        #self.assert_almost_equal(cv.values, )

        if self.has_matplotlib():
            ncfile.plot_pjdos_type(show=False)
            phdos.plot(show=False)
            phdos.plot_harmonic_thermo(tstar=20, tstop=350)

        # Test notebook
        if self.has_nbformat():
            ncfile.write_notebook(nbpath=self.get_tmpname(text=True))

        ncfile.close()
Example #4
0
    def from_files(cls, gsr_paths, phdos_paths):
        """
        Creates an instance of QHA from a list of GSR files and a list of PHDOS.nc files.
        The list should have the same size and the volumes should match.

        Args:
            gsr_paths: list of paths to GSR files.
            phdos_paths: list of paths to PHDOS.nc files.

        Returns: A new instance of QHA
        """
        energies = []
        structures = []
        for gp in gsr_paths:
            with GsrFile.from_file(gp) as g:
                energies.append(g.energy)
                structures.append(g.structure)

        #doses = [PhononDos.as_phdos(dp) for dp in phdos_paths]

        doses = []
        structures_from_phdos = []
        for path in phdos_paths:
            with PhdosFile(path) as p:
                doses.append(p.phdos)
                structures_from_phdos.append(p.structure)

        cls._check_volumes(structures, structures_from_phdos)

        return cls(structures, doses, energies)
Example #5
0
    def __init__(self,
                 ebands_kpath,
                 phbst_file,
                 phdos_file,
                 ebands_kmesh=None):
        self.eb_kpath = ElectronBands.as_ebands(ebands_kpath)
        self.eb_kmesh = ElectronBands.as_ebands(
            ebands_kmesh) if ebands_kmesh is not None else None

        self.phbst_file = phbst_file
        if duck.is_string(self.phbst_file):
            self.phbst_file = PhbstFile(self.phbst_file)
        self.phb_qpath = self.phbst_file.phbands

        self.phdos_file = phdos_file
        if duck.is_string(self.phdos_file):
            self.phdos_file = PhdosFile(phdos_file)
Example #6
0
    def test_plot_functions(self):
        """Testing plotting tools for phonons."""
        phbst_filename = abidata.ref_file("trf2_5.out_PHBST.nc")
        with abilab.abiopen(phbst_filename) as nc:
            phbands = nc.phbands

        phb_objects = [
            phbands,
            phbst_filename,
        ]

        phdos_filename = abidata.ref_file("trf2_5.out_PHDOS.nc")
        phdos = PhdosFile(phdos_filename)
        phdos_objects = [
            phdos,
            phdos_filename,
        ]

        if self.has_matplotlib():
            assert phbands_gridplot(phb_objects, titles=["phonons1", "phonons2"],
                                    phdos_objects=phdos_objects, units="meV", show=False)

        phdos.close()
Example #7
0
class EphPlotter(object):
    """
    This object provides methods to plot electron and phonons for a single system.
    An EphPlotter has:

        - An |ElectronBands| on a k-path
        - An |ElectronBands| on a k-mesh (optional)
        - A |PhbstFile| with phonons along a q-path.
        - A |PhdosFile| with different kinds of phonon DOSes.

    EphPlotter uses these objects/files and other inputs/files provided by
    the user to generate matplotlib plots related to e-ph interaction.

    .. rubric:: Inheritance Diagram
    .. inheritance-diagram:: EphPlotter
    """
    @classmethod
    def from_ddb(cls, ddb, ebands_kpath, ebands_kmesh=None, **kwargs):
        """
        Build the object from the ddb file, invoke anaddb to get phonon properties.
        This entry point is needed to have phonon plots with LO-TO splitting
        as AbiPy will generate an anaddb input with the different q --> 0 directions
        required in phbands.plot to plot the LO-TO splitting correctly.

        Args:
            ddb: |DdbFile| or filepath.
            ebands_kpath: |ElectronBands| with energies on a k-path or filepath.
            ebands_kpath: (optional) |ElectronBands| with energies on a k-mesh or filepath.
            kwargs: Passed to anaget_phbst_and_phdos_files
        """
        ddb = DdbFile.as_ddb(ddb)
        phbst_file, phdos_file = ddb.anaget_phbst_and_phdos_files(**kwargs)
        return cls(ebands_kpath,
                   phbst_file,
                   phdos_file,
                   ebands_kmesh=ebands_kmesh)

    def __init__(self,
                 ebands_kpath,
                 phbst_file,
                 phdos_file,
                 ebands_kmesh=None):
        self.eb_kpath = ElectronBands.as_ebands(ebands_kpath)
        self.eb_kmesh = ElectronBands.as_ebands(
            ebands_kmesh) if ebands_kmesh is not None else None

        self.phbst_file = phbst_file
        if duck.is_string(self.phbst_file):
            self.phbst_file = PhbstFile(self.phbst_file)
        self.phb_qpath = self.phbst_file.phbands

        self.phdos_file = phdos_file
        if duck.is_string(self.phdos_file):
            self.phdos_file = PhdosFile(phdos_file)

    @add_fig_kwargs
    def plot(self, eb_ylims=None, **kwargs):
        """
        Plot electrons with possible (phonon-mediated) scattering channels for the CBM and VBM.
        Also plot phonon band structure and phonon PJDOS.

        Args:
            eb_ylims: Set the data limits for the y-axis of the electron band. Accept tuple e.g. ``(left, right)``
                or scalar e.g. ``left``. If None, limits are selected automatically.

        Return: |matplotlib-Figure|
        """
        # Build grid. Share y-axis for Phbands and Phdos
        import matplotlib.pyplot as plt
        fig = plt.figure()
        ax0 = plt.subplot2grid((3, 3), (0, 0), colspan=3, rowspan=2)
        ax1 = plt.subplot2grid((3, 3), (2, 0), colspan=2, rowspan=1)
        ax2 = plt.subplot2grid((3, 3), (2, 2), colspan=1, rowspan=1)
        ax1.get_shared_y_axes().join(ax1, ax2)

        # Plot electrons with possible e-ph scattering channels.
        self.eb_kpath.plot(ax=ax0,
                           with_gaps=True,
                           ylims=eb_ylims,
                           max_phfreq=self.phb_qpath.maxfreq,
                           show=False)

        # Plot phonon bands
        self.phb_qpath.plot(ax=ax1, show=False)
        #ax1.yaxis.set_visible(False)
        #set_visible(ax1, False, "ylabel")

        # Plot phonon PJDOS
        self.phdos_file.plot_pjdos_type(ax=ax2,
                                        fontsize=8,
                                        exchange_xy=True,
                                        show=False)
        set_visible(ax2, False, "ylabel")
        ax2.tick_params("y", left=False, labelleft=False)
        ax2.tick_params("y", right=True, labelright=True)

        # Adjust y-limits for phonons
        ylims = self.phb_qpath.minfreq, self.phb_qpath.maxfreq + 0.1 * abs(
            self.phb_qpath.maxfreq)
        for ax in (ax1, ax2):
            set_axlims(ax, ylims, "y")

        return fig

    @add_fig_kwargs
    def plot_phonons_occ(self, temps=(100, 200, 300, 400), **kwargs):
        """
        Plot phonon band structure with markers proportional to the occupation
        of each phonon mode for different temperatures.

        Args:
            temps: List of temperatures in Kelvin.

        Return: |matplotlib-Figure|
        """
        temps = np.array(temps)
        ntemp = len(temps)

        # Build plot grid.
        num_plots, ncols, nrows = ntemp, 1, 1
        if num_plots > 1:
            ncols = 2
            nrows = (num_plots // ncols) + (num_plots % ncols)

        ax_list, fig, plt = get_axarray_fig_plt(None,
                                                nrows=nrows,
                                                ncols=ncols,
                                                sharex=True,
                                                sharey=True,
                                                squeeze=False)
        ax_list = ax_list.ravel()

        for ax, temp in zip(ax_list, temps.ravel()):
            self.phb_qpath.plot(ax=ax,
                                units="eV",
                                temp=temp,
                                fontsize=8,
                                show=False)

        return fig

    @add_fig_kwargs
    def plot_linewidths_sigeph(self, sigeph, eb_ylims=None, **kwargs):
        """
        Plot e-bands + e-DOS + Im(Sigma_{eph}) + phonons + gkq^2

        Args:
            sigeph: |SigephFile| or string with path to file.
            eb_ylims: Set the data limits for the y-axis of the electron band. Accept tuple e.g. ``(left, right)``
                or scalar e.g. ``left``. If None, limits are selected automatically.
        """
        closeit = False
        if duck.is_string(sigeph):
            sigeph = SigEPhFile.from_file(sigeph)
            closeit = True

        # Build grid. share y-axis for Phbands and Phdos
        import matplotlib.pyplot as plt
        fig = plt.figure()

        # Electrons
        ax0 = plt.subplot2grid((2, 4), (0, 0), colspan=2, rowspan=1)
        ax1 = plt.subplot2grid((2, 4), (0, 2), colspan=1, rowspan=1)
        ax2 = plt.subplot2grid((2, 4), (0, 3), colspan=1, rowspan=1)
        # Share y-axis
        ax_share("y", ax0, ax1, ax2)

        # Phonons
        ax3 = plt.subplot2grid((2, 4), (1, 0), colspan=2, rowspan=1)
        ax4 = plt.subplot2grid((2, 4), (1, 2), colspan=1, rowspan=1)
        ax5 = plt.subplot2grid((2, 4), (1, 3), colspan=1, rowspan=1)
        # Share y-axis
        ax_share("y", ax3, ax4, ax5)

        e0 = "fermie"

        # Plot electrons with possible e-ph scattering channels.
        self.eb_kpath.plot(ax=ax0,
                           e0=e0,
                           with_gaps=True,
                           ylims=eb_ylims,
                           max_phfreq=self.phb_qpath.maxfreq,
                           show=False)
        sigeph.plot_lws_vs_e0(ax=ax1, e0=e0, exchange_xy=True, show=False)
        sigeph.edos.plot(ax=ax2, e0=e0, exchange_xy=True, show=False)

        # Plot phonon bands
        self.phb_qpath.plot(ax=ax3, show=False)
        sigeph.plot_a2fw_skb_sum(ax=ax4,
                                 what="gkq2",
                                 exchange_xy=True,
                                 fontsize=8,
                                 show=False)
        # Plot phonon PJDOS
        self.phdos_file.plot_pjdos_type(ax=ax5,
                                        fontsize=8,
                                        exchange_xy=True,
                                        show=False)
        #set_visible(ax4, False, "ylabel")
        #ax4.tick_params("y", left=False, labelleft=False)
        #ax4.tick_params("y", right=True, labelright=True)

        if closeit: sigeph.close()

        return fig
Example #8
0
    def test_from_phdosfile(self):
        """Testing PHDOS from netcdf file."""
        ncfile = PhdosFile(abidata.ref_file("trf2_5.out_PHDOS.nc"))
        repr(ncfile); str(ncfile)
        assert ncfile.to_string(verbose=1)
        assert hasattr(ncfile, "structure")
        nw = len(ncfile.wmesh)
        assert nw == 461
        natom3 = len(ncfile.structure) * 3

        # Read PJDOSes
        assert list(ncfile.pjdos_symbol.keys()) == ["Al", "As"]
        od = ncfile.reader.read_pjdos_symbol_xyz_dict()
        assert list(od.keys()) == ["Al", "As"]
        assert all(v.shape == (3, nw) for v in od.values())

        arr = ncfile.reader.read_pjdos_atdir()
        assert arr.shape == (len(ncfile.structure), 3, nw)

        phdos = ncfile.phdos
        # Test integrals of DOS (the tolerance is a bit low likely due to too coarse meshes)
        self.assert_almost_equal(phdos.integral_value, natom3, decimal=1)

        # Summing projected DOSes over types should give the total DOS.
        pj_sum = sum(pjdos.integral_value for pjdos in ncfile.pjdos_symbol.values())
        self.assert_almost_equal(phdos.integral_value, pj_sum)

        # Summing projected DOSes over types and directions should give the total DOS.
        # phdos_rc_type[ntypat, 3, nomega]
        values = ncfile.reader.read_value("pjdos_rc_type").sum(axis=(0, 1))
        tot_dos = abilab.Function1D(phdos.mesh, values)
        self.assert_almost_equal(phdos.integral_value, tot_dos.integral_value)

        assert phdos == PhononDos.as_phdos(abidata.ref_file("trf2_5.out_PHDOS.nc"))

        # Test Thermodinamics in the Harmonic approximation
        self.assert_almost_equal(phdos.zero_point_energy.to("Ha"), 0.0030872835637731303)

        u = phdos.get_internal_energy()
        self.assert_almost_equal(u.values[0], 0.084009326574073395)
        self.assert_almost_equal(u.values[-1], 0.17270110252071791)

        s = phdos.get_entropy()
        self.assert_almost_equal(s.values[0], 1.6270193052583423e-08)
        self.assert_almost_equal(s.values[-1], 0.00058238779354717)

        cv = phdos.get_cv()
        self.assert_almost_equal(cv.values[0], 5.3715488328604253e-08)
        self.assert_almost_equal(cv.values[-1], 0.00045871909188672578)

        f = phdos.get_free_energy()
        self.assert_almost_equal(f.values, (u - s.mesh * s.values).values)

        self.assertAlmostEqual(phdos.debye_temp, 469.01524830328606)
        self.assertAlmostEqual(phdos.get_acoustic_debye_temp(len(ncfile.structure)), 372.2576492728813)

        assert ncfile.to_pymatgen()

        if self.has_matplotlib():
            assert ncfile.plot_pjdos_type(show=False)
            assert ncfile.plot_pjdos_type(units="cm-1", stacked=False, colormap="viridis", show=False)
            assert ncfile.plot_pjdos_cartdirs_type(units="Thz", stacked=True, show=False)
            assert ncfile.plot_pjdos_cartdirs_type(units="meV", stacked=False, alpha=0.5, show=False)
            assert ncfile.plot_pjdos_cartdirs_site(units="meV", stacked=False, alpha=0.5, show=False)
            assert ncfile.plot_pjdos_cartdirs_site(units="meV", view="all", stacked=True, alpha=0.5, show=False)

            assert phdos.plot(units="cm-1", show=False)
            assert phdos.plot_harmonic_thermo(tstar=20, tstop=350, units="eV", formula_units=1, show=False)
            assert phdos.plot_harmonic_thermo(tstar=20, tstop=350, units="Jmol", formula_units=2, show=False)

        # Test notebook
        if self.has_nbformat():
            ncfile.write_notebook(nbpath=self.get_tmpname(text=True))

        ncfile.close()
Example #9
0
    def test_from_phdosfile(self):
        """Testing PHDOS from netcdf file."""
        ncfile = PhdosFile(abidata.ref_file("trf2_5.out_PHDOS.nc"))
        repr(ncfile)
        str(ncfile)
        assert ncfile.to_string(verbose=1)
        assert hasattr(ncfile, "structure")
        nw = len(ncfile.wmesh)
        assert nw == 461
        natom3 = len(ncfile.structure) * 3

        # Read PJDOSes
        assert list(ncfile.pjdos_symbol.keys()) == ["Al", "As"]
        od = ncfile.reader.read_pjdos_symbol_xyz_dict()
        assert list(od.keys()) == ["Al", "As"]
        assert all(v.shape == (3, nw) for v in od.values())

        arr = ncfile.reader.read_pjdos_atdir()
        assert arr.shape == (len(ncfile.structure), 3, nw)

        phdos = ncfile.phdos
        # Test integrals of DOS (the tolerance is a bit low likely due to too coarse meshes)
        self.assert_almost_equal(phdos.integral_value, natom3, decimal=1)

        # Summing projected DOSes over types should give the total DOS.
        pj_sum = sum(pjdos.integral_value
                     for pjdos in ncfile.pjdos_symbol.values())
        self.assert_almost_equal(phdos.integral_value, pj_sum)

        # Summing projected DOSes over types and directions should give the total DOS.
        # phdos_rc_type[ntypat, 3, nomega]
        values = ncfile.reader.read_value("pjdos_rc_type").sum(axis=(0, 1))
        tot_dos = abilab.Function1D(phdos.mesh, values)
        self.assert_almost_equal(phdos.integral_value, tot_dos.integral_value)

        assert phdos == PhononDos.as_phdos(
            abidata.ref_file("trf2_5.out_PHDOS.nc"))

        # Test Thermodinamics in the Harmonic approximation
        self.assert_almost_equal(phdos.zero_point_energy.to("Ha"),
                                 0.0030872835637731303)

        u = phdos.get_internal_energy()
        self.assert_almost_equal(u.values[0], 0.084009326574073395)
        self.assert_almost_equal(u.values[-1], 0.17270110252071791)

        s = phdos.get_entropy()
        self.assert_almost_equal(s.values[0], 1.6270193052583423e-08)
        self.assert_almost_equal(s.values[-1], 0.00058238779354717)

        cv = phdos.get_cv()
        self.assert_almost_equal(cv.values[0], 5.3715488328604253e-08)
        self.assert_almost_equal(cv.values[-1], 0.00045871909188672578)

        f = phdos.get_free_energy()
        self.assert_almost_equal(f.values, (u - s.mesh * s.values).values)

        self.assertAlmostEqual(phdos.debye_temp, 469.01524830328606)
        self.assertAlmostEqual(
            phdos.get_acoustic_debye_temp(len(ncfile.structure)),
            372.2576492728813)

        assert ncfile.to_pymatgen()

        if self.has_matplotlib():
            assert ncfile.plot_pjdos_type(show=False)
            assert ncfile.plot_pjdos_type(units="cm-1",
                                          stacked=False,
                                          colormap="viridis",
                                          show=False)
            assert ncfile.plot_pjdos_type(units="eV",
                                          stacked=True,
                                          colormap="jet",
                                          exchange_xy=True,
                                          fontsize=8,
                                          show=False)
            assert ncfile.plot_pjdos_cartdirs_type(units="Thz",
                                                   stacked=True,
                                                   show=False)
            assert ncfile.plot_pjdos_cartdirs_type(units="meV",
                                                   stacked=False,
                                                   alpha=0.5,
                                                   show=False)
            assert ncfile.plot_pjdos_cartdirs_site(units="meV",
                                                   stacked=False,
                                                   alpha=0.5,
                                                   show=False)
            assert ncfile.plot_pjdos_cartdirs_site(units="meV",
                                                   view="all",
                                                   stacked=True,
                                                   alpha=0.5,
                                                   show=False)

            assert phdos.plot(units="cm-1", show=False)
            assert phdos.plot_harmonic_thermo(tstar=20,
                                              tstop=350,
                                              units="eV",
                                              formula_units=1,
                                              show=False)
            assert phdos.plot_harmonic_thermo(tstar=20,
                                              tstop=350,
                                              units="Jmol",
                                              formula_units=2,
                                              show=False)

        # Test notebook
        if self.has_nbformat():
            ncfile.write_notebook(nbpath=self.get_tmpname(text=True))

        ncfile.close()