Example #1
0
def actual_diele_func_data(test_data_files):
    v = Vasprun(test_data_files / "MgSe_absorption_vasprun.xml")
    o = Outcar(test_data_files / "MgSe_absorption_OUTCAR")
    return make_diele_func(v, o)
Example #2
0
from pymatgen.io.vasp import Outcar

oc = Outcar('OUTCAR')
for i in oc.magnetization:
    print(i['tot'])
Example #3
0
def band_edge_properties(args: Namespace):
    vasprun = Vasprun(args.vasprun)
    outcar = Outcar(args.outcar)
    print(VaspBandEdgeProperties(vasprun, outcar))
Example #4
0
import numpy as np
from pymatgen.io.vasp import Structure, Outcar

s: Structure = Structure.from_file('POSCAR')
out = Outcar('OUTCAR')
e = 1.60217646e-19
v = s.volume
pol = np.zeros(3)

for j in range(4):
    result = np.zeros(3)
    for i in s.get_all_neighbors(2.5)[j]:
        result += i[0].coords
    diff = result / 7 - s.sites[j].coords
    pol += np.inner(out.born[j], diff)

print(pol * e / v * 1e+22)  # uC/cm^2
Example #5
0
    def setUp(self):
        struc = PymatgenTest.get_structure("VO2")
        struc.make_supercell(3)
        struc = struc
        self.vac = Vacancy(struc, struc.sites[0], charge=-3)

        abc = self.vac.bulk_structure.lattice.abc
        axisdata = [np.arange(0.0, lattval, 0.2) for lattval in abc]
        bldata = [
            np.array([1.0 for u in np.arange(0.0, lattval, 0.2)])
            for lattval in abc
        ]
        dldata = [
            np.array([(-1 - np.cos(2 * np.pi * u / lattval))
                      for u in np.arange(0.0, lattval, 0.2)])
            for lattval in abc
        ]
        self.frey_params = {
            "axis_grid": axisdata,
            "bulk_planar_averages": bldata,
            "defect_planar_averages": dldata,
            "dielectric": 15,
            "initial_defect_structure": struc.copy(),
            "defect_frac_sc_coords": struc.sites[0].frac_coords[:],
        }

        kumagai_bulk_struc = Poscar.from_file(
            os.path.join(PymatgenTest.TEST_FILES_DIR, "defect",
                         "CONTCAR_bulk")).structure
        bulk_out = Outcar(
            os.path.join(PymatgenTest.TEST_FILES_DIR, "defect",
                         "OUTCAR_bulk.gz"))
        defect_out = Outcar(
            os.path.join(PymatgenTest.TEST_FILES_DIR, "defect",
                         "OUTCAR_vac_Ga_-3.gz"))
        self.kumagai_vac = Vacancy(kumagai_bulk_struc,
                                   kumagai_bulk_struc.sites[0],
                                   charge=-3)
        kumagai_defect_structure = self.kumagai_vac.generate_defect_structure()
        self.kumagai_params = {
            "bulk_atomic_site_averages":
            bulk_out.electrostatic_potential,
            "defect_atomic_site_averages":
            defect_out.electrostatic_potential,
            "site_matching_indices":
            [[ind, ind - 1] for ind in range(len(kumagai_bulk_struc))],
            "defect_frac_sc_coords": [0.0, 0.0, 0.0],
            "initial_defect_structure":
            kumagai_defect_structure,
            "dielectric":
            18.118 * np.identity(3),
            "gamma":
            0.153156,  # not necessary to load gamma, but speeds up unit test
        }

        v = Vasprun(os.path.join(PymatgenTest.TEST_FILES_DIR, "vasprun.xml"))
        eigenvalues = v.eigenvalues.copy()
        kptweights = v.actual_kpoints_weights
        potalign = -0.1
        vbm = v.eigenvalue_band_properties[2]
        cbm = v.eigenvalue_band_properties[1]
        defect_incar = v.incar
        self.bandfill_params = {
            "eigenvalues": eigenvalues,
            "kpoint_weights": kptweights,
            "potalign": potalign,
            "vbm": vbm,
            "cbm": cbm,
            "run_metadata": {
                "defect_incar": defect_incar
            },
        }

        self.band_edge_params = {
            "hybrid_cbm": 1.0,
            "hybrid_vbm": -1.0,
            "vbm": -0.5,
            "cbm": 0.6,
            "num_hole_vbm": 1.0,
            "num_elec_cbm": 1.0,
        }
