Example #1
0
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
            }
Example #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;
Example #3
0
            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'][:];