Пример #1
0
    def process_vasprun(self, dir_name, taskname, filename):
        """
        Adapted from matgendb.creator

        Process a vasprun.xml file.
        """
        vasprun_file = os.path.join(dir_name, filename)
        if self.bandstructure_mode:
            vrun = Vasprun(vasprun_file, parse_eigen=True, parse_projected_eigen=True)
        else:
            vrun = Vasprun(vasprun_file)

        d = vrun.as_dict()
        for k, v in {"formula_pretty": "pretty_formula",
                     "composition_reduced": "reduced_cell_formula",
                     "composition_unit_cell": "unit_cell_formula"}.items():
            d[k] = d.pop(v)

        for k in ["eigenvalues", "projected_eigenvalues"]:  # large storage space breaks some docs
            if k in d["output"]:
                del d["output"][k]

        comp = Composition(d["composition_unit_cell"])
        d["formula_anonymous"] = comp.anonymized_formula
        d["formula_reduced_abc"] = comp.reduced_composition.alphabetical_formula
        d["dir_name"] = os.path.abspath(dir_name)
        d["completed_at"] = str(datetime.datetime.fromtimestamp(os.path.getmtime(vasprun_file)))
        d["density"] = vrun.final_structure.density
        # replace 'crystal' with 'structure'
        d["input"]["structure"] = d["input"].pop("crystal")
        d["output"]["structure"] = d["output"].pop("crystal")
        for k, v in {"energy": "final_energy", "energy_per_atom": "final_energy_per_atom"}.items():
            d["output"][k] = d["output"].pop(v)

        if self.parse_dos and self.parse_dos != 'final':
            try:
                d["dos"] = vrun.complete_dos.as_dict()
            except:
                raise ValueError("No valid dos data exist in {}.".format(dir_name))

        if self.bandstructure_mode:
            bs = vrun.get_band_structure(line_mode=(self.bandstructure_mode == "line"))
        else:
            bs = vrun.get_band_structure()

        d["bandstructure"] = bs.as_dict()

        d["output"]["vbm"] = bs.get_vbm()["energy"]
        d["output"]["cbm"] = bs.get_cbm()["energy"]
        bs_gap = bs.get_band_gap()
        d["output"]["bandgap"] = bs_gap["energy"]
        d["output"]["is_gap_direct"] = bs_gap["direct"]
        d["output"]["is_metal"] = bs.is_metal()
        d["task"] = {"type": taskname, "name": taskname}
        # phonon-dfpt
        if hasattr(vrun, "force_constants"):
            d["output"]["force_constants"] = vrun.force_constants.tolist()
            d["output"]["normalmode_eigenvals"] = vrun.normalmode_eigenvals.tolist()
            d["output"]["normalmode_eigenvecs"] = vrun.normalmode_eigenvecs.tolist()
        return d
Пример #2
0
 def test_methods(self):
     v = Vasprun(os.path.join(test_dir, "vasprun_Si_bands.xml"))
     p = BSDOSPlotter()
     plt = p.get_plot(v.get_band_structure(
         kpoints_filename=os.path.join(test_dir, "KPOINTS_Si_bands")))
     plt = p.get_plot(v.get_band_structure(
         kpoints_filename=os.path.join(test_dir, "KPOINTS_Si_bands")),
         v.complete_dos)
Пример #3
0
 def test_methods(self):
     v = Vasprun(os.path.join(test_dir, "vasprun_Si_bands.xml"))
     p = BSDOSPlotter()
     plt = p.get_plot(v.get_band_structure(
         kpoints_filename=os.path.join(test_dir, "KPOINTS_Si_bands")))
     plt = p.get_plot(v.get_band_structure(
         kpoints_filename=os.path.join(test_dir, "KPOINTS_Si_bands")),
         v.complete_dos)
Пример #4
0
 def test_methods(self):
     v = Vasprun(
         os.path.join(PymatgenTest.TEST_FILES_DIR, "vasprun_Si_bands.xml"))
     p = BSDOSPlotter()
     plt = p.get_plot(
         v.get_band_structure(kpoints_filename=os.path.join(
             PymatgenTest.TEST_FILES_DIR, "KPOINTS_Si_bands")))
     plt.close()
     plt = p.get_plot(
         v.get_band_structure(kpoints_filename=os.path.join(
             PymatgenTest.TEST_FILES_DIR, "KPOINTS_Si_bands")),
         v.complete_dos,
     )
     plt.close("all")
Пример #5
0
    def run_task(self, fw_spec):
        vr_path = zpath(self.get("vasprun_path", "vasprun.xml"))
        min_gap = self.get("min_gap", None)
        max_gap = self.get("max_gap", None)

        if not os.path.exists(vr_path):
            relax_paths = sorted(glob.glob(vr_path + ".relax*"))
            if relax_paths:
                if len(relax_paths) > 9:
                    raise ValueError(
                        "CheckBandgap doesn't properly handle >9 relaxations!")
                vr_path = relax_paths[-1]

        logger.info("Checking the gap of file: {}".format(vr_path))
        vr = Vasprun(vr_path)
        gap = vr.get_band_structure().get_band_gap()["energy"]
        stored_data = {"band_gap": gap}
        logger.info("The gap is: {}. Min gap: {}. Max gap: {}".format(
            gap, min_gap, max_gap))

        if (min_gap and gap < min_gap) or (max_gap and gap > max_gap):
            logger.info("CheckBandgap: failed test!")
            return FWAction(stored_data=stored_data,
                            exit=True,
                            defuse_workflow=True)

        return FWAction(stored_data=stored_data)
Пример #6
0
    def run_task(self, fw_spec):
        vr_path = self.get("vasprun_path", "vasprun.xml")
        min_gap = self.get("min_gap", None)
        max_gap = self.get("max_gap", None)

        vr_path = zpath(vr_path)

        if not os.path.exists(vr_path):
            relax_paths = sorted(glob.glob(vr_path + ".relax*"), reverse=True)
            if relax_paths:
                if len(relax_paths) > 9:
                    raise ValueError(
                        "CheckBandgap doesn't properly handle >9 relaxations!")
                vr_path = relax_paths[0]

        print("Checking the gap of file: {}".format(vr_path))
        vr = Vasprun(vr_path)
        gap = vr.get_band_structure().get_band_gap()["energy"]
        stored_data = {"band_gap": gap}
        print("The gap is: {}. Min gap: {}. Max gap: {}".format(
            gap, min_gap, max_gap))

        if min_gap and gap < min_gap or max_gap and gap > max_gap:
            print("Defusing based on band gap!")
            return FWAction(stored_data=stored_data,
                            exit=True,
                            defuse_workflow=True)

        print("Gap OK...")
        return FWAction(stored_data=stored_data)
Пример #7
0
    def run_task(self, fw_spec):
        vr_path = self.get("vasprun_path", "vasprun.xml")
        min_gap = self.get("min_gap", None)
        max_gap = self.get("max_gap", None)

        vr_path = zpath(vr_path)

        if not os.path.exists(vr_path):
            relax_paths = sorted(glob.glob(vr_path + ".relax*"), reverse=True)
            if relax_paths:
                if len(relax_paths) > 9:
                    raise ValueError(
                        "CheckBandgap doesn't properly handle >9 relaxations!")
                vr_path = relax_paths[0]


        print("Checking the gap of file: {}".format(vr_path))
        vr = Vasprun(vr_path)
        gap = vr.get_band_structure().get_band_gap()["energy"]
        stored_data = {"band_gap": gap}
        print("The gap is: {}. Min gap: {}. Max gap: {}".format(gap,
                                                                min_gap,
                                                                max_gap))

        if min_gap and gap < min_gap or max_gap and gap > max_gap:
            print("Defusing based on band gap!")
            return FWAction(stored_data=stored_data, exit=True,
                            defuse_workflow=True)

        print("Gap OK...")
        return FWAction(stored_data=stored_data)
Пример #8
0
    def run_task(self, fw_spec):
        vr_path = zpath(self.get("vasprun_path", "vasprun.xml"))
        min_gap = self.get("min_gap", None)
        max_gap = self.get("max_gap", None)

        if not os.path.exists(vr_path):
            relax_paths = sorted(glob.glob(vr_path + ".relax*"))
            if relax_paths:
                if len(relax_paths) > 9:
                    raise ValueError(
                        "CheckBandgap doesn't properly handle >9 relaxations!")
                vr_path = relax_paths[-1]

        logger.info("Checking the gap of file: {}".format(vr_path))
        vr = Vasprun(vr_path)
        gap = vr.get_band_structure().get_band_gap()["energy"]
        stored_data = {"band_gap": gap}
        logger.info(
            "The gap is: {}. Min gap: {}. Max gap: {}".format(gap, min_gap,
                                                              max_gap))

        if (min_gap and gap < min_gap) or (max_gap and gap > max_gap):
            logger.info("CheckBandgap: failed test!")
            return FWAction(stored_data=stored_data, exit=True,
                            defuse_workflow=True)

        return FWAction(stored_data=stored_data)
Пример #9
0
    def get_bandgap_from_aexx(self,
                              structure,
                              aexx,
                              outdir=None,
                              previous=None):
        vasprun_location = os.path.join(outdir,
                                        str(aexx).zfill(2), self.names[-1],
                                        'vasprun.xml')

        # try:
        #     vasprun = Vasprun(vasprun_location, parse_projected_eigen=False)
        #     band_gap = vasprun.get_band_structure().get_band_gap()['energy']
        # except:
        def set_aexx(vasp: Vasp, structure=None):
            vasp.add_keyword('aexx', aexx / 100)
            return vasp

        for x in self.functionals:  # Set nupdown
            x.modifications.append(set_aexx)
        (_, output) = super().call_with_output(structure,
                                               outdir=os.path.join(
                                                   outdir,
                                                   str(aexx).zfill(2)),
                                               previous=previous)
        vasprun = Vasprun(vasprun_location, parse_projected_eigen=False)
        band_gap = vasprun.get_band_structure().get_band_gap()['energy']
        return (band_gap, output)
Пример #10
0
def spin_boltz(vrunfile="", spin=1, k_latt=1.0, write_json=True):
    fname = vrunfile.replace("vasprun.xml", "boltz2data.json")
    if not os.path.isfile(fname):
        kp = vrunfile.replace("vasprun.xml", "KPOINTS")
        v = Vasprun(vrunfile)
        nelect = v.parameters["NELECT"]
        bs = v.get_band_structure(kp, line_mode=False)
        # doping=10.**np.arange(20,22)
        temp_r = np.array([300, 400, 500, 600, 700, 800])
        doping = np.array([0, 10**18, 10**19, 10**20, 10**21, 10**22])
        loader = BandstructureLoader(bs,
                                     v.structures[-1],
                                     spin=spin,
                                     nelect=nelect)
        bztInterp = BztInterpolator(loader, lpfac=2, curvature=True)
        bztTransp = BztTransportProperties(bztInterp,
                                           doping=doping,
                                           temp_r=temp_r)
        xx = bztTransp.compute_properties_doping(doping=doping)
        # 4 temps, 2 doping
        Conductivity_doping = bztTransp.Conductivity_doping
        Seebeck_doping = bztTransp.Seebeck_doping
        Kappa_doping = bztTransp.Kappa_doping
        Effective_mass_doping = bztTransp.Effective_mass_doping
        Power_Factor_doping = bztTransp.Power_Factor_doping
        mu_r_eV = bztTransp.mu_r_eV

        info = {}
        info["mu_r_eV"] = mu_r_eV
        info["temp_r"] = temp_r
        info["doping"] = doping
        info["Conductivity_doping"] = Conductivity_doping
        info["Seebeck_doping"] = Seebeck_doping
        info["Kappa_doping"] = Kappa_doping
        info["Effective_mass_doping"] = Effective_mass_doping
        info["Power_Factor_doping"] = Power_Factor_doping

        info["Conductivity_mu"] = bztTransp.Conductivity_mu
        info["Seebeck_mu"] = bztTransp.Seebeck_mu
        info["Kappa_mu"] = bztTransp.Kappa_mu
        info["Power_Factor_mu"] = bztTransp.Power_Factor_mu
        info["Effective_mass_mu"] = bztTransp.Effective_mass_mu
        info[
            "Hall_carrier_conc_trace_mu"] = bztTransp.Hall_carrier_conc_trace_mu
        zt = []
        temp_zt = []
        for i, ii in enumerate(info["temp_r"]):
            for j, k in zip(info["Power_Factor_mu"][i], info["Kappa_mu"][i]):
                temp_zt.append(0.001 * j * ii / (k + k_latt))
            zt.append(temp_zt)
            temp_zt = []
        zt = np.array(zt)
        info["zt_mu"] = zt
        if write_json == True:
            f = open(fname, "w")
            f.write(json.dumps(info, cls=MontyEncoder))
            f.close()
        return info
    else:
        print("File exists")
Пример #11
0
    def setUp(self):
        vr = Vasprun(os.path.join(amset_files, 'vasprun.xml'))
        bs = vr.get_band_structure()
        num_electrons = vr.parameters['NELECT']

        self.kpoints = np.array(vr.actual_kpoints)
        self.interpolater = BoltzTraP2Interpolater(bs, num_electrons)
Пример #12
0
def select_one_band_structure():
   check_matplotlib()
   step_count=1
   filename='vasprun.xml'
   check_file(filename)
   proc_str="Reading Data From "+ filename +" File ..."
   procs(proc_str,step_count,sp='-->>')
   vsr=Vasprun(filename)

   step_count+=1
   filename='KPOINTS'
   check_file(filename)
   proc_str="Reading Data From "+ filename +" File ..."
   procs(proc_str,step_count,sp='-->>')
   bands = vsr.get_band_structure(filename, line_mode=True, efermi=vsr.efermi)
   nelect=vsr.parameters['NELECT']
   nbands=bands.nb_bands
   if vsr.is_spin:
      proc_str="This Is a Spin-polarized Calculation."
      procs(proc_str,0,sp='-->>')
      ISPIN=2
   else:
      if vsr.parameters['LNONCOLLINEAR']:
         proc_str="This Is a Non-Collinear Calculation."
         procs(proc_str,0,sp='-->>')
         ISPIN=3
      else:
         proc_str="This Is a Non-Spin Calculation."
         procs(proc_str,0,sp='-->>')
         ISPIN=1
   proc_str="Total band number is "+str(nbands)
   procs(proc_str,0,sp='-->>')
   proc_str="Total electron number is "+str(nelect)
   procs(proc_str,0,sp='-->>')

   print("which band would like to select ?")
   wait_sep()
   in_str=""
   while in_str=="":
         in_str=input().strip()
   selected_band=int(in_str)

   step_count+=1
   filename="BAND_"+str(selected_band)+'.dat'
   proc_str="Writting Selected Band Structure Data to "+ filename +" File ..."
   procs(proc_str,step_count,sp='-->>')
   if ISPIN==1 or ISPIN==3:
      band_data=bands.bands[Spin.up][selected_band-1]-vsr.efermi
      data=np.vstack((bands.distance,band_data)).T
      head_line="#%(key1)+12s%(key2)+13s"%{'key1':'K-Distance','key2':'Energy(ev)'}
      write_col_data(filename,data,head_line,len(band_data))
   else:
      band_data_up=bands.bands[Spin.up][selected_band-1]-vsr.efermi
      band_data_down=bands.bands[Spin.down][selected_band-1]-vsr.efermi
      data=np.vstack((bands.distance,band_data_up,band_data_down)).T
      head_line="#%(key1)+12s%(key2)+13s%(key3)+15s"%{'key1':'K-Distance','key2':'UpEnergy(ev)','key3':'DownEnergy(ev)'}
      write_col_data(filename,data,head_line,len(band_data_up))
   return
