Exemplo n.º 1
0
def charges_annotation(E_Fermi, E_for, charge, ax, text_size):
    """ Add an annotation giving the charge of the formation energy at the beginning of the line
    :param E_Fermi: Fermi energy range
    :param E_for: defect formation energy for a given charge 'charge'
    :param charge: charge associated with the defect formation energy
    :param ax: matplotlib.axes object
    :param text_size: size of the text
    """

    if float(charge) > 0:
        index = np.where(np.abs(E_for - ax.get_ylim()[0]) < 5e-4)[0]
        if len(index) != 0:
            coordinates = (E_Fermi[index[-1]], E_for[index[-1]])  # coordinates of the annotation
            hor_al = 'center'  # horizontal alignment of the annotation
            ver_al = 'bottom'  # vertical alignment of the annotation
        else:
            coordinates = (E_Fermi[0] + 0.01 * E_Fermi[-1], E_for[0] + float(charge) * 0.05 * E_Fermi[-1])
            hor_al = 'left'
            ver_al = 'center'
    else:
        index = np.where(np.abs(E_for - ax.get_ylim()[1]) < 5e-4)[0]
        if len(index) != 0:
            coordinates = (E_Fermi[index[0]], E_for[index[0]])
            hor_al = 'center'
            ver_al = 'top'

        else:
            coordinates = (E_Fermi[0] + 0.01 * E_Fermi[-1], E_for[0] + float(charge) * 0.05 * E_Fermi[-1])
            hor_al = 'left'
            ver_al = 'center'

    annotation = ax.annotate('$q = %s$' % bf.float_to_str(charge), xy=coordinates,
                             bbox=dict(boxstyle='square', fc='1', pad=0.05),
                             ha=hor_al, va=ver_al, fontsize=text_size)
    annotation.draggable()
Exemplo n.º 2
0
    def plot_transition_levels(self):
        """ Plot the transition levels of the study """

        E_Fermi = np.linspace(self.tpp.E_range[0], self.tpp.E_range[1], 30000)  # range of fermi energies
        transition_levels = self.get_transition_levels(E_Fermi)  # all transition levels in the range of fermi energies
        gap = self.gaps[self.tpp.gap_choice]

        # ------------------------------------------- FIGURE PARAMETERS -----------------------------------------------

        fig, ax = transition_figure_parameters(self.tpp)
        ax.set_xlim(-0.01, 1.2)

        # -------------------------------------------- PLOT PARAMETERS ------------------------------------------------

        ax.stackplot([0, 0, 1.1, 1.1], [[0, ax.get_ylim()[0]-1, ax.get_ylim()[0]-1, 0]], colors=['grey'], linewidths=4)
        ax.plot([0, 0, 1.1, 1.1], [ax.get_ylim()[1], gap, gap, ax.get_ylim()[1]], color='black', linewidth=4)

        ax.annotate(' $VBM$', xy=(1.1, 0.0), fontsize=self.tpp.text_size, va='center', ha='left').draggable()
        ax.annotate(' $CBM$', xy=(1.1, gap), fontsize=self.tpp.text_size, va='center', ha='left').draggable()

        for transition in transition_levels:
            ax.plot([0.1, 1], [transition[0], transition[0]], linewidth=2, color='black')
            charges = sorted(list(set(np.concatenate([f[2:] for f in transition_levels]))), reverse=True)
            tr_fermi = [f[0] for f in transition_levels]
            for charge, tr in zip(charges, [tr_fermi[0] - 0.06] + list(tr_fermi[:-1] + np.diff(tr_fermi)/2.0) + [tr_fermi[-1] + 0.06]):
                ax.annotate('$' + bf.float_to_str(charge) + '$', xy=(0.55, tr), fontsize=self.tpp.text_size,
                            va='center', ha='center').draggable()

        fig.tight_layout()
        fig.show()
Exemplo n.º 3
0
    def plot_formation_energy(self):
        """ Plot the defect formation energy as a function of the Fermi level energy """

        E_Fermi = np.linspace(self.fpp.E_range[0], np.max(self.gaps.values() +
                                                          [self.fpp.E_range[1]]), 10000)  # energies of the Fermi level
        E_for = [f.E_for_0 + f.Defect_Cell.charge * E_Fermi for f
                 in self.defect_cell_studies.itervalues()]  # corresponding formation energies
        E_for_low = np.transpose([self.get_formation_energy_low_EF(f) for f in E_Fermi])[1]
        transition_levels = self.get_transition_levels(E_Fermi)

        # ------------------------------------------- FIGURE PARAMETERS ------------------------------------------------

        fig, ax = formation_figure_parameters(self.fpp)

        # -------------------------------------------- PLOT PARAMETERS -------------------------------------------------

        [ax.plot(E_Fermi, f, color='black', linewidth=1.5) for f in E_for]  # formation energies
        ax.plot(E_Fermi, E_for_low, color='black', linewidth=4)  # lowest formation energy
        [ax.plot([f[1], f[1]], [ax.get_ylim()[0], ax.get_ylim()[1]], label=f[0], linewidth=2, linestyle='--')
         for f in self.gaps.iteritems()]

        if self.fpp.display_charges is True:
            charges = [f.Defect_Cell.charge for f in self.defect_cell_studies.itervalues()]
            [charges_annotation(E_Fermi, f, g, ax, self.fpp.text_size - 3) for f, g in zip(E_for, charges)]

        if self.fpp.display_transition_levels is True:
            for level in transition_levels:
                ax.plot([level[0], level[0]], [ax.get_ylim()[0], level[1]], linestyle='--', color='black')
                text = r'$\epsilon(' + bf.float_to_str(level[3]) + '/' + bf.float_to_str(level[2]) + ')$'
                annotation = ax.annotate(text, xy=(level[0], ax.get_ylim()[0] + 0.1 * np.diff(ax.get_ylim())[0]),
                                         ha='center', va='top', fontsize=self.fpp.text_size - 2, backgroundcolor='w')
                annotation.draggable()

        legend = ax.legend(loc='best', fancybox=True, fontsize=self.fpp.text_size - 2)
        legend.draggable()

        fig.tight_layout()
        fig.show()
