Exemple #1
0
def get_local_currents(path,ext,atoms, h, s, ef, G0r, GamL,GamR, bias,\
                       basis, indices, cutoff = 0.10, direction=2, ignore = [], trans_real=None):
    """
        Calculate and plot local currents. 
        The Green's functions and selfenergies must have been dumped on an energy grid. 
        Parameters:
            atoms: ase atoms object
                Atom you wish the local currents calculated for. 
            basis: basis specification
                GPAW style. String or library. Example: 'dzp', {H:'dzp'} etc. 
            indices: list
                indices of energies at which to calculate local currents. 
            dump: Boolean
                if dump=False the local current are not plotted. Instead the tranmission across a surface is calculated. 
            cutoff: float or 1D array
                if local current between atom is smaller than cutoff no arrow is drawn. If integer, transmission is first calculated.   
            direction: integer
                transport direction
            ignore: list:
                indices for atoms to have have plotted local currents. Useful if atom are e.g. close to leads where current is not conserved.    
         """
    dim = len(h)
    K = np.empty((dim, dim))
    arrows = np.zeros((len(atoms), len(atoms)))

    Tt = GamL.dot(G0r).dot(GamR).dot(G0r.T.conj())
    # print Tt.trace(), trans_real
    # exit()
    energy = ef
    # Sigma_el_L= Sigma_el_L_left + Sigma_el_L_right
    G0L = 1j * G0r.dot(GamL).dot(G0r.T.conj())
    # G0L *= bias
    # print G0L
    #get lesser Greens function
    # G0L = dot3( G0r , Sigma_el_L , G0r.T.conj() )#np.dot(G0r[:,:,e],np.dot(Sigma_el_L[:,:,e],dagger(G0r[:,:,e])))#
    V = h - energy * s  #Sigma_el_r[:,:,index]
    K_mn = np.multiply(V, G0L.T) - np.multiply(V.T, G0L)
    K_mn[range(dim), range(dim)] = 0  #set diagonal zero
    K[:, :] = np.real(K_mn)

    # print K_mn
    # print np.real(K).max()
    # exit()
    #       np.set_printoptions(precision=2, suppress=True)

    #get currents between atoms
    from gpaw.lcao.tools import get_bfi2
    # print "getting arrows..."
    trans = 0
    dic = {}
    for atom in atoms:
        dic[atom.index] = get_bfi2(atoms.get_chemical_symbols(), basis,
                                   [atom.index])

    for n, atom1 in enumerate(atoms):
        # print n, "of ", len(atoms)
        bfs1 = dic[atom1.index]
        for m, atom2 in enumerate(atoms):
            if m == n:
                # print m, "m"
                continue
            if n in ignore or m in ignore:
                # print n, "n"
                continue
            bfs2 = dic[atom2.index]
            arrows[n, m] = K[:, :].take(bfs1,
                                        axis=0).take(bfs2,
                                                     axis=1).sum(axis=(0, 1))
            #                print arrows[n,m,:]
            if atom1.position[2] < 10.0 and atom2.position[2] > 10.0:
                # print arrows[n,m]
                trans += arrows[n, m]
    np.save('arrows.npy', arrows)
    # print trans, Tt.trace(), trans_real
    # exit()

    f = open(path + ext, 'w')
    f.write('wireframe off \n background white; \n')
    f.write('load "file://{0}/central_region.xyz" \n'.format(path))
    # text_file.write("set defaultdrawarrowscale 0.1 \n")
    norm = np.abs(arrows[:, :]).max()
    # print trans_real
    # print arrows
    # exit()
    arrows2 = arrows / norm
    for atom1 in atoms:
        for atom2 in atoms:
            # print np.real(trans_real)
            # if atom2.position[direction]-atom1.position[direction]<0.0:
            #     print "hi"
            #     continue
            # print np.abs(arrows[atom1.index, atom2.index]), cutoff*np.real(trans_real)
            if np.abs(arrows[atom1.index,
                             atom2.index]) < cutoff * np.real(trans_real):
                # print "arrow too small, continuing"
                continue
            p2 = np.sign(
                arrows[atom1.index,
                       atom2.index])  #positive or negative contribution
            p2 = atom1.position[2] - atom2.position[
                2]  #positive or negative contribution
            if p2 > 0.0:
                c = 'red'
                o1 = atom1.position
                o2 = atom2.position
            else:
                c = 'red'
                o1 = atom2.position
                o2 = atom1.position
            diam = np.abs(arrows2[atom1.index, atom2.index]) / 2
            # print atom1.index, atom2.index, c, diam
            f.write(
                'draw arrow%d_%d arrow {%f %f %f} {%f %f %f} diameter %.6f color %s \n'
                % (atom2.index, atom1.index, o2[0], o2[1], o2[2], o1[0], o1[1],
                   o1[2], diam, c))
    f.write('rotate 90 \n')
    f.write('background white \n')
    f.write('write file:/{0}plots/interatomic_current.png'.format(path))
    # print "got arrows"
    # exit()
    # plot_local_currents(atoms,basis=basis,K=K,energies=[ef],transmission=trans_real)
    # print trans, "Trans"
    return trans
