Exemplo n.º 1
0
    def assimilate(self, path):
        files = os.listdir(path)
        if "relax1" in files and "relax2" in files:
            filepath = glob.glob(os.path.join(path, "relax2",
                                              "vasprun.xml*"))[0]
        else:
            vasprun_files = glob.glob(os.path.join(path, "vasprun.xml*"))
            filepath = None
            if len(vasprun_files) == 1:
                filepath = vasprun_files[0]
            elif len(vasprun_files) > 1:
                # Since multiple files are ambiguous, we will always read
                # the one that it the last one alphabetically.
                filepath = sorted(vasprun_files)[-1]
                warnings.warn("%d vasprun.xml.* found. %s is being parsed." %
                              (len(vasprun_files), filepath))

        try:
            vasprun = Vasprun(filepath)
        except Exception as ex:
            logger.debug("error in {}: {}".format(filepath, ex))
            return None

        entry = vasprun.get_computed_entry(self._inc_structure,
                                           parameters=self._parameters,
                                           data=self._data)
        entry.parameters["history"] = _get_transformation_history(path)
        return entry
    def get_chempot_limits(self):
        """
        Returns atomic chempots from bulk_composition based on data in
        the materials project database. This is abstractly handled in the
        ChemPotAnalyzer

        Note to user: If personal phase diagram desired,
            option exists in the pycdt.core.chemical_potentials to setup,
            run and parse personal phase diagrams for purposes of chemical potentials
        """
        logger = logging.getLogger(__name__)

        if self._mpid:
            cpa = MPChemPotAnalyzer( mpid = self._mpid, sub_species = self._substitution_species,
                                   mapi_key = self._mapi_key)
        else:
            bulkvr = Vasprun(os.path.join( self._root_fldr, "bulk", "vasprun.xml"), parse_potcar_file=False)
            if not bulkvr:
                msg = "Could not fetch computed entry for atomic chempots!"
                logger.warning(msg)
                raise ValueError(msg)
            cpa = MPChemPotAnalyzer( bulk_ce=bulkvr.get_computed_entry(),
                                   sub_species = self._substitution_species,
                                   mapi_key = self._mapi_key)

        chem_lims = cpa.analyze_GGA_chempots()

        return chem_lims
Exemplo n.º 3
0
    def assimilate(self, path):
        files = os.listdir(path)
        if "relax1" in files and "relax2" in files:
            filepath = glob.glob(os.path.join(path, "relax2",
                                              "vasprun.xml*"))[0]
        else:
            vasprun_files = glob.glob(os.path.join(path, "vasprun.xml*"))
            filepath = None
            if len(vasprun_files) == 1:
                filepath = vasprun_files[0]
            elif len(vasprun_files) > 1:
                # Since multiple files are ambiguous, we will always read
                # the one that it the last one alphabetically.
                filepath = sorted(vasprun_files)[-1]
                warnings.warn("%d vasprun.xml.* found. %s is being parsed." %
                              (len(vasprun_files), filepath))

        try:
            vasprun = Vasprun(filepath)
        except Exception as ex:
            logger.debug("error in {}: {}".format(filepath, ex))
            return None

        entry = vasprun.get_computed_entry(self._inc_structure,
                                           parameters=self._parameters,
                                           data=self._data)

        # entry.parameters["history"] = _get_transformation_history(path)
        return entry
Exemplo n.º 4
0
    def assimilate(self, path):
        """
        Assimilate data in a directory path into a ComputedEntry object.

        Args:
            path: directory path

        Returns:
            ComputedEntry
        """
        files = os.listdir(path)
        if "relax1" in files and "relax2" in files:
            filepath = glob.glob(os.path.join(path, "relax2", "vasprun.xml*"))[0]
        else:
            vasprun_files = glob.glob(os.path.join(path, "vasprun.xml*"))
            filepath = None
            if len(vasprun_files) == 1:
                filepath = vasprun_files[0]
            elif len(vasprun_files) > 1:
                # Since multiple files are ambiguous, we will always read
                # the one that it the last one alphabetically.
                filepath = sorted(vasprun_files)[-1]
                warnings.warn(f"{len(vasprun_files)} vasprun.xml.* found. {filepath} is being parsed.")

        try:
            vasprun = Vasprun(filepath)
        except Exception as ex:
            logger.debug(f"error in {filepath}: {ex}")
            return None

        entry = vasprun.get_computed_entry(self._inc_structure, parameters=self._parameters, data=self._data)

        # entry.parameters["history"] = _get_transformation_history(path)
        return entry
Exemplo n.º 5
0
    def assimilate(self, path):
        files = os.listdir(path)
        if "relax1" in files and "relax2" in files:
            filepath = glob.glob(os.path.join(path, "relax2",
                                              "vasprun.xml*"))[0]
        else:
            vasprun_files = glob.glob(os.path.join(path, "vasprun.xml*"))
            filepath = None
            if len(vasprun_files) == 1:
                filepath = vasprun_files[0]
            elif len(vasprun_files) > 1:
                """
                This is a bit confusing, since there maybe be multi-steps. By
                default, assimilate will try to find a file simply named
                vasprun.xml, vasprun.xml.bz2, or vasprun.xml.gz.  Failing which
                it will try to get a relax2 from an aflow style run if
                possible. Or else, a randomly chosen file containing
                vasprun.xml is chosen.
                """
                for fname in vasprun_files:
                    if os.path.basename(fname) in ["vasprun.xml",
                                                   "vasprun.xml.gz",
                                                   "vasprun.xml.bz2"]:
                        filepath = fname
                        break
                    if re.search("relax2", fname):
                        filepath = fname
                        break
                    filepath = fname

        try:
            vasprun = Vasprun(filepath)
        except Exception as ex:
            logger.debug("error in {}: {}".format(filepath, ex))
            return None

        entry = vasprun.get_computed_entry(self._inc_structure,
                                           parameters=self._parameters,
                                           data=self._data)
        entry.parameters["history"] = _get_transformation_history(path)
        return entry
