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