Пример #13
0
    def run_task(self, fw_spec):

        kwargs = self.get("override_default_vasp_params")
        potcar_spec = self.get("potcar_spec", False)

        os.chdir(os.getcwd())
        vrun = Vasprun("vasprun.xml", parse_potcar_file=False)
        bandgap = vrun.get_band_structure().get_band_gap()["energy"]
        structure = vrun.final_structure
        vis = MPScanRelaxSet(structure, bandgap=bandgap, **kwargs)
        vis.write_input(".", potcar_spec=potcar_spec)
Пример #14
0
    def setUp(self):
        vr = Vasprun(os.path.join(gaas_files, "vasprun.xml.gz"),
                     parse_projected_eigen=True)
        bs = vr.get_band_structure()
        num_electrons = vr.parameters["NELECT"]

        self.kpoints = np.array(vr.actual_kpoints)
        self.interpolater = Interpolator(bs,
                                         num_electrons,
                                         interpolate_projections=True,
                                         interpolation_factor=1)
Пример #15
0
    def from_vasprun(cls, vasprun, **kwargs):
        from pymatgen.io.vasp import Vasprun

        if isinstance(vasprun, str):
            vasprun_gz = vasprun + ".gz"

            if Path(vasprun).exists():
                vasprun = Vasprun(vasprun)

            elif Path(vasprun_gz).exists():
                vasprun = Vasprun(vasprun_gz)

        bandstructure = vasprun.get_band_structure()
        nelect = vasprun.parameters["NELECT"]
        soc = vasprun.parameters["LSORBIT"]
        return cls(bandstructure, nelect, soc=soc, **kwargs)
Пример #16
0
    def test_densify(self):
        # mesh = np.array([100, 100, 100])
        # kpts = get_dense_kpoint_mesh_spglib(mesh, spg_order=True, shift=0.)
        # extra_points = np.array([[0.001, 0, 0], [0.002, 0, 0], [0.003, 0, 0]])
        # pv = PeriodicVoronoi(Lattice([3, 0, 0, 0, 3, 0, 0, 0, 3]),
        #                      kpts, mesh, extra_points)
        # vols = pv.compute_volumes()
        # idx = np.argsort(vols)
        # all_k = np.concatenate([kpts, extra_points])
        # print(all_k[idx][:12])
        # print(vols[idx][:12])

        initialize_amset_logger(log_error_traceback=True)

        vr = Vasprun(os.path.join(amset_files, "vasprun.xml.gz"),
                     parse_projected_eigen=True)
        bs = vr.get_band_structure()
        inter = Interpolater(bs,
                             vr.parameters["NELECT"],
                             interpolate_projections=True,
                             interpolation_factor=5)
        amset_data = inter.get_amset_data(energy_cutoff=2, bandgap=1.33)
        amset_data.calculate_dos()
        amset_data.set_doping_and_temperatures(doping=np.array([1e13]),
                                               temperatures=np.array([300]))
        amset_data.calculate_fd_cutoffs(fd_tolerance=0.000001)

        densifier = BandDensifier(inter,
                                  amset_data,
                                  energy_cutoff=2,
                                  bandgap=1.33)
        # print(amset_data.ir_to_full_kpoint_mapping[:200])
        # print(max(amset_data.ir_to_full_kpoint_mapping))
        # print(len(amset_data.ir_to_full_kpoint_mapping))
        print("IR Kpoints idx max", max(amset_data.ir_kpoints_idx))
        amset_data.set_extra_kpoints(*densifier.densify(0.008))
        print(amset_data.ir_to_full_kpoint_mapping.max())
        print(len(amset_data.ir_kpoints))
        print(len(amset_data.ir_kpoints_idx))
        print(max(amset_data.ir_kpoints_idx))
        # print(max(amset_data.ir_to_full_kpoint_mapping))
        # print(len(amset_data.ir_to_full_kpoint_mapping))

        # x = extra_kpts[0][2]
        all_kpoints = amset_data.full_kpoints
        weights = amset_data.kpoint_weights
        mask = (all_kpoints[:, 2] == 0.)

        center_points = all_kpoints[mask][:, :2]
        center_labels = map("{:.3g}".format, weights[mask])

        from scipy.spatial import Voronoi, voronoi_plot_2d
        vor = Voronoi(center_points)
        import matplotlib
        matplotlib.use("TkAgg")
        import matplotlib.pyplot as plt
        voronoi_plot_2d(vor)

        # plt.xlim((-0.48, -0.38))
        # plt.ylim((-0.48, -0.38))
        ax = plt.gca()

        for i, txt in enumerate(center_labels):
            kx = center_points[i][0]
            ky = center_points[i][1]
            if -0.38 > kx > -0.48 and -0.38 > ky > -0.48:
                ax.annotate(str(txt), (kx, ky))

        plt.show()
Пример #17
0
    def process_vasprun(self, dir_name, taskname, filename):
        """
        Adapted from matgendb.creator

        Process a vasprun.xml file.
        """
        vasprun_file = os.path.join(dir_name, filename)
        if self.bandstructure_mode:
            vrun = Vasprun(vasprun_file,
                           parse_eigen=True,
                           parse_projected_eigen=True)
        else:
            vrun = Vasprun(vasprun_file)

        d = vrun.as_dict()
        for k, v in {
                "formula_pretty": "pretty_formula",
                "composition_reduced": "reduced_cell_formula",
                "composition_unit_cell": "unit_cell_formula"
        }.items():
            d[k] = d.pop(v)

        for k in ["eigenvalues", "projected_eigenvalues"
                  ]:  # large storage space breaks some docs
            if k in d["output"]:
                del d["output"][k]

        comp = Composition(d["composition_unit_cell"])
        d["formula_anonymous"] = comp.anonymized_formula
        d["formula_reduced_abc"] = comp.reduced_composition.alphabetical_formula
        d["dir_name"] = os.path.abspath(dir_name)
        d["completed_at"] = str(
            datetime.datetime.fromtimestamp(os.path.getmtime(vasprun_file)))
        d["density"] = vrun.final_structure.density
        # replace 'crystal' with 'structure'
        d["input"]["structure"] = d["input"].pop("crystal")
        d["output"]["structure"] = d["output"].pop("crystal")
        for k, v in {
                "energy": "final_energy",
                "energy_per_atom": "final_energy_per_atom"
        }.items():
            d["output"][k] = d["output"].pop(v)

        if self.parse_dos and self.parse_dos != 'final':
            try:
                d["dos"] = vrun.complete_dos.as_dict()
            except:
                raise ValueError(
                    "No valid dos data exist in {}.".format(dir_name))

        if self.bandstructure_mode:
            bs = vrun.get_band_structure(
                line_mode=(self.bandstructure_mode == "line"))
        else:
            bs = vrun.get_band_structure()

        d["bandstructure"] = bs.as_dict()

        d["output"]["vbm"] = bs.get_vbm()["energy"]
        d["output"]["cbm"] = bs.get_cbm()["energy"]
        bs_gap = bs.get_band_gap()
        d["output"]["bandgap"] = bs_gap["energy"]
        d["output"]["is_gap_direct"] = bs_gap["direct"]
        d["output"]["is_metal"] = bs.is_metal()
        d["task"] = {"type": taskname, "name": taskname}
        # phonon-dfpt
        if hasattr(vrun, "force_constants"):
            d["output"]["force_constants"] = vrun.force_constants.tolist()
            d["output"][
                "normalmode_eigenvals"] = vrun.normalmode_eigenvals.tolist()
            d["output"][
                "normalmode_eigenvecs"] = vrun.normalmode_eigenvecs.tolist()
        return d
Пример #18
0
    def process_vasprun(self, dir_name, taskname, filename):
        """
        Adapted from matgendb.creator

        Process a vasprun.xml file.
        """
        vasprun_file = os.path.join(dir_name, filename)

        vrun = Vasprun(vasprun_file, parse_potcar_file=self.parse_potcar_file)

        d = vrun.as_dict()

        # rename formula keys
        for k, v in {
                "formula_pretty": "pretty_formula",
                "composition_reduced": "reduced_cell_formula",
                "composition_unit_cell": "unit_cell_formula"
        }.items():
            d[k] = d.pop(v)

        for k in ["eigenvalues", "projected_eigenvalues"
                  ]:  # large storage space breaks some docs
            if k in d["output"]:
                del d["output"][k]

        comp = Composition(d["composition_unit_cell"])
        d["formula_anonymous"] = comp.anonymized_formula
        d["formula_reduced_abc"] = comp.reduced_composition.alphabetical_formula
        d["dir_name"] = os.path.abspath(dir_name)
        d["completed_at"] = str(
            datetime.datetime.fromtimestamp(os.path.getmtime(vasprun_file)))
        d["density"] = vrun.final_structure.density

        # replace 'crystal' with 'structure'
        d["input"]["structure"] = d["input"].pop("crystal")
        d["output"]["structure"] = d["output"].pop("crystal")
        for k, v in {
                "energy": "final_energy",
                "energy_per_atom": "final_energy_per_atom"
        }.items():
            d["output"][k] = d["output"].pop(v)

        # Process bandstructure and DOS
        if self.bandstructure_mode != False:
            bs = self.process_bandstructure(vrun)
            if bs:
                d["bandstructure"] = bs

        if self.parse_dos != False:
            dos = self.process_dos(vrun)
            if dos:
                d["dos"] = dos

        # Parse electronic information if possible.
        # For certain optimizers this is broken and we don't get an efermi resulting in the bandstructure
        try:
            bs = vrun.get_band_structure()
            bs_gap = bs.get_band_gap()
            d["output"]["vbm"] = bs.get_vbm()["energy"]
            d["output"]["cbm"] = bs.get_cbm()["energy"]
            d["output"]["bandgap"] = bs_gap["energy"]
            d["output"]["is_gap_direct"] = bs_gap["direct"]
            d["output"]["is_metal"] = bs.is_metal()
            if not bs_gap["direct"]:
                d["output"]["direct_gap"] = bs.get_direct_band_gap()
            if isinstance(bs, BandStructureSymmLine):
                d["output"]["transition"] = bs_gap["transition"]

        except Exception:
            logger.warning("Error in parsing bandstructure")
            if vrun.incar["IBRION"] == 1:
                logger.warning(
                    "Vasp doesn't properly output efermi for IBRION == 1")
            if self.bandstructure_mode is True:
                logger.error(traceback.format_exc())
                logger.error("Error in " + os.path.abspath(dir_name) + ".\n" +
                             traceback.format_exc())
                raise

        # Should roughly agree with information from .get_band_structure() above, subject to tolerances
        # If there is disagreement, it may be related to VASP incorrectly assigning the Fermi level
        try:
            band_props = vrun.eigenvalue_band_properties
            d["output"]["eigenvalue_band_properties"] = {
                "bandgap": band_props[0],
                "cbm": band_props[1],
                "vbm": band_props[2],
                "is_gap_direct": band_props[3]
            }
        except Exception:
            logger.warning("Error in parsing eigenvalue band properties")

        # store run name and location ,e.g. relax1, relax2, etc.
        d["task"] = {"type": taskname, "name": taskname}

        # include output file names
        d["output_file_paths"] = self.process_raw_data(dir_name,
                                                       taskname=taskname)

        # parse axially averaged locpot
        if "locpot" in d["output_file_paths"] and self.parse_locpot:
            locpot = Locpot.from_file(
                os.path.join(dir_name, d["output_file_paths"]["locpot"]))
            d["output"]["locpot"] = {
                i: locpot.get_average_along_axis(i)
                for i in range(3)
            }

        if self.store_volumetric_data:
            for file in self.store_volumetric_data:
                if file in d["output_file_paths"]:
                    try:
                        # assume volumetric data is all in CHGCAR format
                        data = Chgcar.from_file(
                            os.path.join(dir_name,
                                         d["output_file_paths"][file]))
                        d[file] = data.as_dict()
                    except:
                        raise ValueError("Failed to parse {} at {}.".format(
                            file, d["output_file_paths"][file]))

        # parse force constants
        if hasattr(vrun, "force_constants"):
            d["output"]["force_constants"] = vrun.force_constants.tolist()
            d["output"][
                "normalmode_eigenvals"] = vrun.normalmode_eigenvals.tolist()
            d["output"][
                "normalmode_eigenvecs"] = vrun.normalmode_eigenvecs.tolist()

        # perform Bader analysis using Henkelman bader
        if self.parse_bader and "chgcar" in d["output_file_paths"]:
            suffix = '' if taskname == 'standard' else ".{}".format(taskname)
            bader = bader_analysis_from_path(dir_name, suffix=suffix)
            d["bader"] = bader

        return d
