Example #1
0
def cli(input_file: Path, output_directory: Path, verbose: bool) -> None:
    '''
    Converts the VASP WAVECAR to UNK files for wannier90.

    Args:
        input_file (Path): path to WAVECAR file (default='./WAVECAR')
        output_directory (Path): directory where UNKs ar ewritten (default = .)
        verbose (bool): verbose output (default = False)
    '''
    Wavecar(input_file, verbose=verbose).write_unks(output_directory)
Example #2
0
def read_WAVECAR(file='WAVECAR', ks=0, bs=1, s=0, output='wf'):
    # The list of coefficients for each k-point and band for reconstructing the wavefunction. 
    # For non-spin-polarized, the first index corresponds to the kpoint and the second corresponds to the band 
    # (e.g. self.coeffs[kp][b] corresponds to k-point kp and band b). 
    # For spin-polarized calculations, the first index is for the spin.
    wavecar = Wavecar(file)
    for k in ks:
        for b in bs:
            #wf = wavecar.fft_mesh(kpoint=k, band=b-1)
            coeffs = np.array(wavecar.coeffs)
            if coeffs.ndim == 3:
                wf = coeffs[s][k][b]
            else:
                wf = coeffs[k][b]
            print('wf.shape', wf.shape)
            print('wavecar.kpoints', wavecar.kpoints)
            np.save('{}_k{}b{}.npy'.format(output, k, b), wf)
Example #3
0
def get_Wif_from_wavecars(
        wavecars: List,
        init_wavecar_path: str,
        def_index: int,
        bulk_index: Sequence[int],
        spin: int = 0,
        kpoint: int = 1,
        fig=None
) -> List:
    """Compute the electron-phonon matrix element using the WAVECARs.

    This function reads in the pseudo-wavefunctions from the WAVECAR files and
    computes the overlaps necessary.

    *** WARNING: USE AT YOUR OWN RISK ***
    Because these are pseudo-wavefunctions, the core information from the PAWs
    is missing. As a result, the resulting Wif value may be unreliable. A good
    test of this is how close the Q=0 overlap is to 0. (it would be exactly 0.
    if you include the corrections from the PAWs). This should only be used
    to get a preliminary idea of the Wif value.
    ***************

    Parameters
    ----------
    wavecars : list((Q, wavecar_path))
        a list of tuples where the first value is the Q and the second is the
        path to the WAVECAR file
    init_wavecar_path : string
        path to the initial wavecar for computing overlaps
    def_index : int
        index corresponding to the defect wavefunction (1-based indexing)
    bulk_index : int, list(int)
        index or list of indices corresponding to the bulk wavefunction
        (1-based indexing)
    spin : int
        spin channel to read from (0 - up, 1 - down)
    kpoint : int
        kpoint to read from (defaults to the first kpoint)
    fig : matplotlib.figure.Figure
        optional figure object to plot diagnostic information

    Returns
    -------
    list((bulk_index, Wif))
        electron-phonon matrix element Wif in units of
        eV amu^{-1/2} Angstrom^{-1} for each bulk_index
    """
    bulk_index = np.array(bulk_index)
    initial_wavecar = Wavecar(init_wavecar_path)
    if initial_wavecar.spin == 2:
        psi_i = initial_wavecar.coeffs[spin][kpoint-1][def_index-1]
    else:
        psi_i = initial_wavecar.coeffs[kpoint-1][def_index-1]

    Nw, Nbi = (len(wavecars), len(bulk_index))
    Q, matels, deig = (np.zeros(Nw+1), np.zeros((Nbi, Nw+1)), np.zeros(Nbi))

    # first compute the Q = 0 values and eigenvalue differences
    for i, bi in enumerate(bulk_index):
        if initial_wavecar.spin == 2:
            psi_f = initial_wavecar.coeffs[spin][kpoint-1][bi-1]
            deig[i] = initial_wavecar.band_energy[spin][kpoint-1][bi-1][0] - \
                initial_wavecar.band_energy[spin][kpoint-1][def_index-1][0]
        else:
            psi_f = initial_wavecar.coeffs[kpoint-1][bi-1]
            deig[i] = initial_wavecar.band_energy[kpoint-1][bi-1][0] - \
                initial_wavecar.band_energy[kpoint-1][def_index-1][0]
        matels[i, Nw] = _compute_matel(psi_i, psi_f)
    deig = np.abs(deig)

    # now compute for each Q
    for i, (q, fname) in enumerate(wavecars):
        Q[i] = q
        final_wavecar = Wavecar(fname)
        for j, bi in enumerate(bulk_index):
            if final_wavecar.spin == 2:
                psi_f = final_wavecar.coeffs[spin][kpoint-1][bi-1]
            else:
                psi_f = final_wavecar.coeffs[kpoint-1][bi-1]
            matels[j, i] = _compute_matel(psi_i, psi_f)

    if fig is not None:
        ax = fig.subplots(1, Nbi)
        ax = np.array(ax)
        for a, i in zip(ax, range(Nbi)):
            a.scatter(Q, matels[i, :])
            a.set_title(f'{bulk_index[i]}')

    return [(bi, deig[i] * np.mean(np.abs(np.gradient(matels[i, :], Q))))
            for i, bi in enumerate(bulk_index)]