Example #6
0
    def test_kumagai(self):
        gamma = 0.19357221
        prec = 28
        lattice = Lattice([[4.692882, -8.12831, 0.0], [4.692882, 8.12831, 0.0],
                           [0.0, 0.0, 10.03391]])

        # note that real/recip vector generation is not dependent on epsilon
        g_vecs, _, r_vecs, _ = generate_R_and_G_vecs(gamma, prec, lattice,
                                                     80.0 * np.identity(3))

        # test real space summation (bigger for large epsilon)
        kc_high_diel = KumagaiCorrection(80.0 * np.identity(3), gamma=gamma)
        real_sum = kc_high_diel.get_real_summation(gamma, r_vecs[0])
        self.assertAlmostEqual(real_sum, 0.00843104)

        # test recip space summation (bigger for small epsilon)
        kc_low_diel = KumagaiCorrection(0.1 * np.identity(3), gamma=gamma)
        recip_sum = kc_low_diel.get_recip_summation(gamma, g_vecs[0],
                                                    lattice.volume)
        self.assertAlmostEqual(recip_sum, 0.31117099)

        # test self interaction
        si_corr = kc_low_diel.get_self_interaction(gamma)
        self.assertAlmostEqual(si_corr, -0.54965249)

        # test potenital shift interaction correction
        ps_corr = kc_low_diel.get_potential_shift(gamma, lattice.volume)
        self.assertAlmostEqual(ps_corr, -0.00871593)

        # """Test Defect Entry approach to correction """
        bulk_struc = Poscar.from_file(
            os.path.join(test_dir, "defect", "CONTCAR_bulk")).structure
        bulk_out = Outcar(os.path.join(test_dir, "defect", "OUTCAR_bulk.gz"))
        defect_out = Outcar(
            os.path.join(test_dir, "defect", "OUTCAR_vac_Ga_-3.gz"))
        epsilon = 18.118 * np.identity(3)
        vac = Vacancy(bulk_struc, bulk_struc.sites[0], charge=-3)
        defect_structure = vac.generate_defect_structure()
        defect_frac_coords = [0.0, 0.0, 0.0]

        parameters = {
            "bulk_atomic_site_averages":
            bulk_out.electrostatic_potential,
            "defect_atomic_site_averages":
            defect_out.electrostatic_potential,
            "site_matching_indices":
            [[ind, ind - 1] for ind in range(len(bulk_struc))],
            "initial_defect_structure":
            defect_structure,
            "defect_frac_sc_coords":
            defect_frac_coords,
        }
        dentry = DefectEntry(vac, 0.0, parameters=parameters)
        kc = KumagaiCorrection(epsilon)
        kcorr = kc.get_correction(dentry)
        self.assertAlmostEqual(kcorr["kumagai_electrostatic"], 0.88236299)
        self.assertAlmostEqual(kcorr["kumagai_potential_alignment"],
                               2.09704862)

        # test ES correction
        high_diel_es_corr = kc_high_diel.perform_es_corr(
            gamma, prec, lattice, -3.0)
        self.assertAlmostEqual(high_diel_es_corr, 0.25176240)

        low_diel_es_corr = kc_low_diel.perform_es_corr(gamma, prec, lattice,
                                                       -3.0)
        self.assertAlmostEqual(low_diel_es_corr, 201.28810966)

        # test pot correction
        site_list = []
        for bs_ind, ds_ind in dentry.parameters["site_matching_indices"]:
            Vqb = -(defect_out.electrostatic_potential[ds_ind] -
                    bulk_out.electrostatic_potential[bs_ind])
            site_list.append([defect_structure[ds_ind], Vqb])

        sampling_radius = dentry.parameters["kumagai_meta"]["sampling_radius"]
        gamma = dentry.parameters["kumagai_meta"]["gamma"]
        q = -3
        g_vecs, _, r_vecs, _ = generate_R_and_G_vecs(gamma, 28,
                                                     defect_structure.lattice,
                                                     np.identity(3))
        high_diel_pot_corr = kc_high_diel.perform_pot_corr(
            defect_structure,
            defect_frac_coords,
            site_list,
            sampling_radius,
            q,
            r_vecs[0],
            g_vecs[0],
            gamma,
        )
        self.assertAlmostEqual(high_diel_pot_corr, 2.35840716)
        low_diel_pot_corr = kc_low_diel.perform_pot_corr(
            defect_structure,
            defect_frac_coords,
            site_list,
            sampling_radius,
            q,
            r_vecs[0],
            g_vecs[0],
            gamma,
        )
        self.assertAlmostEqual(low_diel_pot_corr, -58.83598095)

        # test the kumagai plotter
        kcp = kc.plot()
        self.assertTrue(kcp)

        # check that uncertainty metadata exists
        self.assertAlmostEqual(
            set(kc.metadata["pot_corr_uncertainty_md"].keys()),
            set(["number_sampled", "stats"]),
        )
