示例#1
0
文件: solver.py 项目: hungdt/scf_dmft
def solver_post_process(parms, aWeiss, h5, tmph5filename):
    N_LAYERS = int(parms["N_LAYERS"])
    FLAVORS = int(parms["FLAVORS"])
    NCOR = int(parms["NCOR"])
    SPINS = 2
    # NOTE: for collecting all spins, symmetrize them later if neccessary
    if len(aWeiss) == 1:
        aWeiss = r_[aWeiss, aWeiss]
        # SPINS = 1 case
    dmft_id = system.getDMFTCorrIndex(parms)

    if not os.path.isfile(tmph5filename):
        print >> sys.stderr, "File %s not found" % tmph5filename
        return None
    tmph5 = h5py.File(tmph5filename, "r")
    if tmph5["L"][1] < N_LAYERS:
        print >> sys.stderr, "Unfinish solving the impurity model"
        return None

    # save data from temporary file
    h5solver = h5["SolverData"]
    it = tmph5["L"][0]
    MEASURE_freq = True if "Gw" in tmph5 else False

    for s in tmph5["Observables"]:
        new_group_str = "Observables/%d/%s" % (it, s)
        for k in tmph5["Observables/%s" % s]:
            v = tmph5["Observables/%s/%s" % (s, k)]
            try:
                h5solver.create_dataset(new_group_str + "/" + k, v.shape, dtype=v.dtype, data=v)
            except:
                h5solver[new_group_str + "/" + k][:] = v

    Gmat = zeros((SPINS, int(parms["N_MAX_FREQ"]), NCOR), dtype=complex)
    Smat = zeros((SPINS, int(parms["N_MAX_FREQ"]), NCOR), dtype=complex)
    Ntau = max(int(parms["N_TAU"]) / 20, 400) + 1
    Htau = tmph5["Hybtau"][:, ::20, :]

    # the updated density: for DMFT bands, get from Gtau, for inert bands, get from Gavg of previous iteration
    nf = h5["log_density"][0 if int(val_def(parms, "FIXED_HARTREE", 0)) > 0 else it - 1, 4:].reshape(-1, NCOR + 1)
    if len(nf) == 1:
        nf = r_[nf, nf]
    nf = nf[:, :NCOR]
    nf[:, dmft_id] = -assign(tmph5["Gtau"][-1, :], N_LAYERS)

    # get raw Gmat and Smat
    for f in range(size(tmph5["Gtau"], 1)):
        g = cppext.FT_tau2mat(tmph5["Gtau"][:, f].copy(), float(parms["BETA"]), int(parms["N_MAX_FREQ"]))
        try:
            tmp = c_[tmp, g]
        except:
            tmp = g.copy()
    Gmat[:, :, dmft_id] = assign(tmp, N_LAYERS)
    Smat[:, :, dmft_id] = aWeiss[:, :, dmft_id] - 1 / Gmat[:, :, dmft_id]
    if MEASURE_freq:
        nfreq = size(tmph5["Gw"][:], 0)
        Gmat[:, :nfreq, dmft_id] = assign(tmph5["Gw"], N_LAYERS)
        Stmp = assign(tmph5["Sw"], N_LAYERS)
        # adjust self energy measured using improved estimator
        # with contribution from inertial d-bands
        for L in range(N_LAYERS):
            SE_inert = get_inert_band_HF(parms, nf[:, L::N_LAYERS])
            Stmp[0, :, L::N_LAYERS] += SE_inert[0]
            Stmp[1, :, L::N_LAYERS] += SE_inert[1]
        Smat[:, :nfreq, dmft_id] = Stmp

    # symmetrize orbital and spin if necessary
    paraorb = [int(s) for s in val_def(parms, "PARAORBITAL", "").split()]
    if len(paraorb) == 1:
        if paraorb[0] > 0:
            if parms["DTYPE"] == "3bands":
                paraorb = [[0, 1, 2]]
                # t2g only HARD CODE
            else:
                paraorb = [[0, 3], [1, 2, 4]]
                # t2g and eg HARD CODE
        else:
            paraorb = []
    if len(paraorb) > 0:
        if type(paraorb[0]) != list:
            paraorb = [paraorb]
        print "Symmetrize over orbital ", paraorb
        for L in range(N_LAYERS):
            for s in range(SPINS):
                for sym_bands in paraorb:
                    gm = zeros(size(Gmat, 1), dtype=complex)
                    sm = zeros(size(Smat, 1), dtype=complex)
                    nf_tmp = 0.0
                    for f in sym_bands:
                        gm += Gmat[s, :, L + f * N_LAYERS]
                        sm += Smat[s, :, L + f * N_LAYERS]
                        nf_tmp += nf[s, L + f * N_LAYERS]
                    for f in sym_bands:
                        Gmat[s, :, L + f * N_LAYERS] = gm / float(len(sym_bands))
                        Smat[s, :, L + f * N_LAYERS] = sm / float(len(sym_bands))
                        nf[s, L + f * N_LAYERS] = nf_tmp / float(len(sym_bands))
    if int(parms["SPINS"]) == 1:
        print "Symmetrize over spins"
        Gmat = array([mean(Gmat, 0)])
        Smat = array([mean(Smat, 0)])
        nf = array([mean(nf, 0)])

    # smooth Gmat and Smat
    SPINS = int(parms["SPINS"])
    Smat = smooth_selfenergy(it, h5, Smat, nf)
    NCutoff = int(parms["N_CUTOFF"])
    Gmat[:, NCutoff:, :] = 1.0 / (aWeiss[:SPINS, NCutoff:, :] - Smat[:, NCutoff:, :])

    # calculate Gtau from Gmat (after symmtrization)
    Gtau = zeros((SPINS, Ntau, NCOR), dtype=float)
    S0 = zeros((SPINS, NCOR))
    for L in range(N_LAYERS):
        S0[:, L::N_LAYERS] = get_asymp_selfenergy(parms, nf[:, L::N_LAYERS])[:, 0, :]
    for s in range(SPINS):
        for f in range(NCOR):
            if f not in dmft_id:
                Smat[s, :, f] = S0[s, f]
                Gmat[s, :, f] = 1.0 / (aWeiss[s, :, f] - Smat[s, :, f])
            Gtau[s, :, f] = cppext.IFT_mat2tau(Gmat[s, :, f].copy(), Ntau, float(parms["BETA"]), 1.0, 0.0)

    Gtau[:, 0, :] = -(1.0 - nf)
    Gtau[:, -1, :] = -nf

    # saving data
    dT = 5
    Nb2 = size(tmph5["Gtau"], 0) / 2
    Gb2 = array([mean(tmph5["Gtau"][Nb2 - dT : Nb2 + dT, f], 0) for f in range(size(tmph5["Gtau"], 1))])
    log_data(h5solver, "log_Gbeta2", it, Gb2.flatten(), data_type=float)
    log_data(h5solver, "log_nsolve", it, -tmph5["Gtau"][-1, :].flatten(), data_type=float)
    log_data(h5solver, "hyb_asym_coeffs", it, tmph5["hyb_asym_coeffs"][:].flatten(), data_type=float)
    save_data(h5solver, it, ("Gtau", "Hybtau", "Hybmat"), (Gtau, Htau, tmph5["Hybmat"][:]))
    tmph5.close()
    del tmph5
    os.system("rm %s" % tmph5filename)
    return Gmat, Smat
示例#2
0
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;