Exemple #2
0
def all_this(atoms,
             calc,
             path,
             basis,
             basis_full,
             xc,
             FDwidth,
             kpts,
             mode,
             h,
             vacuum=4):
    wfs = calc.wfs
    from ase.dft.kpoints import monkhorst_pack
    from ase.io import write as ase
    kpt = monkhorst_pack((1, 1, 1))

    H_kin = wfs.T_qMM[0]
    np.save(path + "H_kin.npy", H_kin)
    # exit()

    # path = "/kemi/aj/local_gpaw/data/H20/"
    # basename = "basis_{0}__xc_{1}__fdwithd_{3}__kpts_{4}__mode_{5}__vacuum_{6}__".format(basis, xc, FDwidth, kpts, mode, vacuum)

    basename = "basis_{0}__xc_{1}__h_{2}__fdwithd_{3}__kpts_{4}__mode_{5}__vacuum_{6}__".format(
        basis, xc, h, FDwidth, kpts, mode, vacuum)

    # basename = "basis_{0}__xc_{1}__a_{2}__c_{3}__d_{4}__h_{5}__fdwithd_{6}__kpts_{7}__mode_{8}__vacuum_{9}__".format(basis,xc,a,c,d,h,FDwidth,kpts,mode,vacuum)

    a_list = range(0, len(atoms))
    symbols = atoms.get_chemical_symbols()
    bfs = get_bfi2(symbols, basis_full, range(len(a_list)))
    rot_mat = np.diag(v=np.ones(len(bfs)))
    c_fo_xi = asc(rot_mat.real.T)  # coefficients
    phi_xg = calc.wfs.basis_functions.gd.zeros(len(c_fo_xi))
    wfs = calc.wfs
    gd0 = calc.wfs.gd
    calc.wfs.basis_functions.lcao_to_grid(c_fo_xi, phi_xg, -1)

    np.save(path + basename + "ao_basis_grid", [phi_xg, gd0])
    plot_basis(atoms, phi_xg, ns=len(bfs), folder_name=path + "basis/ao")

    summ = np.zeros(phi_xg[0, :, :, :].shape)
    ns = np.arange(len(bfs))
    for n, phi in zip(ns, phi_xg.take(ns, axis=0)):
        summ += abs(phi) * abs(phi)
    write(path + "basis/ao/sum.cube", atoms, data=summ)
    """Lowdin"""
    dump_hamiltonian_parallel(path + 'scat_' + basename, atoms, direction='z')
    atoms.write(path + basename + ".traj")

    H_ao, S_ao = pickle.load(open(path + 'scat_' + basename + '0.pckl', 'rb'))
    H_ao = H_ao[0, 0]
    S_ao = S_ao[0]
    n = len(S_ao)
    eig, rot = np.linalg.eig(S_ao)
    rot = np.dot(rot / np.sqrt(eig), rot.T.conj())
    r_mat = np.identity(n)
    r_mat[:] = np.dot(r_mat, rot)
    A = r_mat
    U = np.linalg.inv(A)
    rot_mat = A
    c_fo_xi = asc(rot_mat.real.T)  # coefficients
    lowdin_phi_xg = calc.wfs.basis_functions.gd.zeros(len(c_fo_xi))
    wfs = calc.wfs
    gd0 = calc.wfs.gd
    calc.wfs.basis_functions.lcao_to_grid(c_fo_xi, lowdin_phi_xg, -1)
    np.save(path + basename + "lowdin_basis", [lowdin_phi_xg])
    np.save(path + basename + "lowdin_U", U)
    plot_basis(atoms,
               lowdin_phi_xg,
               ns=len(bfs),
               folder_name=path + "basis/lowdin")

    # MO - basis
    eig, vec = np.linalg.eig(np.dot(np.linalg.inv(S_ao), H_ao))
    order = np.argsort(eig)
    eig = eig.take(order)
    vec = vec.take(order, axis=1)
    S_mo = np.dot(np.dot(vec.T.conj(), S_ao), vec)
    vec = vec / np.sqrt(np.diag(S_mo))
    S_mo = np.dot(np.dot(vec.T.conj(), S_ao), vec)
    H_mo = np.dot(np.dot(vec.T, H_ao), vec)

    rot_mat = vec
    c_fo_xi = asc(rot_mat.real.T)  # coefficients
    mo_phi_xg = calc.wfs.basis_functions.gd.zeros(len(c_fo_xi))
    wfs = calc.wfs
    gd0 = calc.wfs.gd
    calc.wfs.basis_functions.lcao_to_grid(c_fo_xi, mo_phi_xg, -1)
    np.save(path + basename + "mo_energies", eig)
    np.save(path + basename + "mo_basis", mo_phi_xg)
    plot_basis(atoms, mo_phi_xg, ns=len(bfs), folder_name=path + "basis/mo")

    # eigenchannels
    from new2 import ret_gf_ongrid, calc_trans, fermi_ongrid,\
        lesser_gf_ongrid, lesser_se_ongrid, ret_gf_ongrid2,\
        lesser_gf_ongrid2, retarded_gf2
    gamma = 1e0
    H_cen = H_ao
    S_cen = S_ao
    n = len(H_cen)
    GamL = np.zeros([n, n])
    GamR = np.zeros([n, n])
    GamL[0, 0] = gamma
    GamR[n - 1, n - 1] = gamma

    # #C8
    # bfs = get_bfi2(symbols, basis, [23,24])
    # print bfs, "left"
    # GamL[bfs[0],bfs[0]] = GamL[bfs[1],bfs[1]] = gamma
    # symbols = atoms.get_chemical_symbols()
    # bfs = get_bfi2(symbols, basis, [21,22])
    # print bfs, "right"
    # GamR[bfs[0],bfs[0]] = GamR[bfs[1],bfs[1]] = gamma

    # for ef in [eig[22], 0, eig[27]]:
    for ef in [0]:
        """Current approx at low temp"""
        Sigma_r = -1j / 2 * (GamL + GamR)
        # Gr_approx = retarded_gf2(H_cen, S_cen, ef, Sigma_r)
        Gr_approx = retarded_gf2(H_cen, S_cen, ef, Sigma_r)

        # print Gr_approx, "Gr_approx"

        # from new import calc_trans, ret_gf_ongrid
        # e_grid = np.arange(eig[15],eig[30],0.001)
        # Gamma_L = [GamL for en in range(len(e_grid))]
        # Gamma_R = [GamR for en in range(len(e_grid))]
        # Gamma_L = np.swapaxes(Gamma_L, 0, 2)
        # Gamma_R = np.swapaxes(Gamma_R, 0, 2)
        # Gr = ret_gf_ongrid(e_grid, H_cen, S_cen, Gamma_L, Gamma_R)
        # trans = calc_trans(e_grid,Gr,Gamma_L,Gamma_R)

        # np.save("/Users/andersjensen/Desktop/trans.npy",np.array([e_grid,trans]))

        # Tt = GamL.dot(Gr_approx).dot(GamR).dot(Gr_approx.T.conj())
        # print Tt.trace(), "transmission"

        def get_left_channels(Gr, S, GamL, GamR, nchan=1):
            g_s_ii = Gr
            lambda_l_ii = GamL
            lambda_r_ii = GamR

            s_mm = S
            s_s_i, s_s_ii = np.linalg.eig(s_mm)
            s_s_i = np.abs(s_s_i)
            s_s_sqrt_i = np.sqrt(s_s_i)  # sqrt of eigenvalues
            s_s_sqrt_ii = np.dot(s_s_ii * s_s_sqrt_i, s_s_ii.T.conj())
            s_s_isqrt_ii = np.dot(s_s_ii / s_s_sqrt_i, s_s_ii.T.conj())

            lambdab_r_ii = np.dot(np.dot(s_s_isqrt_ii, lambda_r_ii),
                                  s_s_isqrt_ii)
            a_l_ii = np.dot(np.dot(g_s_ii, lambda_l_ii), g_s_ii.T.conj())  # AL
            ab_l_ii = np.dot(np.dot(s_s_sqrt_ii, a_l_ii),
                             s_s_sqrt_ii)  # AL in lowdin
            lambda_i, u_ii = np.linalg.eig(ab_l_ii)  # lambda and U
            ut_ii = np.sqrt(lambda_i / (2.0 * np.pi)) * u_ii  # rescaled
            m_ii = 2 * np.pi * np.dot(np.dot(ut_ii.T.conj(), lambdab_r_ii),
                                      ut_ii)
            T_i, c_in = np.linalg.eig(m_ii)
            T_i = np.abs(T_i)

            channels = np.argsort(-T_i)
            c_in = np.take(c_in, channels, axis=1)
            T_n = np.take(T_i, channels)
            v_in = np.dot(np.dot(s_s_isqrt_ii, ut_ii), c_in)
            return T_n, v_in

        T_n, v_in = get_left_channels(Gr_approx, S_cen, GamL, GamR)

        def get_eigenchannels(Gr, GamR):
            """
            Calculate the eigenchannels from
            G Gamma G
            """
            A = Gr.dot(GamL).dot(Gr.T.conj())
            Teigs, Veigs = np.linalg.eig(A)
            order = np.argsort(Teigs)
            Teigs = Teigs.take(order)
            Veigs = Veigs.take(order, axis=1)

            return Teigs, Veigs

            # T_n, v_in = get_eigenchannels(Gr_approx,GamL)

            # print T_n
            # eig, vec = np.linalg.eig(Tt)
            # order = np.argsort(eig)
            # eig = eig.take(order)
            # vec = vec.take(order, axis=1)

            # print v_in
            # print np.abs(v_in)

            # print eig, "eigs"

            # rot_mat = np.abs(v_in)
            rot_mat = v_in.real
            # rot_mat = vec
            #         print rot_mat
            c_fo_xi = asc(rot_mat.T)  # coefficients
            #         print c_fo_xi
            #         print c_fo_xi.max(), c_fo_xi.min()
            # exit()
            # c_fo_xi = asc(rot_mat)#coefficients
            teig_phi_xg = calc.wfs.basis_functions.gd.zeros(len(c_fo_xi))
            wfs = calc.wfs
            gd0 = calc.wfs.gd
            calc.wfs.basis_functions.lcao_to_grid(c_fo_xi, teig_phi_xg, -1)
            np.save(path + basename + "eigenchannels__ef_{0}.npy".format(ef),
                    teig_phi_xg)
            np.save(path + basename + "Teig__ef_{0}.npy".format(ef), eig)
            plot_eig(atoms,
                     teig_phi_xg,
                     ns=2,
                     folder_name=path + "basis/eigchan",
                     ext="real_ef_{0}".format(ef))

            # rot_mat = np.abs(v_in)
            rot_mat = v_in.imag
            # rot_mat = vec
            #         print rot_mat
            c_fo_xi = asc(rot_mat.T)  # coefficients
            #         print c_fo_xi
            #         print c_fo_xi.max(), c_fo_xi.min()
            # exit()
            # c_fo_xi = asc(rot_mat)#coefficients
            teig_phi_xg = calc.wfs.basis_functions.gd.zeros(len(c_fo_xi))
            wfs = calc.wfs
            gd0 = calc.wfs.gd
            calc.wfs.basis_functions.lcao_to_grid(c_fo_xi, teig_phi_xg, -1)
            np.save(path + basename + "eigenchannels__ef_{0}.npy".format(ef),
                    teig_phi_xg)
            np.save(path + basename + "Teig__ef_{0}.npy".format(ef), eig)
            plot_eig(atoms,
                     teig_phi_xg,
                     ns=2,
                     folder_name=path + "basis/eigchan",
                     ext="imag_ef_{0}".format(ef))