Example #7
0
def elastic_analysis():

    filename = 'OUTCAR'
    step_count = 1
    check_file(filename)
    proc_str = "Reading Data From " + filename + " File ..."
    procs(proc_str, step_count, sp='-->>')
    outcar = Outcar(filename)
    outcar.read_elastic_tensor()
    cij_tensor = np.array(outcar.data['elastic_tensor'])

    filename = 'vasprun.xml'
    step_count += 1
    check_file(filename)
    proc_str = "Reading Data From " + filename + " File ..."
    procs(proc_str, step_count, sp='-->>')
    vsr = Vasprun(filename)
    struct0 = vsr.structures[0]
    natom = struct0.num_sites
    weight = struct0.composition.weight
    volume = struct0.lattice.volume

    ## converting the units
    volume *= 1.0e-30  ## from Angstrom to meters
    weight *= weight * 1.0e-3  ## from gram to kg
    density = weight / (volume * Avogadro)

    asa = analyzer.SpacegroupAnalyzer(struct0)
    #   lat_type=asa.get_crystal_system()

    crys_type = asa.get_lattice_type()

    ## Redefining the Cij matrix into the correct Voigt notation since VASP's OUTCAR has a different order
    ## In VASP: Columns and rows are listed as: 1, 2, 3, 6, 4, 5
    ## In this format OUTCAR's C44 values would be actually C66, C55 would be C44, and C66 would be C55.
    ## OUTCAR follows the below order:
    ## [C11 C12 C13 C16 C14 C15]
    ## [C21 C22 C23 C26 C24 C25]
    ## [C31 C32 C33 C36 C34 C35]
    ## [C61 C62 C63 C66 C64 C65]
    ## [C41 C42 C43 C46 C44 C45]
    ## [C51 C52 C53 C56 C54 C55]

    cnew = np.zeros((6, 6))
    snew = np.zeros((6, 6))
    cnew = np.copy(cij_tensor)

    for j in range(0, 6):
        cnew[3][j] = cij_tensor[4][j]
        cnew[4][j] = cij_tensor[5][j]
        cnew[5][j] = cij_tensor[3][j]

    ctemp = np.zeros((6, 6))
    ctemp = np.copy(cnew)

    for i in range(0, 6):
        cnew[i][3] = cnew[i][4]
        cnew[i][4] = cnew[i][5]
        cnew[i][5] = ctemp[i][3]

    # Change the units of Cij from kBar to GPa
    cnew = cnew / 10.0
    proc_str = "\n Modified elastic tensor in correct order (in GPa units)"
    print(proc_str)
    fmt = "%7.3f " * 6
    for i in range(6):
        print(fmt % tuple(cnew[i, :]))

    def check_symmetric(a, tol=1e-8):
        return np.allclose(a, a.T, atol=tol)

    print(
        '\n Checking if the elastic tensor is symmetric: i.e. Cij = Cji:  %5s'
        % check_symmetric(cnew))
    print("\n Eigen Values of the elastic tensor:")
    evals = LA.eigvals(cnew)
    print(fmt % tuple(evals))
    if np.all(evals) > 0.0:
        print("\n All eigen values are positive indicating elastic stability.")
    else:
        print(
            "\n ATTENTION: One or more eigen values are negative indicating elastic instability."
        )
    calc_elastic_prop(cnew, snew, crys_type, density, weight, natom)
Example #8
0
    def post_process(self, dir_name, d):
        """
        Simple post-processing for various files other than the vasprun.xml.
        Called by generate_task_doc. Modify this if your runs have other
        kinds of processing requirements.

        Args:
            dir_name:
                The dir_name.
            d:
                Current doc generated.
        """
        logger.info("Post-processing dir:{}".format(dir_name))

        fullpath = os.path.abspath(dir_name)

        # VASP input generated by pymatgen's alchemy has a
        # transformations.json file that keeps track of the origin of a
        # particular structure. This is extremely useful for tracing back a
        # result. If such a file is found, it is inserted into the task doc
        # as d["transformations"]
        transformations = {}
        filenames = glob.glob(os.path.join(fullpath, "transformations.json*"))
        if len(filenames) >= 1:
            with zopen(filenames[0], "rt") as f:
                transformations = json.load(f)
                try:
                    m = re.match("(\d+)-ICSD",
                                 transformations["history"][0]["source"])
                    if m:
                        d["icsd_id"] = int(m.group(1))
                except Exception as ex:
                    logger.warning("Cannot parse ICSD from transformations "
                                   "file.")
                    pass
        else:
            logger.warning("Transformations file does not exist.")

        other_parameters = transformations.get("other_parameters")
        new_tags = None
        if other_parameters:
            # We don't want to leave tags or authors in the
            # transformations file because they'd be copied into
            # every structure generated after this one.
            new_tags = other_parameters.pop("tags", None)
            new_author = other_parameters.pop("author", None)
            if new_author:
                d["author"] = new_author
            if not other_parameters:  # if dict is now empty remove it
                transformations.pop("other_parameters")

        d["transformations"] = transformations

        # Calculations done using custodian has a custodian.json,
        # which tracks the jobs performed and any errors detected and fixed.
        # This is useful for tracking what has actually be done to get a
        # result. If such a file is found, it is inserted into the task doc
        # as d["custodian"]
        filenames = glob.glob(os.path.join(fullpath, "custodian.json*"))
        if len(filenames) >= 1:
            with zopen(filenames[0], "r") as f:
                d["custodian"] = json.load(f)

        # Parse OUTCAR for additional information and run stats that are
        # generally not in vasprun.xml.
        try:
            run_stats = {}
            for filename in glob.glob(os.path.join(fullpath, "OUTCAR*")):
                outcar = Outcar(filename)
                i = 1 if re.search("relax2", filename) else 0
                taskname = "relax2" if re.search("relax2", filename) else \
                    "relax1"
                d["calculations"][i]["output"]["outcar"] = outcar.as_dict()
                run_stats[taskname] = outcar.run_stats
        except:
            logger.error("Bad OUTCAR for {}.".format(fullpath))

        try:
            overall_run_stats = {}
            for key in [
                    "Total CPU time used (sec)", "User time (sec)",
                    "System time (sec)", "Elapsed time (sec)"
            ]:
                overall_run_stats[key] = sum(
                    [v[key] for v in run_stats.values()])
            run_stats["overall"] = overall_run_stats
        except:
            logger.error("Bad run stats for {}.".format(fullpath))

        d["run_stats"] = run_stats

        #Convert to full uri path.
        if self.use_full_uri:
            d["dir_name"] = get_uri(dir_name)

        if new_tags:
            d["tags"] = new_tags

        logger.info("Post-processed " + fullpath)
            fE = tot_E - ref_dict[el[0]] - ref_dict[
                el[1]] - 1.5 * ref_dict['O2_corr']

            if el[0] or el[1] in U_corr_dict:
                for x in range(len(el)):
                    if el[x] in U_corr_dict:
                        fE = fE - U_corr_dict[el[x]]
            fE = fE / len(conv_struc)  # eV/atom

            df_bulk.DHf[idx + 1] = fE
            df_bulk.Err_DHf[idx +
                            1] = df_bulk.DHf_ref[idx + 1] - df_bulk.DHf[idx +
                                                                        1]

            outcar = Outcar(file_path + 'OUTCAR')

            magm_list = []
            for atom in range(len(conv_struc)):
                magm_list.append(outcar.magnetization[atom]['tot'])
            df_bulk.Magm[idx + 1] = magm_list

            if tot_mag >= 0.5:  # not a physical definition
                df_bulk.Mag_O[idx + 1] = 'FM'
            elif tot_mag < 0.5:
                df_bulk.Mag_O[idx + 1] = 'NM'

            bulk_opt = read_vasp(file_path + 'CONTCAR')
            elements = []
            for element in bulk_opt.get_chemical_symbols():
                if element not in elements:
            df_bulk.Err_V_percent[idx+1] = (volume_ref - volume) / volume_ref * 100

            el = v.as_dict()['elements']
            el.remove('O')

            fE = tot_E - ref_dict[el[0]] - ref_dict[el[1]] - 1.5*ref_dict['O2_corr']
    
            if el[0] or el[1] in U_corr_dict:
                for x in range(len(el)):
                    if el[x] in U_corr_dict:
                        fE = fE - U_corr_dict[el[x]]
                        
            df_bulk.DHf[idx+1] = fE/5.0
            df_bulk.Err_DHf[idx+1] = df_bulk.DHf_ref[idx+1] - df_bulk.DHf[idx+1]
            
            outcar = Outcar('%03d_%s/2nd/OUTCAR' % (idx + 1.0, formula))
            
            magm_list = []
            for atom in range(len(conv_struc)):  
                magm_list.append(outcar.magnetization[atom]['tot'])
            df_bulk.Magm[idx + 1] = magm_list
            
            if tot_mag >= 0.5:    # not a physical definition 
                df_bulk.Mag_O[idx+1] = 'FM'
            elif tot_mag < 0.5:
                df_bulk.Mag_O[idx+1] = 'NM'
                
        except FileNotFoundError:
            # print('%03d_%s/2nd files are not found' % (idx + 1.0, formula))
            f.writelines('%03d_%s/2nd files are not found\n' % (idx + 1.0, formula))
            continue
