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 }
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;
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; h5['parms/%d/DELTA'%it][...] = str(delta_in); h5['parms/%d/MU'%it][...] = str(mu_in); aWeiss = 1./Gavg[:, :, corr_id] + SelfEnergy_in; save_data(h5, it, ['avgGreen', 'WeissField', 'StaticCoulomb'], [Gavg0, aWeiss, VCoulomb]); NthOrder = 3; dispersion_avg = system.getAvgDispersion(parms, NthOrder, extra); h5['SolverData/AvgDispersion'][:] = dispersion_avg; else: Gavg0 = h5['avgGreen/%d'%it][:]; aWeiss = h5['WeissField/%d'%it][:]; VCoulomb = h5['StaticCoulomb/%d'%it][:]; time_spent = r_[time_spent, time.time()]; # run the solver here and get Gimp # need: path for data file, iteration number, layer index if str(it) not in h5['SelfEnergy']: print "Tedious part: Running impurity solver %d times"%N_LAYERS; dispersion_avg = h5['SolverData/AvgDispersion'][:];