Ejemplo n.º 1
0
def plot_basis(r,
               atoms,
               ns,
               basis='dzp',
               folder_name='./basis',
               vacuum=3.0,
               h=0.20):
    """
    r: coefficients of atomcentered basis functions
    atoms: Atoms-object 
    ns: indices of bfs functions to plot. 

    """
    from gpaw import GPAW
    from gpaw import setup_paths
    from os.path import exists
    from subprocess import call
    from numpy import ascontiguousarray as asc
    from ase.io import write

    if exists(folder_name) == False:
        print "making folder for basis functions"
        call('mkdir %s' % folder_name, shell=True)

    symbols = atoms.get_chemical_symbols()
    ns = np.array(ns)
    atoms.center(vacuum=vacuum)
    calc = GPAW(h=h, mode='lcao', basis=basis, txt='basis.txt')
    atoms.set_calculator(calc)
    calc.initialize(atoms)
    calc.set_positions(atoms)
    c_fo_xi = asc(r.real.T)  #coefficients
    phi_xG = calc.wfs.basis_functions.gd.zeros(len(c_fo_xi))
    calc.wfs.basis_functions.lcao_to_grid(c_fo_xi, phi_xG, -1)
    for n, phi in zip(ns, phi_xG.take(ns, axis=0)):
        print "writing %d of %d" % (n, len(ns)),
        write('%s/%d.cube' % (folder_name, n), atoms, data=phi)
    summ = np.zeros(phi_xG[0, :, :, :].shape)
    print "sum", summ.shape
    for n, phi in zip(ns, phi_xG.take(ns, axis=0)):
        summ += phi
    write('%s/sum.cube' % folder_name, atoms, data=summ)
Ejemplo n.º 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))
Ejemplo n.º 3
0
        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))
Ejemplo n.º 4
0
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]