Example #11
0
    def run_task(self, fw_spec):
        write_output = True
        job_info_array = fw_spec['_job_info']

        # get dummy index
        with open(os.path.join(job_info_array[-1]['launch_dir'], 'POSCAR'),
                  'rt') as f:
            poscar_lines = f.readlines()
        elem_list = poscar_lines[0].split()
        num_ions = [int(item) for item in poscar_lines[5].split()]

        dummy_index = 0
        for elem, amount in zip(elem_list, num_ions):
            if elem == self['dummy_atom']:
                if amount == 1:
                    break
                else:
                    raise ValueError(
                        'More than one dummy atom in the structure')
            else:
                dummy_index += amount

        # get charges
        charges = []
        incar_bare = Incar.from_file(
            os.path.join(job_info_array[0]['launch_dir'], 'INCAR'))
        outcar_bare = Outcar(
            os.path.join(job_info_array[0]['launch_dir'], 'OUTCAR'))
        bare_magmoms = [
            item['tot'] for item, ref in zip(outcar_bare.magnetization,
                                             incar_bare['MAGMOM']) if ref != 0
        ]
        for step in [1, 2]:
            outcar = Outcar(
                os.path.join(job_info_array[step]['launch_dir'], 'OUTCAR'))
            with open(
                    os.path.join(job_info_array[step]['launch_dir'],
                                 'is_converged'), 'r') as f:
                conv_info = f.readline()

            if 'f' in outcar.charge[dummy_index]:
                charges.append(outcar.charge[dummy_index]['f'])
            else:
                charges.append(outcar.charge[dummy_index]['d'])

            final_magmoms = [
                item['tot'] for item, ref in zip(
                    outcar.magnetization, incar_bare['MAGMOM']) if ref != 0
            ]
            for bare_magmom, final_magmom in zip(bare_magmoms, final_magmoms):
                if bare_magmom != 0:
                    # if the magnetic moment changes too much, do not write charges in output
                    if final_magmom / bare_magmom < 0.8 or final_magmom / bare_magmom > 1.2 \
                            or conv_info == 'NONCONVERGED':
                        write_output = False

        if write_output:
            with open(
                    os.path.join(os.environ.get('AUTOMAG_PATH'), 'CalcFold',
                                 self['filename']), 'a') as f:
                f.write(
                    f"{self['pert_value']:5.2f}  {charges[0]}  {charges[1]}\n")
Example #12
0
 def _inner(_dir: Path):
     calc_results = make_calc_results_from_vasp(
         vasprun=Vasprun(_dir / defaults.vasprun),
         outcar=Outcar(_dir / defaults.outcar))
     calc_results.to_json_file(str(_dir / "calc_results.json"))
Example #13
0
 def Get_ElasConst(self, filepath):
     outcar = Outcar(filepath + "OUTCAR")
     outcar.read_elastic_tensor()
     self.tensor = np.array(
         outcar.data["elastic_tensor"]) / 10  #unit in GPa
