Esempio n. 1
0
def plot_exciton_spectrum(en, T, M, broadening=0.005, units="nm"):
    """
    plot absorption and circular dichroism spectra on top of each other

    Parameters
    ----------
    en: numpy array with shape (Nst), excitation energies in Hartree
    T : numpy array with shape (3,Nst), electric transition dipoles
    M : numpy array with shape (3,Nst), magnetic transition dipoles
    """
    # oscillator strengths and rotational strength
    nst = len(en)
    f = np.zeros(nst)
    R = np.zeros(nst)
    angleEM = np.zeros(nst)
    for i in range(0, nst):
        f[i] = 2.0/3.0 * en[i] * np.dot(T[:,i].conjugate(), T[:,i])
        # Im{ T_(0->i) * M[i->0] }
        R[i] = np.dot(T[:,i], M[:,i])


    import matplotlib.pyplot as plt
    from DFTB.Analyse.absorption_spectrum import broadened_spectrum, convert_energy

    ens, ab_spec = broadened_spectrum(en, f, broadening)
    ens, cd_spec  = broadened_spectrum(en, R, broadening)

    ax_cd = plt.subplot(211)
    ax_ab = plt.subplot(212, sharex = ax_cd)

    # convert energies from Hartree to nm
    ens = convert_energy(ens, "Hartree", units)
    
    fs = 18.0  # fontsize
    ax_cd.set_xlabel("Energy / %s" % units, fontsize=fs)
    # circular dichroism spectrum
    ax_cd.plot(ens, cd_spec)
    ax_cd.set_ylabel("Rotational Strength / arb. units", fontsize=fs)

    # absorption spectrum
    ax_ab.plot(ens, ab_spec)
    ax_cd.set_ylabel("Oscillator Strength / arb. units", fontsize=fs)

    plt.show()
Esempio n. 2
0
    def plotDOS(self):
        self.figDOS.clf()
        ax = self.figDOS.add_subplot(111)

        units = self.energyUnits.itemText(self.energyUnits.currentIndex())
        broadening = abs(float(self.broadening.text()))
        ax.set_title("Density of States (DOS)")
        ax.set_xlabel("Kohn-Sham Energy / %s" % units, fontsize=15)
        ax.set_ylabel("DOS / arbitrary units", fontsize=15)

        ens = self.tddftb.dftb2.getKSEnergies()
        dos = 1.0 * np.ones(ens.shape)
        # stick spectrum
        ens_out = convert_energy(ens, "Hartree", units)
        ax.vlines(ens_out,
                  np.zeros(ens_out.shape),
                  dos,
                  lw=2,
                  color="black",
                  picker=5)

        # selected states are highlighted
        selected = self.tableMOs.selectionModel().selectedRows()
        for s in selected:
            i = s.row()
            ax.vlines(ens_out[i], [0.0], dos[i], lw=3, color="green")
            ax.text(ens_out[i], dos[i], "%s %s" % (i + 1, self.mo_names[i]))

        def onpick(event):
            self.tableMOs.setCurrentCell(event.ind[0], 0)

        self.figDOS.canvas.mpl_connect('pick_event', onpick)

        if broadening > 0.0:
            ens_broadened, spec = broadened_spectrum(ens, dos, broadening)
            ens_broadened_out = convert_energy(ens_broadened, "Hartree", units)
            scale = spec.max() / dos.max() / 1.1
            x, y = ens_broadened_out, spec / scale
            ax.plot(x, y, lw=1, color="blue")

            x_occ = x[x <= ens_out[self.H**O]]
            y_occ = y[x <= ens_out[self.H**O]]
            x_virt = x[x >= ens_out[self.LUMO]]
            y_virt = y[x >= ens_out[self.LUMO]]

            ax.fill_between(x_occ, 0, y_occ, alpha=0.5, color="blue")
            ax.fill_between(x_virt, 0, y_virt, alpha=0.5, color="red")

            ax.annotate('',
                        xy=(ens_out[self.H**O], 1.1),
                        xycoords='data',
                        xytext=(ens_out[self.LUMO], 1.1),
                        textcoords='data',
                        arrowprops={'arrowstyle': '<->'})
            ax.annotate(
                'gap = %4.3f' % (ens_out[self.LUMO] - ens_out[self.H**O]),
                xy=((ens_out[self.H**O] + ens_out[self.LUMO]) / 2.0, 1.1),
                xycoords='data',
                xytext=(0, 5),
                textcoords='offset points')

        self.canvasDOS.draw()

        self.showMullikenCharges()
        if len(selected) > 0:
            i = selected[0].row()
            self.moLabel.setText("Molecular Orbital: %s %s" %
                                 (i + 1, self.mo_names[i]))
            if i in self.mo_cubes:
                mo_cube = self.mo_cubes[i]
                self.molecularOrbitalViewer.setCubes([mo_cube])
            else:
                print("No cube for molecular orbital %d" % (i + 1))
Esempio n. 3
0
    def plotSpectrum(self):
        self.figSpectrum.clf()
        ax = self.figSpectrum.add_subplot(111)

        units = self.energyUnits.itemText(self.energyUnits.currentIndex())
        broadening = abs(float(self.broadening.text()))
        ax.set_title("Absorption Spectrum")
        ax.set_xlabel("Excitation Energy / %s" % units, fontsize=15)
        ax.set_ylabel("Oscillator strength", fontsize=15)

        ens = self.tddftb.Omega
        osz = self.tddftb.oscillator_strength
        # stick spectrum
        ens_out = convert_energy(ens, "Hartree", units)
        ax.vlines(ens_out,
                  np.zeros(ens_out.shape),
                  osz,
                  lw=2,
                  color="black",
                  picker=5)

        # selected states are highlighted
        selected = self.tableStates.selectionModel().selectedRows()
        for s in selected:
            I = s.row()
            ax.vlines(ens_out[I], [0.0], osz[I], lw=3, color="green")
            ax.text(
                ens_out[I], osz[I], "%s (%s$_{%d}$)" %
                (self.tddftb.Irreps[I], self.tddftb.multiplicity, I + 1))

        def onpick(event):
            self.tableStates.setCurrentCell(event.ind[0], 0)

        self.figSpectrum.canvas.mpl_connect('pick_event', onpick)

        if broadening > 0.0:
            ens_broadened, spec = broadened_spectrum(ens, osz, broadening)
            ens_broadened_out = convert_energy(ens_broadened, "Hartree", units)
            scale = spec.max() / osz.max() / 1.1
            ax.plot(ens_broadened_out, spec / scale, lw=1, color="blue")

        self.canvasSpectrum.draw()

        if len(selected) > 0:
            I = selected[0].row()
            self.tdenseLabel.setText(
                "Excited State: %s (%s%d)" %
                (self.tddftb.Irreps[I], self.tddftb.multiplicity, I + 1))
            self.showPartialCharges(I)
            if I in self.tdense_cubes:
                tdense_cube = self.tdense_cubes[I]
                self.transitionDensityViewer.setCubes([tdense_cube])
                difdense_cube = self.difdense_cubes[I]
                self.differenceDensityViewer.setCubes([difdense_cube])
            else:
                print(
                    "No cube for transition and difference density of state %d"
                    % (I + 1))
            # transition densities in occ-virt plane
            self.plotExcitationCoefficients2D(I)
        self.canvasExvec.draw()