Exemplo n.º 6
0
    def assimilate(self, path):
        files = os.listdir(path)
        if "relax1" in files and "relax2" in files:
            filepath = glob.glob(os.path.join(path, "relax2",
                                              "vasprun.xml*"))[0]
        else:
            vasprun_files = glob.glob(os.path.join(path, "vasprun.xml*"))
            filepath = None
            if len(vasprun_files) == 1:
                filepath = vasprun_files[0]
            elif len(vasprun_files) > 1:
                """
                This is a bit confusing, since there maybe be multi-steps. By
                default, assimilate will try to find a file simply named
                vasprun.xml, vasprun.xml.bz2, or vasprun.xml.gz.  Failing which
                it will try to get a relax2 from an aflow style run if
                possible. Or else, a randomly chosen file containing
                vasprun.xml is chosen.
                """
                for fname in vasprun_files:
                    if os.path.basename(fname) in ["vasprun.xml",
                                                   "vasprun.xml.gz",
                                                   "vasprun.xml.bz2"]:
                        filepath = fname
                        break
                    if re.search(r"relax2", fname):
                        filepath = fname
                        break
                    filepath = fname

        try:
            vasprun = Vasprun(filepath)
        except Exception as ex:
            logger.debug("error in {}: {}".format(filepath, ex))
            return None

        entry = vasprun.get_computed_entry(self._inc_structure,
                                           parameters=self._parameters,
                                           data=self._data)
        entry.parameters["history"] = _get_transformation_history(path)
        return entry