Example #14
0
def calc_results(vasp_files):
    vasprun = Vasprun(vasp_files / "MgO_conv_Va_O_0" / "vasprun.xml")
    outcar = Outcar(vasp_files / "MgO_conv_Va_O_0" / "OUTCAR")
    return make_calc_results_from_vasp(vasprun, outcar)
Example #15
0
    def correct(self):
        backup(VASP_BACKUP_FILES | {self.output_filename})
        actions = []
        vi = VaspInput.from_directory(".")

        if self.errors.intersection(["tet", "dentet"]):
            actions.append({
                "dict": "INCAR",
                "action": {
                    "_set": {
                        "ISMEAR": 0
                    }
                }
            })

        if "inv_rot_mat" in self.errors:
            actions.append({
                "dict": "INCAR",
                "action": {
                    "_set": {
                        "SYMPREC": 1e-8
                    }
                }
            })

        if "brmix" in self.errors:
            # If there is not a valid OUTCAR already, increment
            # error count to 1 to skip first fix
            if self.error_count['brmix'] == 0:
                try:
                    assert (Outcar(zpath(os.path.join(
                        os.getcwd(), "OUTCAR"))).is_stopped is False)
                except:
                    self.error_count['brmix'] += 1

            if self.error_count['brmix'] == 0:
                # Valid OUTCAR - simply rerun the job and increment
                # error count for next time
                actions.append({
                    "dict": "INCAR",
                    "action": {
                        "_set": {
                            "ISTART": 1
                        }
                    }
                })
                self.error_count['brmix'] += 1

            elif self.error_count['brmix'] == 1:
                # Use Kerker mixing w/default values for other parameters
                actions.append({
                    "dict": "INCAR",
                    "action": {
                        "_set": {
                            "IMIX": 1
                        }
                    }
                })
                self.error_count['brmix'] += 1

            elif self.error_count['brmix'] == 2 and vi["KPOINTS"].style \
                    == Kpoints.supported_modes.Gamma:
                actions.append({
                    "dict": "KPOINTS",
                    "action": {
                        "_set": {
                            "generation_style": "Monkhorst"
                        }
                    }
                })
                actions.append({
                    "dict": "INCAR",
                    "action": {
                        "_unset": {
                            "IMIX": 1
                        }
                    }
                })
                self.error_count['brmix'] += 1

            elif self.error_count['brmix'] in [2, 3] and vi["KPOINTS"].style \
                    == Kpoints.supported_modes.Monkhorst:
                actions.append({
                    "dict": "KPOINTS",
                    "action": {
                        "_set": {
                            "generation_style": "Gamma"
                        }
                    }
                })
                actions.append({
                    "dict": "INCAR",
                    "action": {
                        "_unset": {
                            "IMIX": 1
                        }
                    }
                })
                self.error_count['brmix'] += 1

                if vi["KPOINTS"].num_kpts < 1:
                    all_kpts_even = all(
                        [bool(n % 2 == 0) for n in vi["KPOINTS"].kpts[0]])
                    print("all_kpts_even = {}".format(all_kpts_even))
                    if all_kpts_even:
                        new_kpts = (tuple(n + 1
                                          for n in vi["KPOINTS"].kpts[0]), )
                        print("new_kpts = {}".format(new_kpts))
                        actions.append({
                            "dict": "KPOINTS",
                            "action": {
                                "_set": {
                                    "kpoints": new_kpts
                                }
                            }
                        })

            else:
                actions.append({
                    "dict": "INCAR",
                    "action": {
                        "_set": {
                            "ISYM": 0
                        }
                    }
                })

                if vi["KPOINTS"].style == Kpoints.supported_modes.Monkhorst:
                    actions.append({
                        "dict": "KPOINTS",
                        "action": {
                            "_set": {
                                "generation_style": "Gamma"
                            }
                        }
                    })

                # Based on VASP forum's recommendation, you should delete the
                # CHGCAR and WAVECAR when dealing with this error.
                actions.append({
                    "file": "CHGCAR",
                    "action": {
                        "_file_delete": {
                            'mode': "actual"
                        }
                    }
                })
                actions.append({
                    "file": "WAVECAR",
                    "action": {
                        "_file_delete": {
                            'mode': "actual"
                        }
                    }
                })

        if "zpotrf" in self.errors:
            # Usually caused by short bond distances. If on the first step,
            # volume needs to be increased. Otherwise, it was due to a step
            # being too big and POTIM should be decreased.
            try:
                oszicar = Oszicar("OSZICAR")
                nsteps = len(oszicar.ionic_steps)
            except:
                nsteps = 0

            if nsteps >= 1:
                potim = float(vi["INCAR"].get("POTIM", 0.5)) / 2.0
                actions.append({
                    "dict": "INCAR",
                    "action": {
                        "_set": {
                            "ISYM": 0,
                            "POTIM": potim
                        }
                    }
                })
            else:
                s = vi["POSCAR"].structure
                s.apply_strain(0.2)
                actions.append({
                    "dict": "POSCAR",
                    "action": {
                        "_set": {
                            "structure": s.as_dict()
                        }
                    }
                })

            # Based on VASP forum's recommendation, you should delete the
            # CHGCAR and WAVECAR when dealing with this error.

            actions.append({
                "file": "CHGCAR",
                "action": {
                    "_file_delete": {
                        'mode': "actual"
                    }
                }
            })
            actions.append({
                "file": "WAVECAR",
                "action": {
                    "_file_delete": {
                        'mode': "actual"
                    }
                }
            })

        if self.errors.intersection(
            ["subspacematrix", "rspher", "real_optlay"]):
            actions.append({
                "dict": "INCAR",
                "action": {
                    "_set": {
                        "LREAL": False
                    }
                }
            })

        if self.errors.intersection(["tetirr", "incorrect_shift"]):

            if vi["KPOINTS"].style == Kpoints.supported_modes.Monkhorst:
                actions.append({
                    "dict": "KPOINTS",
                    "action": {
                        "_set": {
                            "generation_style": "Gamma"
                        }
                    }
                })

        if "rot_matrix" in self.errors:
            if vi["KPOINTS"].style == Kpoints.supported_modes.Monkhorst:
                actions.append({
                    "dict": "KPOINTS",
                    "action": {
                        "_set": {
                            "generation_style": "Gamma"
                        }
                    }
                })
            else:
                actions.append({
                    "dict": "INCAR",
                    "action": {
                        "_set": {
                            "ISYM": 0
                        }
                    }
                })

        if "amin" in self.errors:
            actions.append({
                "dict": "INCAR",
                "action": {
                    "_set": {
                        "AMIN": "0.01"
                    }
                }
            })

        if "triple_product" in self.errors:
            s = vi["POSCAR"].structure
            trans = SupercellTransformation(((1, 0, 0), (0, 0, 1), (0, 1, 0)))
            new_s = trans.apply_transformation(s)
            actions.append({
                "dict": "POSCAR",
                "action": {
                    "_set": {
                        "structure": new_s.as_dict()
                    }
                },
                "transformation": trans.as_dict()
            })

        if "pricel" in self.errors:
            actions.append({
                "dict": "INCAR",
                "action": {
                    "_set": {
                        "SYMPREC": 1e-8,
                        "ISYM": 0
                    }
                }
            })

        if "brions" in self.errors:
            potim = float(vi["INCAR"].get("POTIM", 0.5)) + 0.1
            actions.append({
                "dict": "INCAR",
                "action": {
                    "_set": {
                        "POTIM": potim
                    }
                }
            })

        if "zbrent" in self.errors:
            actions.append({
                "dict": "INCAR",
                "action": {
                    "_set": {
                        "IBRION": 1
                    }
                }
            })

        if "too_few_bands" in self.errors:
            if "NBANDS" in vi["INCAR"]:
                nbands = int(vi["INCAR"]["NBANDS"])
            else:
                with open("OUTCAR") as f:
                    for line in f:
                        if "NBANDS" in line:
                            try:
                                d = line.split("=")
                                nbands = int(d[-1].strip())
                                break
                            except (IndexError, ValueError):
                                pass
            actions.append({
                "dict": "INCAR",
                "action": {
                    "_set": {
                        "NBANDS": int(1.1 * nbands)
                    }
                }
            })

        if "pssyevx" in self.errors:
            actions.append({
                "dict": "INCAR",
                "action": {
                    "_set": {
                        "ALGO": "Normal"
                    }
                }
            })
        if "eddrmm" in self.errors:
            #RMM algorithm is not stable for this calculation
            if vi["INCAR"].get("ALGO", "Normal") in ["Fast", "VeryFast"]:
                actions.append({
                    "dict": "INCAR",
                    "action": {
                        "_set": {
                            "ALGO": "Normal"
                        }
                    }
                })
            else:
                potim = float(vi["INCAR"].get("POTIM", 0.5)) / 2.0
                actions.append({
                    "dict": "INCAR",
                    "action": {
                        "_set": {
                            "POTIM": potim
                        }
                    }
                })

            actions.append({
                "file": "CHGCAR",
                "action": {
                    "_file_delete": {
                        'mode': "actual"
                    }
                }
            })
            actions.append({
                "file": "WAVECAR",
                "action": {
                    "_file_delete": {
                        'mode': "actual"
                    }
                }
            })
        if "edddav" in self.errors:
            actions.append({
                "file": "CHGCAR",
                "action": {
                    "_file_delete": {
                        'mode': "actual"
                    }
                }
            })
            actions.append({
                "dict": "INCAR",
                "action": {
                    "_set": {
                        "ALGO": "All"
                    }
                }
            })

        VaspModder(vi=vi).apply_actions(actions)
        return {"errors": list(self.errors), "actions": actions}
    def setUp(self):
        struc = PymatgenTest.get_structure("VO2")
        struc.make_supercell(3)
        struc = struc
        self.vac = Vacancy(struc, struc.sites[0], charge=-3)

        abc = self.vac.bulk_structure.lattice.abc
        axisdata = [np.arange(0., lattval, 0.2) for lattval in abc]
        bldata = [
            np.array([1. for u in np.arange(0., lattval, 0.2)])
            for lattval in abc
        ]
        dldata = [
            np.array([(-1 - np.cos(2 * np.pi * u / lattval))
                      for u in np.arange(0., lattval, 0.2)]) for lattval in abc
        ]
        self.frey_params = {
            'axis_grid': axisdata,
            'bulk_planar_averages': bldata,
            'defect_planar_averages': dldata,
            'dielectric': 15,
            'initial_defect_structure': struc.copy(),
            'defect_frac_sc_coords': struc.sites[0].frac_coords[:]
        }

        kumagai_bulk_struc = Poscar.from_file(
            os.path.join(test_dir, 'defect', 'CONTCAR_bulk')).structure
        bulk_out = Outcar(os.path.join(test_dir, 'defect', 'OUTCAR_bulk.gz'))
        defect_out = Outcar(
            os.path.join(test_dir, 'defect', 'OUTCAR_vac_Ga_-3.gz'))
        self.kumagai_vac = Vacancy(kumagai_bulk_struc,
                                   kumagai_bulk_struc.sites[0],
                                   charge=-3)
        kumagai_defect_structure = self.kumagai_vac.generate_defect_structure()
        self.kumagai_params = {
            'bulk_atomic_site_averages':
            bulk_out.electrostatic_potential,
            'defect_atomic_site_averages':
            defect_out.electrostatic_potential,
            'site_matching_indices':
            [[ind, ind - 1] for ind in range(len(kumagai_bulk_struc))],
            'defect_frac_sc_coords': [0., 0., 0.],
            'initial_defect_structure':
            kumagai_defect_structure,
            'dielectric':
            18.118 * np.identity(3),
            'gamma':
            0.153156  # not neccessary to load gamma, but speeds up unit test
        }

        v = Vasprun(os.path.join(test_dir, 'vasprun.xml'))
        eigenvalues = v.eigenvalues.copy()
        kptweights = v.actual_kpoints_weights
        potalign = -0.1
        vbm = v.eigenvalue_band_properties[2]
        cbm = v.eigenvalue_band_properties[1]
        self.bandfill_params = {
            'eigenvalues': eigenvalues,
            'kpoint_weights': kptweights,
            'potalign': potalign,
            'vbm': vbm,
            'cbm': cbm
        }

        self.band_edge_params = {
            'hybrid_cbm': 1.,
            'hybrid_vbm': -1.,
            'vbm': -0.5,
            'cbm': 0.6,
            'num_hole_vbm': 1.,
            'num_elec_cbm': 1.
        }