Exemple #3
0
def plot_local_currents(atoms,
                        basis,
                        K,
                        energies,
                        transmission,
                        cutoff=0.1,
                        ignore=[],
                        direction=2):
    from ase.io import write
    from gpaw.lcao.tools import get_bfi2
    dic = {}
    for atom in atoms:
        dic[atom.index] = get_bfi2(atoms.get_chemical_symbols(), basis,
                                   [atom.index])
    mask = np.ones((len(atoms), len(atoms)))
    for bf1 in ignore:
        for bf2 in ignore:
            mask[bf1, bf2] = 0.0
    arrows = np.zeros(len(atoms), len(atoms))

    f = open('flux_e%.2f.dat' % energies[0], 'w')
    f.write('wireframe off \n background white; \n')
    #get arrows
    for n, atom1 in enumerate(atoms):
        bfs1 = dic[atom1.index]
        for m, atom2 in enumerate(atoms):
            if m == n:
                arrows[n, m] = 0.0
                continue
            if n in ignore or m in ignore:
                arrows[n, m] = 0.0
                continue
            bfs2 = dic[atom2.index]
            arrows[n, m] = K[:, :].take(bfs1,
                                        axis=0).take(bfs2,
                                                     axis=1).sum(axis=(0, 1))
    norm = np.abs(np.multiply(mask, arrows[:, :])).max()
    arrows2 = arrows[:, :] / norm
    for atom1 in atoms:
        for atom2 in atoms:
            # print direction, "direction"
            exit()
            if atom2.position[direction] - atom1.position[direction] < 0.0:
                continue
            if np.abs(arrows[e, atom1.index,
                             atom2.index]) < cutoff * transmission[e]:
                #                        print "arrow too small, continuing"
                continue
            p2 = np.sign(
                arrows[e, atom1.index,
                       atom2.index])  #positive or negative contribution
            if p2 > 0.0:
                c = 'red'
                o1 = atom1.position
                o2 = atom2.position
            else:
                c = 'blue'
                o1 = atom2.position
                o2 = atom1.position
            diam = np.abs(arrows2[atom1.index, atom2.index])
            #                    print atom1.index, atom2.index, c, diam
            # print "hi"
            f.write(
                'draw arrow%d_%d arrow {%f %f %f} {%f %f %f} diameter %.6f color %s \n'
                % (atom1.index, atom2.index, o1[0], o1[1], o1[2], o2[0], o2[1],
                   o2[2], diam, c))
    np.save('arrows.npy', arrows)
    return