Exemplo n.º 7
0
    def test_properties(self):

        filepath = os.path.join(test_dir, 'vasprun.xml.nonlm')
        vasprun = Vasprun(filepath, parse_potcar_file=False)
        orbs = list(vasprun.complete_dos.pdos[vasprun.final_structure[
            0]].keys())
        self.assertIn(OrbitalType.s, orbs)
        filepath = os.path.join(test_dir, 'vasprun.xml')
        vasprun = Vasprun(filepath, parse_potcar_file=False)

        #Test NELM parsing.
        self.assertEqual(vasprun.parameters["NELM"], 60)
        #test pdos parsing

        pdos0 = vasprun.complete_dos.pdos[vasprun.final_structure[0]]
        self.assertAlmostEqual(pdos0[Orbital.s][Spin.up][16], 0.0026)
        self.assertAlmostEqual(pdos0[Orbital.pz][Spin.down][16], 0.0012)
        self.assertEqual(pdos0[Orbital.s][Spin.up].shape, (301, ))


        filepath2 = os.path.join(test_dir, 'lifepo4.xml')
        vasprun_ggau = Vasprun(filepath2, parse_projected_eigen=True,
                               parse_potcar_file=False)
        totalscsteps = sum([len(i['electronic_steps'])
                            for i in vasprun.ionic_steps])
        self.assertEqual(29, len(vasprun.ionic_steps))
        self.assertEqual(len(vasprun.structures), len(vasprun.ionic_steps))
        self.assertEqual(vasprun.lattice,
                         vasprun.lattice_rec.reciprocal_lattice)

        for i, step in enumerate(vasprun.ionic_steps):
            self.assertEqual(vasprun.structures[i], step["structure"])

        self.assertTrue(all([vasprun.structures[i] == vasprun.ionic_steps[i][
            "structure"] for i in range(len(vasprun.ionic_steps))]))

        self.assertEqual(308, totalscsteps,
                         "Incorrect number of energies read from vasprun.xml")

        self.assertEqual(['Li'] + 4 * ['Fe'] + 4 * ['P'] + 16 * ["O"],
                         vasprun.atomic_symbols)
        self.assertEqual(vasprun.final_structure.composition.reduced_formula,
                         "LiFe4(PO4)4")
        self.assertIsNotNone(vasprun.incar, "Incar cannot be read")
        self.assertIsNotNone(vasprun.kpoints, "Kpoints cannot be read")
        self.assertIsNotNone(vasprun.eigenvalues, "Eigenvalues cannot be read")
        self.assertAlmostEqual(vasprun.final_energy, -269.38319884, 7)
        self.assertAlmostEqual(vasprun.tdos.get_gap(), 2.0589, 4)
        expectedans = (2.539, 4.0906, 1.5516, False)
        (gap, cbm, vbm, direct) = vasprun.eigenvalue_band_properties
        self.assertAlmostEqual(gap, expectedans[0])
        self.assertAlmostEqual(cbm, expectedans[1])
        self.assertAlmostEqual(vbm, expectedans[2])
        self.assertEqual(direct, expectedans[3])
        self.assertFalse(vasprun.is_hubbard)
        self.assertEqual(vasprun.potcar_symbols,
                         ['PAW_PBE Li 17Jan2003', 'PAW_PBE Fe 06Sep2000',
                          'PAW_PBE Fe 06Sep2000', 'PAW_PBE P 17Jan2003',
                          'PAW_PBE O 08Apr2002'])
        self.assertIsNotNone(vasprun.kpoints, "Kpoints cannot be read")
        self.assertIsNotNone(vasprun.actual_kpoints,
                             "Actual kpoints cannot be read")
        self.assertIsNotNone(vasprun.actual_kpoints_weights,
                             "Actual kpoints weights cannot be read")
        for atomdoses in vasprun.pdos:
            for orbitaldos in atomdoses:
                self.assertIsNotNone(orbitaldos, "Partial Dos cannot be read")

        # test skipping ionic steps.
        vasprun_skip = Vasprun(filepath, 3, parse_potcar_file=False)
        self.assertEqual(vasprun_skip.nionic_steps, 29)
        self.assertEqual(len(vasprun_skip.ionic_steps),
                         int(vasprun.nionic_steps / 3) + 1)
        self.assertEqual(len(vasprun_skip.ionic_steps),
                         len(vasprun_skip.structures))
        self.assertEqual(len(vasprun_skip.ionic_steps),
                         int(vasprun.nionic_steps / 3) + 1)
        # Check that nionic_steps is preserved no matter what.
        self.assertEqual(vasprun_skip.nionic_steps,
                         vasprun.nionic_steps)

        self.assertNotAlmostEqual(vasprun_skip.final_energy,
                                  vasprun.final_energy)

        # Test with ionic_step_offset
        vasprun_offset = Vasprun(filepath, 3, 6, parse_potcar_file=False)
        self.assertEqual(len(vasprun_offset.ionic_steps),
                         int(len(vasprun.ionic_steps) / 3) - 1)
        self.assertEqual(vasprun_offset.structures[0],
                         vasprun_skip.structures[2])

        self.assertTrue(vasprun_ggau.is_hubbard)
        self.assertEqual(vasprun_ggau.hubbards["Fe"], 4.3)
        self.assertAlmostEqual(vasprun_ggau.projected_eigenvalues[(Spin.up, 0,
                                                                   0, 96,
                                                                   Orbital.s)],
                               0.0032)
        d = vasprun_ggau.as_dict()
        self.assertEqual(d["elements"], ["Fe", "Li", "O", "P"])
        self.assertEqual(d["nelements"], 4)

        filepath = os.path.join(test_dir, 'vasprun.xml.unconverged')
        with warnings.catch_warnings(record=True) as w:
            # Cause all warnings to always be triggered.
            warnings.simplefilter("always")
            # Trigger a warning.
            vasprun_unconverged = Vasprun(filepath, parse_potcar_file=False)
            # Verify some things
            self.assertEqual(len(w), 1)
            self.assertTrue(issubclass(w[-1].category,
                                       UnconvergedVASPWarning))

            self.assertTrue(vasprun_unconverged.converged_ionic)
            self.assertFalse(vasprun_unconverged.converged_electronic)
            self.assertFalse(vasprun_unconverged.converged)

        filepath = os.path.join(test_dir, 'vasprun.xml.dfpt')
        vasprun_dfpt = Vasprun(filepath, parse_potcar_file=False)
        self.assertAlmostEqual(vasprun_dfpt.epsilon_static[0][0], 3.26105533)
        self.assertAlmostEqual(vasprun_dfpt.epsilon_static[0][1], -0.00459066)
        self.assertAlmostEqual(vasprun_dfpt.epsilon_static[2][2], 3.24330517)
        self.assertAlmostEqual(vasprun_dfpt.epsilon_static_wolfe[0][0], 3.33402531)
        self.assertAlmostEqual(vasprun_dfpt.epsilon_static_wolfe[0][1], -0.00559998)
        self.assertAlmostEqual(vasprun_dfpt.epsilon_static_wolfe[2][2], 3.31237357)
        self.assertTrue(vasprun_dfpt.converged)

        entry = vasprun_dfpt.get_computed_entry()
        entry = MaterialsProjectCompatibility(check_potcar_hash=False).process_entry(entry)
        self.assertAlmostEqual(entry.uncorrected_energy + entry.correction,
                               entry.energy)


        filepath = os.path.join(test_dir, 'vasprun.xml.dfpt.ionic')
        vasprun_dfpt_ionic = Vasprun(filepath, parse_potcar_file=False)
        self.assertAlmostEqual(vasprun_dfpt_ionic.epsilon_ionic[0][0], 515.73485838)
        self.assertAlmostEqual(vasprun_dfpt_ionic.epsilon_ionic[0][1], -0.00263523)
        self.assertAlmostEqual(vasprun_dfpt_ionic.epsilon_ionic[2][2], 19.02110169)


        filepath = os.path.join(test_dir, 'vasprun.xml.dfpt.unconverged')
        vasprun_dfpt_unconv = Vasprun(filepath, parse_potcar_file=False)
        self.assertFalse(vasprun_dfpt_unconv.converged_electronic)
        self.assertTrue(vasprun_dfpt_unconv.converged_ionic)
        self.assertFalse(vasprun_dfpt_unconv.converged)

        vasprun_uniform = Vasprun(os.path.join(test_dir, "vasprun.xml.uniform"),
                                  parse_potcar_file=False)
        self.assertEqual(vasprun_uniform.kpoints.style,
                         Kpoints.supported_modes.Reciprocal)


        vasprun_no_pdos = Vasprun(os.path.join(test_dir, "Li_no_projected.xml"),
                                  parse_potcar_file=False)
        self.assertIsNotNone(vasprun_no_pdos.complete_dos)
        self.assertFalse(vasprun_no_pdos.dos_has_errors)

        vasprun_diel = Vasprun(os.path.join(test_dir, "vasprun.xml.dielectric"),
                               parse_potcar_file=False)
        self.assertAlmostEqual(0.4294,vasprun_diel.dielectric[0][10])
        self.assertAlmostEqual(19.941,vasprun_diel.dielectric[1][51][0])
        self.assertAlmostEqual(19.941,vasprun_diel.dielectric[1][51][1])
        self.assertAlmostEqual(19.941,vasprun_diel.dielectric[1][51][2])
        self.assertAlmostEqual(0.0,vasprun_diel.dielectric[1][51][3])
        self.assertAlmostEqual(34.186,vasprun_diel.dielectric[2][85][0])
        self.assertAlmostEqual(34.186,vasprun_diel.dielectric[2][85][1])
        self.assertAlmostEqual(34.186,vasprun_diel.dielectric[2][85][2])
        self.assertAlmostEqual(0.0,vasprun_diel.dielectric[2][85][3])

        v = Vasprun(os.path.join(test_dir, "vasprun.xml.indirect.gz"))
        (gap, cbm, vbm, direct) = v.eigenvalue_band_properties
        self.assertFalse(direct)