Пример #19
0
    def process_vasprun(self, dir_name, taskname, filename):
        """
        Adapted from matgendb.creator

        Process a vasprun.xml file.
        """
        vasprun_file = os.path.join(dir_name, filename)

        vrun = Vasprun(vasprun_file)

        d = vrun.as_dict()

        # rename formula keys
        for k, v in {"formula_pretty": "pretty_formula",
                     "composition_reduced": "reduced_cell_formula",
                     "composition_unit_cell": "unit_cell_formula"}.items():
            d[k] = d.pop(v)

        for k in ["eigenvalues", "projected_eigenvalues"]:  # large storage space breaks some docs
            if k in d["output"]:
                del d["output"][k]

        comp = Composition(d["composition_unit_cell"])
        d["formula_anonymous"] = comp.anonymized_formula
        d["formula_reduced_abc"] = comp.reduced_composition.alphabetical_formula
        d["dir_name"] = os.path.abspath(dir_name)
        d["completed_at"] = str(datetime.datetime.fromtimestamp(os.path.getmtime(vasprun_file)))
        d["density"] = vrun.final_structure.density

        # replace 'crystal' with 'structure'
        d["input"]["structure"] = d["input"].pop("crystal")
        d["output"]["structure"] = d["output"].pop("crystal")
        for k, v in {"energy": "final_energy", "energy_per_atom": "final_energy_per_atom"}.items():
            d["output"][k] = d["output"].pop(v)

        # Process bandstructure and DOS
        if self.bandstructure_mode != False:
            bs = self.process_bandstructure(vrun)
            if bs:
                d["bandstructure"] = bs

        if self.parse_dos != False:
            dos = self.process_dos(vrun)
            if dos:
                d["dos"] = dos

        # Parse electronic information if possible.
        # For certain optimizers this is broken and we don't get an efermi resulting in the bandstructure
        try:
            bs = vrun.get_band_structure()
            bs_gap = bs.get_band_gap()
            d["output"]["vbm"] = bs.get_vbm()["energy"]
            d["output"]["cbm"] = bs.get_cbm()["energy"]
            d["output"]["bandgap"] = bs_gap["energy"]
            d["output"]["is_gap_direct"] = bs_gap["direct"]
            d["output"]["is_metal"] = bs.is_metal()
            if not bs_gap["direct"]:
                d["output"]["direct_gap"] = bs.get_direct_band_gap()
            if isinstance(bs, BandStructureSymmLine):
                d["output"]["transition"] = bs_gap["transition"]

        except Exception:
            logger.warning("Error in parsing bandstructure")
            if vrun.incar["IBRION"] == 1:
                logger.warning("Vasp doesn't properly output efermi for IBRION == 1")
            if self.bandstructure_mode is True:
                logger.error(traceback.format_exc())
                logger.error("Error in " + os.path.abspath(dir_name) + ".\n" + traceback.format_exc())
                raise

        # store run name and location ,e.g. relax1, relax2, etc.
        d["task"] = {"type": taskname, "name": taskname}

        # include output file names
        d["output_file_paths"] = self.process_raw_data(dir_name, taskname=taskname)

        # parse axially averaged locpot
        if "locpot" in d["output_file_paths"] and self.parse_locpot:
            locpot = Locpot.from_file(os.path.join(dir_name, d["output_file_paths"]["locpot"]))
            d["output"]["locpot"] = {i: locpot.get_average_along_axis(i) for i in range(3)}

        if self.parse_chgcar != False:
            # parse CHGCAR file only for static calculations
            # TODO require static run later
            # if self.parse_chgcar == True and vrun.incar.get("NSW", 0) < 1:
            try:
                chgcar = self.process_chgcar(os.path.join(dir_name, d["output_file_paths"]["chgcar"]))
            except:
                raise ValueError("No valid charge data exist")
            d["chgcar"] = chgcar

        if self.parse_aeccar != False:
            try:
                chgcar = self.process_chgcar(os.path.join(dir_name, d["output_file_paths"]["aeccar0"]))
            except:
                raise ValueError("No valid charge data exist")
            d["aeccar0"] = chgcar
            try:
                chgcar = self.process_chgcar(os.path.join(dir_name, d["output_file_paths"]["aeccar2"]))
            except:
                raise ValueError("No valid charge data exist")
            d["aeccar2"] = chgcar

        # parse force constants
        if hasattr(vrun, "force_constants"):
            d["output"]["force_constants"] = vrun.force_constants.tolist()
            d["output"]["normalmode_eigenvals"] = vrun.normalmode_eigenvals.tolist()
            d["output"]["normalmode_eigenvecs"] = vrun.normalmode_eigenvecs.tolist()

        # Try and perform bader
        if self.parse_bader:
            try:
                bader = bader_analysis_from_path(dir_name, suffix=".{}".format(taskname))
            except Exception as e:
                bader = "Bader analysis failed: {}".format(e)
            d["bader"] = bader

        return d
Пример #20
0
v = Vasprun('./vasprun.xml', parse_dos=True)
cdos = v.complete_dos
element_dos = cdos.get_element_dos()
plotter = DosPlotter()
plotter.add_dos_dict(element_dos)
plotter.save_plot('plots/dos.pdf', img_format='pdf', xlim=None, ylim=None)
# plotter.save_plot('spin-up_dos.pdf', img_format='pdf', xlim= None, ylim = [0,None])   # up-spin dos
"""
Plot Band
"""

from pymatgen.io.vasp import BSVasprun
from pymatgen.electronic_structure.plotter import BSPlotter

v = BSVasprun('./vasprun.xml', parse_projected_eigen=True)
bs = v.get_band_structure(kpoints_filename='./KPOINTS', line_mode=True)
bsplot = BSPlotter(bs)

bsplot.get_plot(zero_to_efermi=True, ylim=[-5, 5]).savefig('plots/band.pdf')

# add some features
ax = plt.gca()
#ax.set_title("Bandstructure", fontsize = 40) # use this for setting title
xlim = ax.get_xlim()
ax.hlines(0, xlim[0], xlim[1], linestyles="dashed", color="black")

# add legend
ax.plot((), (), "b-", label="spin up")
ax.plot((), (), "r--", label="spin-down")
ax.legend(fontsize=16, loc="upper left")
Пример #21
0
from pymatgen.io.vasp import Vasprun
from pymatgen.electronic_structure.plotter import BSPlotter, BSPlotterProjected

vr = Vasprun("nself/vasprun.xml")
bs = vr.get_band_structure(kpoints_filename="nself/KPOINTS", line_mode=True)
bsp = BSPlotter(bs)
#plt = bsp.get_elt_projected_plots(zero_to_efermi=False)
#plt.savefig("band_structure.png", format="png")
bsp.save_plot(filename="band_structure.png", img_format="png")
Пример #22
0
if __name__ == "__main__":
    # read data
    # ---------

    # kpoints labels
    labels = [r"$L$", r"$\Gamma$", r"$X$", r"$U,K$", r"$\Gamma$"]

    # density of states
    dosrun = Vasprun("./DOS/vasprun.xml")
    spd_dos = dosrun.complete_dos.get_spd_dos()

    # bands
    run = Vasprun("./Bandes/vasprun.xml", parse_projected_eigen=True)
    bands = run.get_band_structure("./Bandes/KPOINTS",
                                   line_mode=True,
                                   efermi=dosrun.efermi)

    # set up matplotlib plot
    # ----------------------

    # general options for plot
    font = {'family': 'serif', 'size': 24}
    plt.rc('font', **font)

    # set up 2 graph with aspec ration 2/1
    # plot 1: bands diagram
    # plot 2: Density of States
    gs = GridSpec(1, 2, width_ratios=[2, 1])
    fig = plt.figure(figsize=(11.69, 8.27))
    fig.suptitle("Bands diagram of silicon")
Пример #23
0
def band_structure():
    check_matplotlib()
    step_count=1

    filename='vasprun.xml'
    check_file(filename)
    proc_str="Reading Data From "+ filename +" File ..."
    procs(proc_str,step_count,sp='-->>')
    vsr=Vasprun(filename)

    step_count+=1
    filename='KPOINTS'
    check_file(filename)
    proc_str="Reading Data From "+ filename +" File ..."
    procs(proc_str,step_count,sp='-->>')
    bands = vsr.get_band_structure(filename, line_mode=True, efermi=vsr.efermi)

    step_count+=1
    filename='OUTCAR'
    check_file(filename)
    proc_str="Reading Data From "+ filename +" File ..."
    procs(proc_str,step_count,sp='-->>')
    outcar=Outcar('OUTCAR')
    mag=outcar.as_dict()['total_magnetization']

    if vsr.is_spin:
       proc_str="This Is a Spin-polarized Calculation."
       procs(proc_str,0,sp='-->>')
       tdos=vsr.tdos
       SpinUp_gap=tdos.get_gap(spin=Spin.up) 
       cbm_vbm_up=tdos.get_cbm_vbm(spin=Spin.up)
       SpinDown_gap=tdos.get_gap(spin=Spin.down) 
       cbm_vbm_down=tdos.get_cbm_vbm(spin=Spin.up)

       if SpinUp_gap > min_gap and SpinDown_gap > min_gap:
          is_metal=False
          is_semimetal=False
       elif SpinUp_gap > min_gap and SpinDown_gap < min_gap:
          is_metal=False
          is_semimetal=True
       elif SpinUp_gap < min_gap and SpinDown_gap > min_gap:
          is_metal=False
          is_semimetal=True
       elif SpinUp_gap < min_gap and SpinDown_gap < min_gap:
          is_metal=True
          is_semimetal=False
          
       if is_metal:   
          proc_str="This Material Is a Metal."
          procs(proc_str,0,sp='-->>')
       if not is_metal and is_semimetal:
          proc_str="This Material Is a Semimetal."
          procs(proc_str,0,sp='-->>')
       else:
          proc_str="This Material Is a Semiconductor."
          procs(proc_str,0,sp='-->>')
          proc_str="Total magnetization is "+str(mag)
          procs(proc_str,0,sp='-->>')
          if mag > min_mag:
             proc_str="SpinUp  : vbm=%f eV cbm=%f eV gap=%f eV"%(cbm_vbm_up[1],cbm_vbm_up[0],SpinUp_gap)
             procs(proc_str,0,sp='-->>')
             proc_str="SpinDown: vbm=%f eV cbm=%f eV gap=%f eV"%(cbm_vbm_down[1],cbm_vbm_down[0],SpinUp_gap)
             procs(proc_str,0,sp='-->>')
          else:
             proc_str="SpinUp  : vbm=%f eV cbm=%f eV gap=%f eV"%(cbm_vbm_up[1],cbm_vbm_up[0],SpinUp_gap)
             procs(proc_str,0,sp='-->>')
       step_count+=1
       filename="BAND.dat"
       proc_str="Writting Band Structure Data to "+ filename +" File ..."
       procs(proc_str,step_count,sp='-->>')
       band_data_up=bands.bands[Spin.up]
       band_data_down=bands.bands[Spin.down]
       y_data_up=band_data_up.reshape(1,band_data_up.shape[0]*band_data_up.shape[1])[0]-vsr.efermi #shift fermi level to 0
       y_data_down=band_data_down.reshape(1,band_data_down.shape[0]*band_data_down.shape[1])[0]-vsr.efermi #shift fermi level to 0
       x_data=np.array(bands.distance*band_data_up.shape[0])
       data=np.vstack((x_data,y_data_up,y_data_down)).T
       head_line="#%(key1)+12s%(key2)+13s%(key3)+15s"%{'key1':'K-Distance','key2':'UpEnergy(ev)','key3':'DownEnergy(ev)'}
       write_col_data(filename,data,head_line,band_data_up.shape[1])
 
    else:
       if vsr.parameters['LNONCOLLINEAR']:
          proc_str="This Is a Non-Collinear Calculation."
       else:
           proc_str="This Is a Non-Spin Calculation."
       procs(proc_str,0,sp='-->>')
       cbm=bands.get_cbm()['energy']
       vbm=bands.get_vbm()['energy']
       gap=bands.get_band_gap()['energy']
       if not bands.is_metal():
          proc_str="This Material Is a Semiconductor."
          procs(proc_str,0,sp='-->>')
          proc_str="vbm=%f eV cbm=%f eV gap=%f eV"%(vbm,cbm,gap)
          procs(proc_str,0,sp='-->>')
       else:
          proc_str="This Material Is a Metal."
          procs(proc_str,0,sp='-->>')
       
       step_count+=1
       filename3="BAND.dat"
       proc_str="Writting Band Structure Data to "+ filename3 +" File ..."
       procs(proc_str,step_count,sp='-->>')
       band_data=bands.bands[Spin.up]
       y_data=band_data.reshape(1,band_data.shape[0]*band_data.shape[1])[0]-vsr.efermi #shift fermi level to 0
       x_data=np.array(bands.distance*band_data.shape[0])
       data=np.vstack((x_data,y_data)).T
       head_line="#%(key1)+12s%(key2)+13s"%{'key1':'K-Distance','key2':'Energy(ev)'}
       write_col_data(filename3,data,head_line,band_data.shape[1])
       step_count+=1
       bsp=BSPlotter(bands)
       filename4="HighSymmetricPoints.dat"
       proc_str="Writting Label infomation to "+ filename4 +" File ..."
       procs(proc_str,step_count,sp='-->>')
       head_line="#%(key1)+12s%(key2)+12s%(key3)+12s"%{'key1':'index','key2':'label','key3':'position'}
       line=head_line+'\n'
       for i,label in enumerate(bsp.get_ticks()['label']):
           new_line="%(key1)12d%(key2)+12s%(key3)12f\n"%{'key1':i,'key2':label,'key3':bsp.get_ticks()['distance'][i]}
           line+=new_line
       line+='\n'
       write_col_data(filename4,line,'',str_data=True) 
    try:
       step_count+=1
       filename5="BAND.png"
       proc_str="Saving Plot to "+ filename5 +" File ..."
       procs(proc_str,step_count,sp='-->>')
       bsp.save_plot(filename5, img_format="png")
    except:
       print("Figure output fails !!!")   
Пример #24
0
from pymatgen.electronic_structure.plotter import BSPlotter, BSPlotterProjected
from pymatgen.io.vasp import Vasprun, BandStructure

v = Vasprun("AgTe_bs/vasprun.xml")
bands = v.get_band_structure(kpoints_filename="AgTe_bs/KPOINTS",
                             line_mode=True)

print(bands.get_band_gap())

plt = BSPlotter(bands)
#plt.plot_brillouin()

