def plot_local_potential(axis=2, ylim=(-20, 0), fmt='pdf'): """ Plot data from the LOCPOT file along any of the 3 primary axes. Useful for determining surface dipole moments and electric potentials on the interior of the material. Args: axis (int): 0 = x, 1 = y, 2 = z ylim (tuple): minimum and maximum potentials for the plot's y-axis. fmt (str): matplotlib format style. Check the matplotlib docs for options. """ ax = plt.figure(figsize=(16, 10)).gca() locpot = Locpot.from_file('LOCPOT') structure = Structure.from_file('CONTCAR') vd = VolumetricData(structure, locpot.data) abs_potentials = vd.get_average_along_axis(axis) vacuum_level = max(abs_potentials) vasprun = Vasprun('vasprun.xml') bs = vasprun.get_band_structure() if not bs.is_metal(): cbm = bs.get_cbm()['energy'] - vacuum_level vbm = bs.get_vbm()['energy'] - vacuum_level potentials = [potential - vacuum_level for potential in abs_potentials] axis_length = structure.lattice._lengths[axis] positions = np.arange(0, axis_length, axis_length / len(potentials)) ax.plot(positions, potentials, linewidth=2, color='k') ax.set_xlim(0, axis_length) ax.set_ylim(ylim[0], ylim[1]) ax.set_xticklabels( [r'$\mathrm{%s}$' % tick for tick in ax.get_xticks()], size=20) ax.set_yticklabels( [r'$\mathrm{%s}$' % tick for tick in ax.get_yticks()], size=20) ax.set_xlabel(r'$\mathrm{\AA}$', size=24) ax.set_ylabel(r'$\mathrm{V\/(eV)}$', size=24) if not bs.is_metal(): ax.text(ax.get_xlim()[1], cbm, r'$\mathrm{CBM}$', horizontalalignment='right', verticalalignment='bottom', size=20) ax.text(ax.get_xlim()[1], vbm, r'$\mathrm{VBM}$', horizontalalignment='right', verticalalignment='top', size=20) ax.fill_between(ax.get_xlim(), cbm, ax.get_ylim()[1], facecolor=plt.cm.jet(0.3), zorder=0, linewidth=0) ax.fill_between(ax.get_xlim(), ax.get_ylim()[0], vbm, facecolor=plt.cm.jet(0.7), zorder=0, linewidth=0) if fmt == "None": return ax else: plt.savefig('locpot.{}'.format(fmt)) plt.close()
def plot_local_potential(axis=2, ylim=(-20, 0), fmt='pdf'): """ Plot data from the LOCPOT file along any of the 3 primary axes. Useful for determining surface dipole moments and electric potentials on the interior of the material. Args: axis (int): 0 = x, 1 = y, 2 = z ylim (tuple): minimum and maximum potentials for the plot's y-axis. fmt (str): matplotlib format style. Check the matplotlib docs for options. """ ax = plt.figure(figsize=(16, 10)).gca() locpot = Locpot.from_file('LOCPOT') structure = Structure.from_file('CONTCAR') vd = VolumetricData(structure, locpot.data) abs_potentials = vd.get_average_along_axis(axis) vacuum_level = max(abs_potentials) vasprun = Vasprun('vasprun.xml') bs = vasprun.get_band_structure() if not bs.is_metal(): cbm = bs.get_cbm()['energy'] - vacuum_level vbm = bs.get_vbm()['energy'] - vacuum_level potentials = [potential - vacuum_level for potential in abs_potentials] axis_length = structure.lattice.lengths[axis] positions = np.arange(0, axis_length, axis_length / len(potentials)) ax.plot(positions, potentials, linewidth=2, color='k') ax.set_xlim(0, axis_length) ax.set_ylim(ylim[0], ylim[1]) ax.set_xticklabels( [r'$\mathrm{%s}$' % tick for tick in ax.get_xticks()], size=20) ax.set_yticklabels( [r'$\mathrm{%s}$' % tick for tick in ax.get_yticks()], size=20) ax.set_xlabel(r'$\mathrm{\AA}$', size=24) ax.set_ylabel(r'$\mathrm{V\/(eV)}$', size=24) if not bs.is_metal(): ax.text(ax.get_xlim()[1], cbm, r'$\mathrm{CBM}$', horizontalalignment='right', verticalalignment='bottom', size=20) ax.text(ax.get_xlim()[1], vbm, r'$\mathrm{VBM}$', horizontalalignment='right', verticalalignment='top', size=20) ax.fill_between(ax.get_xlim(), cbm, ax.get_ylim()[1], facecolor=plt.cm.jet(0.3), zorder=0, linewidth=0) ax.fill_between(ax.get_xlim(), ax.get_ylim()[0], vbm, facecolor=plt.cm.jet(0.7), zorder=0, linewidth=0) if fmt == "None": return ax else: plt.savefig('locpot.{}'.format(fmt)) plt.close()
def get_freysoldt_correction(defect_type, defect_specie, path_to_defect_locpot,path_to_pure_locpot,charge, dielectric_constant,defect_site_coordinates,energy_cutoff=500,get_plot=False): ''' Function to perform charge corrections according to the method proposed py Freysoldt If this correction is used, please reference Freysoldt's original paper. doi: 10.1103/PhysRevLett.102.016402 Args: defect_type: 'vacancy' or 'interstitial' defect_specie: string with element occupying the defect site path_to_defect_locpot: path to LOCPOT file of defect structure path_to_pure_locpot: path to LOCPOT file of Pure structure charge: Charge of the defected system dielectric_constant: Dielectric constant defect_site_coordinates: numpy array with fractional coordinates of defect site energy_cutoff: Cut-off of plane wave expansion get_plot: return also Matplotlib object with plot Returns: Freysoldt corrections values as a dictionary ''' # acquiring data from LOCPOT files locpot_pure = Locpot.from_file(path_to_pure_locpot) vol_data_pure = VolumetricData(locpot_pure.structure,locpot_pure.data) locpot_defect = Locpot.from_file(path_to_defect_locpot) vol_data_defect = VolumetricData(locpot_defect.structure,locpot_defect.data) parameters = {} parameters['axis_grid'] = [] parameters['bulk_planar_averages'] = [] parameters['defect_planar_averages'] = [] for i in range(0,3): parameters['axis_grid'].append(vol_data_pure.get_axis_grid(i)) parameters['bulk_planar_averages'].append(vol_data_pure.get_average_along_axis(i)) parameters['defect_planar_averages'].append(vol_data_defect.get_average_along_axis(i)) parameters['initial_defect_structure'] = locpot_defect.structure parameters['defect_frac_sc_coords'] = defect_site_coordinates structure_bulk = locpot_pure.structure defect_site = PeriodicSite(defect_specie, coords=defect_site_coordinates, lattice = locpot_pure.structure.lattice) module = importlib.import_module("pymatgen.analysis.defects.core") defect_class = getattr(module,defect_type) defect = defect_class(structure_bulk, defect_site, charge=charge, multiplicity=None) defect_entry = DefectEntry(defect,None,corrections=None,parameters=parameters) freysoldt_class = FreysoldtCorrection(dielectric_constant,energy_cutoff=energy_cutoff) freysoldt_corrections = freysoldt_class.get_correction(defect_entry) if get_plot: plt = freysoldt_class.plot(1) return freysoldt_corrections , plt else: return freysoldt_corrections
def from_file(cls, filename): (poscar, data, data_aug) = VolumetricData.parse_file(filename) return cls(poscar, data, data_aug=data_aug)