from gpaw.lcao.tools import get_bfi2

# Import Hamiltonian and overlap matrix. This example is calculated using GPAW. 
h = np.loadtxt('files_benzene/h.txt')
s = np.loadtxt('files_benzene/s.txt')

# Import Atoms object 
mol = read('files_benzene/benzene.txt')

# Specify number of electron pairs. 
ne = 15

# Generate library which links atoms to basis functions 
basis_dic = {}
for atom in mol:
	basis_dic[atom.index]=get_bfi2(mol.get_chemical_symbols(), 'dzp', [atom.index])

# Initialize
benz = NO(h=h, s=s, ne=ne, mol=mol, basis_dic = basis_dic)

# Get Natural Atomic Orbitals (NAOs)
NAO = benz.get_NAO()

# Get indices of NAOs with occupancy of 1. For benzene, these correspond to the pz-orbitals.
pzs = benz.get_single_occupancy_NAO_indices(threshold=0.01)

# plot pz orbitals to make sure you are happy with the basis
plot_basis(benz.NAOs, mol, pzs, basis = 'dzp', folder_name='./files_benzene/pzs') 

##### transport #######
# Specify energy grid. 
Exemple #5
0
    def __init__(
        self,
        gpwfilename,
        fixedenergy=0.0,
        spin=0,
        ibl=True,
        basis="sz",
        zero_fermi=False,
        pwfbasis=None,
        lcaoatoms=None,
        projection_data=None,
    ):
        calc = GPAW(gpwfilename, txt=None, basis=basis)
        assert calc.wfs.gd.comm.size == 1
        assert calc.wfs.kpt_comm.size == 1
        assert calc.wfs.band_comm.size == 1
        if zero_fermi:
            try:
                Ef = calc.get_fermi_level()
            except NotImplementedError:
                Ef = calc.get_homo_lumo().mean()
        else:
            Ef = 0.0

        self.ibzk_kc = calc.get_ibz_k_points()
        self.nk = len(self.ibzk_kc)
        self.eps_kn = [calc.get_eigenvalues(kpt=q, spin=spin) - Ef for q in range(self.nk)]
        self.M_k = [sum(eps_n <= fixedenergy) for eps_n in self.eps_kn]
        print "Fixed states:", self.M_k
        self.calc = calc
        self.dtype = self.calc.wfs.dtype
        self.spin = spin
        self.ibl = ibl
        self.pwf_q = []
        self.norms_qn = []
        self.S_qww = []
        self.H_qww = []

        if ibl:
            if pwfbasis is not None:
                pwfmask = basis_subset2(calc.atoms.get_chemical_symbols(), basis, pwfbasis)
            if lcaoatoms is not None:
                lcaoindices = get_bfi2(calc.atoms.get_chemical_symbols(), basis, lcaoatoms)
            else:
                lcaoindices = None
            self.bfs = get_bfs(calc)
            if projection_data is None:
                V_qnM, H_qMM, S_qMM, self.P_aqMi = get_lcao_projections_HSP(
                    calc, bfs=self.bfs, spin=spin, projectionsonly=False
                )
            else:
                V_qnM, H_qMM, S_qMM, self.P_aqMi = projection_data
            H_qMM -= Ef * S_qMM
            for q, M in enumerate(self.M_k):
                if pwfbasis is None:
                    pwf = ProjectedWannierFunctionsIBL(V_qnM[q], S_qMM[q], M, lcaoindices)
                else:
                    pwf = PWFplusLCAO(V_qnM[q], S_qMM[q], M, pwfmask, lcaoindices)
                self.pwf_q.append(pwf)
                self.norms_qn.append(pwf.norms_n)
                self.S_qww.append(pwf.S_ww)
                self.H_qww.append(pwf.rotate_matrix(self.eps_kn[q][:M], H_qMM[q]))
        else:
            if projection_data is None:
                V_qnM = get_lcao_projections_HSP(calc, spin=spin)
            else:
                V_qnM = projection_data
            for q, M in enumerate(self.M_k):
                pwf = ProjectedWannierFunctionsFBL(V_qnM[q], M, ortho=False)
                self.pwf_q.append(pwf)
                self.norms_qn.append(pwf.norms_n)
                self.S_qww.append(pwf.S_ww)
                self.H_qww.append(pwf.rotate_matrix(self.eps_kn[q]))

        for S in self.S_qww:
            print "Condition number: %0.1e" % condition_number(S)
