Exemplo n.º 1
0
    def __init__(self, filename="COPL", to_eV=False):

        # COPL files have an extra trailing blank line
        with zopen(filename, "rt") as f:
            contents = f.read().split("\n")[:-1]
        # The parameters line is the second line in a COPL file. It
        # contains all parameters that are needed to map the file.
        parameters = contents[1].split()
        num_bonds = int(parameters[0])

        if int(parameters[1]) == 2:
            spins = [Spin.up, Spin.down]
            self.is_spin_polarized = True
        else:
            spins = [Spin.up]
            self.is_spin_polarized = False

        # The COHP data start in row num_bonds + 3
        data = np.array([np.array(row.split(), dtype=float)
                        for row in contents[num_bonds+2:]]).transpose()
        if to_eV:
            # LMTO energies have 5 sig figs
            self.energies = np.array([round_to_sigfigs(energy, 5)
                                     for energy in data[0] * Ry_to_eV],
                                     dtype=float)
            self.efermi = round_to_sigfigs(float(parameters[-1])*Ry_to_eV, 5)
        else:
            self.energies = data[0]
            self.efermi = float(parameters[-1])

        cohp_data = {}
        for bond in range(num_bonds):
            label, length, sites = self._get_bond_data(contents[2+bond])
            cohp = {spin: data[2*(bond+s*num_bonds)+1]
                    for s, spin in enumerate(spins)}
            if to_eV:
                icohp = {spin: np.array([round_to_sigfigs(i, 5) for i in
                                        data[2*(bond+s*num_bonds)+2] * Ry_to_eV])
                         for s, spin in enumerate(spins)}
            else:
                icohp = {spin: data[2*(bond+s*num_bonds)+2]
                         for s, spin in enumerate(spins)}

            # This takes care of duplicate labels
            if label in cohp_data:
                i = 1
                lab = "%s-%d" % (label, i)
                while lab in cohp_data:
                    i += 1
                    lab = "%s-%d" % (label, i)
                label = lab

            cohp_data[label] = {"COHP": cohp, "ICOHP": icohp,
                                "length": length, "sites": sites}
        self.cohp_data = cohp_data
Exemplo n.º 2
0
 def test_energies(self):
     self.assertEqual(self.copl_bise.efermi, -0.17223)
     self.assertEqual(self.copl_bise_eV.efermi, -2.3433)
     self.assertEqual(self.copl_fe.efermi, -0.085683)
     ener_eV = np.array([round_to_sigfigs(energy, 5)
                         for energy in self.copl_bise.energies * Ry_to_eV],
                        dtype=float)
     self.assertArrayEqual(ener_eV, self.copl_bise_eV.energies)
     copl_icohp = self.copl_bise.cohp_data["Bi1-Se7"]["ICOHP"][Spin.up]
     icohp = np.array([round_to_sigfigs(i, 5)
                       for i in copl_icohp * Ry_to_eV],
                      dtype=float)
     icohp_eV = self.copl_bise_eV.cohp_data["Bi1-Se7"]["ICOHP"][Spin.up]
     self.assertArrayEqual(icohp, icohp_eV)
Exemplo n.º 3
0
 def test_energies(self):
     self.assertEqual(self.copl_bise.efermi, -0.17223)
     self.assertEqual(self.copl_bise_eV.efermi, -2.3433)
     self.assertEqual(self.copl_fe.efermi, -0.085683)
     ener_eV = np.array([
         round_to_sigfigs(energy, 5)
         for energy in self.copl_bise.energies * Ry_to_eV
     ],
                        dtype=float)
     self.assertArrayEqual(ener_eV, self.copl_bise_eV.energies)
     copl_icohp = self.copl_bise.cohp_data["Bi1-Se7"]["ICOHP"][Spin.up]
     icohp = np.array(
         [round_to_sigfigs(i, 5) for i in copl_icohp * Ry_to_eV],
         dtype=float)
     icohp_eV = self.copl_bise_eV.cohp_data["Bi1-Se7"]["ICOHP"][Spin.up]
     self.assertArrayEqual(icohp, icohp_eV)
