def getGavgFromSelfEnergy(parms, se_filename = None): N_LAYERS = int(parms['N_LAYERS']); FLAVORS = int(parms['FLAVORS']); SPINS = int(parms['SPINS']); parms['BETA'] = 10; # prepare data NMaxFreq = int(parms['N_MAX_FREQ']); if se_filename is not None: print 'load self energy from file: ', se_filename; tmp = genfromtxt(se_filename); if NMaxFreq > len(tmp): NMaxFreq = len(tmp); w = tmp[:,0] + 1j*float(parms['BROADENING']); tmp = tmp[:, 1:]; tmp = tmp[:NMaxFreq, 0::2] + 1j*tmp[:NMaxFreq, 1::2]; se = zeros((SPINS, NMaxFreq, N_LAYERS*FLAVORS), dtype = complex); for s in range(SPINS): for f in range(N_LAYERS*FLAVORS): se[s, :, f] = tmp[:, SPINS*f+s]; else: se = zeros((SPINS, NMaxFreq, N_LAYERS*FLAVORS), dtype = complex); w = linspace(float(parms['EMIN']), float(parms['EMAX']), NMaxFreq) + 1j*float(parms['BROADENING']); # tight binding Hamiltonian HR, R = getHamiltonian(parms['RHAM'], 4); parms['NORB'] = len(HR[0]) extra = { 'HR' : HR, 'R': R }; if int(val_def(parms, 'FORCE_DIAGONAL', 0)) > 0: print 'FORCE_DIAGONAL is used'; ind = nonzero(sum(R**2, 1)==0)[0][0]; H0 = HR[ind]; else: H0 = None; rot_mat = getRotationMatrix(N_LAYERS, FLAVORS, val_def(parms, 'ROT_MAT', None), H0); # prepare for k-integrate bp, wf = grule(int(parms['NUMK'])); extra.update({ 'GaussianData' : [bp, wf], 'rot_mat' : rot_mat }); delta = float(parms['DELTA']); mu = float(parms['MU']); # running Gavg = averageGreen(delta, mu, w, se, parms, -1, -1, 0, extra)[1]; # swap the Gavg to the format of my code # swap_vec = zeros((2, N_LAYERS*FLAVORS), dtype = int); # for L in range(N_LAYERS): # for f in range(FLAVORS): swap_vec[:,f*N_LAYERS+L] = array([f*N_LAYERS+L, L*FLAVORS+f]); # for s in range(SPINS): Gavg[s, :, swap_vec[1]] = Gavg[s, :, swap_vec[0]]; spec = -1/pi * Gavg.imag; if SPINS == 1: savetxt('spec.dat', c_[w.real, spec[0]]); elif SPINS > 1: savetxt('spec_up.dat', c_[w.real, spec[0]]); savetxt('spec_dn.dat', c_[w.real, spec[1]]);
def getSpectraFromSelfEnergy(h5, se_filename, rham, rotmat, numk = None, setail_filename = None, it = 0): # prepare data w, se_refreq = ProcessSelfEnergy(se_filename, emin = -5, emax = 5, NFreq = 500); it = h5['iter'][0] - it; parms = load_parms(h5, it); print 'work on iteration ', it; if rham is not None: print 'new path for rham file is: ', rham; parms['RHAM'] = rham; if rotmat is not None: print 'new path for rot_mat file is ', rotmat; parms['ROT_MAT'] = rotmat; BETA = float(parms['BETA']); N_LAYERS = int(parms['N_LAYERS']); FLAVORS = int(parms['FLAVORS']); SPINS = int(parms['SPINS']); NORB = int(parms['NORB']); dmft_id = system.getDMFTCorrIndex(parms, all = False); dmft_id_len = len(dmft_id); # get the se tails tmp = h5['SolverData/selfenergy_asymp_coeffs'][:]; se_tail = tmp[tmp[:,0] == it, 1:].reshape(SPINS, 2, -1)[:, :, ::N_LAYERS]; if setail_filename is not None: print 'use the tail from external source: ', setail_filename; tmp = genfromtxt(setail_filename); se_tail[:, :, dmft_id] = array([tmp[:, s::SPINS] for s in range(SPINS)]); print se_tail; # restore SelfEnergy se = zeros((SPINS, len(se_refreq), N_LAYERS*FLAVORS), dtype = complex); for s in range(SPINS): for f in range(N_LAYERS*FLAVORS): if f/N_LAYERS not in dmft_id: se[s,:,f] = se_tail[s, 0, f/N_LAYERS]; else: f1 = nonzero(f/N_LAYERS == dmft_id)[0][0]; se[s, :, f] = se_refreq[:, SPINS*f1+s]*se_tail[s, 1, f/N_LAYERS] + se_tail[s, 0, f/N_LAYERS]; # tight binding Hamiltonian if 'RHAM' in parms: HR, R = getHamiltonian(parms['RHAM'], 4); if parms['DTYPE'] == '3bands': FLAVORS = 3; extra = { 'HR' : HR, 'R': R }; # rotation matrix if int(val_def(parms, 'FORCE_DIAGONAL', 0)) > 0: print 'FORCE_DIAGONAL is used'; ind = nonzero(sum(R**2, 1)==0)[0][0]; H0 = HR[ind]; else: H0 = None; rot_mat = getRotationMatrix(N_LAYERS, FLAVORS, val_def(parms, 'ROT_MAT', None), H0); # prepare for k-integrate parms['NUMK'] = 16 if numk is None else numk; bp, wf = grule(int(parms['NUMK'])); broadening = 0.01; extra.update({ 'GaussianData' : [bp, wf], 'rot_mat' : rot_mat }); delta = float(parms['DELTA']); mu = float(parms['MU']); # running print 'generating interacting DOS with parameters' for k, v in parms.iteritems(): print '%s = %s'%(k, v); Gr = averageGreen(delta, mu, w+1j*broadening, se, parms, float(parms['ND']), float(parms['DENSITY']), 0, extra)[1]; if SPINS == 1: savetxt(parms['ID']+'.idos', c_[w, -1/pi*Gr[0].imag], fmt = '%g'); elif SPINS == 2: savetxt(parms['ID']+'_up.idos', c_[w, -1/pi*Gr[0].imag], fmt = '%g'); savetxt(parms['ID']+'_dn.idos', c_[w, -1/pi*Gr[1].imag], fmt = '%g'); # calculate original G(iwn), only consider one "LAYERS" Giwn_orig = h5['ImpurityGreen/%d'%it][:,:,::N_LAYERS]; NMatsubara = size(Giwn_orig, 1); wn = (2*arange(NMatsubara) + 1)*pi/BETA; Giwn = zeros((NMatsubara, 2*FLAVORS*SPINS), dtype = float); # 2 for real and imag for f in range(FLAVORS): for s in range(SPINS): Giwn[:, 2*(SPINS*f+s)] = Giwn_orig[s, :, f].real; Giwn[:, 2*(SPINS*f+s)+1] = Giwn_orig[s, :, f].imag; savetxt(parms['ID']+'.gmat', c_[wn, Giwn]); # calculate G(iwn) for reference, only consider one "LAYERS" NMatsubara = 200; wn = (2*arange(NMatsubara) + 1)*pi/BETA; Giwn = zeros((NMatsubara, 2*FLAVORS*SPINS), dtype = float); # 2 for real and imag for f in range(FLAVORS): for s in range(SPINS): A = -1/pi * Gr[s, :, f*N_LAYERS].imag; for n in range(NMatsubara): tck_re = splrep(w, real(A / (1j*wn[n] - w))); tck_im = splrep(w, imag(A / (1j*wn[n] - w))); Giwn[n, 2*(SPINS*f+s)] = splint(w[0], w[-1], tck_re); Giwn[n, 2*(SPINS*f+s)+1] = splint(w[0], w[-1], tck_im); savetxt(parms['ID']+'.gmat.ref', c_[wn, Giwn]);
def HartreeRun(parms, extra): print "Initialization using Hartree approximation\n" N_LAYERS = int(parms['N_LAYERS']); FLAVORS = int(parms['FLAVORS']); SPINS = 1; p = dict({ 'MU' : float(val_def(parms, 'MU', 0)), 'N_LAYERS': N_LAYERS, 'NORB' : int(parms['NORB']), 'U' : float(parms['U']), 'J' : float(parms['J']), 'DELTA': float(val_def(parms, 'DELTA', 0)), 'ND' : N_LAYERS*float(val_def(parms, 'ND', -1)), 'DENSITY' : N_LAYERS*float(parms['DENSITY']), 'FLAVORS' : FLAVORS, 'SPINS' : 1, 'OUTPUT' : '.' + parms['DATA_FILE'] + '_HartreeInit', 'NN' : None, 'N_MAX_FREQ' : 30, 'BETA' : float(parms['BETA']), 'NUMK' : int(val_def(parms, 'INIT_NUMK', 8)), 'TUNEUP' : int(val_def(parms, 'NO_TUNEUP', 0)) == 0, 'MAX_ITER' : 15, 'ALPHA' : 0.5, # pay attention at this parm sometimes 'DTYPE' : parms['DTYPE'], 'INTEGRATE_MOD' : val_def(parms, 'INTEGRATE_MOD', 'integrate'), 'np' : parms['np'] }); for k, v in p.iteritems(): print k + ': ', v; bp, wf = grule(p['NUMK']); X, W = generateGaussPoints(p['N_MAX_FREQ']); wn = 1/sqrt(X)/p['BETA']; p.update({ 'X' : X, 'W' : W, 'w' : wn }); if p['NN'] is None and os.path.isfile(p['OUTPUT']+'.nn'): p['NN'] = p['OUTPUT']; # running TOL = 1e-2; if p['NN'] is None: nn = ones(N_LAYERS*FLAVORS, dtype = 'f8') * p['DENSITY']/p['NORB']/2; # 2 for spin mu = p['MU']; delta = p['DELTA']; else: print 'Continue from '+p['NN']; nn = genfromtxt(p['NN']+'.nn')[2:]; mu = genfromtxt(p['NN']+'.nn')[1]; delta = genfromtxt(p['NN']+'.nn')[0]; Gavg = zeros((p['N_MAX_FREQ'], p['NORB']), dtype = 'c16'); se = zeros((SPINS, p['N_MAX_FREQ'], N_LAYERS*FLAVORS), dtype = 'c16'); stop = False; count = 0; ALPHA = p['ALPHA']; corr1 = system.getDMFTCorrIndex(parms, all = False); corr2 = array([i for i in range(FLAVORS) if i not in corr1]); # index for eg bands old_GaussianData = extra['GaussianData']; extra['GaussianData'] = [bp, wf]; while not stop: count += 1; nn_old = nn.copy(); p['MU'] = mu; p['DELTA'] = delta; Gavg_old = Gavg.copy(); for L in range(N_LAYERS): se_coef = functions.get_asymp_selfenergy(p, array([nn[L:N_LAYERS*FLAVORS:N_LAYERS]]))[0, 0, :]; for s in range(SPINS): for f in range(len(se_coef)): se[s, :, f*N_LAYERS+L] = se_coef[f]; Gavg, delta, mu, Vc = averageGreen(delta, mu, 1j*wn, se, p, p['ND'], p['DENSITY'], p['TUNEUP'], extra); Gavg = mean(Gavg, 0); nn = getDensity(Gavg, p); # no spin/orbital polarization, no charge order for L in range(N_LAYERS): nf1 = nn[0:N_LAYERS*FLAVORS:N_LAYERS]; for id in range(FLAVORS): if id in corr1: nf1[id] = mean(nf1[corr1]); else: nf1[id] = mean(nf1[corr2]); nn[L:N_LAYERS*FLAVORS:N_LAYERS] = nf1; err = linalg.norm(r_[delta, mu, nn] - r_[p['DELTA'], p['MU'], nn_old]); savetxt(p['OUTPUT']+'.nn', r_[delta, mu, nn]); print 'Step %d: %.5f'%(count, err); if (err < TOL): stop = True; print 'converged'; if count > p['MAX_ITER']: break; mu = ALPHA*mu + (1-ALPHA)*p['MU']; delta = ALPHA*delta + (1-ALPHA)*p['DELTA']; nn = ALPHA*nn + (1-ALPHA)*nn_old; # DOS NFREQ = 500; BROADENING = 0.03; extra['GaussianData'] = old_GaussianData; parms_tmp = parms.copy(); parms_tmp['DELTA'] = delta; Eav = system.getAvgDispersion(parms_tmp, 3, extra)[0,0,:]; Ed = mean(Eav[:N_LAYERS*FLAVORS][corr1]); Ep = mean(Eav[N_LAYERS*FLAVORS:]) if N_LAYERS*FLAVORS < p['NORB'] else Ed; emax = min(4, p['U']); emin = -(Ed - Ep + max(se_coef) + min(4, p['U'])); print "Energy range for HF DOS: ", emin, emax w = linspace(emin, emax, NFREQ) + 1j*BROADENING; se = zeros((SPINS, NFREQ, N_LAYERS*FLAVORS), dtype = 'c16'); for L in range(N_LAYERS): se_coef = functions.get_asymp_selfenergy(p, array([nn[L:N_LAYERS*FLAVORS:N_LAYERS]]))[0, 0, :]; for s in range(SPINS): for f in range(len(se_coef)): se[s, :, f*N_LAYERS+L] = se_coef[f]; Gr = average_green.averageGreen(delta, mu, w, se, p,p['ND'], p['DENSITY'], 0, extra)[1][0]; savetxt(parms['ID']+'.dos', c_[w.real, -1/pi*Gr.imag], fmt = '%.6f'); print ('End Hartree approx.:%d Ntot=%.2f Nd=%.2f Delta=%.4f ' 'Delta_eff=%.4f')%(count, 2*sum(nn)/N_LAYERS, 2*sum(nn[:N_LAYERS*FLAVORS]/N_LAYERS), delta, delta-mean(se_coef[corr1])), ': \n', \ nn[:N_LAYERS*FLAVORS].reshape(-1, N_LAYERS),\ '\n\n' # os.system('rm ' + p['OUTPUT']+'.nn'); return delta, mu, array([nn for s in range(int(parms['SPINS']))]), Vc;
def initialize(h5file, parms): if parms['ID'] in h5file.keys(): # group exists h5 = h5file[parms['ID']]; it = h5["iter"][0]; if it < 0: del h5file[parms['ID']]; else: parms1 = parms.copy(); # not allow to change these fixed parameters for s in ('DELTA', 'U', 'J', 'UJRAT', 'BETA'): if s in parms1: del parms1[s]; parms = load_parms(h5, it+1); for k, v in parms1.iteritems(): try: if parms[k] != parms1[k]: parms[k] = parms1[k]; except: parms[k] = parms1[k]; # NOTE: basic information for the structure N_LAYERS = int(parms['N_LAYERS']); SPINS = int(val_def(parms, 'SPINS', 2)); if int(val_def(parms, 'PARAMAGNET', 0)) > 0: SPINS = 1; DENSITY = N_LAYERS*float(parms['DENSITY']); BETA = float(parms["BETA"]); Nd = N_LAYERS*float(val_def(parms, 'ND', -1)); if 'DTYPE' not in parms: parms['DTYPE'] = ''; if 'RHAM' in parms: FLAVORS = 5; # 5 d-bands HR, R = getHamiltonian(parms['RHAM'], 4); # max distance is 4 NORB = len(HR[0]); if parms['DTYPE'] == '3bands': FLAVORS = 3; else: FLAVORS = int(parms['FLAVORS']); NORB = int(parms['NORB']); if int(val_def(parms, 'AFM', 0)) > 0: print 'This is AFM self consistent loop!'; if SPINS == 1: exit('SPINS must be 2 for AFM calculation'); if int(val_def(parms, 'FORCE_DIAGONAL', 0)) > 0: print 'FORCE_DIAGONAL is used'; ind = nonzero(sum(R**2, 1)==0)[0][0]; H0 = HR[ind]; else: H0 = None; rot_mat = getRotationMatrix(N_LAYERS, FLAVORS, val_def(parms, 'ROT_MAT', None), H0); if 'MAX_FREQ' in parms.keys(): parms['N_MAX_FREQ'] = int(round((BETA*float(parms['MAX_FREQ'])/pi - 1)/2.)); if 'N_CUTOFF' not in parms.keys(): cutoff_factor = float(val_def(parms, 'CUTOFF_FACTOR', 7)); parms['N_CUTOFF'] = int(round((BETA/pi*float(val_def(parms,'CUTOFF_FREQ', cutoff_factor*float(parms['U']))) - 1)/2.)); parms['CUTOFF_FREQ'] = (2*int(parms['N_CUTOFF'])+1)*pi/BETA; parms['MAX_FREQ'] = (2*int(parms['N_MAX_FREQ'])+1)*pi/BETA; parms['FLAVORS'] = FLAVORS; # mixing mixer = Mixing(float(val_def(parms, "MIXING", 1)), int(val_def(parms, 'MIXING_FIXED', 1))); mixer_SE = Mixing(float(val_def(parms, "MIXING", 1)), int(val_def(parms, 'MIXING_FIXED', 1))); wn = (2*arange(int(parms['N_MAX_FREQ']))+1)*pi/BETA; extra = { 'correction' : zeros(SPINS), 'GaussianData' : grule(int(val_def(parms, 'NUMK', 30))), 'rot_mat' : rot_mat }; if 'RHAM' in parms: extra.update({'HR' : HR, 'R' : R }); else: extra.update({ 'tight_binding_parms' : array([float(s) for s in parms['TB_PARMS'].split()]) }); corr_id = system.getCorrIndex(parms); NCOR = len(corr_id); if not parms['ID'] in h5file.keys(): it = 0; # create main group ID and its subgroups h5 = h5file.create_group(parms['ID']); h5.create_dataset("iter", (1,), int, data = -1); crt_tuple = ("ImpurityGreen", "avgGreen", "SelfEnergy", "WeissField", "parms", "StaticCoulomb", "SolverData", "SolverData/Gtau", "SolverData/Hybmat", "SolverData/Hybtau", "SolverData/Observables"); for obj in crt_tuple: h5.create_group(obj); parms['SPINS'] = SPINS; parms['NORB'] = NORB; parms['ND'] = Nd/float(N_LAYERS); parms['NCOR'] = NCOR; parms['N_TAU'] = val_def(parms, 'N_TAU', 400); if 'UJRAT' in parms.keys(): parms['J'] = float(parms['U']) / float(parms['UJRAT']); # generate initial conditions if 'USE_DATAFILE' in parms.keys(): print 'Get initial data from file ' + parms['USE_DATAFILE']; is_hdf5 = True if os.path.abspath(parms['USE_DATAFILE']) != os.path.abspath(parms['DATA_FILE']): try: g5file = h5py.File(parms['USE_DATAFILE'], 'r'); g5 = g5file[val_def(parms, 'USE_DATAFILE_ID', g5file.keys()[0])]; except: is_hdf5 = False else: g5file = None; g5 = h5file[val_def(parms, 'USE_DATAFILE_ID', h5file.keys()[0])]; if is_hdf5: g5it = g5['iter'][0]; parms['MU'] = val_def(parms, 'MU0', str(g5['parms/%d/MU'%(g5it+1)][...])); parms['DELTA'] = val_def(parms, 'DELTA', str(g5['parms/%d/DELTA'%(g5it+1)][...])); SelfEnergy, se_coef = get_self_energy_hdf5(g5, parms, wn) if not g5file is None: g5file.close(); del g5file, g5; else: parms['MU'] = val_def(parms, 'MU0', 0); parms['DELTA'] = val_def(parms, 'DELTA', 0); SelfEnergy, se_coef = get_self_energy_text(parms['USE_DATAFILE'], parms, wn) else: SelfEnergy = zeros((SPINS, int(parms["N_MAX_FREQ"]), NCOR), dtype = complex); if int(val_def(parms, 'HARTREE_INIT', 0)) == 1: delta, mu, nf, VCoulomb = hartree.HartreeRun(parms, extra); nf = nf[:, corr_id]; parms['MU'] = mu; parms['DELTA'] = delta; else: mu = float(val_def(parms, 'MU0', 0)); # don't know which default MU is good delta = float(val_def(parms, 'DELTA', 0)); parms['MU'] = mu; parms['DELTA'] = delta; Gavg, Gavg0, delta, mu, VCoulomb = averageGreen(delta, mu, 1j*wn, SelfEnergy, parms, Nd, DENSITY, False, extra); nf = getDensityFromGmat(Gavg, BETA, extra); se_coef = zeros((SPINS, 2, NCOR), dtype = float); for L in range(N_LAYERS): se_coef[:, :, L::N_LAYERS] = get_asymp_selfenergy(parms, nf[:, L::N_LAYERS]); for s in range(SPINS): for f in range(NCOR): SelfEnergy[s, :, f] = se_coef[s, 0, f]; if int(val_def(parms, 'NO_TUNEUP', 0)) == 0: parms['MU'] = mu; parms['DELTA'] = delta; log_data(h5['SolverData'], 'selfenergy_asymp_coeffs', it, se_coef.flatten(), data_type = float); save_data(h5, it, ['SelfEnergy'], [SelfEnergy]); save_parms(h5, it, parms); save_parms(h5, it+1, parms); # get average dispersion up to nth order NthOrder = 3; dispersion_avg = system.getAvgDispersion(parms, NthOrder, extra); h5.create_dataset('SolverData/AvgDispersion', dispersion_avg.shape, dtype = float, data = dispersion_avg); h5["iter"][...] = it; # this is the mark that iteration 'it' is done return { 'parms' : parms, 'h5' : h5, 'mixer' : mixer, 'mixer_SE': mixer_SE, 'extra' : extra, 'N_LAYERS': N_LAYERS, 'NCOR' : NCOR, 'Nd' : Nd, 'DENSITY' : DENSITY, 'wn' : wn, 'corr_id' : corr_id }
print ' %s=%s'%('N_CUTOFF', str(parms['N_CUTOFF'])) time_spent = time.time(); print "ITERATION: %d\n"%it; # average over k-space for Gavg then produce Weiss field # use Gauss quadrature with C++ extension code # mixing self energy tmp = mixer_SE.do_task(r_[SelfEnergy_out.real.flatten(), SelfEnergy_out.imag.flatten()]).reshape(2, -1); SelfEnergy_in = (tmp[0] + 1j*tmp[1]).reshape(SelfEnergy_out.shape); mu_orig = mu_in; delta_orig = delta_in; if str(it) not in h5['WeissField']: print "Tedious part: averaging Green function"; extra.update(system.getInfoForDensityCalculation(h5, it-1)); print 'Density correction = \n', extra['correction'][:, :NCOR]; Gavg, Gavg0, delta_out, mu_out, VCoulomb = averageGreen(delta_in, mu_in, 1j*wn, SelfEnergy_in, parms, Nd, DENSITY, int(val_def(parms, 'NO_TUNEUP', 0)) == 0, extra); delta_in, mu_in = mixer.do_task(r_[delta_out, mu_out]); if mu_in != mu_out or delta_in != delta_out: print 'There is mixing, average Green function once more'; extra['G_asymp_coefs'][:N_LAYERS*int(parms['FLAVORS'])] -= delta_out - delta_in; extra['G_asymp_coefs'] -= mu_out - mu_in; Gavg, Gavg0, delta_in, mu_in, VCoulomb = averageGreen(delta_in, mu_in, 1j*wn, SelfEnergy_in, parms, Nd, DENSITY, False, extra); parms["DELTA"] = delta_in; parms["MU"] = mu_in; # just want MU shown in log_density corresponding to nf nf = getDensityFromGmat(Gavg0, float(parms['BETA']), extra); nf = c_[nf[:,:NCOR], sum(nf[:,NCOR:], 1)]; log_density(h5, it-1, parms, nf); parms["DELTA"] = delta_in; parms["MU"] = mu_in;