plt.get_plot(zero_to_efermi=True, vbm_cbm_marker=True, ylim=(-3, 3)).show()
#plt.get_plot(zero_to_efermi=True,vbm_cbm_marker=True,ylim=(-2.2,0.5)).savefig(fname="bs.eps",img_format="eps")
Пример #25
0
def plot_bands(vasprun_dos, vasprun_bands, kpoints, element, ylim = (None, None)):
    # read data
    # ---------

    # kpoints labels
    # labels = [r"$L$", r"$\Gamma$", r"$X$", r"$U,K$", r"$\Gamma$"]

    labels = read_kpoint_labels(kpoints)


    # density of states
    # dosrun = Vasprun(vasprun_dos)
    dosrun = Vasprun(vasprun_bands)
    spd_dos = dosrun.complete_dos.get_spd_dos()

    # bands
    run = Vasprun(vasprun_bands, parse_projected_eigen=True)
    bands = run.get_band_structure(kpoints,
                                   line_mode=True,
                                   efermi=dosrun.efermi)

    # set up matplotlib plot
    # ----------------------

    # general options for plot
    font = {'family': 'serif', 'size': 24}
    plt.rc('font', **font)

    # set up 2 graph with aspec ration 2/1
    # plot 1: bands diagram
    # plot 2: Density of States
    gs = GridSpec(1, 2, width_ratios=[2, 1])
    fig = plt.figure(figsize=(11.69, 8.27))
    # fig.suptitle("Bands diagram of copper")
    ax1 = plt.subplot(gs[0])
    ax2 = plt.subplot(gs[1])  # , sharey=ax1)

    # set ylim for the plot
    # ---------------------
    if ylim[0]:
        emin = ylim[0]
    else: 
        emin = -10.
    if ylim[1]:
        emax = ylim[1]
    else: 
        emax =  10.

    ax1.set_ylim(emin, emax)
    ax2.set_ylim(emin, emax)

    # Band Diagram
    # ------------
    name = element 
    pbands = bands.get_projections_on_elements_and_orbitals({name: ["s", "p", "d"]})
    # print(pbands)

    # compute s, p, d normalized contributions
    contrib = np.zeros((bands.nb_bands, len(bands.kpoints), 3))
    for b in range(bands.nb_bands):
        for k in range(len(bands.kpoints)):
            sc = pbands[Spin.up][b][k][name]["s"]**2
            pc = pbands[Spin.up][b][k][name]["p"]**2
            dc = pbands[Spin.up][b][k][name]["d"]**2
            tot = sc + pc + dc
            if tot != 0.0:
                contrib[b, k, 0] = sc / tot
                contrib[b, k, 1] = pc / tot
                contrib[b, k, 2] = dc / tot

    # plot bands using rgb mapping
    for b in range(bands.nb_bands):
        rgbline(ax1,
                range(len(bands.kpoints)),
                [e - bands.efermi for e in bands.bands[Spin.up][b]],
                contrib[b, :, 0],
                contrib[b, :, 1],
                contrib[b, :, 2])

    # style
    ax1.set_xlabel("k-points")
    ax1.set_ylabel(r"$E - E_f$   /   eV")
    ax1.grid()

    # fermi level at 0
    ax1.hlines(y=0, xmin=0, xmax=len(bands.kpoints), color="k", linestyle = '--', lw=1)

    # labels
    nlabs = len(labels)
    step = len(bands.kpoints) / (nlabs - 1)
    for i, lab in enumerate(labels):
        ax1.vlines(i * step, emin, emax, "k")
    ax1.set_xticks([i * step for i in range(nlabs)])
    ax1.set_xticklabels(labels)

    ax1.set_xlim(0, len(bands.kpoints))

    # Density of states
    # ----------------

    ax2.set_yticklabels([])
    ax2.grid()
    ax2.set_xlim(1e-4, 5)
    ax2.set_xticklabels([])
    ax2.hlines(y=0, xmin=0, xmax=5, color="k", lw=2)
    ax2.set_xlabel("Density of States", labelpad=28)

    # spd contribution
    ax2.plot(spd_dos[OrbitalType.s].densities[Spin.up],
             dosrun.tdos.energies - dosrun.efermi,
             "r-", label="3s", lw=2)
    ax2.plot(spd_dos[OrbitalType.p].densities[Spin.up],
             dosrun.tdos.energies - dosrun.efermi,
             "g-", label="3p", lw=2)
    ax2.plot(spd_dos[OrbitalType.d].densities[Spin.up],
             dosrun.tdos.energies - dosrun.efermi,
             "b-", label="3d", lw=2)

    # total dos
    ax2.fill_between(dosrun.tdos.densities[Spin.up],
                     0,
                     dosrun.tdos.energies - dosrun.efermi,
                     color=(0.7, 0.7, 0.7),
                     facecolor=(0.7, 0.7, 0.7))

    ax2.plot(dosrun.tdos.densities[Spin.up],
             dosrun.tdos.energies - dosrun.efermi,
             color=(0.6, 0.6, 0.6),
             label="total DOS")

    # plot format style
    # -----------------
    ax2.legend(fancybox=True, shadow=True, prop={'size': 18})
    plt.subplots_adjust(wspace=0)

    # plt.show()
    plt.savefig("figs/bands.png")
Пример #26
0
def plot_bands_old(vasprun_dos, vasprun_bands, kpoints, element, ylim = (None, None)):
    """
    This function is used to build plot of the electronic band structure along with
    the density of states (DOS) plot. It has feature to provide contributions from different
    elements to both band structure and DOS

    INPUT:
        - vasprun_dos (str) - path to the vasprun file of the DOS calculation
        - vasprun_band (str) - path to the vasprun file of the band structure calculation
        - kpoints (str) - path to the KPOINTS file of the band structure calculation
        - element (str) - label of the chemical element, for which the contribution
                          to the band structure and DOS
        - ylim (tuple of floats) - energy range of the band structure and DOS plots, units are eV
    RETURN:
        None
    SOURCE:
        Credit https://github.com/gVallverdu/bandstructureplots
    TODO:
        Some improvements
    """



    labels = read_kpoint_labels(kpoints)


    # density of states
    # dosrun = Vasprun(vasprun_dos)
    dosrun = Vasprun(vasprun_bands)
    spd_dos = dosrun.complete_dos.get_spd_dos()

    # bands
    run = Vasprun(vasprun_bands, parse_projected_eigen=True)
    bands = run.get_band_structure(kpoints,
                                   line_mode=True,
                                   efermi=dosrun.efermi)

    # set up matplotlib plot
    # ----------------------

    # general options for plot
    font = {'family': 'serif', 'size': 24}
    plt.rc('font', **font)

    # set up 2 graph with aspec ration 2/1
    # plot 1: bands diagram
    # plot 2: Density of States
    gs = GridSpec(1, 2, width_ratios=[2, 1])
    fig = plt.figure(figsize=(11.69, 8.27))
    # fig.suptitle("Bands diagram of copper")
    ax1 = plt.subplot(gs[0])
    ax2 = plt.subplot(gs[1])  # , sharey=ax1)

    # set ylim for the plot
    # ---------------------
    if ylim[0]:
        emin = ylim[0]
    else: 
        emin = -10.
    if ylim[1]:
        emax = ylim[1]
    else: 
        emax =  10.

    ax1.set_ylim(emin, emax)
    ax2.set_ylim(emin, emax)

    # Band Diagram
    # ------------
    name = element 
    pbands = bands.get_projections_on_elements_and_orbitals({name: ["s", "p", "d"]})
    # print(bands)

    # compute s, p, d normalized contributions
    contrib = np.zeros((bands.nb_bands, len(bands.kpoints), 3))
    # print(pbands)
    for b in range(bands.nb_bands):
        for k in range(len(bands.kpoints)):
            # print(Spin.up)
            sc = pbands[Spin.up][b][k][name]["s"]**2
            pc = pbands[Spin.up][b][k][name]["p"]**2
            dc = pbands[Spin.up][b][k][name]["d"]**2
            tot = sc + pc + dc
            if tot != 0.0:
                contrib[b, k, 0] = sc / tot
                contrib[b, k, 1] = pc / tot
                contrib[b, k, 2] = dc / tot

    # plot bands using rgb mapping
    for b in range(bands.nb_bands):
        rgbline(ax1,
                range(len(bands.kpoints)),
                [e - bands.efermi for e in bands.bands[Spin.up][b]],
                contrib[b, :, 0],
                contrib[b, :, 1],
                contrib[b, :, 2])

    # style
    ax1.set_xlabel("k-points")
    ax1.set_ylabel(r"$E - E_f$   /   eV")
    ax1.grid()

    # fermi level at 0
    ax1.hlines(y=0, xmin=0, xmax=len(bands.kpoints), color="k", linestyle = '--', lw=1)

    # labels
    nlabs = len(labels)
    step = len(bands.kpoints) / (nlabs - 1)
    for i, lab in enumerate(labels):
        ax1.vlines(i * step, emin, emax, "k")
    ax1.set_xticks([i * step for i in range(nlabs)])
    ax1.set_xticklabels(labels)

    ax1.set_xlim(0, len(bands.kpoints))

    # Density of states
    # ----------------

    ax2.set_yticklabels([])
    ax2.grid()
    ax2.set_xlim(1e-4, 5)
    ax2.set_xticklabels([])
    ax2.hlines(y=0, xmin=0, xmax=5, color="k", lw=2)
    ax2.set_xlabel("Density of States", labelpad=28)

    # spd contribution
    ax2.plot(spd_dos[OrbitalType.s].densities[Spin.up],
             dosrun.tdos.energies - dosrun.efermi,
             "r-", label="3s", lw=2)
    ax2.plot(spd_dos[OrbitalType.p].densities[Spin.up],
             dosrun.tdos.energies - dosrun.efermi,
             "g-", label="3p", lw=2)
    ax2.plot(spd_dos[OrbitalType.d].densities[Spin.up],
             dosrun.tdos.energies - dosrun.efermi,
             "b-", label="3d", lw=2)

    # total dos
    ax2.fill_between(dosrun.tdos.densities[Spin.up],
                     0,
                     dosrun.tdos.energies - dosrun.efermi,
                     color=(0.7, 0.7, 0.7),
                     facecolor=(0.7, 0.7, 0.7))

    ax2.plot(dosrun.tdos.densities[Spin.up],
             dosrun.tdos.energies - dosrun.efermi,
             color=(0.6, 0.6, 0.6),
             label="total DOS")

    # plot format style
    # -----------------
    ax2.legend(fancybox=True, shadow=True, prop={'size': 18})
    plt.subplots_adjust(wspace=0)

    # plt.show()
    makedir("figs/bands.png")
    plt.savefig("figs/bands.png")
Пример #27
0
              performance_params={'Ecut': 1.0}
                  )
    amset.read_vrun(vasprun_file=vrun_file)
    amset.update_cbm_vbm_dos(coeff_file)
    extrema = amset.find_all_important_points(coeff_file,
                                              nbelow_vbm=0,
                                              nabove_cbm=0,
                                              interpolation="boltztrap1",
                                              line_density=LINE_DENSITY
                                              )

    hsk = HighSymmKpath(vrun.final_structure)
    hs_kpoints , _ = hsk.get_kpoints(line_density=LINE_DENSITY)
    hs_kpoints = kpts_to_first_BZ(hs_kpoints)

    bs = vrun.get_band_structure()
    bsd = {}
    bsd['kpoints'] = hs_kpoints
    hs_kpoints = np.array(hs_kpoints)

    bsd['str_kpts'] = [str(k) for k in bsd['kpoints']]
    bsd['cartesian kpoints (1/nm)'] = [amset.get_cartesian_coords(k)/A_to_nm for k in bsd['kpoints']]
    bsd['normk'] = np.linalg.norm(bsd['cartesian kpoints (1/nm)'], axis=1)

    cbm_idx, cbm_spin = get_bindex_bspin(bs.get_cbm(), is_cbm=True)
    vbmd = bs.get_vbm()
    vbm_idx, vbm_spin = get_bindex_bspin(vbmd, is_cbm=False)
    vbm = vbmd['energy']
    print(np.array(bs.bands[Spin.up]).shape)

    interp_params = get_energy_args(coeff_file, ibands=[vbm_idx+1, vbm_idx+2])
Пример #28
0
    def test_get_energies_symprec(self):
        # vr = Vasprun(os.path.join(tin_dioxide_files, 'vasprun.xml.gz'),
        #              parse_projected_eigen=True)
        vr = Vasprun(os.path.join(pbs_files, "vasprun.xml.gz"),
                     parse_projected_eigen=True)
        bs = vr.get_band_structure()
        num_electrons = vr.parameters["NELECT"]
        interpolater = Interpolator(bs,
                                    num_electrons,
                                    interpolate_projections=True,
                                    interpolation_factor=1)

        ir_kpoints, weights, kpoints, ir_kpoints_idx, ir_to_full_idx = get_kpoints(
            [13, 15, 29],
            vr.final_structure,
            boltztrap_ordering=True,
            return_full_kpoints=True,
        )

        initialize_amset_logger()

        (
            energies,
            velocities,
            curvature,
            projections,
            sym_info,
        ) = interpolater.get_energies(
            kpoints,
            None,
            return_velocity=True,
            atomic_units=True,
            return_curvature=True,
            return_projections=True,
            symprec=0.1,
            return_vel_outer_prod=True,
            return_kpoint_mapping=True,
        )

        (
            energies_no_sym,
            velocities_no_sym,
            curvature_no_sym,
            projections_no_sym,
        ) = interpolater.get_energies(
            kpoints,
            None,
            return_velocity=True,
            atomic_units=True,
            return_curvature=True,
            return_projections=True,
            return_vel_outer_prod=True,
            symprec=None,
        )

        np.testing.assert_array_equal(ir_to_full_idx,
                                      sym_info["ir_to_full_idx"])
        np.testing.assert_array_equal(ir_kpoints_idx,
                                      sym_info["ir_kpoints_idx"])

        # print(velocities[Spin.up][5, :, :, -3:])
        # print(velocities_no_sym[Spin.up][5, :, :, -3:])
        # print(sym_info["ir_to_full_idx"][-10:])

        np.testing.assert_array_almost_equal(energies[Spin.up],
                                             energies_no_sym[Spin.up],
                                             decimal=12)
        np.testing.assert_array_almost_equal(velocities[Spin.up],
                                             velocities_no_sym[Spin.up],
                                             decimal=12)
        np.testing.assert_array_almost_equal(curvature[Spin.up],
                                             curvature_no_sym[Spin.up],
                                             decimal=12)

        for l in projections[Spin.up]:
            np.testing.assert_array_almost_equal(
                projections[Spin.up][l], projections_no_sym[Spin.up][l])