Exemplo n.º 4
0
    def test_round(self):
        vals = [
            424.2425, 2.3425356, 0.000042535636653, 0.23, 2.468e6, 0, -1.392156
        ]
        sigfigs = range(1, 6)
        rounded_vals = [[400.0, 420.0, 424.0, 424.2, 424.24],
                        [2.0, 2.3, 2.34, 2.343, 2.3425],
                        [4e-5, 4.3e-5, 4.25e-5, 4.254e-5, 4.2536e-5],
                        [0.2, 0.23, 0.23, 0.23, 0.23],
                        [2e6, 2.5e6, 2.47e6, 2.468e6, 2.468e6],
                        [0, 0, 0, 0, 0], [-1, -1.4, -1.39, -1.392, -1.3922]]

        for v, val in enumerate(vals):
            for s, sig in enumerate(sigfigs):
                self.assertEqual(round_to_sigfigs(val, sig),
                                 rounded_vals[v][s])
        with self.assertRaises(ValueError):
            round_to_sigfigs(3.5, -2)
        with self.assertRaises(TypeError):
            round_to_sigfigs(3.5, 3.5)
Exemplo n.º 5
0
    def test_round(self):
        vals = [424.2425, 2.3425356, 0.000042535636653,
                0.23, 2.468e6, 0, -1.392156]
        sigfigs = range(1, 6)
        rounded_vals = [[400.0, 420.0, 424.0, 424.2, 424.24],
                        [2.0, 2.3, 2.34, 2.343, 2.3425],
                        [4e-5, 4.3e-5, 4.25e-5, 4.254e-5, 4.2536e-5],
                        [0.2, 0.23, 0.23, 0.23, 0.23],
                        [2e6, 2.5e6, 2.47e6, 2.468e6, 2.468e6],
                        [0, 0, 0, 0, 0],
                        [-1, -1.4, -1.39, -1.392, -1.3922]]

        for v, val in enumerate(vals):
            for s, sig in enumerate(sigfigs):
                self.assertEqual(round_to_sigfigs(val, sig),
                                 rounded_vals[v][s])
        with self.assertRaises(ValueError):
            round_to_sigfigs(3.5, -2)
        with self.assertRaises(TypeError):
            round_to_sigfigs(3.5, 3.5)