Exemplo n.º 8
0
    def test_properties(self):

        filepath = os.path.join(test_dir, 'vasprun.xml.nonlm')
        vasprun = Vasprun(filepath, parse_potcar_file=False)
        orbs = list(vasprun.complete_dos.pdos[vasprun.final_structure[
            0]].keys())
        self.assertIn(OrbitalType.s, orbs)
        filepath = os.path.join(test_dir, 'vasprun.xml')
        vasprun = Vasprun(filepath, parse_potcar_file=False)

        #Test NELM parsing.
        self.assertEqual(vasprun.parameters["NELM"], 60)
        #test pdos parsing

        pdos0 = vasprun.complete_dos.pdos[vasprun.final_structure[0]]
        self.assertAlmostEqual(pdos0[Orbital.s][Spin.up][16], 0.0026)
        self.assertAlmostEqual(pdos0[Orbital.pz][Spin.down][16], 0.0012)
        self.assertEqual(pdos0[Orbital.s][Spin.up].shape, (301, ))


        filepath2 = os.path.join(test_dir, 'lifepo4.xml')
        vasprun_ggau = Vasprun(filepath2, parse_projected_eigen=True,
                               parse_potcar_file=False)
        totalscsteps = sum([len(i['electronic_steps'])
                            for i in vasprun.ionic_steps])
        self.assertEqual(29, len(vasprun.ionic_steps))
        self.assertEqual(len(vasprun.structures), len(vasprun.ionic_steps))
        self.assertEqual(vasprun.lattice,
                         vasprun.lattice_rec.reciprocal_lattice)

        for i, step in enumerate(vasprun.ionic_steps):
            self.assertEqual(vasprun.structures[i], step["structure"])

        self.assertTrue(all([vasprun.structures[i] == vasprun.ionic_steps[i][
            "structure"] for i in range(len(vasprun.ionic_steps))]))

        self.assertEqual(308, totalscsteps,
                         "Incorrect number of energies read from vasprun.xml")

        self.assertEqual(['Li'] + 4 * ['Fe'] + 4 * ['P'] + 16 * ["O"],
                         vasprun.atomic_symbols)
        self.assertEqual(vasprun.final_structure.composition.reduced_formula,
                         "LiFe4(PO4)4")
        self.assertIsNotNone(vasprun.incar, "Incar cannot be read")
        self.assertIsNotNone(vasprun.kpoints, "Kpoints cannot be read")
        self.assertIsNotNone(vasprun.eigenvalues, "Eigenvalues cannot be read")
        self.assertAlmostEqual(vasprun.final_energy, -269.38319884, 7)
        self.assertAlmostEqual(vasprun.tdos.get_gap(), 2.0589, 4)
        expectedans = (2.539, 4.0906, 1.5516, False)
        (gap, cbm, vbm, direct) = vasprun.eigenvalue_band_properties
        self.assertAlmostEqual(gap, expectedans[0])
        self.assertAlmostEqual(cbm, expectedans[1])
        self.assertAlmostEqual(vbm, expectedans[2])
        self.assertEqual(direct, expectedans[3])
        self.assertFalse(vasprun.is_hubbard)
        self.assertEqual(vasprun.potcar_symbols,
                         ['PAW_PBE Li 17Jan2003', 'PAW_PBE Fe 06Sep2000',
                          'PAW_PBE Fe 06Sep2000', 'PAW_PBE P 17Jan2003',
                          'PAW_PBE O 08Apr2002'])
        self.assertIsNotNone(vasprun.kpoints, "Kpoints cannot be read")
        self.assertIsNotNone(vasprun.actual_kpoints,
                             "Actual kpoints cannot be read")
        self.assertIsNotNone(vasprun.actual_kpoints_weights,
                             "Actual kpoints weights cannot be read")
        for atomdoses in vasprun.pdos:
            for orbitaldos in atomdoses:
                self.assertIsNotNone(orbitaldos, "Partial Dos cannot be read")

        # test skipping ionic steps.
        vasprun_skip = Vasprun(filepath, 3, parse_potcar_file=False)
        self.assertEqual(vasprun_skip.nionic_steps, 29)
        self.assertEqual(len(vasprun_skip.ionic_steps),
                         int(vasprun.nionic_steps / 3) + 1)
        self.assertEqual(len(vasprun_skip.ionic_steps),
                         len(vasprun_skip.structures))
        self.assertEqual(len(vasprun_skip.ionic_steps),
                         int(vasprun.nionic_steps / 3) + 1)
        # Check that nionic_steps is preserved no matter what.
        self.assertEqual(vasprun_skip.nionic_steps,
                         vasprun.nionic_steps)

        self.assertNotAlmostEqual(vasprun_skip.final_energy,
                                  vasprun.final_energy)

        # Test with ionic_step_offset
        vasprun_offset = Vasprun(filepath, 3, 6, parse_potcar_file=False)
        self.assertEqual(len(vasprun_offset.ionic_steps),
                         int(len(vasprun.ionic_steps) / 3) - 1)
        self.assertEqual(vasprun_offset.structures[0],
                         vasprun_skip.structures[2])

        self.assertTrue(vasprun_ggau.is_hubbard)
        self.assertEqual(vasprun_ggau.hubbards["Fe"], 4.3)
        self.assertAlmostEqual(vasprun_ggau.projected_eigenvalues[Spin.up][
                                   0][0][96][0], 0.0032)
        d = vasprun_ggau.as_dict()
        self.assertEqual(d["elements"], ["Fe", "Li", "O", "P"])
        self.assertEqual(d["nelements"], 4)

        filepath = os.path.join(test_dir, 'vasprun.xml.unconverged')
        with warnings.catch_warnings(record=True) as w:
            # Cause all warnings to always be triggered.
            warnings.simplefilter("always")
            # Trigger a warning.
            vasprun_unconverged = Vasprun(filepath, parse_potcar_file=False)
            # Verify some things
            self.assertEqual(len(w), 1)
            self.assertTrue(issubclass(w[-1].category,
                                       UnconvergedVASPWarning))

            self.assertTrue(vasprun_unconverged.converged_ionic)
            self.assertFalse(vasprun_unconverged.converged_electronic)
            self.assertFalse(vasprun_unconverged.converged)

        filepath = os.path.join(test_dir, 'vasprun.xml.dfpt')
        vasprun_dfpt = Vasprun(filepath, parse_potcar_file=False)
        self.assertAlmostEqual(vasprun_dfpt.epsilon_static[0][0], 3.26105533)
        self.assertAlmostEqual(vasprun_dfpt.epsilon_static[0][1], -0.00459066)
        self.assertAlmostEqual(vasprun_dfpt.epsilon_static[2][2], 3.24330517)
        self.assertAlmostEqual(vasprun_dfpt.epsilon_static_wolfe[0][0], 3.33402531)
        self.assertAlmostEqual(vasprun_dfpt.epsilon_static_wolfe[0][1], -0.00559998)
        self.assertAlmostEqual(vasprun_dfpt.epsilon_static_wolfe[2][2], 3.31237357)
        self.assertTrue(vasprun_dfpt.converged)

        entry = vasprun_dfpt.get_computed_entry()
        entry = MaterialsProjectCompatibility(check_potcar_hash=False).process_entry(entry)
        self.assertAlmostEqual(entry.uncorrected_energy + entry.correction,
                               entry.energy)

        filepath = os.path.join(test_dir, 'vasprun.xml.dfpt.ionic')
        vasprun_dfpt_ionic = Vasprun(filepath, parse_potcar_file=False)
        self.assertAlmostEqual(vasprun_dfpt_ionic.epsilon_ionic[0][0], 515.73485838)
        self.assertAlmostEqual(vasprun_dfpt_ionic.epsilon_ionic[0][1], -0.00263523)
        self.assertAlmostEqual(vasprun_dfpt_ionic.epsilon_ionic[2][2], 19.02110169)

        filepath = os.path.join(test_dir, 'vasprun.xml.dfpt.unconverged')
        vasprun_dfpt_unconv = Vasprun(filepath, parse_potcar_file=False)
        self.assertFalse(vasprun_dfpt_unconv.converged_electronic)
        self.assertTrue(vasprun_dfpt_unconv.converged_ionic)
        self.assertFalse(vasprun_dfpt_unconv.converged)

        vasprun_uniform = Vasprun(os.path.join(test_dir, "vasprun.xml.uniform"),
                                  parse_potcar_file=False)
        self.assertEqual(vasprun_uniform.kpoints.style,
                         Kpoints.supported_modes.Reciprocal)

        vasprun_no_pdos = Vasprun(os.path.join(test_dir, "Li_no_projected.xml"),
                                  parse_potcar_file=False)
        self.assertIsNotNone(vasprun_no_pdos.complete_dos)
        self.assertFalse(vasprun_no_pdos.dos_has_errors)

        vasprun_diel = Vasprun(os.path.join(test_dir, "vasprun.xml.dielectric"),
                               parse_potcar_file=False)
        self.assertAlmostEqual(0.4294,vasprun_diel.dielectric[0][10])
        self.assertAlmostEqual(19.941,vasprun_diel.dielectric[1][51][0])
        self.assertAlmostEqual(19.941,vasprun_diel.dielectric[1][51][1])
        self.assertAlmostEqual(19.941,vasprun_diel.dielectric[1][51][2])
        self.assertAlmostEqual(0.0,vasprun_diel.dielectric[1][51][3])
        self.assertAlmostEqual(34.186,vasprun_diel.dielectric[2][85][0])
        self.assertAlmostEqual(34.186,vasprun_diel.dielectric[2][85][1])
        self.assertAlmostEqual(34.186,vasprun_diel.dielectric[2][85][2])
        self.assertAlmostEqual(0.0,vasprun_diel.dielectric[2][85][3])

        v = Vasprun(os.path.join(test_dir, "vasprun.xml.indirect.gz"))
        (gap, cbm, vbm, direct) = v.eigenvalue_band_properties
        self.assertFalse(direct)