Пример #29
0
    def process_vasprun(self, dir_name, taskname, filename):
        """
        Adapted from matgendb.creator

        Process a vasprun.xml file.
        """
        vasprun_file = os.path.join(dir_name, filename)

        vrun = Vasprun(vasprun_file)

        d = vrun.as_dict()

        # rename formula keys
        for k, v in {"formula_pretty": "pretty_formula",
                     "composition_reduced": "reduced_cell_formula",
                     "composition_unit_cell": "unit_cell_formula"}.items():
            d[k] = d.pop(v)

        for k in ["eigenvalues", "projected_eigenvalues"]:  # large storage space breaks some docs
            if k in d["output"]:
                del d["output"][k]

        comp = Composition(d["composition_unit_cell"])
        d["formula_anonymous"] = comp.anonymized_formula
        d["formula_reduced_abc"] = comp.reduced_composition.alphabetical_formula
        d["dir_name"] = os.path.abspath(dir_name)
        d["completed_at"] = str(datetime.datetime.fromtimestamp(os.path.getmtime(vasprun_file)))
        d["density"] = vrun.final_structure.density

        # replace 'crystal' with 'structure'
        d["input"]["structure"] = d["input"].pop("crystal")
        d["output"]["structure"] = d["output"].pop("crystal")
        for k, v in {"energy": "final_energy", "energy_per_atom": "final_energy_per_atom"}.items():
            d["output"][k] = d["output"].pop(v)

        if self.parse_dos == True or (str(self.parse_dos).lower() == "auto" and vrun.incar.get("NSW", 1) == 0):
            try:
                d["dos"] = vrun.complete_dos.as_dict()
            except:
                raise ValueError("No valid dos data exist in {}.".format(dir_name))

        # Band structure parsing logic
        if str(self.bandstructure_mode).lower() == "auto":
            # if line mode nscf
            if vrun.incar.get("ICHARG", 0) > 10 and vrun.kpoints.num_kpts > 0:
                bs_vrun = BSVasprun(vasprun_file, parse_projected_eigen=True)
                bs = bs_vrun.get_band_structure(line_mode=True)
            # else if nscf
            elif vrun.incar.get("ICHARG", 0) > 10:
                bs_vrun = BSVasprun(vasprun_file, parse_projected_eigen=True)
                bs = bs_vrun.get_band_structure()
            # else just regular calculation
            else:
                bs = vrun.get_band_structure()

            # only save the bandstructure if not moving ions
            if vrun.incar["NSW"] == 0:
                d["bandstructure"] = bs.as_dict()
        # legacy line/True behavior for bandstructure_mode
        elif self.bandstructure_mode:
            bs_vrun = BSVasprun(vasprun_file, parse_projected_eigen=True)
            bs = bs_vrun.get_band_structure(line_mode=(str(self.bandstructure_mode).lower() == "line"))
            d["bandstructure"] = bs.as_dict()
        # parse bandstructure for vbm/cbm/bandgap but don't save
        else:
            bs = vrun.get_band_structure()

        # Parse electronic information if possible.
        # For certain optimizers this is broken and we don't get an efermi resulting in the bandstructure
        try:
            bs_gap = bs.get_band_gap()
            d["output"]["vbm"] = bs.get_vbm()["energy"]
            d["output"]["cbm"] = bs.get_cbm()["energy"]
            d["output"]["bandgap"] = bs_gap["energy"]
            d["output"]["is_gap_direct"] = bs_gap["direct"]
            d["output"]["is_metal"] = bs.is_metal()
            if not bs_gap["direct"]:
                d["output"]["direct_gap"] = bs.get_direct_band_gap()
            if isinstance(bs, BandStructureSymmLine):
                d["output"]["transition"] = bs_gap["transition"]

        except Exception:
            if self.bandstructure_mode is True:
                import traceback
                logger.error(traceback.format_exc())
                logger.error("Error in " + os.path.abspath(dir_name) + ".\n" + traceback.format_exc())
                raise
            logger.warning("Error in parsing bandstructure")
            if vrun.incar["IBRION"] == 1:
                logger.warning("Vasp doesn't properly output efermi for IBRION == 1")

        d["task"] = {"type": taskname, "name": taskname}

        d["output_file_paths"] = self.process_raw_data(dir_name, taskname=taskname)

        if "locpot" in d["output_file_paths"] and self.parse_locpot:
            locpot = Locpot.from_file(os.path.join(dir_name, d["output_file_paths"]["locpot"]))
            d["output"]["locpot"] = {i: locpot.get_average_along_axis(i) for i in range(3)}

        if hasattr(vrun, "force_constants"):
            # phonon-dfpt
            d["output"]["force_constants"] = vrun.force_constants.tolist()
            d["output"]["normalmode_eigenvals"] = vrun.normalmode_eigenvals.tolist()
            d["output"]["normalmode_eigenvecs"] = vrun.normalmode_eigenvecs.tolist()
        return d
Пример #30
0
def projected_band_structure():
   step_count=1
   filename='vasprun.xml'
   check_file(filename)
   proc_str="Reading Data From "+ filename +" File ..."
   procs(proc_str,step_count,sp='-->>')
   vsr=Vasprun(filename)

   filename='PROCAR'
   check_file(filename)
   step_count+=1
   proc_str="Reading Data From "+ filename +" File ..."
   procs(proc_str,step_count,sp='-->>')
   procar=Procar(filename)
   nbands=procar.nbands
   nions=procar.nions
   norbitals=len(procar.orbitals)
   nkpoints=procar.nkpoints

   step_count+=1
   filename='KPOINTS'
   check_file(filename)
   proc_str="Reading Data From "+ filename +" File ..."
   procs(proc_str,step_count,sp='-->>')
   bands = vsr.get_band_structure(filename, line_mode=True, efermi=vsr.efermi)
   struct=vsr.final_structure
   (atom_index,in_str)=atom_selection(struct)
   
   if len(atom_index)==0:
      print("No atoms selected!")
      return
#   print(atom_index)

   if vsr.is_spin:
      proc_str="This Is a Spin-polarized Calculation."
      procs(proc_str,0,sp='-->>')
      ISPIN=2
      contrib=np.zeros((nkpoints,nbands,norbitals,2))
      for i in atom_index:
          contrib[:,:,:,0]=contrib[:,:,:,0]+procar.data[Spin.up][:,:,i,:]
          contrib[:,:,:,1]=contrib[:,:,:,1]+procar.data[Spin.down][:,:,i,:]

      for ispin in range(2):
          proj_band=contrib[:,:,:,ispin].reshape(nkpoints*nbands,norbitals)
          step_count+=1
          if ispin==0:
              filename="PBAND_Up.dat"
          else:
              filename="PBAND_Down.dat"
          proc_str="Writting Projected Band Structure Data to "+ filename +" File ..."
          procs(proc_str,step_count,sp='-->>')
          band_data=bands.bands[Spin.up]
          y_data=band_data.reshape(1,nbands*nkpoints)[0]-vsr.efermi #shift fermi level to 0
          x_data=np.array(bands.distance*nbands)
          data=np.vstack((x_data,y_data,proj_band.T)).T
          tmp1_str="#%(key1)+12s%(key2)+12s"
          tmp2_dic={'key1':'K-Distance','key2':'Energy(ev)'}
          for i in range(norbitals):
              tmp1_str+="%(key"+str(i+3)+")+12s"
              tmp2_dic["key"+str(i+3)]=procar.orbitals[i]

#          print(tmp1_str)
          atom_index_str=[str(x+1) for x in atom_index]
          head_line1="#String: "+in_str+'\n#Selected atom: ' +' '.join(atom_index_str)+'\n'
          head_line2=tmp1_str % tmp2_dic
          head_line=head_line1+head_line2
          write_col_data(filename,data,head_line,nkpoints)

   else:
      if vsr.parameters['LNONCOLLINEAR']:
         proc_str="This Is a Non-Collinear Calculation."
         procs(proc_str,0,sp='-->>')
         ISPIN=3
      else:
         proc_str="This Is a Non-Spin Calculation."
         procs(proc_str,0,sp='-->>')
         ISPIN=1

      contrib=np.zeros((nkpoints,nbands,norbitals))
      for i in atom_index:
          contrib[:,:,:]=contrib[:,:,:]+procar.data[Spin.up][:,:,i,:]
 
      proj_band=contrib.reshape(nkpoints*nbands,norbitals)        
      step_count+=1
      filename="PBAND.dat"
      proc_str="Writting Projected Band Structure Data to "+ filename +" File ..."
      procs(proc_str,step_count,sp='-->>')
      band_data=bands.bands[Spin.up]
      y_data=band_data.reshape(1,nbands*nkpoints)[0]-vsr.efermi #shift fermi level to 0
      x_data=np.array(bands.distance*nbands)
      data=np.vstack((x_data,y_data,proj_band.T)).T
      tmp1_str="#%(key1)+12s%(key2)+12s"
      tmp2_dic={'key1':'K-Distance','key2':'Energy(ev)'}
      for i in range(norbitals):
          tmp1_str+="%(key"+str(i+3)+")+12s"
          tmp2_dic["key"+str(i+3)]=procar.orbitals[i]

#      print(tmp1_str)
      atom_index_str=[str(x+1) for x in atom_index]
      head_line1="#String: "+in_str+'\n#Selected atom: ' +' '.join(atom_index_str)+'\n'
      head_line2=tmp1_str % tmp2_dic
      head_line=head_line1+head_line2
      write_col_data(filename,data,head_line,nkpoints)

   step_count+=1
   bsp=BSPlotter(bands)
   filename="HighSymmetricPoints.dat"
   proc_str="Writting Label infomation to "+ filename +" File ..."
   procs(proc_str,step_count,sp='-->>')
   head_line="#%(key1)+12s%(key2)+12s%(key3)+12s"%{'key1':'index','key2':'label','key3':'position'}
   line=head_line+'\n'
   for i,label in enumerate(bsp.get_ticks()['label']):
       new_line="%(key1)12d%(key2)+12s%(key3)12f\n"%{'key1':i,'key2':label,'key3':bsp.get_ticks()['distance'][i]}
       line+=new_line
   write_col_data(filename,line,'',str_data=True) 
Пример #31
0
def optplot(
    modes=("absorption", ),
    filenames=None,
    codes="vasp",
    prefix=None,
    directory=None,
    gaussian=None,
    band_gaps=None,
    labels=None,
    average=True,
    height=6,
    width=6,
    xmin=0,
    xmax=None,
    ymin=0,
    ymax=1e5,
    colours=None,
    style=None,
    no_base_style=None,
    image_format="pdf",
    dpi=400,
    plt=None,
    fonts=None,
    units="eV",
):
    """A script to plot optical absorption spectra from VASP calculations.

    Args:
        modes (:obj:`list` or :obj:`tuple`):
            Ordered list of :obj:`str` determining properties to plot.
            Accepted options are 'absorption' (default), 'eps', 'eps-real',
            'eps-im', 'n', 'n-real', 'n-im', 'loss' (equivalent to n-im).
        filenames (:obj:`str` or :obj:`list`, optional): Path to data file.
            For VASP this is a *vasprun.xml* file (can be gzipped); for
            Questaal the *opt.ext* file from *lmf* or *eps_BSE.out* from
            *bethesalpeter* may be used.
            Alternatively, a list of paths can be
            provided, in which case the absorption spectra for each will be
            plotted concurrently.
        codes (:obj:`str` or :obj:`list`, optional): Original
            calculator. Accepted values are 'vasp' and 'questaal'. Items should
            correspond to filenames.
        prefix (:obj:`str`, optional): Prefix for file names.
        directory (:obj:`str`, optional): The directory in which to save files.
        gaussian (:obj:`float`): Standard deviation for gaussian broadening.
        band_gaps (:obj:`float`, :obj:`str` or :obj:`list`, optional): The band
            gap as a :obj:`float`, in eV, plotted as a dashed line. If plotting
            multiple spectra then a :obj:`list` of band gaps can be provided.
            Band gaps can be provided as a floating-point number or as a path
            to a *vasprun.xml* file. To skip over a line, set its bandgap to
            zero or a negative number to place it outside the visible range.
        labels (:obj:`str` or :obj:`list`): A label to identify the spectra.
            If plotting multiple spectra then a :obj:`list` of labels can
            be provided.
        average (:obj:`bool`, optional): Average the dielectric response across
            all lattice directions. Defaults to ``True``.
        height (:obj:`float`, optional): The height of the plot.
        width (:obj:`float`, optional): The width of the plot.
        xmin (:obj:`float`, optional): The minimum energy on the x-axis.
        xmax (:obj:`float`, optional): The maximum energy on the x-axis.
        ymin (:obj:`float`, optional): The minimum absorption intensity on the
            y-axis.
        ymax (:obj:`float`, optional): The maximum absorption intensity on the
            y-axis.
        colours (:obj:`list`, optional): A :obj:`list` of colours to use in the
            plot. The colours can be specified as a hex code, set of rgb
            values, or any other format supported by matplotlib.
        style (:obj:`list` or :obj:`str`, optional): (List of) matplotlib style
            specifications, to be composed on top of Sumo base style.
        no_base_style (:obj:`bool`, optional): Prevent use of sumo base style.
            This can make alternative styles behave more predictably.
        image_format (:obj:`str`, optional): The image file format. Can be any
            format supported by matplotlib, including: png, jpg, pdf, and svg.
            Defaults to pdf.
        dpi (:obj:`int`, optional): The dots-per-inch (pixel density) for
            the image.
        plt (:obj:`matplotlib.pyplot`, optional): A
            :obj:`matplotlib.pyplot` object to use for plotting.
        fonts (:obj:`list`, optional): Fonts to use in the plot. Can be a
            a single font, specified as a :obj:`str`, or several fonts,
            specified as a :obj:`list` of :obj:`str`.
        units (:obj:`str`, optional): X-axis units for the plot. 'eV' for
           energy in electronvolts or 'nm' for wavelength in nanometers.
           Defaults to 'eV'.

    Returns:
        A matplotlib pyplot object.
    """

    # Don't write files if this is being done to manipulate existing plt
    save_files = False if plt else True

    # BUILD LIST OF FILES AUTOMATICALLY IF NECESSARY

    if codes == "vasp":
        if not filenames:
            if os.path.exists("vasprun.xml"):
                filenames = ["vasprun.xml"]
            elif os.path.exists("vasprun.xml.gz"):
                filenames = ["vasprun.xml.gz"]
            else:
                logging.error("ERROR: No vasprun.xml found!")
                sys.exit()

    elif codes == "questaal":
        if not filenames:
            if len(glob("opt.*")) > 0:
                filenames = glob("opt.*")
                if len(filenames) == 1:
                    logging.info("Found optics file: " + filenames[0])
                else:
                    logging.info("Found optics files: " + ", ".join(filenames))

    if isinstance(filenames, str):
        filenames = [filenames]

    if isinstance(codes, str):
        codes = [codes] * len(filenames)
    elif len(codes) == 1:
        codes = list(codes) * len(filenames)

    # ITERATE OVER FILES READING DIELECTRIC DATA

    dielectrics = []
    auto_labels = []
    auto_band_gaps = []
    for i, (filename, code) in enumerate(zip(filenames, codes)):
        if code == "vasp":
            vr = Vasprun(filename)
            dielectrics.append(vr.dielectric)

            auto_labels.append(
                latexify(
                    vr.final_structure.composition.reduced_formula).replace(
                        "$_", r"$_\mathregular"))

            if isinstance(band_gaps, list) and not band_gaps:
                # band_gaps = [], auto band gap requested
                auto_band_gaps.append(
                    vr.get_band_structure().get_band_gap()["energy"])
            else:
                auto_band_gaps.append(None)

        elif code == "questaal":
            if not save_files:
                out_filename = None
            elif len(filenames) == 1:
                out_filename = "dielectric.dat"
            else:
                out_filename = f"dielectric_{i + 1}.dat"

            dielectrics.append(
                questaal.dielectric_from_file(filename, out_filename))

            auto_band_gaps.append(None)
            auto_labels.append(filename.split(".")[-1])
            if isinstance(band_gaps, list) and not band_gaps:
                logging.info("Bandgap requested but not supported for Questaal"
                             " file {}: skipping...".format(filename))

        else:
            raise Exception(f'Code selection "{code}" not recognised')

    if not labels and len(filenames) > 1:
        labels = auto_labels

    # PROCESS DIELECTRIC DATA: BROADENING AND DERIVED PROPERTIES

    if gaussian:
        dielectrics = [broaden_eps(d, gaussian) for d in dielectrics]

    # initialize spectrum data ready to append from each dataset
    abs_data = OrderedDict()

    for mode in modes:
        abs_data.update({mode: []})

    # for each calculation, get all required properties and append to data
    for d in dielectrics:
        # TODO: add support for other eigs and full modes
        energies, properties = calculate_dielectric_properties(
            d, set(modes), mode="average" if average else "trace")
        for mode, spectrum in properties.items():
            abs_data[mode].append((energies, spectrum))

    if isinstance(band_gaps, list) and not band_gaps:
        # empty list therefore use bandgaps collected from vasprun files
        band_gaps = auto_band_gaps
    elif isinstance(band_gaps, list):
        # list containing filenames and/or values: mutate the list in-place
        for i, item in enumerate(band_gaps):
            if item is None:
                pass
            elif _floatable(item):
                band_gaps[i] = float(item)
            elif "vasprun" in item:
                band_gaps[i] = (Vasprun(
                    item).get_band_structure().get_band_gap()["energy"])
            else:
                raise ValueError(
                    f"Format not recognised for auto bandgap: {item}.")

    plotter = SOpticsPlotter(abs_data, band_gap=band_gaps, label=labels)
    plt = plotter.get_plot(
        width=width,
        height=height,
        xmin=xmin,
        xmax=xmax,
        ymin=ymin,
        ymax=ymax,
        colours=colours,
        dpi=dpi,
        plt=plt,
        fonts=fonts,
        style=style,
        no_base_style=no_base_style,
        units=units,
    )

    if save_files:
        basename = "absorption"
        if prefix:
            basename = f"{prefix}_{basename}"
        image_filename = f"{basename}.{image_format}"

        if directory:
            image_filename = os.path.join(directory, image_filename)
        plt.savefig(image_filename, format=image_format, dpi=dpi)
        for mode, data in abs_data.items():
            basename = "absorption" if mode == "abs" else mode
            write_files(data,
                        basename=basename,
                        prefix=prefix,
                        directory=directory)
    else:
        return plt