Example #17
0
    def generate_doc(self, dir_name, vasprun_files, outcar_files):
        """
        Adapted from matgendb.creator.generate_doc
        """
        try:
            # basic properties, incl. calcs_reversed and run_stats
            fullpath = os.path.abspath(dir_name)
            d = {k: v for k, v in self.additional_fields.items()}
            d["schema"] = {"code": "atomate", "version": VaspDrone.__version__}
            d["dir_name"] = fullpath
            d["calcs_reversed"] = [self.process_vasprun(dir_name, taskname, filename)
                                   for taskname, filename in vasprun_files.items()]
            outcar_data = [Outcar(os.path.join(dir_name, filename)).as_dict()
                           for taskname, filename in outcar_files.items()]
            run_stats = {}
            for i, d_calc in enumerate(d["calcs_reversed"]):
                run_stats[d_calc["task"]["name"]] = outcar_data[i].pop("run_stats")
                if d_calc.get("output"):
                    d_calc["output"].update({"outcar": outcar_data[i]})
                else:
                    d_calc["output"] = {"outcar": outcar_data[i]}
            try:
                overall_run_stats = {}
                for key in ["Total CPU time used (sec)", "User time (sec)", "System time (sec)",
                            "Elapsed time (sec)"]:
                    overall_run_stats[key] = sum([v[key] for v in run_stats.values()])
                run_stats["overall"] = overall_run_stats
            except:
                logger.error("Bad run stats for {}.".format(fullpath))
            d["run_stats"] = run_stats

            # reverse the calculations data order so newest calc is first
            d["calcs_reversed"].reverse()

            # set root formula/composition keys based on initial and final calcs
            d_calc_init = d["calcs_reversed"][-1]
            d_calc_final = d["calcs_reversed"][0]
            d["chemsys"] = "-".join(sorted(d_calc_final["elements"]))
            comp = Composition(d_calc_final["composition_unit_cell"])
            d["formula_anonymous"] = comp.anonymized_formula
            d["formula_reduced_abc"] = comp.reduced_composition.alphabetical_formula
            for root_key in ["completed_at", "nsites", "composition_unit_cell",
                             "composition_reduced", "formula_pretty", "elements", "nelements"]:
                d[root_key] = d_calc_final[root_key]

            # store the input key based on initial calc
            # store any overrides to the exchange correlation functional
            xc = d_calc_init["input"]["incar"].get("GGA")
            if xc:
                xc = xc.upper()
            p = d_calc_init["input"]["potcar_type"][0].split("_")
            pot_type = p[0]
            functional = "lda" if len(pot_type) == 1 else "_".join(p[1:])
            d["input"] = {"structure": d_calc_init["input"]["structure"],
                          "is_hubbard": d_calc_init.pop("is_hubbard"),
                          "hubbards": d_calc_init.pop("hubbards"),
                          "is_lasph": d_calc_init["input"]["incar"].get("LASPH", False),
                          "potcar_spec": d_calc_init["input"].get("potcar_spec"),
                          "xc_override": xc,
                          "pseudo_potential": {"functional": functional.lower(),
                                               "pot_type": pot_type.lower(),
                                               "labels": d_calc_init["input"]["potcar"]},
                          "parameters": d_calc_init["input"]["parameters"],
                          "incar": d_calc_init["input"]["incar"]
                          }

            # store the output key based on final calc
            d["output"] = {
                "structure": d_calc_final["output"]["structure"],
                "density": d_calc_final.pop("density"),
                "energy": d_calc_final["output"]["energy"],
                "energy_per_atom": d_calc_final["output"]["energy_per_atom"]}

            # patch calculated magnetic moments into final structure
            if len(d_calc_final["output"]["outcar"]["magnetization"]) != 0:
                magmoms = [m["tot"] for m in d_calc_final["output"]["outcar"]["magnetization"]]
                s = Structure.from_dict(d["output"]["structure"])
                s.add_site_property('magmom', magmoms)
                d["output"]["structure"] = s.as_dict()

            calc = d["calcs_reversed"][0]

            try:
                d["output"].update({"bandgap": calc["output"]["bandgap"],
                                    "cbm": calc["output"]["cbm"],
                                    "vbm": calc["output"]["vbm"],
                                    "is_gap_direct": calc["output"]["is_gap_direct"],
                                    "is_metal": calc["output"]["is_metal"]})
            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

            sg = SpacegroupAnalyzer(Structure.from_dict(d_calc_final["output"]["structure"]), 0.1)
            if not sg.get_symmetry_dataset():
                sg = SpacegroupAnalyzer(Structure.from_dict(d_calc_final["output"]["structure"]),
                                        1e-3, 1)
            d["output"]["spacegroup"] = {
                "source": "spglib",
                "symbol": sg.get_space_group_symbol(),
                "number": sg.get_space_group_number(),
                "point_group": sg.get_point_group_symbol(),
                "crystal_system": sg.get_crystal_system(),
                "hall": sg.get_hall()}
            if d["input"]["parameters"].get("LEPSILON"):
                for k in ['epsilon_static', 'epsilon_static_wolfe', 'epsilon_ionic']:
                    d["output"][k] = d_calc_final["output"][k]
                if SymmOp.inversion() not in sg.get_symmetry_operations():
                    for k in ["piezo_ionic_tensor", "piezo_tensor"]:
                        d["output"][k] = d_calc_final["output"]["outcar"][k]

            d["state"] = "successful" if d_calc["has_vasp_completed"] else "unsuccessful"

            self.set_analysis(d)

            d["last_updated"] = datetime.datetime.today()
            return d

        except Exception:
            import traceback
            logger.error(traceback.format_exc())
            logger.error("Error in " + os.path.abspath(dir_name) + ".\n" + traceback.format_exc())
            raise