Exemplo n.º 9
0
    def read_phase_diagram_and_chempots(self,
                                        full_sub_approach=False,
                                        include_mp_entries=True):
        """
        Once phase diagram has been set up and run by user (in a folder 
        called "PhaseDiagram"), this method parses and prints the chemical 
        potentials based on the computed entries. The methodology is 
        basically identical to that in the analyze_GGA_chempots method.

        Will supplement unfinished entries with MP database entries 
        unless no_mp_entries is set to False

        Args:
            full_sub_approach: same attribute as described at length in 
                the analyze_GGA_chempots method. Basically, the user can 
                set this to True if they want to mix extrinsic species 
                in the phase diagram

            include_mp_entries: if set to True, extra entries from 
                Materials Project will be added to phase diagram
                according to phases that are stable in the Materials 
                Project database

        """
        pdfile = os.path.join(self.path_base, 'PhaseDiagram')
        if not os.path.exists(pdfile):
            print('Phase diagram file does not exist at ', pdfile)
            return

        # this is where we read computed entries into a list for parsing...
        # NOTE TO USER: If not running with VASP need to use another
        # pymatgen functionality for importing computed entries below...
        personal_entry_list = []
        for structfile in os.listdir(pdfile):
            if os.path.exists(os.path.join(pdfile, structfile, 'vasprun.xml')):
                try:
                    print('loading ', structfile)
                    vr = Vasprun(os.path.join(pdfile, structfile,
                                              'vasprun.xml'),
                                 parse_potcar_file=False)
                    personal_entry_list.append(vr.get_computed_entry())
                except:
                    print('Could not load ', structfile)

        #add bulk computed entry to phase diagram, and see if it is stable
        if not self.bulk_ce:
            vr_path = os.path.join(self.path_base, 'bulk', 'vasprun.xml')
            if os.path.exists(vr_path):
                print('loading bulk computed entry')
                bulkvr = Vasprun(vr_path)
                self.bulk_ce = bulkvr.get_computed_entry()
            else:
                print ('No bulk entry given locally. Phase diagram ' + \
                       'calculations cannot be set up without this')
                return

        self.bulk_composition = self.bulk_ce.composition
        self.redcomp = self.bulk_composition.reduced_composition

        # Supplement entries to phase diagram with those from MP database
        if include_mp_entries:
            mpcpa = MPChemPotAnalyzer(bulk_ce=self.bulk_ce,
                                      sub_species=self.sub_species,
                                      mapi_key=self.mapi_key)
            tempcl = mpcpa.analyze_GGA_chempots(
                full_sub_approach=full_sub_approach)  # Use MPentries

            curr_pd = PhaseDiagram(
                list(set().union(mpcpa.entries['bulk_derived'],
                                 mpcpa.entries['subs_set'])))
            stable_idlist = {
                i.composition.reduced_composition:
                [i.energy_per_atom, i.entry_id, i]
                for i in curr_pd.stable_entries
            }
            for mpcomp, mplist in stable_idlist.items():
                matched = False
                for pe in personal_entry_list:
                    if (pe.composition.reduced_composition == mpcomp):
                        # #USER: uncomment this if you want additional stable phases of identical composition included in your phase diagram
                        # if personalentry.energy_per_atom > mplist[0]:
                        #     print('Adding entry from MP-database:',mpcomp,'(entry-id:',mplist[1])
                        #     personal_entry_list.append(mplist[2])
                        matched = True
                if not matched:
                    print('Adding entry from MP-database:', mpcomp,
                          '(entry-id:', mplist[1])
                    personal_entry_list.append(mplist[2])
        else:
            personal_entry_list.append(self.bulk_ce)
            #if you dont have entries for elemental corners of phase diagram then code breaks
            #manually inserting entries with energies of zero for competeness...USER DO NOT USE THIS
            eltcount = {
                elt: 0
                for elt in set(self.bulk_ce.composition.elements)
            }
            for pentry in personal_entry_list:
                if pentry.is_element:
                    eltcount[pentry.composition.elements[0]] += 1
            for elt, eltnum in eltcount.items():
                if not eltnum:
                    s = Structure([[1., 0., 0.], [0., 1., 0.], [0., 0., 1.]],
                                  [elt], [[0, 0, 0]])
                    eltentry = ComputedStructureEntry(s, 0.)
                    print(
                        'USER! Note that you have added a fake ' + str(elt) +
                        ' structure to prevent from breaking the '
                        'Phase Diagram Analyzer.\n As a result DO NOT trust the chemical potential results for regions '
                        'of phase diagram that involve the element ' +
                        str(elt))
                    personal_entry_list.append(eltentry)

        personal_entry_list.append(self.bulk_ce)

        #compute chemical potentials
        if full_sub_approach:
            pd = PhaseDiagram(personal_entry_list)
            chem_lims = self.get_chempots_from_pd(pd)
        else:
            #first seperate out the bulk associated elements from those of substitutional elements
            entry_list = []
            sub_associated_entry_list = []
            for localentry in personal_entry_list:
                bulk_associated = True
                for elt in localentry.composition.elements:
                    if elt not in self.bulk_composition.elements:
                        bulk_associated = False

                if bulk_associated:
                    entry_list.append(localentry)
                else:
                    sub_associated_entry_list(localentry)

            #now iterate through and collect chemical potentials
            pd = PhaseDiagram(entry_list)
            chem_lims = self.get_chempots_from_pd(pd)

            finchem_lims = {}  # this will be final chem_lims dictionary
            for key in chem_lims.keys():
                face_list = key.split('-')
                blk, blknom, subnom = self.diff_bulk_sub_phases(face_list)
                finchem_lims[blknom] = {}
                finchem_lims[blknom] = chem_lims[key]

            # Now consider adding single elements to extend the phase diagram,
            # adding new additions to chemical potentials ONLY for the cases
            # where the phases in equilibria are those from the bulk phase
            # diagram. This is essentially the assumption that the majority of
            # the elements in the total composition will be from the native
            # species present rather than the sub species (a good approximation)
            for sub_el in self.sub_species:
                sub_specie_entries = entry_list[:]
                for entry in sub_associated_entry_list:
                    if sub_el in entry.composition.elements:
                        sub_specie_entries.append(entry)

                pd = PhaseDiagram(sub_specie_entries)
                chem_lims = self.get_chempots_from_pd(pd)

                for key in chem_lims.keys():
                    face_list = key.split('-')
                    blk, blknom, subnom = self.diff_bulk_sub_phases(
                        face_list, sub_el=sub_el)
                    # if one less than number of bulk species then can be
                    # grouped with rest of structures
                    if len(blk) == len(self.bulk_species_symbol):
                        if blknom not in finchem_lims.keys():
                            finchem_lims[blknom] = chem_lims[key]
                        else:
                            finchem_lims[blknom][sub_el] = \
                                chem_lims[key][sub_el]
                        if 'name-append' not in finchem_lims[blknom].keys():
                            finchem_lims[blknom]['name-append'] = subnom
                        else:
                            finchem_lims[blknom]['name-append'] += '-' + subnom
                    else:
                        # if chem pots determined by two (or more) sub-specie
                        # containing phases, skip this facet!
                        continue

            # run a check to make sure all facets dominantly defined by bulk species
            overdependent_chempot = False
            facets_to_delete = []
            for facet_name, cps in finchem_lims.items():
                cp_key_num = (len(cps.keys()) -
                              1) if 'name-append' in cps else len(cps.keys())
                bulk_species_symbol = [
                    s.symbol for s in self.bulk_composition.elements
                ]
                if cp_key_num != (len(bulk_species_symbol) +
                                  len(self.sub_species)):
                    facets_to_delete.append(facet_name)
                    print(
                        "Not using facet {} because insufficient number of bulk facets for "
                        "bulk set {} with sub_species set {}. (only dependent on {})."
                        "".format(facet_name, self.bulk_species_symbol,
                                  self.sub_species, cps.get('name-append')))
            if len(facets_to_delete) == len(finchem_lims):
                overdependent_chempot = True
                print(
                    "Determined chemical potentials to be over dependent"
                    " on a substitutional specie. Needing to revert to full_sub_approach. If "
                    "multiple sub species exist this could take a while/break the code..."
                )
            else:
                finchem_lims = {
                    k: v
                    for k, v in finchem_lims.items()
                    if k not in facets_to_delete
                }

            if not overdependent_chempot:
                chem_lims = {}
                for orig_facet, fc_cp_dict in finchem_lims.items():
                    if 'name-append' not in fc_cp_dict:
                        facet_nom = orig_facet
                    else:
                        full_facet_list = orig_facet.split('-')
                        full_facet_list.extend(
                            fc_cp_dict['name-append'].split('-'))
                        full_facet_list.sort()
                        facet_nom = '-'.join(full_facet_list)
                    chem_lims[facet_nom] = {
                        k: v
                        for k, v in fc_cp_dict.items() if k != 'name-append'
                    }
            else:
                # This is for when overdetermined chempots occur, forcing the full_sub_approach to happen
                for sub, subentries in self.entries['subs_set'].items():
                    for subentry in subentries:
                        entry_list.append(subentry)
                pd = PhaseDiagram(entry_list)
                chem_lims = self.get_chempots_from_pd(pd)

        return chem_lims