Exemple #6
0
    def __init__(self,
                 gpwfilename,
                 fixedenergy=0.,
                 spin=0,
                 ibl=True,
                 basis='sz',
                 zero_fermi=False,
                 pwfbasis=None,
                 lcaoatoms=None,
                 projection_data=None):
        calc = GPAW(gpwfilename, txt=None, basis=basis)
        assert calc.wfs.gd.comm.size == 1
        assert calc.wfs.kd.comm.size == 1
        assert calc.wfs.bd.comm.size == 1
        if zero_fermi:
            try:
                Ef = calc.get_fermi_level()
            except NotImplementedError:
                Ef = calc.get_homo_lumo().mean()
        else:
            Ef = 0.0

        self.ibzk_kc = calc.get_ibz_k_points()
        self.nk = len(self.ibzk_kc)
        self.eps_kn = [
            calc.get_eigenvalues(kpt=q, spin=spin) - Ef for q in range(self.nk)
        ]
        self.M_k = [sum(eps_n <= fixedenergy) for eps_n in self.eps_kn]
        print('Fixed states:', self.M_k)
        self.calc = calc
        self.dtype = self.calc.wfs.dtype
        self.spin = spin
        self.ibl = ibl
        self.pwf_q = []
        self.norms_qn = []
        self.S_qww = []
        self.H_qww = []

        if ibl:
            if pwfbasis is not None:
                pwfmask = basis_subset2(calc.atoms.get_chemical_symbols(),
                                        basis, pwfbasis)
            if lcaoatoms is not None:
                lcaoindices = get_bfi2(calc.atoms.get_chemical_symbols(),
                                       basis, lcaoatoms)
            else:
                lcaoindices = None
            self.bfs = get_bfs(calc)
            if projection_data is None:
                V_qnM, H_qMM, S_qMM, self.P_aqMi = get_lcao_projections_HSP(
                    calc, bfs=self.bfs, spin=spin, projectionsonly=False)
            else:
                V_qnM, H_qMM, S_qMM, self.P_aqMi = projection_data
            H_qMM -= Ef * S_qMM
            for q, M in enumerate(self.M_k):
                if pwfbasis is None:
                    pwf = ProjectedWannierFunctionsIBL(V_qnM[q], S_qMM[q], M,
                                                       lcaoindices)
                else:
                    pwf = PWFplusLCAO(V_qnM[q], S_qMM[q], M, pwfmask,
                                      lcaoindices)
                self.pwf_q.append(pwf)
                self.norms_qn.append(pwf.norms_n)
                self.S_qww.append(pwf.S_ww)
                self.H_qww.append(
                    pwf.rotate_matrix(self.eps_kn[q][:M], H_qMM[q]))
        else:
            if projection_data is None:
                V_qnM = get_lcao_projections_HSP(calc, spin=spin)
            else:
                V_qnM = projection_data
            for q, M in enumerate(self.M_k):
                pwf = ProjectedWannierFunctionsFBL(V_qnM[q], M, ortho=False)
                self.pwf_q.append(pwf)
                self.norms_qn.append(pwf.norms_n)
                self.S_qww.append(pwf.S_ww)
                self.H_qww.append(pwf.rotate_matrix(self.eps_kn[q]))

        for S in self.S_qww:
            print('Condition number: %0.1e' % condition_number(S))
            })