Пример #32
0
def carrier_mobility(calc_init=(),
                     calc_deform_x=(),
                     calc_deform_y=(),
                     vbm=1,
                     vbm_point=0,
                     cbm=2,
                     cbm_point=0,
                     deform_x=(),
                     n_points_x=2,
                     deform_y=(),
                     n_points_y=2,
                     temperature_range=(300, 900),
                     temperature_ref=300,
                     effective_mass_el={},
                     effective_mass_xy_el={},
                     effective_mass_hole={},
                     effective_mass_xy_hole={},
                     lab_size=15,
                     tick_size=15,
                     leg_size=15,
                     fig_size=(9, 17),
                     fig_title='',
                     xlim=(),
                     ylim_elastic=(),
                     ylim_deform=(),
                     expression='Guo2021_JMCC',
                     database=None,
                     folder=''):

    from math import pi, sqrt, acos, sin
    from pymatgen.io.vasp import Vasprun, Outcar
    from pymatgen.electronic_structure.core import Spin, OrbitalType
    from analysis_functions import Approximation as A
    import matplotlib.pyplot as plt
    import matplotlib.gridspec as gspec

    # Transformation coefficients
    ang = 1e-10  # Angstrom, m
    ev_in_j = 1.60217662e-19  # Electron-volt, J

    # Functions for calculation of the carrier mobility
    def carrier_Guo2021_JMCC(t, c2d, el, m, md):
        # Constants
        e = 1.60217662e-19  # Electron charge, Coulomb
        m_e = 9.10938356e-31  # Electron mass, kg
        k_B = 1.38064852e-23  # Boltzmann constant, J/K
        h = 6.62607004e-34  # Plank constant, J*s
        mu = (e * (h / (2 * pi))**3 * c2d * 10000) / (k_B * t * m * md *
                                                      m_e**2 * el**2)
        return mu

    # Lists of deformation along x and y axes
    step_x = (deform_x[1] - deform_x[0]) / (n_points_x - 1)
    eps_x = [deform_x[0] + step_x * i for i in range(n_points_x)]

    step_y = (deform_y[1] - deform_y[0]) / (n_points_y - 1)
    eps_y = [deform_y[0] + step_y * i for i in range(n_points_y)]

    # Reading energies
    energy_x = []
    energy_vbm_x = []
    energy_cbm_x = []
    for i in calc_deform_x[2]:
        calc_cur = database[(calc_deform_x[0], calc_deform_x[1], i)]
        energy_x.append(calc_cur.energy_sigma0)

        path_vasprun = calc_cur.path['output'].replace('OUTCAR', 'vasprun.xml')
        path_kpoints = calc_cur.path['output'].replace(
            str(i) + '.OUTCAR', 'IBZKPT')
        run = Vasprun(path_vasprun, parse_projected_eigen=True)
        dosrun = Vasprun(path_vasprun)
        try:
            bands = run.get_band_structure(path_kpoints,
                                           line_mode=True,
                                           efermi=dosrun.efermi)
        except Exception:
            path_kpoints = calc_cur.path['output'].replace(
                str(i) + '.OUTCAR', 'KPOINTS')
            bands = run.get_band_structure(path_kpoints,
                                           line_mode=True,
                                           efermi=dosrun.efermi)

        energy_vbm_x.append(bands.bands[Spin.up][vbm - 1][vbm_point])
        energy_cbm_x.append(bands.bands[Spin.up][cbm - 1][cbm_point])

    energy_y = []
    energy_vbm_y = []
    energy_cbm_y = []
    for i in calc_deform_y[2]:
        calc_cur = database[(calc_deform_y[0], calc_deform_y[1], i)]
        energy_y.append(calc_cur.energy_sigma0)

        path_vasprun = calc_cur.path['output'].replace('OUTCAR', 'vasprun.xml')
        path_kpoints = calc_cur.path['output'].replace(
            str(i) + '.OUTCAR', 'IBZKPT')
        run = Vasprun(path_vasprun, parse_projected_eigen=True)
        dosrun = Vasprun(path_vasprun)
        try:
            bands = run.get_band_structure(path_kpoints,
                                           line_mode=True,
                                           efermi=dosrun.efermi)
        except Exception:
            path_kpoints = calc_cur.path['output'].replace(
                str(i) + '.OUTCAR', 'KPOINTS')
            bands = run.get_band_structure(path_kpoints,
                                           line_mode=True,
                                           efermi=dosrun.efermi)

        energy_vbm_y.append(bands.bands[Spin.up][vbm - 1][vbm_point])
        energy_cbm_y.append(bands.bands[Spin.up][cbm - 1][cbm_point])

    # Calculation of the initial surface area s0
    a = list(database[calc_init].end.rprimd[0])
    b = list(database[calc_init].end.rprimd[1])
    mod_a = sqrt(a[0]**2 + a[1]**2 + a[2]**2)
    mod_b = sqrt(b[0]**2 + b[1]**2 + b[2]**2)
    sc_ab = a[0] * b[0] + a[1] * b[1] + a[2] * b[2]
    angle = acos(sc_ab / (mod_a * mod_b))
    s0 = mod_a * mod_b * sin(angle)

    # ********************************************* 2D elastic moduli ********************************************
    # 2D Elastic modulus
    # Deformation along x direction
    ek1 = A()
    ek1.aprx_lsq('a0*x**2+a1*x+a2', 3, eps_x, energy_x)
    C_2D_x = ek1.coefs[0] * ev_in_j / (s0 * ang**2)
    a0_x = ek1.coefs[0]
    a1_x = ek1.coefs[1]
    a2_x = ek1.coefs[2]

    eps_x_fit = [
        deform_x[0] + (deform_x[1] - deform_x[0]) / 999 * i
        for i in range(1000)
    ]
    energy_x_fit = [a0_x * i**2 + a1_x * i + a2_x for i in eps_x_fit]

    # Deformation along y direction
    ek2 = A()
    ek2.aprx_lsq('a0*x**2+a1*x+a2', 3, eps_y, energy_y)
    C_2D_y = ek2.coefs[0] * ev_in_j / (s0 * ang**2)
    a0_y = ek2.coefs[0]
    a1_y = ek2.coefs[1]
    a2_y = ek2.coefs[2]

    eps_y_fit = [
        deform_y[0] + (deform_y[1] - deform_y[0]) / 999 * i
        for i in range(1000)
    ]
    energy_y_fit = [a0_y * i**2 + a1_y * i + a2_y for i in eps_y_fit]
    # ************************************************************************************************************

    # ***************************************** Deformation potential ********************************************
    # Deformation potential
    # X direction
    ek3 = A()
    ek3.aprx_lsq('a0*x+a1', 2, eps_x, energy_vbm_x)
    E_l_hole_x = ek3.coefs[0] * ev_in_j
    vbm_x_0 = ek3.coefs[0]
    vbm_x_1 = ek3.coefs[1]

    ek4 = A()
    ek4.aprx_lsq('a0*x+a1', 2, eps_x, energy_cbm_x)
    E_l_el_x = ek4.coefs[0] * ev_in_j
    cbm_x_0 = ek4.coefs[0]
    cbm_x_1 = ek4.coefs[1]

    energy_vbm_x_fit = [vbm_x_0 * i + vbm_x_1 for i in eps_x_fit]
    energy_cbm_x_fit = [cbm_x_0 * i + cbm_x_1 for i in eps_x_fit]

    # Y direction
    ek5 = A()
    ek5.aprx_lsq('a0*x+a1', 2, eps_y, energy_vbm_y)
    E_l_hole_y = ek5.coefs[0] * ev_in_j
    vbm_y_0 = ek5.coefs[0]
    vbm_y_1 = ek5.coefs[1]

    ek6 = A()
    ek6.aprx_lsq('a0*x+a1', 2, eps_y, energy_cbm_y)
    E_l_el_y = ek6.coefs[0] * ev_in_j
    cbm_y_0 = ek6.coefs[0]
    cbm_y_1 = ek6.coefs[1]

    energy_vbm_y_fit = [vbm_y_0 * i + vbm_y_1 for i in eps_y_fit]
    energy_cbm_y_fit = [cbm_y_0 * i + cbm_y_1 for i in eps_y_fit]

    # Writing files with the energy dependencies on deformation value
    f = open(folder + '/elastic_x.out', 'w')
    for i in range(len(eps_x)):
        f.write('{0:15.5f} {1:15.10f}'.format(eps_x[i], energy_x[i]) + '\n')
    f.close()

    f = open(folder + '/elastic_y.out', 'w')
    for i in range(len(eps_y)):
        f.write('{0:15.5f} {1:15.10f}'.format(eps_y[i], energy_y[i]) + '\n')
    f.close()

    f = open(folder + '/elastic_x_fit.out', 'w')
    for i in range(len(eps_x_fit)):
        f.write('{0:15.5f} {1:15.10f}'.format(eps_x_fit[i], energy_x_fit[i]) +
                '\n')
    f.close()

    f = open(folder + '/elastic_y_fit.out', 'w')
    for i in range(len(eps_y_fit)):
        f.write('{0:15.5f} {1:15.10f}'.format(eps_y_fit[i], energy_y_fit[i]) +
                '\n')
    f.close()

    f = open(folder + '/deformation_potential_x_hole.out', 'w')
    for i in range(len(eps_x)):
        f.write('{0:15.5f} {1:15.10f}'.format(eps_x[i], energy_vbm_x[i]) +
                '\n')
    f.close()

    f = open(folder + '/deformation_potential_x_electron.out', 'w')
    for i in range(len(eps_x)):
        f.write('{0:15.5f} {1:15.10f}'.format(eps_x[i], energy_cbm_x[i]) +
                '\n')
    f.close()

    f = open(folder + '/deformation_potential_x_hole_fit.out', 'w')
    for i in range(len(eps_x_fit)):
        f.write(
            '{0:15.5f} {1:15.10f}'.format(eps_x_fit[i], energy_vbm_x_fit[i]) +
            '\n')
    f.close()

    f = open(folder + '/deformation_potential_x_electron_fit.out', 'w')
    for i in range(len(eps_x_fit)):
        f.write(
            '{0:15.5f} {1:15.10f}'.format(eps_x_fit[i], energy_cbm_x_fit[i]) +
            '\n')
    f.close()

    f = open(folder + '/deformation_potential_y_hole.out', 'w')
    for i in range(len(eps_y)):
        f.write('{0:15.5f} {1:15.10f}'.format(eps_y[i], energy_vbm_y[i]) +
                '\n')
    f.close()

    f = open(folder + '/deformation_potential_y_electron.out', 'w')
    for i in range(len(eps_y)):
        f.write('{0:15.5f} {1:15.10f}'.format(eps_y[i], energy_cbm_y[i]) +
                '\n')
    f.close()

    f = open(folder + '/deformation_potential_y_hole_fit.out', 'w')
    for i in range(len(eps_y_fit)):
        f.write(
            '{0:15.5f} {1:15.10f}'.format(eps_y_fit[i], energy_vbm_y_fit[i]) +
            '\n')
    f.close()

    f = open(folder + '/deformation_potential_y_electron_fit.out', 'w')
    for i in range(len(eps_y_fit)):
        f.write(
            '{0:15.5f} {1:15.10f}'.format(eps_y_fit[i], energy_cbm_y_fit[i]) +
            '\n')
    f.close()
    # ************************************************************************************************************

    # Figure with Elastic moduli and Deformation potential
    interval = 0.05
    npoint = 50
    precision = 0.000001
    shift_left = 100000.15
    shift_right = 100000.20
    # Use GridSpec to set subplots
    gs = gspec.GridSpec(1, 2, width_ratios=[1.0, 1.0],
                        height_ratios=[1.0])  #  height_ratios = [5, 5, 5]
    gs.update(bottom=0.07,
              hspace=0.17,
              wspace=0.25,
              top=0.93,
              right=0.97,
              left=0.1)
    # ========================== Vanadium =================================
    plt1 = plt.subplot(gs[0, 0])
    plt1.plot(eps_x,
              energy_x,
              linewidth=2,
              linestyle='',
              marker='o',
              markersize=7,
              color='red')
    plt1.plot(eps_x_fit,
              energy_x_fit,
              linewidth=2,
              linestyle='-',
              color='red',
              label='x: $C_{2D} = $' + '{0:7.2f}'.format(C_2D_x) + ' N/m')
    plt1.plot(eps_y,
              energy_y,
              linewidth=2,
              linestyle='',
              marker='o',
              markersize=7,
              color='blue')
    plt1.plot(eps_y_fit,
              energy_y_fit,
              linewidth=2,
              linestyle='-',
              color='blue',
              label='y: $C_{2D} = $' + '{0:7.2f}'.format(C_2D_y) + ' N/m')
    plt.xticks(fontsize=tick_size)
    plt.yticks(fontsize=tick_size)
    plt.xlabel('$\epsilon$', fontsize=lab_size)
    plt.ylabel('Energy, eV', fontsize=lab_size)
    if xlim: plt1.set_xlim(xlim[0], xlim[1])
    if ylim_elastic: plt1.set_ylim(ylim_elastic[0], ylim_elastic[1])
    plt1.legend(bbox_to_anchor=(0.5, 0.5),
                borderaxespad=0.,
                labelspacing=0.3,
                numpoints=1,
                frameon=True,
                fancybox=True,
                markerscale=1.,
                handletextpad=0.3,
                fontsize=leg_size)

    # ========================== Chromium =================================
    plt2 = plt.subplot(gs[0, 1])
    plt2.plot(eps_x,
              energy_vbm_x,
              linewidth=2,
              linestyle='',
              marker='o',
              markersize=7,
              color='red')
    plt2.plot(eps_x_fit,
              energy_vbm_x_fit,
              linewidth=2,
              linestyle='-',
              color='red',
              label='x: VBM $E_{l} = $' +
              '{0:7.2f}'.format(E_l_hole_x / ev_in_j) + ' eV')
    plt2.plot(eps_x,
              energy_cbm_x,
              linewidth=2,
              linestyle='',
              marker='o',
              markersize=7,
              color='blue')
    plt2.plot(eps_x_fit,
              energy_cbm_x_fit,
              linewidth=2,
              linestyle='-',
              color='blue',
              label='x: CBM $E_{l} = $' +
              '{0:7.2f}'.format(E_l_el_x / ev_in_j) + ' eV')
    plt2.plot(eps_y,
              energy_vbm_y,
              linewidth=2,
              linestyle='',
              marker='s',
              markersize=7,
              color='orange')
    plt2.plot(eps_y_fit,
              energy_vbm_y_fit,
              linewidth=2,
              linestyle='-',
              color='orange',
              label='y: VBM $E_{l} = $' +
              '{0:7.2f}'.format(E_l_hole_y / ev_in_j) + ' eV')
    plt2.plot(eps_y,
              energy_cbm_y,
              linewidth=2,
              linestyle='',
              marker='s',
              markersize=7,
              color='green')
    plt2.plot(eps_y_fit,
              energy_cbm_y_fit,
              linewidth=2,
              linestyle='-',
              color='green',
              label='y: CBM $E_{l} = $' +
              '{0:7.2f}'.format(E_l_el_y / ev_in_j) + ' eV')
    plt.xticks(fontsize=tick_size)
    plt.yticks(fontsize=tick_size)
    plt.xlabel('$\epsilon$', fontsize=lab_size)
    plt.ylabel('Energy, eV', fontsize=lab_size)
    if xlim: plt2.set_xlim(xlim[0], xlim[1])
    if ylim_deform: plt2.set_ylim(ylim_deform[0], ylim_deform[1])
    plt2.legend(bbox_to_anchor=(0.5, 0.5),
                borderaxespad=0.,
                labelspacing=0.3,
                numpoints=1,
                frameon=True,
                fancybox=True,
                markerscale=1.,
                handletextpad=0.3,
                fontsize=leg_size)

    # Make figure with the chosen size
    fig = plt.figure(1, dpi=600)
    fig.set_figheight(fig_size[0])
    fig.set_figwidth(fig_size[1])
    fig.savefig(folder + '/Elastic_moduli_Deformation_potential.pdf',
                format="pdf",
                dpi=600)
    plt.clf()
    plt.cla()
    # Calculation of the carrier mobility
    # Check if the temperature range option is used
    if temperature_range:
        step_t = (temperature_range[1] - temperature_range[0]) / (1000 - 1)
        t_list = [temperature_range[0] + i * step_t for i in range(1000)]

    # Make calculations
    f = open(folder + '/carrier_mobility_t' + str(temperature_ref) + '.out',
             'w')
    if expression == 'Guo2021_JMCC':
        cite = 'The expression for the carrier mobility was taken from \n S.-D. Guo, W.-Q. Mu, Y.-T. Zhu, R.-Y. Han, W.-C. Ren, J. Mater. Chem. C. 9 (2021) 2464–2473. doi:10.1039/D0TC05649A. (Eq. 4)\n'
    f.write(cite)
    f.write('\n')
    f.write('Temperature ' + str(temperature_ref) + ' K\n')
    f.write('{0:^15s}{1:^10s}{2:^15s}{3:^15s}{4:^15s}{5:^17s}'.format(
        'Carrier type', 'Direction', 'C_2D, N/m', 'm*, m_e', 'E_l, eV',
        'mu_2D, cm^2V^(-1)s^(-1)') + '\n')

    if expression == 'Guo2021_JMCC':
        function_cm = carrier_Guo2021_JMCC
    else:
        raise RuntimeError(
            'Choose the appropriate expression for carrier mobility!!!')

    for j in effective_mass_el.keys():
        f.write('CBM -> ' + j + '\n')
        if expression == 'Guo2021_JMCC':
            mu_el_x = function_cm(t=temperature_ref,
                                  c2d=C_2D_x,
                                  el=E_l_el_x,
                                  m=effective_mass_el[j],
                                  md=effective_mass_xy_el['X'])
            mu_el_y = function_cm(t=temperature_ref,
                                  c2d=C_2D_y,
                                  el=E_l_el_y,
                                  m=effective_mass_el[j],
                                  md=effective_mass_xy_el['Y'])

        f.write(
            '{0:^15s}{1:^10s}{2:^15.2f}{3:^15.2f}{4:^15.2f}{5:^17.2f}'.format(
                'Electron', 'x', C_2D_x, effective_mass_el[j], E_l_el_x /
                ev_in_j, mu_el_x) + '\n')
        f.write(
            '{0:^15s}{1:^10s}{2:^15.2f}{3:^15.2f}{4:^15.2f}{5:^17.2f}'.format(
                'Electron', 'y', C_2D_y, effective_mass_el[j], E_l_el_y /
                ev_in_j, mu_el_y) + '\n')

        # If the temperature range is set
        if temperature_range:
            mu_el_x_list = [
                function_cm(t=i,
                            c2d=C_2D_x,
                            el=E_l_el_x,
                            m=effective_mass_el[j],
                            md=effective_mass_xy_el['X']) for i in t_list
            ]
            mu_el_y_list = [
                function_cm(t=i,
                            c2d=C_2D_y,
                            el=E_l_el_y,
                            m=effective_mass_el[j],
                            md=effective_mass_xy_el['Y']) for i in t_list
            ]

            f1 = open(
                folder + '/carrier_mobility_t' + str(temperature_range[0]) +
                '_' + str(temperature_range[1]) + '_el_CBM_' + j + '_X.out',
                'w')
            for i in range(len(t_list)):
                f1.write('{0:^15.2f} {1:^15.2f}'.format(
                    t_list[i], mu_el_x_list[i]) + '\n')
            f1.close()

            f1 = open(
                folder + '/carrier_mobility_t' + str(temperature_range[0]) +
                '_' + str(temperature_range[1]) + '_el_CBM_' + j + '_Y.out',
                'w')
            for i in range(len(t_list)):
                f1.write('{0:^15.2f} {1:^15.2f}'.format(
                    t_list[i], mu_el_y_list[i]) + '\n')
            f1.close()

            # Make figure for the temperature dependence of the carrier mobility of electrons
            plt.plot(t_list,
                     mu_el_x_list,
                     linewidth=2,
                     linestyle='-',
                     color='red',
                     label='X')
            plt.plot(t_list,
                     mu_el_y_list,
                     linewidth=2,
                     linestyle='-',
                     color='blue',
                     label='Y')
            plt.xlabel('Temperature, K', fontsize=lab_size)
            plt.ylabel('$\mu_{2D}, cm^2V^{-1}s^{-1}$', fontsize=lab_size)
            plt.legend(bbox_to_anchor=(0.5, 0.5),
                       borderaxespad=0.,
                       labelspacing=0.3,
                       numpoints=1,
                       frameon=True,
                       fancybox=True,
                       markerscale=1.,
                       handletextpad=0.3,
                       fontsize=leg_size)
            plt.title('Electron CBM ->' + j)
            fig = plt.figure(1)
            fig.set_figheight(9)
            fig.set_figwidth(9)
            fig.savefig(folder + '/carrier_mobility_t' +
                        str(temperature_range[0]) + '_' +
                        str(temperature_range[1]) + '_el_CBM_' + j + '_XY.pdf',
                        format="pdf",
                        dpi=600)
            plt.clf()
            plt.cla()

    for j in effective_mass_hole.keys():
        f.write('VBM -> ' + j + '\n')
        if expression == 'Guo2021_JMCC':
            mu_hole_x = function_cm(t=temperature_ref,
                                    c2d=C_2D_x,
                                    el=E_l_hole_x,
                                    m=effective_mass_hole[j],
                                    md=effective_mass_xy_hole['X'])
            mu_hole_y = function_cm(t=temperature_ref,
                                    c2d=C_2D_y,
                                    el=E_l_hole_y,
                                    m=effective_mass_hole[j],
                                    md=effective_mass_xy_hole['Y'])

        f.write('{0:^15s}{1:^10s}{2:^15.2f}{3:^15.2f}{4:^15.2f}{5:^17.2f}'.
                format('Hole', 'x', C_2D_x, effective_mass_hole[j], E_l_el_x /
                       ev_in_j, mu_hole_x) + '\n')
        f.write('{0:^15s}{1:^10s}{2:^15.2f}{3:^15.2f}{4:^15.2f}{5:^17.2f}'.
                format('Hole', 'y', C_2D_y, effective_mass_hole[j], E_l_el_y /
                       ev_in_j, mu_hole_y) + '\n')

        # If the temperature range is set
        if temperature_range:
            mu_hole_x_list = [
                function_cm(t=i,
                            c2d=C_2D_x,
                            el=E_l_hole_x,
                            m=effective_mass_hole[j],
                            md=effective_mass_xy_hole['X']) for i in t_list
            ]
            mu_hole_y_list = [
                function_cm(t=i,
                            c2d=C_2D_y,
                            el=E_l_hole_y,
                            m=effective_mass_hole[j],
                            md=effective_mass_xy_hole['Y']) for i in t_list
            ]

            f1 = open(
                folder + '/carrier_mobility_t' + str(temperature_range[0]) +
                '_' + str(temperature_range[1]) + '_hole_VBM_' + j + '_X.out',
                'w')
            for i in range(len(t_list)):
                f1.write('{0:^15.2f} {1:^15.2f}'.format(
                    t_list[i], mu_hole_x_list[i]) + '\n')
            f1.close()

            f1 = open(
                folder + '/carrier_mobility_t' + str(temperature_range[0]) +
                '_' + str(temperature_range[1]) + '_hole_VBM_' + j + '_Y.out',
                'w')
            for i in range(len(t_list)):
                f1.write('{0:^15.2f} {1:^15.2f}'.format(
                    t_list[i], mu_hole_y_list[i]) + '\n')
            f1.close()

            # Make figure for the temperature dependence of the carrier mobility of holes
            plt.plot(t_list,
                     mu_hole_x_list,
                     linewidth=2,
                     linestyle='-',
                     color='red',
                     label='X')
            plt.plot(t_list,
                     mu_hole_y_list,
                     linewidth=2,
                     linestyle='-',
                     color='blue',
                     label='Y')
            plt.xlabel('Temperature, K', fontsize=lab_size)
            plt.ylabel('$\mu_{2D}, cm^2V^{-1}s^{-1}$', fontsize=lab_size)
            plt.legend(bbox_to_anchor=(0.5, 0.5),
                       borderaxespad=0.,
                       labelspacing=0.3,
                       numpoints=1,
                       frameon=True,
                       fancybox=True,
                       markerscale=1.,
                       handletextpad=0.3,
                       fontsize=leg_size)
            plt.title('Hole CBM ->' + j)
            fig = plt.figure(1)
            fig.set_figheight(9)
            fig.set_figwidth(9)
            fig.savefig(
                folder + '/carrier_mobility_t' + str(temperature_range[0]) +
                '_' + str(temperature_range[1]) + '_hole_VBM_' + j + '_XY.pdf',
                format="pdf",
                dpi=600)
            plt.clf()
            plt.cla()

    f.close()
