Exemplo n.º 1
0
def averageGreen(delta0, mu0, w, SelfEnergy, parms, Nd, Ntot, tuneup, extra):
    BETA     = float(parms["BETA"]);
    N_LAYERS = int(parms['N_LAYERS']); FLAVORS = int(parms['FLAVORS']); SPINS = int(parms['SPINS']);
    rot_mat = extra['rot_mat'];
    
    # calculate intersite Coulomb energy here
    Vc = zeros(N_LAYERS, dtype = 'f8');

    # convert self energy to the C++ form
    SelfEnergy_rot = array([functions.irotate(SelfEnergy[s], extra['rot_mat']) for s in range(SPINS)]);
    SE = [array([s.flatten() for s in SelfEnergy_rot[n]]) for n in range(SPINS)];

    v_delta = empty(0, 'f8');
    v_nd    = empty(0, 'f8');
    ddelta = 0.; delta_step = 1.;
    dmu = 0.; mu_step = 5; 
    tol = 0.005;
    # Delta loop
    while True:
        delta = delta0 + ddelta;

        v_mu = empty(0, 'f8');
        v_n = empty(0, 'f8');
        # mu loop
        while True:
            mu = mu0 + dmu;
            
            Gavg = average_green.integrate(w, delta, mu, SE, parms, extra);
            Gavg_diag = array([Gavg[0, :, i, i] for i in range(int(parms['NORB']))]).T;
            nf = getDensity(Gavg_diag, parms); 
            my_ntot = 2*sum(nf); # factor of 2 due to spin
    
            if tuneup: print "   adjust mu: " + str(mu) + " " + str(dmu) + " " + str(my_ntot);
            if Ntot < 0 or abs(Ntot - my_ntot) < tol or not tuneup: break;
     
            v_mu = r_[v_mu, dmu];
            v_n = r_[v_n, my_ntot];
            if v_n.min() < Ntot and v_n.max() > Ntot: dmu = interp_root(v_mu, v_n, Ntot);
            else: dmu += (1. if my_ntot < Ntot else -1.)*mu_step;
           
        my_nd = 2*sum(nf[:N_LAYERS*FLAVORS]);

        if tuneup: print "adjust double counting: " + str(delta) + " " + str(ddelta) + " " + str(my_nd) + " " + str(my_nd/N_LAYERS);
        if Nd < 0 or abs(Nd - my_nd) < tol or not tuneup: break;

        v_delta = r_[v_delta, ddelta];
        v_nd = r_[v_nd, my_nd];
        if v_nd.min() < Nd and v_nd.max() > Nd: ddelta = interp_root(v_delta, v_nd, Nd);
        else: ddelta += (1. if my_nd < Nd else -1.)*delta_step;

    Gavg = array([functions.rotate_all(Gavg[s], rot_mat) for s in range(SPINS)]);
    return Gavg, delta, mu, Vc;
Exemplo n.º 2
0
def getGavgFromSelfEnergy(parms, se_filename = None):
    N_LAYERS = int(parms['N_LAYERS'])
    FLAVORS  = int(parms['FLAVORS'])
    SPINS = int(parms['SPINS'])
    beta = float(parms['BETA'])

    # prepare data
    NMaxFreq = int(round((beta*float(parms['MAX_FREQ'])/pi - 1)/2.))
    iwn = 1j * (2*arange(NMaxFreq)+1)*pi/beta
    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);
        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[:NMaxFreq, SPINS*f+s]
    else: 
        se = zeros((SPINS, NMaxFreq, N_LAYERS*FLAVORS), dtype = complex)
        

    # 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
    SelfEnergy_rot = array([irotate(se[s], rot_mat) for s in range(SPINS)])
    SE = array([array([s.flatten() for s in SelfEnergy_rot[n]]) for n in range(SPINS)])
    Gavg = integrate(iwn, delta, mu, SE, parms, extra, parallel = False)
    g = array([rotate_green(Gavg, rot_mat, layer=L) for L in range(N_LAYERS)])

    return iwn, g
SelfEnergy_rot = array([irotate(SelfEnergy[s], rot_mat)
                        for s in range(SPINS)])
SE = array([array([s.flatten() for s in SelfEnergy_rot[n]])
            for n in range(SPINS)])

# prepare the parameter dict
parms = {
        'H' : magnetic_field,
        'N_LAYERS' : N_LAYERS,
        'FLAVORS' : FLAVORS,
        'SPINS' : SPINS,
        'NORB' : NORB,
        'INTEGRATE_MOD' : 'int_donly_tilted_3bands',
        'np' : num_processes,
        }

extra = {
        'HR' : HR,
        'R' : R,
        'GaussianData' : grule(numk),
        }

# calculate the k-integral
Gavg = average_green.integrate(w+1j*broadening, double_counting, mu, SE,
                               parms, extra, parallel)
Gavg = array([rotate_all(Gavg[s], rot_mat, need_extra = True) for s in range(SPINS)])

dos = -1/pi*Gavg[0].imag 
savetxt('dos_dft_mlwf.mpi', c_[w, dos], fmt='%.6f')