Example #4
0
from pymatgen.symmetry.analyzer import SpacegroupAnalyzer
from matplotlib import pyplot as plt
from pymatgen.ext.matproj import MPRester
from pymatgen.io.vasp.inputs import Poscar

from pymatgen.io.cif import CifWriter
from pymatgen.cli.pmg_plot import get_chgint_plot
from pymatgen.io.vasp.outputs import Chgcar,Wavecar,VolumetricData,Procar,Elfcar
import os

from pymatgen.util.plotting import pretty_plot

dire = r'D:\Desktop\合作计算数据\数据\FeS101-O2'
os.chdir(dire)
print (os.getcwd())
wavecar = Wavecar(filename ='WAVECAR')
poscar = Poscar.from_file("POSCAR")
chgcar = wavecar.get_parchg(poscar,0,1)
# procar = Procar('PROCAR')
# data = procar.data
struct = poscar.structure
s = chgcar.structure
finder = SpacegroupAnalyzer(s, symprec=0.1)
sites = [sites[0] for sites in finder.get_symmetrized_structure().equivalent_sites]
atom_ind = [s.sites.index(site) for site in sites]  
for i in atom_ind:
    d = chgcar.get_integrated_diff(i, 1, 30)
    plt.plot(d[:, 0], d[:, 1],
                 label="Atom {} - {}".format(i, s[i].species_string))