Exemplo n.º 4
0
    def __init__(self, Host_Cell, Defect_Cell, DefectS, spheres_radius, z_e, z_h, geometry, e_r, mk_1_1, DE_VBM, DE_CBM,
                 potential_alignment_correction=True, moss_burstein_correction=True, phs_correction=True,
                 vbm_correction=True, makov_payne_correction=True):

        """
        :param Host_Cell: Cell object of the host cell calculation
        :param Defect_Cell: Cell object of the defect cell calculation
        :param DefectS: list of Defect objects
        :param spheres_radius: radius of the spheres in angstrom (float)
        :param z_e: number of electrons in the PHS
        :param z_h: number of holes in the PHS
        :param geometry: geometry of the host cell
        :param e_r: relative permittivity
        :param mk_1_1: value of the first term of the Makov-Payne correction in the case q = 1 & e_r = 1
        :param DE_VBM: correction of the VBM
        :param DE_CBM: correction of the CBM
        :param potential_alignment_correction: if True, the potential alignment correction is done
        :param moss_burstein_correction: if True, the Moss-Burstein correction is done
        :param phs_correction: if True, the PHS correction is done
        :param vbm_correction: if True, the VBM correction is done
        :param makov_payne_correction: if True, the Makov-Payne correction is done
        """

        self.Host_Cell = Host_Cell
        self.Defect_Cell = Defect_Cell
        self.DefectS = DefectS
        self.spheres_radius = spheres_radius

        # Check that the Host Cell and the Defect Cell have the same cristal parameters
        if Host_Cell.cell_parameters != Defect_Cell.cell_parameters:
            raise bf.PydefDefectCellError("The host cell is not consistent with the defect cell")

        # if Defect_Cell.isym != 0:
        #    raise bf.PydefDefectCellError('You should se ISYM to 0')

        # Title of the defects for display (name of the defects + charge of the cell)
        if len(DefectS) == 1:
            self.defects_title = self.DefectS[0].name + '^{' + bf.float_to_str(int(self.Defect_Cell.charge)) + '}'
        else:
            self.defects_title = '(' + ' & '.join([f.name for f in self.DefectS]) + ')^{' \
                                 + bf.float_to_str(int(self.Defect_Cell.charge)) + '}'

        # Title of the Defect Cell Study for display
        self.title = Host_Cell.display_rname + ' - ' + self.defects_title

        # --------------------------------------------- CORRECTIONS ---------------------------------------------------

        if potential_alignment_correction is True:
            self.pa_corr_temp = zc.potential_alignment_correction(Host_Cell, Defect_Cell, DefectS,
                                                                  spheres_radius, False)[-1]
            self.pa_corr = self.pa_corr_temp * Defect_Cell.charge
        else:
            self.pa_corr = 0.0

        if moss_burstein_correction is True:
            self.mb_corr = zc.moss_burstein_correction(Host_Cell, Defect_Cell, DefectS, spheres_radius)
        else:
            self.mb_corr = [0.0, 0.0]

        if phs_correction is True:
            self.phs_corr = zc.phs_correction(z_h, z_e, DE_VBM, DE_CBM)
        else:
            self.phs_corr = [0.0, 0.0]

        if vbm_correction is True:
            self.vbm_corr = zc.vbm_correction(Defect_Cell, DE_VBM)
        else:
            self.vbm_corr = 0.0

        if makov_payne_correction is True:
            self.mp_corr = zc.makov_payne_correction(Defect_Cell, geometry, e_r, mk_1_1)
        else:
            self.mp_corr = 0.0

        # Total correction
        self.tot_corr = self.pa_corr + sum(self.mb_corr) + sum(self.phs_corr) + self.vbm_corr + self.mp_corr

        self.E_for_0 = Defect_Cell.energy - Host_Cell.energy + sum([f.n * f.chem_pot for f in DefectS]) \
                       + Defect_Cell.charge * Host_Cell.VBM + self.tot_corr