Exemplo n.º 6
0
    def from_file(cls, fmt, filename=None,
                  structure_file=None, are_coops=False):
        """
        Creates a CompleteCohp object from an output file of a COHP
        calculation. Valid formats are either LMTO (for the Stuttgart
        LMTO-ASA code) or LOBSTER (for the LOBSTER code).

        Args:
            cohp_file: Name of the COHP output file. Defaults to COPL
                for LMTO and COHPCAR.lobster/COOPCAR.lobster for LOBSTER.

            are_coops: Indicates whether the populations are COOPs or
                COHPs. Defaults to False for COHPs.

            fmt: A string for the code that was used to calculate
                the COHPs so that the output file can be handled
                correctly. Can take the values "LMTO" or "LOBSTER".

            structure_file: Name of the file containing the structure.
                If no file name is given, use CTRL for LMTO and POSCAR
                for LOBSTER.

        Returns:
            A CompleteCohp object.
        """
        fmt = fmt.upper()
        if fmt == "LMTO":
            # LMTO COOPs and orbital-resolved COHP cannot be handled yet.
            are_coops = False
            orb_res_cohp = None
            if structure_file is None:
                structure_file = "CTRL"
            if filename is None:
                filename = "COPL"
            cohp_file = LMTOCopl(filename=filename, to_eV=True)
        elif fmt == "LOBSTER":
            if structure_file is None:
                structure_file = "POSCAR"
            if filename is None:
                filename = "COOPCAR.lobster" if are_coops \
                    else "COHPCAR.lobster"
            warnings.warn(
                "The bond labels are currently consistent with ICOHPLIST.lobster/ICOOPLIST.lobster, not with "
                "COHPCAR.lobster/COOPCAR.lobster. Please be aware!")
            cohp_file = Cohpcar(filename=filename, are_coops=are_coops)
            orb_res_cohp = cohp_file.orb_res_cohp
        else:
            raise ValueError("Unknown format %s. Valid formats are LMTO "
                             "and LOBSTER." % fmt)

        structure = Structure.from_file(structure_file)
        efermi = cohp_file.efermi
        cohp_data = cohp_file.cohp_data
        energies = cohp_file.energies

        # Lobster shifts the energies so that the Fermi energy is at zero.
        # Shifting should be done by the plotter object though.

        spins = [Spin.up, Spin.down] if cohp_file.is_spin_polarized \
            else [Spin.up]
        if fmt == "LOBSTER":
            energies += efermi

        if orb_res_cohp is not None:
            # If no total COHPs are present, calculate the total
            # COHPs from the single-orbital populations. Total COHPs
            # may not be present when the cohpgenerator keyword is used
            # in LOBSTER versions 2.2.0 and earlier.
            # TODO: Test this more extensively
            for label in orb_res_cohp:
                if cohp_file.cohp_data[label]["COHP"] is None:
                    # print(label)
                    cohp_data[label]["COHP"] = {
                        sp: np.sum([orb_res_cohp[label][orbs]["COHP"][sp] for orbs in orb_res_cohp[label]], axis=0)
                        for sp in spins}
                if cohp_file.cohp_data[label]["ICOHP"] is None:
                    cohp_data[label]["ICOHP"] = \
                        {sp: np.sum([orb_res_cohp[label][orbs]["ICOHP"][sp]
                                     for orbs in orb_res_cohp[label]],
                                    axis=0) for sp in spins}

        if fmt == "LMTO":
            # Calculate the average COHP for the LMTO file to be
            # consistent with LOBSTER output.
            avg_data = {"COHP": {}, "ICOHP": {}}
            for i in avg_data:
                for spin in spins:
                    rows = np.array([cohp_data[label][i][spin]
                                     for label in cohp_data])
                    avg = np.average(rows, axis=0)
                    # LMTO COHPs have 5 significant figures
                    avg_data[i].update({spin: np.array([round_to_sigfigs(a, 5)
                                        for a in avg], dtype=float)})
            avg_cohp = Cohp(efermi, energies,
                            avg_data["COHP"],
                            icohp=avg_data["ICOHP"])
        else:
            avg_cohp = Cohp(efermi, energies,
                            cohp_data["average"]["COHP"],
                            icohp=cohp_data["average"]["COHP"],
                            are_coops=are_coops)
            del cohp_data["average"]

        cohp_dict = {label: Cohp(efermi, energies,
                                 cohp_data[label]["COHP"],
                                 icohp=cohp_data[label]["ICOHP"],
                                 are_coops=are_coops)
                     for label in cohp_data}

        bond_dict = {label: {"length": cohp_data[label]["length"],
                             "sites": [structure.sites[site]
                                       for site in cohp_data[label]["sites"]]}
                     for label in cohp_data}

        return CompleteCohp(structure, avg_cohp, cohp_dict, bonds=bond_dict,
                            are_coops=are_coops, orb_res_cohp=orb_res_cohp)