plt.legend(loc="upper left")
plt.xlabel("Radius (A)")
Example #5
0
    def overlap_so_spinpol(self):
        """
        Main function to calculate SOC spillage
        """
        noso = Wavecar(self.wf_noso)
        so = Wavecar(self.wf_so)

        bcell = np.linalg.inv(noso.a).T
        tmp = np.linalg.norm(np.dot(np.diff(noso.kpoints, axis=0), bcell),
                             axis=1)
        noso_k = np.concatenate(([0], np.cumsum(tmp)))
        noso_bands = np.array(noso.band_energy)[:, :, :, 0]
        noso_kvecs = np.array(noso.kpoints)
        noso_occs = np.array(noso.band_energy)[:, :, :, 2]
        noso_nkpts = len(noso_k)

        bcell = np.linalg.inv(so.a).T
        tmp = np.linalg.norm(np.dot(np.diff(so.kpoints, axis=0), bcell),
                             axis=1)
        so_k = np.concatenate(([0], np.cumsum(tmp)))
        so_bands = np.array([np.array(so.band_energy)[:, :, 0]])
        so_kvecs = np.array(so.kpoints)
        # so_occs = np.array([np.array(so.band_energy)[:, :, 2]])
        so_nkpts = len(so_k)

        nelec_list = []
        for nk1 in range(1, noso_nkpts + 1):  # no spin orbit kpoints loop
            knoso = noso_kvecs[nk1 - 1, :]
            for nk2 in range(1, so_nkpts + 1):  # spin orbit
                kso = so_kvecs[nk2 - 1, :]
                if (self.isclose(kso[0], knoso[0])
                        and self.isclose(kso[1], knoso[1]) and self.isclose(
                            kso[2], knoso[2])):  # do kpoints match?
                    for c, e in enumerate(noso_occs[0, nk1 - 1, :]):
                        if e < 0.5:
                            cup = c
                            break
                    for c, e in enumerate(noso_occs[1, nk1 - 1, :]):
                        if e < 0.5:
                            cdn = c
                            break

                    nelec_list.append([cup, cdn, cup + cdn])
        n_arr = np.array(nelec_list)

        n_up = int(round(np.mean(n_arr[:, 0])))
        n_dn = int(round(np.mean(n_arr[:, 1])))
        n_tot = int(round(np.mean(n_arr[:, 2])))

        nelec = int(n_tot)

        # noso_homo_up = np.max(noso_bands[0, :, n_up - 1])
        # noso_lumo_up = np.min(noso_bands[0, :, n_up])

        # noso_homo_dn = np.max(noso_bands[1, :, n_dn - 1])
        # noso_lumo_dn = np.min(noso_bands[1, :, n_dn])

        so_homo = np.max(so_bands[0, :, nelec - 1])
        so_lumo = np.min(so_bands[0, :, nelec])

        # noso_direct_up = np.min(noso_bands[0, :, n_up] - noso_bands[0, :, n_up - 1])
        # noso_direct_dn = np.min(noso_bands[1, :, n_dn] - noso_bands[1, :, n_dn - 1])

        so_direct = np.min(so_bands[0, :, nelec] - so_bands[0, :, nelec - 1])

        noso_direct = 1000000.0
        noso_homo = -10000000.0
        noso_lumo = 100000000.0
        for i in range(noso_bands.shape[1]):
            homo_k = max(noso_bands[0, i, n_up - 1], noso_bands[1, i,
                                                                n_dn - 1])
            lumo_k = min(noso_bands[0, i, n_up], noso_bands[1, i, n_dn])
            noso_direct = min(noso_direct, lumo_k - homo_k)

            noso_homo = max(noso_homo, homo_k)
            noso_lumo = min(noso_lumo, lumo_k)

        gamma_k = []
        kpoints = []
        np.set_printoptions(precision=4)

        x = []
        y = []

        nelec_tot = 0.0
        for nk1 in range(1, noso_nkpts + 1):  # no spin orbit kpoints loop
            knoso = noso_kvecs[nk1 - 1, :]
            for nk2 in range(1, so_nkpts + 1):  # spin orbit
                kso = so_kvecs[nk2 - 1, :]
                if (self.isclose(kso[0], knoso[0])
                        and self.isclose(kso[1], knoso[1]) and self.isclose(
                            kso[2], knoso[2])):  # do kpoints match?

                    # changes section 2
                    nelec_up = n_arr[nk1 - 1, 0]
                    nelec_dn = n_arr[nk1 - 1, 1]
                    nelec_tot = n_arr[nk1 - 1, 2]

                    kpoints.append(kso)
                    Mmn = 0.0
                    vnoso = np.array(
                        noso.coeffs[0][nk1 - 1][0]
                    )  # noso.readBandCoeff(ispin=1, ikpt=nk1, iband=1, norm=False)
                    n_noso1 = vnoso.shape[0]
                    vnoso = np.array(
                        noso.coeffs[1][nk1 - 1][0]
                    )  # noso.readBandCoeff(ispin=2, ikpt=nk1, iband=1, norm=False)
                    # n_noso2 = vnoso.shape[0]
                    vso = so.coeffs[nk1 - 1][0].flatten(
                    )  # so.readBandCoeff(ispin=1, ikpt=nk2, iband=1, norm=False)
                    n_so = vso.shape[0]

                    vs = min(n_noso1 * 2, n_so)
                    Vnoso = np.zeros((vs, nelec_tot), dtype=complex)
                    Vso = np.zeros((vs, nelec_tot), dtype=complex)

                    if np.array(noso.coeffs[1][nk1 - 1]).shape[1] == vs // 2:
                        # if nk1==10 and nk2==10:
                        # print (np.array(noso.coeffs[1][nk1-1]).shape[1], )
                        # prepare matricies
                        for n1 in range(1, nelec_up + 1):
                            Vnoso[0:vs // 2, n1 - 1] = np.array(
                                noso.coeffs[0][nk1 - 1][n1 - 1])[0:vs // 2]
                        for n1 in range(1, nelec_dn + 1):
                            Vnoso[vs // 2:vs, n1 - 1 + nelec_up] = np.array(
                                noso.coeffs[1][nk1 - 1][n1 - 1])[0:vs // 2]
                        for n1 in range(1, nelec_tot + 1):
                            t = so.coeffs[nk2 - 1][n1 - 1].flatten()
                            Vso[0:vs // 2, n1 - 1] = t[0:vs // 2]
                            Vso[vs // 2:vs,
                                n1 - 1] = t[n_so // 2:n_so // 2 + vs // 2]
                        Qnoso, num_noso = self.orth(
                            Vnoso)  # make orthonormal basis?

                        Qso, num_so = self.orth(Vso)

                        gamma_k.append(nelec_tot)
                        a = []
                        for n1 in range(0, nelec_tot):  # noso occupied bands
                            v1 = Qnoso[:, n1]
                            aa = 0.0
                            for n2 in range(0, nelec_tot):  # so occupied bands
                                v2 = Qso[:, n2]

                                t = np.dot(np.conj(v1), v2)
                                Mmn += t * t.conj()
                                aa += (t * t.conj()).real
                            a.append(aa)
                        gamma_k[-1] -= Mmn  # eq 4 in prb 90 125133
                        x.append(kso)
                        y.append(np.real(gamma_k[-1]))
                        if gamma_k[-1] > 0.5:
                            print(
                                "nk1 nk2 kpoint gamma_k ",
                                nk1,
                                nk2,
                                kso,
                                knoso,
                                np.real(gamma_k[-1]),
                                "!!!!!!!!!!",
                            )

        gmax = max(np.real(gamma_k))
        nkmax = np.argmax(np.real(gamma_k))
        kmax = kpoints[nkmax]

        print("------------------------------------")
        print()
        print("                   INDIRECT DIRECT      H**O/LUMO (eV)")
        print(
            "no spin-orbit gaps",
            "{:+.3f}".format(float(noso_lumo - noso_homo)),
            "{:+.3f}".format(noso_direct),
            "   ",
            [noso_homo, noso_lumo],
        )
        print(
            "spin-orbit gaps   ",
            "{:+.3f}".format(float(so_lumo - so_homo)),
            "{:+.3f}".format(so_direct),
            "   ",
            [so_homo, so_lumo],
        )
        print("gamma max", np.real(gmax), " at k =  ", kmax)
        return gmax
Example #6
0
def charged_supercell_scaling_VASP(wavecar_path: str,
                                   bulk_index: int,
                                   def_index: int = -1,
                                   def_coord: Optional[np.ndarray] = None,
                                   cutoff: float = 0.02,
                                   limit: float = 5.,
                                   spin: int = 0,
                                   kpoint: int = 1,
                                   fig=None,
                                   full_range=False) -> float:
    """
    Estimate the interaction between the defect and bulk wavefunction.

    This function estimates the interaction between the defect and bulk
    wavefunction due to spurious effects as a result of using a charged
    supercell. The radial distribution of the bulk wavefunction is compared to
    a perfectly homogenous wavefunction to estimate the scaling.

    Either def_index or def_coord must be specified.

    If you get wonky results with def_index, try using def_coord as there may
    be a problem with finding the defect position if the defect charge is at
    the boundary of the cell.

    Parameters
    ----------
    wavecar_path : str
        path to the WAVECAR file that contains the relevant wavefunctions
    def_index, bulk_index : int
        index of the defect and bulk wavefunctions in the WAVECAR file
    def_coord : np.array(dim=(3,))
        cartesian coordinates of defect position
    cutoff : float
        cutoff for determining zero slope regions
    limit : float
        upper limit for windowing procedure
    spin : int
        spin channel to read from (0 - up, 1 - down)
    kpoint : int
        kpoint to read from (defaults to the first kpoint)
    fig : matplotlib.figure.Figure
        optional figure object to plot diagnostic information (recommended)
    full_range : bool
        determines if full range of first plot is shown

    Returns
    -------
    float
        estimated scaling value to apply to the capture coefficient
    """
    if def_index == -1 and def_coord is None:
        raise ValueError('either def_index or def_coord must be specified')

    wavecar = Wavecar(wavecar_path)

    # compute relevant things
    if def_coord is None:
        psi_def = wavecar.fft_mesh(spin=spin,
                                   kpoint=kpoint - 1,
                                   band=def_index - 1)
        fft_psi_def = np.fft.ifftn(psi_def)
        den_def = np.abs(np.conj(fft_psi_def) * fft_psi_def) / \
            np.abs(np.vdot(fft_psi_def, fft_psi_def))
        def_coord = find_charge_center(den_def, wavecar.a)

    psi_bulk = wavecar.fft_mesh(spin=spin,
                                kpoint=kpoint - 1,
                                band=bulk_index - 1)
    fft_psi_bulk = np.fft.ifftn(psi_bulk)
    return charged_supercell_scaling(fft_psi_bulk,
                                     wavecar.a,
                                     def_coord,
                                     cutoff=cutoff,
                                     limit=limit,
                                     fig=fig,
                                     full_range=full_range)
Example #7
0
from pymatgen.io.vasp.outputs import Wavecar, Vasprun, Chgcar
from pymatgen.io.vasp.inputs import Poscar

wc = Wavecar()
poscar = Poscar.from_file('CONTCAR')

kpoint = 0
band = 126 # chosen reading PROCAR file for kpoint Gamma. Partial DOS of d-orbitals big "enough"

chgcar = wc.get_parchg(poscar, kpoint, band)
chgcar.write_file('CHGCAR_k0_band126.vasp')
Example #8
0
from pymatgen.io.vasp.outputs import Wavecar
import os

if __name__ == '__main__':

    os.chdir('/home/jinho93/tmdc/mos2/2h/hse/bulk/dos')
    wave = Wavecar()
    print(wave)
    print(len(wave.coeffs[0][0]))