Ejemplo n.º 1
0
def smooth_selfenergy(it, h5, SelfEnergy, nf):
    parms = load_parms(h5, it);
    N_LAYERS = int(parms['N_LAYERS']); FLAVORS = int(parms['FLAVORS']); 
    SPINS = size(nf, 0);   # this SPINS may be different from parms['SPINS']
    NCOR = int(parms['NCOR']);

    # calculate asymptotic coeffs and smooth
    se_coefs = zeros((SPINS, 2, NCOR), dtype = float);
    for L in range(N_LAYERS): 
        st='SolverData/Observables/%d/L%d'%(it, L);
        try: nn = h5[st+'/nn'][:];
        except: nn = None;
        se_coefs[:, :, L::N_LAYERS] = get_asymp_selfenergy(parms, nf[:, L::N_LAYERS], nn);
    if int(val_def(parms, 'USE_SELFENERGY_TAIL', 0)) > 0:
        minorder = 0
        se_coefs = None

        for L in range(N_LAYERS): 
            st='SolverData/Observables/%d/L%d'%(it, L);
            se_tail = h5[st+'/SelfEnergyTail'][:]
            minorder = se_tail[0, 0]
            maxorder = se_tail[-1, 0]
            se_tail = se_tail[1:-1]
            if se_coefs is None: se_coefs = zeros((SPINS, maxorder-minorder+1, NCOR))
            for n in range(len(se_tail)):
                tail = se_tail[n].reshape(-1, 2)
                if SPINS == 1: tail = [mean(tail, 1)]
                for s in range(SPINS): 
                    se_coefs[s, n, L::N_LAYERS] = tail[s]
    elif int(parms.get('FIT_SELFENERGY_TAIL', 1)) > 0:
        n_max_freq = int(parms['N_MAX_FREQ'])
        n_cutoff = int(parms['N_CUTOFF'])
        n_fit_stop = n_cutoff + 5
        n_fit_start = n_cutoff - 5
        wn = (2*arange(n_max_freq)+1)*pi/float(parms['BETA'])
        for f in range(NCOR):
            for s in range(SPINS):
                x_fit = wn[n_fit_start:n_fit_stop]
                y_fit = x_fit*SelfEnergy[s, n_fit_start:n_fit_stop, f].imag
                p = polyfit(x_fit, y_fit, 0)
                se_coefs[s, 1, f] = -p[0]
    log_data(h5['SolverData'], 'selfenergy_asymp_coeffs', it, se_coefs.flatten(), data_type = float);
    list_NCutoff = ones((SPINS, NCOR), dtype = int)*int(parms['N_CUTOFF']);
    ind = SelfEnergy.imag > 0;
    SelfEnergy[ind] = real(SelfEnergy[ind]);
    return smooth(SelfEnergy, se_coefs, int(parms['N_MAX_FREQ']), float(parms['BETA']), list_NCutoff, minorder = 0);
Ejemplo n.º 2
0
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