Exemplo n.º 10
0
class VasprunAnalysis():
    """
    can perform all custermized analysis of a single vasprun.xml file

    Includes:
        phase diagram analysis, energy above hull, formation energy.....

        Band gap....

        will add more functionality in the future
    """
    def __init__(self, vasprun_file, cal_pd=False):
        self.vasprun = Vasprun(vasprun_file)
        if cal_pd:
            self.pd, self.entry = self.get_pd()

    def get_pd(self):
        """
        get the phase diagram object for this compound

        Returns:
            phase diagram, entry
        """
        #make MP compatible entry from vasprun
        entry = self.vasprun.get_computed_entry()
        compat = MaterialsProjectCompatibility()
        entry = compat.process_entry(entry)

        el = [specie.symbol for specie in entry.composition.keys()]
        with MPRester(api_key=API_KEY) as mpr:
            entries = mpr.get_entries_in_chemsys(el)
        entries.append(entry)
        pd = PhaseDiagram(entries)
        return pd, entry

    def get_e_above_hull(self):
        """ 
        Get e_above_hull for this compound

        Args: 
            allow_negative: whether to calculate negative energy above hull for stable compound

        Returns:
            decomposition, energy above hull
        """
        pda = PDAnalyzer(self.pd)
        (decomp, hull) = pda.get_decomp_and_e_above_hull(self.entry)
        decomp = [compound.composition.reduced_formula for compound in decomp]
        return (decomp, hull)

    def get_formation_energy(self):
        """
        get formation energy per atom for this compound

        Returns: 
            formation energy per atom
        """
        return self.pd.get_form_energy_per_atom(self.entry)

    def get_equilibrium_reaction_energy(self):
        """
        Adapted from pymatgen. Only work if entry is stable(hull = 0)

        Provides the reaction energy of a stable entry from the neighboring
        equilibrium stable entries (also known as the inverse distance to
        hull).

        Returns:
            Equilibrium reaction energy of entry. Stable entries should have
            equilibrium reaction energy <= 0.
        """
        if self.entry not in self.pd.stable_entries:
            raise ValueError("Equilibrium reaction energy is available only "
                             "for stable entries.")
        entries = [e for e in self.pd.stable_entries if e != self.entry
                   ]  #all stable entries without this stable entry
        modpd = PhaseDiagram(entries, self.pd.elements)
        analyzer = PDAnalyzer(modpd)
        (decomp,
         hull) = analyzer.get_decomp_and_e_above_hull(self.entry,
                                                      allow_negative=True)
        decomp = [compound.composition.reduced_formula for compound in decomp]
        return (decomp, hull)

    def get_eg(self):
        """
        return the band gap(by me), band gap(by pymatgen) and direct band gap

        two ways of calculating band gap to test the correctness of pymatgen algorithm

        Returns:
            eg1: band gap calculated by me
            eg2: band gap calculated by pymatgen algorithm
            eg_direct: direct band gap
        """
        eg1 = self.vasprun.eigenvalue_band_properties[0]
        efermi = self.vasprun.efermi
        vbm = self.vasprun.eigenvalue_band_properties[2]

        eig = [self.vasprun.eigenvalues[i] for i in self.vasprun.eigenvalues]
        occu = [i.tolist() for i in eig]
        occu_flat = [
            i[1] for sublist in occu for subsublist in sublist
            for i in subsublist
        ]
        occu_set = set(occu_flat)

        if efermi < vbm:
            eg1 = 0
        elif len(occu_set) > 2:
            eg1 = 0

        bs = self.vasprun.get_band_structure()
        eg2 = bs.get_band_gap()['energy']
        eg_direct = bs.get_direct_band_gap()

        print('eg1 = {}, eg2 = {}, eg_direct = {}'.format(eg1, eg2, eg_direct))
        print('check if eg1 = eg2, it should')
        print('transition: {}'.format(bs.get_band_gap()['transition']))

        return eg1, eg2, eg_direct