Пример #33
0
def plot_bands(vasprun_dos, vasprun_bands, kpoints, element, ylim = (None, None), folder = '', renew_folder=True, vb_top=0, cb_bottom=1, vbm_pos=0, cbm_pos=0):
    """
    This function is used to build plot of the electronic band structure along with
    the density of states (DOS) plot. It has feature to provide contributions from different
    elements to both band structure and DOS. In addition, the band gap (in eV) is automatically
    calculated.

    INPUT:
        - vasprun_dos (str) - path to the vasprun file of the DOS calculation
        - vasprun_band (str) - path to the vasprun file of the band structure calculation
        - kpoints (str) - path to the KPOINTS file of the band structure calculation
        - element (str) - label of the chemical element, for which the contribution
                          to the band structure and DOS
        - ylim (tuple of floats) - energy range of the band structure and DOS plots, units are eV
        - folder (str) - directory where all the results will be built
        - renew_folder (bool) - if True then the folder will be renewed with removing old one
        - vb_top (int) - number of the last occupied band (valence band) (count starts from '1')
        - vbm_pos (int) - supposed number of the k-point in the IBZKPT file, at which the valence band maximum (VBM) is located (count starts from '0')
        - cb_bottom (int) - number of the first unoccupied band (conduction band) (count starts from '1')
        - cbm_pos (int) - supposed number of the k-point in the IBZKPT file, at which the conduction band minimum (CBM) is located (count starts from '0')
 
    RETURN:
        None
    SOURCE:
        Credit https://github.com/gVallverdu/bandstructureplots
    TODO:
        Some improvements
    """    

    from siman.small_functions import makedir
    # The folder to collect data necessary for graph building
    full_name_folder_data = folder+vasprun_bands.split('/')[-2]
    print('bands.py, string 274, full_name_folder_data ', full_name_folder_data)
    makedir(full_name_folder_data+'/', renew_folder = renew_folder)




    labels = read_kpoint_labels(kpoints)

    # density of states
    # dosrun = Vasprun(vasprun_dos)
    dosrun = Vasprun(vasprun_bands)
    spd_dos = dosrun.complete_dos.get_spd_dos()

    # bands
    run = Vasprun(vasprun_bands, parse_projected_eigen=True)
    bands = run.get_band_structure(kpoints,
                                   line_mode=True,
                                   efermi=dosrun.efermi)

    # set up matplotlib plot
    # ----------------------

    # general options for plot
    font = {'family': 'serif', 'size': 24}
    plt.rc('font', **font)

    # set up 2 graph with aspec ration 2/1
    # plot 1: bands diagram
    # plot 2: Density of States
    gs = GridSpec(1, 2, width_ratios=[2, 1])
    fig = plt.figure(figsize=(11.69, 8.27))
    # fig.suptitle("Bands diagram of copper")
    ax1 = plt.subplot(gs[0])
    ax2 = plt.subplot(gs[1])  # , sharey=ax1)

    # set ylim for the plot
    # ---------------------
    if ylim[0]:
        emin = ylim[0]
    else: 
        emin = -10.
    if ylim[1]:
        emax = ylim[1]
    else: 
        emax =  10.

    ax1.set_ylim(emin, emax)
    ax2.set_ylim(emin, emax)

    # Band Diagram
    # ------------
    name = element 
    pbands = bands.get_projections_on_elements_and_orbitals({name: ["s", "p", "d"]})
    # print(pbands)

    # compute s, p, d normalized contributions
    contrib = np.zeros((bands.nb_bands, len(bands.kpoints), 3))
    for b in range(bands.nb_bands):
        for k in range(len(bands.kpoints)):
            sc = pbands[Spin.up][b][k][name]["s"]**2
            pc = pbands[Spin.up][b][k][name]["p"]**2
            dc = pbands[Spin.up][b][k][name]["d"]**2
            tot = sc + pc + dc
            if tot != 0.0:
                contrib[b, k, 0] = sc / tot
                contrib[b, k, 1] = pc / tot
                contrib[b, k, 2] = dc / tot

    # plot bands using rgb mapping
    for b in range(bands.nb_bands):
        edif = [e - bands.efermi for e in bands.bands[Spin.up][b]]
        rgbline(ax1,
                range(len(bands.kpoints)),
                [e - bands.efermi for e in bands.bands[Spin.up][b]],
                contrib[b, :, 0],
                contrib[b, :, 1],
                contrib[b, :, 2])
        f = open(full_name_folder_data+'/band_'+str(b), 'w')
        for i in range(len(bands.kpoints)):
            f.write('{0:10d} {1:15.8f}'.format(i, edif[i])+'\n')
        f.close()

    f = open(full_name_folder_data+'/band_structure_full', 'w')
    for j in range(len(bands.kpoints)):
        s = str(j)+3*' '
        for i in range(bands.nb_bands):
            f1 = open(full_name_folder_data+'/band_'+str(i))
            l1 = f1.readlines()
            f1.close()
            s += l1[i].rstrip().split()[1]+3*' '
        s += '\n'
        f.write(s)
    f.close()

    # Calculating the band gap
    print('band_'+str(cb_bottom)+'_'+str(cbm_pos), bands.bands[Spin.up][cb_bottom-1][cbm_pos])
    print('band_'+str(vb_top)+'_'+str(vbm_pos), bands.bands[Spin.up][vb_top-1][vbm_pos])
    print('Eg = ', min(bands.bands[Spin.up][cb_bottom-1])-max(bands.bands[Spin.up][vb_top-1]), 'eV')
    print('Eg_man = ', bands.bands[Spin.up][cb_bottom-1][cbm_pos]-bands.bands[Spin.up][vb_top-1][vbm_pos], 'eV') 
    print('band_'+str(cb_bottom)+'_min', min(bands.bands[Spin.up][cb_bottom-1]))
    print('band_'+str(vb_top)+'_max', max(bands.bands[Spin.up][vb_top-1]))       
    print('band_'+str(cb_bottom)+'_min_point', list(bands.bands[Spin.up][cb_bottom-1]).index(min(bands.bands[Spin.up][cb_bottom-1])))
    print('band_'+str(vb_top)+'_max_point', list(bands.bands[Spin.up][vb_top-1]).index(max(bands.bands[Spin.up][vb_top-1])))


    # style
    ax1.set_xlabel("k-points")
    ax1.set_ylabel(r"$E - E_f$   /   eV")
    ax1.grid()

    # fermi level at 0
    ax1.hlines(y=0, xmin=0, xmax=len(bands.kpoints), color="k", linestyle = '--', lw=1)

    # labels
    nlabs = len(labels)
    step = len(bands.kpoints) / (nlabs - 1)
    for i, lab in enumerate(labels):
        ax1.vlines(i * step, emin, emax, "k")
    ax1.set_xticks([i * step for i in range(nlabs)])
    ax1.set_xticklabels(labels)

    ax1.set_xlim(0, len(bands.kpoints))

    # Density of states
    # ----------------

    ax2.set_yticklabels([])
    ax2.grid()
    ax2.set_xlim(1e-4, 5)
    ax2.set_xticklabels([])
    ax2.hlines(y=0, xmin=0, xmax=5, color="k", lw=2)
    ax2.set_xlabel("Density of States", labelpad=28)

    # spd contribution
    ax2.plot(spd_dos[OrbitalType.s].densities[Spin.up],
             dosrun.tdos.energies - dosrun.efermi,
             "r-", label="s", lw=2)
    ax2.plot(spd_dos[OrbitalType.p].densities[Spin.up],
             dosrun.tdos.energies - dosrun.efermi,
             "g-", label="p", lw=2)
    ax2.plot(spd_dos[OrbitalType.d].densities[Spin.up],
             dosrun.tdos.energies - dosrun.efermi,
             "b-", label="d", lw=2)

    # total dos
    ax2.fill_between(dosrun.tdos.densities[Spin.up],
                     0,
                     dosrun.tdos.energies - dosrun.efermi,
                     color=(0.7, 0.7, 0.7),
                     facecolor=(0.7, 0.7, 0.7))

    ax2.plot(dosrun.tdos.densities[Spin.up],
             dosrun.tdos.energies - dosrun.efermi,
             color=(0.6, 0.6, 0.6),
             label="total DOS")

    edif1 = dosrun.tdos.energies - dosrun.efermi
    f = open(full_name_folder_data+'/dos_s_'+element, 'w')
    for i in range(len(spd_dos[OrbitalType.s].densities[Spin.up])):
        f.write('{0:15.8f} {1:15.8f}'.format(spd_dos[OrbitalType.s].densities[Spin.up][i], edif1[i])+'\n')
    f.close()

    f = open(full_name_folder_data+'/dos_p_'+element, 'w')
    for i in range(len(spd_dos[OrbitalType.p].densities[Spin.up])):
        f.write('{0:15.8f} {1:15.8f}'.format(spd_dos[OrbitalType.p].densities[Spin.up][i], edif1[i])+'\n')
    f.close()

    f = open(full_name_folder_data+'/dos_d_'+element, 'w')
    for i in range(len(spd_dos[OrbitalType.d].densities[Spin.up])):
        f.write('{0:15.8f} {1:15.8f}'.format(spd_dos[OrbitalType.d].densities[Spin.up][i], edif1[i])+'\n')
    f.close()

    f = open(full_name_folder_data+'/dos_tot', 'w')
    for i in range(len(dosrun.tdos.densities[Spin.up])):
        f.write('{0:15.8f} {1:15.8f}'.format(dosrun.tdos.densities[Spin.up][i], edif1[i])+'\n')
    f.close()

    # plot format style
    # -----------------
    ax2.legend(fancybox=True, shadow=True, prop={'size': 18})
    plt.subplots_adjust(wspace=0)
    plt.tight_layout()

    # plt.show()
    plt.savefig(folder+vasprun_bands.split('/')[-2]+".pdf", format='pdf', dpi=600)
    # print('bands.efermi ', bands.efermi)
    # print('dosrun.efermi', dosrun.efermi)