eig, vec = np.linalg.eig(np.dot(np.linalg.inv(S_ao), H_ao))
Ejemplo n.º 5
0
def main() -> None:
    parser = argparse.ArgumentParser(description='Process some integers.')
    parser.add_argument('--path', default='data/', help='path to data folder')
    parser.add_argument('--basis', default='dzp', help='basis (sz, dzp, ...)')
    parser.add_argument('--config',
                        default=None,
                        help='name of the config file')
    args = parser.parse_args()
    path = str(os.path.abspath(args.path)) + "/"

    basis = args.basis
    xyzname = "hh_junc.traj"
    config = args.config

    # Load config values (e.g. h-spacing, functional, align atoms etc.)
    if config is None:
        raise FileNotFoundError('No config file has been chosen')

    config_values = read_config(config)

    # Configuration and constants
    if "ef" in config_values:
        ef = float(config_values["ef"])
    else:
        ef = 0.0

    if 'functional' in config_values:
        xc = config_values['functional']

        # To make sure the right basis set is used
        basis += "." + xc
    else:
        xc = 'PBE'

    h_basis = "sz." + xc

    if 'h_spacing' in config_values:
        h = float(config_values['h_spacing'])
    else:
        h = 0.2

    if 'charge' in config_values:
        charge = int(config_values['charge'])
    else:
        charge = 0

    if "cutoff" in config_values:
        cutoff = int(config_values["cutoff"])
    else:
        cutoff = 20

    # Constants
    FDwidth: float = 0.1
    kpts = (1, 1, 1)
    mode: str = 'lcao'
    eV2au: float = 1 / Hartree
    bias: float = 1e-3 * eV2au
    gamma: float = 1e0 * eV2au
    ef: float = ef * eV2au  # If ef has been set to a custom value.
    estart, eend = [-6 * eV2au, 6 * eV2au]
    energy_step: float = 1e-2 * eV2au
    energy_grid = np.arange(estart, eend, energy_step)

    # Align z-axis and cutoff at these atoms, OBS paa retningen.
    if 'bottom_atom' not in config_values:
        raise ValueError(
            'You need to specify the bottom atom to align molecule')

    if 'top_atom' not in config_values:
        raise ValueError('You need to specify the top atom to align molecule')

    align1: int = int(config_values['bottom_atom']) - 1
    align2: int = int(config_values['top_atom']) - 1

    basis_full = {
        'H': h_basis,
        'C': basis,
        'S': basis,
        'N': basis,
        'Si': basis,
        'Ge': basis,
        'B': basis,
        'O': basis,
        'F': basis,
        'Cl': basis,
        'P': basis,
        'Br': basis,
        'Ru': basis
    }

    # Divider for h - size of the arrows for current density
    grid_size: int = 1

    plot_basename: str = "plots/"
    data_basename: str = "data/"

    molecule = read(path + xyzname)

    # Identify end atoms and align according to z-direction
    atoms = utils_zcolor.identify_and_align(molecule, align1, align2)
    symbols = atoms.get_chemical_symbols()
    np.save(path + "positions.npy", atoms.get_positions())
    np.save(path + "symbols.npy", symbols)
    atoms.write(path + "central_region.xyz")

    # Run and converge calculation
    calc = GPAW(h=h,
                xc=xc,
                basis=basis_full,
                occupations=FermiDirac(width=FDwidth),
                kpts=kpts,
                mode=mode,
                nbands="nao",
                symmetry={
                    'point_group': False,
                    'time_reversal': False
                },
                charge=charge,
                txt="logfile.txt")
    atoms.set_calculator(calc)
    atoms.get_potential_energy()  # Converge everything!
    print('Fermi is', atoms.calc.get_fermi_level())

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

    # Write AO basis to disk
    bfs = get_bfi(calc, range(len(atoms)))
    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))
    gd0 = calc.wfs.gd

    calc.wfs.basis_functions.lcao_to_grid(c_fo_xi, phi_xg, -1)
    # Writing this to disk while going multiprocessing with GPAW
    # Reason: Numpy tries to pickle the objects, but gd0 is
    # not pickleable as it's a MPI object
    # np.save(path + "ao_basis_grid", [phi_xg, gd0])
    utils_zcolor.plot_basis(atoms, phi_xg, folder_name=path + "basis/ao")

    H_ao, S_ao = pickle.load(open(path + 'scat_0.pckl', 'rb'))
    H_ao = H_ao[0, 0]
    H_ao *= eV2au
    S_ao = S_ao[0]

    # Convert AO's to MO's
    eig_vals, eig_vec = np.linalg.eig(np.dot(np.linalg.inv(S_ao), H_ao))
    order = np.argsort(eig_vals)
    eig_vals = eig_vals.take(order)
    eig_vec = eig_vec.take(order, axis=1)
    S_mo = np.dot(np.dot(eig_vec.T.conj(), S_ao), eig_vec)
    eig_vec = eig_vec / np.sqrt(np.diag(S_mo))
    S_mo = np.dot(np.dot(eig_vec.T.conj(), S_ao), eig_vec)
    H_mo = np.dot(np.dot(eig_vec.T, H_ao), eig_vec)

    # Save the MO basis as .cube files
    c_fo_xi = asc(eig_vec.real.T)  # coefficients
    mo_phi_xg = calc.wfs.basis_functions.gd.zeros(len(c_fo_xi))
    calc.wfs.basis_functions.lcao_to_grid(c_fo_xi, mo_phi_xg, -1)
    np.save(path + "mo_energies", eig_vals)

    utils_zcolor.plot_basis(atoms, mo_phi_xg, folder_name=path + "basis/mo")

    n = len(H_ao)

    GamL = np.zeros([n, n], dtype="float64")
    GamR = np.zeros([n, n], dtype="float64")
    GamL[0, 0] = gamma
    GamR[n - 1, n - 1] = gamma

    Gamma_L = [GamL for en in range(len(energy_grid))]
    Gamma_R = [GamR for en in range(len(energy_grid))]
    Gamma_L = np.swapaxes(Gamma_L, 0, 2)
    Gamma_R = np.swapaxes(Gamma_R, 0, 2)

    Gr = utils_zcolor.ret_gf_ongrid(energy_grid, H_ao, S_ao, Gamma_L, Gamma_R)

    # Calculate the transmission - AO basis
    print("Calculating transmission - AO-basis")

    # To optimize the following matrix operations
    Gamma_L = Gamma_L.astype(dtype='float32', order='F')
    Gamma_R = Gamma_R.astype(dtype='float32', order='F')
    Gr = Gr.astype(dtype='complex128', order='F')
    trans = utils_zcolor.calc_trans(energy_grid, Gr, Gamma_L, Gamma_R)

    utils_zcolor.plot_transmission(energy_grid * Hartree, np.real(trans),
                                   path + plot_basename + "trans.png")
    np.save(path + data_basename + 'trans_full.npy',
            [energy_grid * Hartree, trans])
    print("AO-transmission done!")

    # Find H**O and LUMO
    for n in range(len(eig_vals)):
        if eig_vals[n] < 0 and eig_vals[n + 1] > 0:
            H**O = eig_vals[n]
            LUMO = eig_vals[n + 1]
            midgap = (H**O + LUMO) / 2.0

            np.savetxt(
                path + "basis/mo/" + 'homo_index.txt',
                X=['H**O index is ', n],
                fmt='%.10s',
                newline='\n',
            )
            break

    hl_gap = [
        'H**O is ', H**O * Hartree, 'LUMO is ', LUMO * Hartree, 'mid-gap is ',
        midgap * Hartree
    ]
    np.savetxt(path + 'HOMO_LUMO.txt', X=hl_gap, fmt='%.10s', newline='\n')
    """Current with fermi functions"""
    fR, fL = utils_zcolor.fermi_ongrid(energy_grid, ef, bias)
    dE = energy_grid[1] - energy_grid[0]
    current_trans = (1 / (2 * np.pi)) * np.array([
        trans[en].real * (fL[en] - fR[en]) * dE
        for en in range(len(energy_grid))
    ]).sum()
    np.save(path + data_basename + "current_trans.npy", current_trans)
    """Current approx at low temp"""
    sigma_r = -1j / 2. * (GamL + GamR)  # + V_pot
    Gr_approx = utils_zcolor.retarded_gf2(H_ao, S_ao, ef, sigma_r)

    Gles = np.dot(np.dot(Gr_approx, GamL), Gr_approx.T.conj())
    Gles *= bias
    np.save(path + data_basename + "matrices_dV.npy", [Gr_approx, Gles, GamL])

    utils_zcolor.plot_complex_matrix(Gles, path + "Gles")

    Tt = np.dot(np.dot(np.dot(GamL, Gr_approx), GamR), Gr_approx.T.conj())
    current_dV = (bias / (2 * np.pi)) * Tt.trace()
    np.save(path + "data/trans_dV.npy", [ef, Tt.trace()])
    np.save(path + "data/current_dV.npy", current_dV)

    # Non corrected current - AO basis
    mlt = 1j * Gles / (4 * np.pi)
    np.save(path + "data/Gles_dV.npy", mlt)

    x_cor = gd0.coords(0)
    y_cor = gd0.coords(1)
    z_cor = gd0.coords(2)
    np.save(path + "data/xyz_cor.npy", [x_cor, y_cor, z_cor])

    dx = x_cor[1] - x_cor[0]
    dy = y_cor[1] - y_cor[0]
    dz = z_cor[1] - z_cor[0]

    # 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)

    GamL_mo = np.dot(np.dot(vec.T, GamL), vec)
    GamR_mo = np.dot(np.dot(vec.T, GamR), vec)
    Gamma_L_mo = [GamL_mo for en in range(len(energy_grid))]
    Gamma_R_mo = [GamR_mo for en in range(len(energy_grid))]
    Gamma_L_mo = np.swapaxes(Gamma_L_mo, 0, 2)
    Gamma_R_mo = np.swapaxes(Gamma_R_mo, 0, 2)

    # Convert and save mlt in MO basis
    sigma_r_mo = -1j / 2. * (GamL_mo + GamR_mo)  # + V_pot
    Gr_approx_mo = utils_zcolor.retarded_gf2(H_mo, S_mo, ef, sigma_r_mo)

    Gles_mo = np.dot(np.dot(Gr_approx_mo, GamL_mo), Gr_approx_mo.T.conj())
    Gles_mo *= bias
    np.save(path + data_basename + "matrices_dV_mo.npy",
            [Gr_approx_mo, Gles_mo, GamL_mo])

    utils_zcolor.plot_complex_matrix(Gles_mo, path + "Gles_mo")

    Tt_mo = np.dot(np.dot(np.dot(GamL_mo, Gr_approx_mo), GamR_mo),
                   Gr_approx_mo.T.conj())
    current_dV_mo = (bias / (2 * np.pi)) * Tt_mo.trace()  # Single spin current
    np.save(path + "data/trans_dV_mo.npy", [ef, Tt_mo.trace()])
    np.save(path + "data/current_dV_mo.npy", current_dV_mo)

    # Non corrected current - MO basis
    mlt_mo = 1j * Gles_mo / (4 * np.pi)
    np.save(path + "data/Gles_dV_mo.npy", mlt_mo)

    print("Calculating gradient..")
    print("Calculating real part of current")
    current_c, jx, jy, jz = Gradient().jc_current(mo_phi_xg, mlt_mo.real, dx,
                                                  dy, dz)
    dims = phi_xg.shape
    jx = np.reshape(jx, dims[1:])
    jy = np.reshape(jy, dims[1:])
    jz = np.reshape(jz, dims[1:])

    np.save(
        path + "data/" + "current_all.npy",
        [jx, jy, jz, x_cor, y_cor, z_cor],
    )
    np.save(path + data_basename + "current_c.npy", current_c)

    SI = 31
    EI = -31
    print(f"jz shape: {jz.shape}")
    jx_cut = jx[:, :, SI:EI]
    jy_cut = jy[:, :, SI:EI]
    jz_cut = jz[:, :, SI:EI]
    print(f"jz_cut shape: {jz_cut.shape}")
    cut_off = jz_cut.max() / cutoff
    multiplier = 1 / (2 * np.sqrt(jx_cut**2 + jy_cut**2 + jz_cut**2).max())

    # Sixth last arg is the divider for the real space grid, multiplier gives a thicker diameter
    print("Writing .spt files..")
    utils_zcolor.plot_current(jx, jy, jz, x_cor, y_cor, z_cor,
                              path + "current", grid_size, multiplier, cut_off,
                              path, align1, align2)

    utils_zcolor.plot_convergence()