Exemplo n.º 7
0
    def from_file(cls, fmt, filename=None,
                  structure_file=None, are_coops=False):
        """
        Creates a CompleteCohp object from an output file of a COHP
        calculation. Valid formats are either LMTO (for the Stuttgart
        LMTO-ASA code) or LOBSTER (for the LOBSTER code).

        Args:
            cohp_file: Name of the COHP output file. Defaults to COPL
                for LMTO and COHPCAR.lobster/COOPCAR.lobster for LOBSTER.

            are_coops: Indicates whether the populations are COOPs or
                COHPs. Defaults to False for COHPs.

            fmt: A string for the code that was used to calculate
                the COHPs so that the output file can be handled
                correctly. Can take the values "LMTO" or "LOBSTER".

            structure_file: Name of the file containing the structure.
                If no file name is given, use CTRL for LMTO and POSCAR
                for LOBSTER.

        Returns:
            A CompleteCohp object.
        """
        fmt = fmt.upper()
        if fmt == "LMTO":
            # LMTO COOPs and orbital-resolved COHP cannot be handled yet.
            are_coops = False
            orb_res_cohp = None
            if structure_file is None:
                structure_file = "CTRL"
            if filename is None:
                filename = "COPL"
            cohp_file = LMTOCopl(filename=filename, to_eV=True)
        elif fmt == "LOBSTER":
            if structure_file is None:
                structure_file = "POSCAR"
            if filename is None:
                filename = "COOPCAR.lobster" if are_coops \
                            else "COHPCAR.lobster"
            cohp_file = Cohpcar(filename=filename, are_coops=are_coops)
            orb_res_cohp = cohp_file.orb_res_cohp
        else:
            raise ValueError("Unknown format %s. Valid formats are LMTO "
                             "and LOBSTER." % fmt)

        structure = Structure.from_file(structure_file)
        efermi = cohp_file.efermi
        cohp_data = cohp_file.cohp_data
        energies = cohp_file.energies

        # Lobster shifts the energies so that the Fermi energy is at zero.
        # Shifting should be done by the plotter object though.

        spins = [Spin.up, Spin.down] if cohp_file.is_spin_polarized \
            else [Spin.up]
        if fmt == "LOBSTER":
            energies += efermi

        if orb_res_cohp is not None:
            # If no total COHPs are present, calculate the total
            # COHPs from the single-orbital populations. Total COHPs
            # may not be present when the cohpgenerator keyword is used
            # in LOBSTER versions 2.2.0 and earlier.
            for label in orb_res_cohp:
                if cohp_file.cohp_data[label]["COHP"] is None:
                    cohp_data[label]["COHP"] = \
                        {sp: np.sum([orb_res_cohp[label][orbs]["COHP"][sp]
                                     for orbs in orb_res_cohp[label]],
                                    axis=0) for sp in spins}
                if cohp_file.cohp_data[label]["ICOHP"] is None:
                    cohp_data[label]["ICOHP"] = \
                        {sp: np.sum([orb_res_cohp[label][orbs]["ICOHP"][sp]
                                     for orbs in orb_res_cohp[label]],
                                    axis=0) for sp in spins}

        if fmt == "LMTO":
            # Calculate the average COHP for the LMTO file to be
            # consistent with LOBSTER output.
            avg_data = {"COHP": {}, "ICOHP": {}}
            for i in avg_data:
                for spin in spins:
                        rows = np.array([cohp_data[label][i][spin]
                                         for label in cohp_data])
                        avg = np.average(rows, axis=0)
                        # LMTO COHPs have 5 significant figures
                        avg_data[i].update({spin:
                                            np.array([round_to_sigfigs(a, 5)
                                                      for a in avg],
                                                     dtype=float)})
            avg_cohp = Cohp(efermi, energies,
                            avg_data["COHP"],
                            icohp=avg_data["ICOHP"])
        else:
            avg_cohp = Cohp(efermi, energies,
                            cohp_data["average"]["COHP"],
                            icohp=cohp_data["average"]["COHP"],
                            are_coops=are_coops)
            del cohp_data["average"]

        cohp_dict = {label: Cohp(efermi, energies,
                                 cohp_data[label]["COHP"],
                                 icohp=cohp_data[label]["ICOHP"],
                                 are_coops=are_coops)
                     for label in cohp_data}

        bond_dict = {label: {"length": cohp_data[label]["length"],
                             "sites": [structure.sites[site]
                                       for site in cohp_data[label]["sites"]]}
                     for label in cohp_data}

        return CompleteCohp(structure, avg_cohp, cohp_dict, bonds=bond_dict,
                            are_coops=are_coops, orb_res_cohp=orb_res_cohp)