Example #18
0
 def process_outcar(self, dir_name, filename):
     """
     Process the outcar file
     """
     return Outcar(os.path.join(dir_name, filename)).as_dict()
Example #19
0
    def from_dir(cls, root_dir, relaxation_dirs=None, **kwargs):
        """
        Initializes a NEBAnalysis object from a directory of a NEB run.
        Note that OUTCARs must be present in all image directories. For the
        terminal OUTCARs from relaxation calculations, you can specify the
        locations using relaxation_dir. If these are not specified, the code
        will attempt to look for the OUTCARs in 00 and 0n directories,
        followed by subdirs "start", "end" or "initial", "final" in the
        root_dir. These are just some typical conventions used
        preferentially in Shyue Ping's MAVRL research group. For the
        non-terminal points, the CONTCAR is read to obtain structures. For
        terminal points, the POSCAR is used. The image directories are
        assumed to be the only directories that can be resolved to integers.
        E.g., "00", "01", "02", "03", "04", "05", "06". The minimum
        sub-directory structure that can be parsed is of the following form (
        a 5-image example is shown):

        00:
        - POSCAR
        - OUTCAR
        01, 02, 03, 04, 05:
        - CONTCAR
        - OUTCAR
        06:
        - POSCAR
        - OUTCAR

        Args:
            root_dir (str): Path to the root directory of the NEB calculation.
            relaxation_dirs (tuple): This specifies the starting and ending
                relaxation directories from which the OUTCARs are read for the
                terminal points for the energies.

        Returns:
            NEBAnalysis object.
        """
        neb_dirs = []

        for d in os.listdir(root_dir):
            pth = os.path.join(root_dir, d)
            if os.path.isdir(pth) and d.isdigit():
                i = int(d)
                neb_dirs.append((i, pth))
        neb_dirs = sorted(neb_dirs, key=lambda d: d[0])
        outcars = []
        structures = []

        # Setup the search sequence for the OUTCARs for the terminal
        # directories.
        terminal_dirs = []
        if relaxation_dirs is not None:
            terminal_dirs.append(relaxation_dirs)
        terminal_dirs.append((neb_dirs[0][1], neb_dirs[-1][1]))
        terminal_dirs.append(
            [os.path.join(root_dir, d) for d in ["start", "end"]])
        terminal_dirs.append(
            [os.path.join(root_dir, d) for d in ["initial", "final"]])

        for i, d in neb_dirs:
            outcar = glob.glob(os.path.join(d, "OUTCAR*"))
            contcar = glob.glob(os.path.join(d, "CONTCAR*"))
            poscar = glob.glob(os.path.join(d, "POSCAR*"))
            terminal = i == 0 or i == neb_dirs[-1][0]
            if terminal:
                for ds in terminal_dirs:
                    od = ds[0] if i == 0 else ds[1]
                    outcar = glob.glob(os.path.join(od, "OUTCAR*"))
                    if outcar:
                        outcar = sorted(outcar)
                        outcars.append(Outcar(outcar[-1]))
                        break
                else:
                    raise ValueError("OUTCAR cannot be found for terminal "
                                     "point %s" % d)
                structures.append(Poscar.from_file(poscar[0]).structure)
            else:
                outcars.append(Outcar(outcar[0]))
                structures.append(Poscar.from_file(contcar[0]).structure)
        return NEBAnalysis.from_outcars(outcars, structures, **kwargs)
Example #20
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 !!!")