atoms.set_calculator(calc)
atoms.get_potential_energy()  # Converge everything!
Ef = atoms.calc.get_fermi_level()

wfs = calc.wfs
kpt = monkhorst_pack((1, 1, 1))

basename = "basis_{0}__xc_{1}__h_{2}__fdwithd_{3}__kpts_{4}__mode_{5}__vacuum_{6}__".format(
    basis, xc, h, FDwidth, kpts, mode, vacuum)

dump_hamiltonian_parallel(path + 'scat_' + basename, atoms, direction='z')

a_list = range(0, len(atoms))
symbols = atoms.get_chemical_symbols()
bfs = get_bfi2(symbols, basis_full, range(len(a_list)))
rot_mat = np.diag(v=np.ones(len(bfs)))
c_fo_xi = asc(rot_mat.real.T)  # coefficients
phi_xg = calc.wfs.basis_functions.gd.zeros(len(c_fo_xi))
wfs = calc.wfs
gd0 = calc.wfs.gd
calc.wfs.basis_functions.lcao_to_grid(c_fo_xi, phi_xg, -1)
np.save(path + basename + "ao_basis_grid", [phi_xg, gd0])
plot_basis(atoms, phi_xg, ns=len(bfs), folder_name=path + "basis/ao")
print('fermi is', Ef)

# MO - basis

H_ao, S_ao = pickle.load(open(path + 'scat_' + basename + '0.pckl', 'rb'))
H_ao = H_ao[0, 0]
S_ao = S_ao[0]