Пример #34
0
def plot_bands(vasprun_dos,
               vasprun_bands,
               kpoints,
               element,
               ylim=(None, None),
               folder='',
               renew_folder=True,
               vb_top=0,
               cb_bottom=1,
               vbm_pos=0,
               cbm_pos=0):
    # read data
    # ---------

    # kpoints labels
    # labels = [r"$L$", r"$\Gamma$", r"$X$", r"$U,K$", r"$\Gamma$"]
    from functions_system import make_dir as MD
    # The folder to collect data necessary for graph building
    full_name_folder_data = folder + vasprun_bands.split('/')[-2]
    MD(full_name_folder_data, renew_dir=renew_folder)

    labels = read_kpoint_labels(kpoints)

    # density of states
    # dosrun = Vasprun(vasprun_dos)
    dosrun = Vasprun(vasprun_bands)
    spd_dos = dosrun.complete_dos.get_spd_dos()

    # bands
    run = Vasprun(vasprun_bands, parse_projected_eigen=True)
    bands = run.get_band_structure(kpoints,
                                   line_mode=True,
                                   efermi=dosrun.efermi)

    # set up matplotlib plot
    # ----------------------

    # general options for plot
    font = {'family': 'serif', 'size': 24}
    plt.rc('font', **font)

    # set up 2 graph with aspec ration 2/1
    # plot 1: bands diagram
    # plot 2: Density of States
    gs = GridSpec(1, 2, width_ratios=[2, 1])
    fig = plt.figure(figsize=(11.69, 8.27))
    # fig.suptitle("Bands diagram of copper")
    ax1 = plt.subplot(gs[0])
    ax2 = plt.subplot(gs[1])  # , sharey=ax1)

    # set ylim for the plot
    # ---------------------
    if ylim[0]:
        emin = ylim[0]
    else:
        emin = -10.
    if ylim[1]:
        emax = ylim[1]
    else:
        emax = 10.

    ax1.set_ylim(emin, emax)
    ax2.set_ylim(emin, emax)

    # Band Diagram
    # ------------
    name = element
    pbands = bands.get_projections_on_elements_and_orbitals(
        {name: ["s", "p", "d"]})
    # print(pbands)

    # compute s, p, d normalized contributions
    contrib = np.zeros((bands.nb_bands, len(bands.kpoints), 3))
    for b in range(bands.nb_bands):
        for k in range(len(bands.kpoints)):
            sc = pbands[Spin.up][b][k][name]["s"]**2
            pc = pbands[Spin.up][b][k][name]["p"]**2
            dc = pbands[Spin.up][b][k][name]["d"]**2
            tot = sc + pc + dc
            if tot != 0.0:
                contrib[b, k, 0] = sc / tot
                contrib[b, k, 1] = pc / tot
                contrib[b, k, 2] = dc / tot

    # plot bands using rgb mapping
    for b in range(bands.nb_bands):
        edif = [e - bands.efermi for e in bands.bands[Spin.up][b]]
        rgbline(ax1, range(len(bands.kpoints)),
                [e - bands.efermi for e in bands.bands[Spin.up][b]],
                contrib[b, :, 0], contrib[b, :, 1], contrib[b, :, 2])
        f = open(full_name_folder_data + '/band_' + str(b), 'w')
        for i in range(len(bands.kpoints)):
            f.write('{0:10d} {1:15.8f}'.format(i, edif[i]) + '\n')
        f.close()

    f = open(full_name_folder_data + '/band_structure_full', 'w')
    for j in range(len(bands.kpoints)):
        s = str(j) + 3 * ' '
        for i in range(bands.nb_bands):
            f1 = open(full_name_folder_data + '/band_' + str(i))
            l1 = f1.readlines()
            f1.close()
            s += l1[i].rstrip().split()[1] + 3 * ' '
        s += '\n'
        f.write(s)
    f.close()

    # Calculating the band gap
    print('band_' + str(cb_bottom) + '_' + str(cbm_pos),
          bands.bands[Spin.up][cb_bottom - 1][cbm_pos])
    print('band_' + str(vb_top) + '_' + str(vbm_pos),
          bands.bands[Spin.up][vb_top - 1][vbm_pos])
    print(
        'Eg = ',
        min(bands.bands[Spin.up][cb_bottom - 1]) -
        max(bands.bands[Spin.up][vb_top - 1]), 'eV')
    print(
        'Eg_man = ', bands.bands[Spin.up][cb_bottom - 1][cbm_pos] -
        bands.bands[Spin.up][vb_top - 1][vbm_pos], 'eV')
    print('band_' + str(cb_bottom) + '_min',
          min(bands.bands[Spin.up][cb_bottom - 1]))
    print('band_' + str(vb_top) + '_max',
          max(bands.bands[Spin.up][vb_top - 1]))
    print(
        'band_' + str(cb_bottom) + '_min_point',
        list(bands.bands[Spin.up][cb_bottom - 1]).index(
            min(bands.bands[Spin.up][cb_bottom - 1])))
    print(
        'band_' + str(vb_top) + '_max_point',
        list(bands.bands[Spin.up][vb_top - 1]).index(
            max(bands.bands[Spin.up][vb_top - 1])))

    # style
    ax1.set_xlabel("k-points")
    ax1.set_ylabel(r"$E - E_f$   /   eV")
    ax1.grid()

    # fermi level at 0
    ax1.hlines(y=0,
               xmin=0,
               xmax=len(bands.kpoints),
               color="k",
               linestyle='--',
               lw=1)

    # labels
    nlabs = len(labels)
    step = len(bands.kpoints) / (nlabs - 1)
    for i, lab in enumerate(labels):
        ax1.vlines(i * step, emin, emax, "k")
    ax1.set_xticks([i * step for i in range(nlabs)])
    ax1.set_xticklabels(labels)

    ax1.set_xlim(0, len(bands.kpoints))

    # Density of states
    # ----------------

    ax2.set_yticklabels([])
    ax2.grid()
    ax2.set_xlim(1e-4, 5)
    ax2.set_xticklabels([])
    ax2.hlines(y=0, xmin=0, xmax=5, color="k", lw=2)
    ax2.set_xlabel("Density of States", labelpad=28)

    # spd contribution
    ax2.plot(spd_dos[OrbitalType.s].densities[Spin.up],
             dosrun.tdos.energies - dosrun.efermi,
             "r-",
             label="s",
             lw=2)
    ax2.plot(spd_dos[OrbitalType.p].densities[Spin.up],
             dosrun.tdos.energies - dosrun.efermi,
             "g-",
             label="p",
             lw=2)
    ax2.plot(spd_dos[OrbitalType.d].densities[Spin.up],
             dosrun.tdos.energies - dosrun.efermi,
             "b-",
             label="d",
             lw=2)

    # total dos
    ax2.fill_between(dosrun.tdos.densities[Spin.up],
                     0,
                     dosrun.tdos.energies - dosrun.efermi,
                     color=(0.7, 0.7, 0.7),
                     facecolor=(0.7, 0.7, 0.7))

    ax2.plot(dosrun.tdos.densities[Spin.up],
             dosrun.tdos.energies - dosrun.efermi,
             color=(0.6, 0.6, 0.6),
             label="total DOS")

    edif1 = dosrun.tdos.energies - dosrun.efermi
    f = open(full_name_folder_data + '/dos_s_' + element, 'w')
    for i in range(len(spd_dos[OrbitalType.s].densities[Spin.up])):
        f.write('{0:15.8f} {1:15.8f}'.format(
            spd_dos[OrbitalType.s].densities[Spin.up][i], edif1[i]) + '\n')
    f.close()

    f = open(full_name_folder_data + '/dos_p_' + element, 'w')
    for i in range(len(spd_dos[OrbitalType.p].densities[Spin.up])):
        f.write('{0:15.8f} {1:15.8f}'.format(
            spd_dos[OrbitalType.p].densities[Spin.up][i], edif1[i]) + '\n')
    f.close()

    f = open(full_name_folder_data + '/dos_d_' + element, 'w')
    for i in range(len(spd_dos[OrbitalType.d].densities[Spin.up])):
        f.write('{0:15.8f} {1:15.8f}'.format(
            spd_dos[OrbitalType.d].densities[Spin.up][i], edif1[i]) + '\n')
    f.close()

    f = open(full_name_folder_data + '/dos_tot', 'w')
    for i in range(len(dosrun.tdos.densities[Spin.up])):
        f.write('{0:15.8f} {1:15.8f}'.format(dosrun.tdos.densities[Spin.up][i],
                                             edif1[i]) + '\n')
    f.close()

    # plot format style
    # -----------------
    ax2.legend(fancybox=True, shadow=True, prop={'size': 18})
    plt.subplots_adjust(wspace=0)
    plt.tight_layout()

    # plt.show()
    plt.savefig(folder + vasprun_bands.split('/')[-2] + ".pdf",
                format='pdf',
                dpi=600)