Exemplo n.º 11
0
#for same composition
from pymatgen.io.vasp.outputs import Vasprun
from pymatgen.entries.computed_entries import ComputedEntry

import os

entries = []
rootdir = os.getcwd()
directory_contents = os.listdir(rootdir)
for dir in directory_contents:
    if os.path.isdir(dir):
        os.chdir(dir)
        if os.path.isfile("vasprun.xml"):
            print("File exist")
            vrun = Vasprun("vasprun.xml")
            entry_temp = vrun.get_computed_entry()
            entry_temp.entry_id = dir
            entries.append(entry_temp)
        os.chdir("../")

entries_sorted = sorted(entries,
                        key=lambda entry: entry.energy_per_atom)  # sort by age

from pymatgen.io.vasp.outputs import Vasprun
from pymatgen.entries.compatibility import MaterialsProjectCompatibility
import os
import glob
from os import path
import copy
import json
all = []
Exemplo n.º 12
0
    def assimilate(self, path):
        files = os.listdir(path)
        ciffilepath = None
        if any("relax1" in s for s in files) and any("relax2" in s for s in files):
            filepath = glob.glob(os.path.join(path,
                                              "vasprun.xml.relax2*"))[0]
            try:
                incarfilepath = glob.glob(os.path.join(path,'INCAR.relax1*'))[0]
            except:
                print path

            #Get cif from directory
            # if glob.glob(os.path.join(path,'*cif')):
            #     ciffilepath = glob.glob(os.path.join(path,'*cif'))[0]

            contcarfile = glob.glob(os.path.join(path,"CONTCAR.relax2*"))[0]

        else:
            vasprun_files = glob.glob(os.path.join(path, "vasprun.xml*"))
            try:
                incarfilepath = glob.glob(os.path.join(path,"INCAR*"))[0]
            except:
                print path

            #Get cif from directory
            # if glob.glob(os.path.join(path,'*cif')):
            #     ciffilepath = glob.glob(os.path.join(path,'*cif'))[0]

            contcarfile = glob.glob(os.path.join(path,"CONTCAR*"))[0]

            filepath = None
            if len(vasprun_files) == 1:
                filepath = vasprun_files[0]
                logging.debug(filepath)
            elif len(vasprun_files) > 1:
                """
                This is a bit confusing, since there maybe be multi-steps. By
                default, assimilate will try to find a file simply named
                vasprun.xml, vasprun.xml.bz2, or vasprun.xml.gz.  Failing which
                it will try to get a relax2 from an aflow style run if
                possible. Or else, a randomly chosen file containing
                vasprun.xml is chosen.
                """
                for fname in vasprun_files:
                    if os.path.basename(fname) in ["vasprun.xml",
                                                   "vasprun.xml.gz",
                                                   "vasprun.xml.bz2"]:
                        filepath = fname
                        break
                    if re.search("relax2", fname):
                        filepath = fname
                        break
                    filepath = fname

        try:
            vasprun = Vasprun(filepath)
        except Exception as ex:
            logger.debug("error in {}: {}".format(filepath, ex))
            return None

        logging.debug('Done entry if')

        entry = vasprun.get_computed_entry(self._inc_structure,
                                           parameters=self._parameters,
                                           data=self._data)
        logging.debug(entry)
        entry.parameters["history"] = _get_transformation_history(path)

        incar = Incar.from_file(incarfilepath)
        try:
            entry.data['NUPDOWN'] = incar['NUPDOWN']
            entry.data['ISMEAR'] = incar['ISMEAR']
        except:
            pass
        logging.debug('Return Entry step')
        entry.data['CONTCAR_Structure'] = Structure.from_file(contcarfile,primitive=False)

        # if ciffilepath:
        #     entry.data['Cif_Structure'] = Structure.from_file(ciffilepath,primitive=False)
        return entry