Beispiel #1
0
 def __init__(self, archive, *args, **kwargs):
     self.archive = archive
     if not os.path.exists(archive) and mpi.is_master_node():
         archive = HDFArchive(archive, 'w')
         archive.create_group('results')
         archive['results']['n_dmft_loops'] = 0
         del archive
     mpi.barrier()
Beispiel #2
0
    S.G0_iw[bn][i,i] <<= inverse(iOmega_n +mu - atomic_levels[(bn,i)] - delta_w)

    # Dump Delta parameters
    if Delta_dump:
        Delta_dump_file.write(bn + '\t')
        Delta_dump_file.write(str(V) + '\t')
        Delta_dump_file.write(str(e) + '\n')

print_master("Running the simulation...")

# Solve the problem
S.solve(**p)

# Save the results  
if mpi.rank==0:
    Results = HDFArchive(results_file_name,'w')
    for b in gf_struct: Results[b] = S.G_tau[b]

    import pytriqs.applications.impurity_solvers.cthyb.version as version
    import inspect
    import __main__
    Results.create_group("log")
    log = Results["log"]
    log["version"] = version.version
    log["release"] = version.release
    log["triqs_hash"] = version.triqs_hash
    log["cthyb_hash"] = version.cthyb_hash
    log["script"] = inspect.getsource(__main__)
    log["params"] = inspect.getsource(params)
Beispiel #3
0
    G_w = arch_ed['G_w'].copy()
    histograms = {}
    for bn, g_block in G:
        # Construct a SOM object
        cont = Som(g_block, kind = kind)
        # Run!
        cont.run(**som_params)

        G_w[bn] << cont
        G_rec[bn] << cont
        histograms[bn] = cont.histograms

    if mpi.is_master_node():
        with HDFArchive(som_filename,'a') as arch_som:
            gr = 'G_'+mesh_suffix
            if gr not in arch_som: arch_som.create_group(gr)
            arch_som[gr]['G'] = G
            arch_som[gr]['G_rec'] = G_rec
            arch_som[gr]['G_w'] = G_w
            arch_som[gr]['histograms'] = histograms
else:
    chi_rec = chi.copy()
    chi_w = arch_ed['chi_w'].copy()

    chi_iw = arch['chi_iw']
    norms = np.pi * np.array([chi_iw.data[n_iw-1,0,0],chi_iw.data[n_iw-1,1,1]])
    if kind == "BosonAutoCorr": norms = norms / 2

    # Construct a SOM object
    cont = Som(g_block, kind = kind, norms = norms)
    # Run!
Beispiel #4
0
        cols = filter(lambda s: s, line.split(' '))
        histo.append((type_of_col_1(cols[0]), float(cols[1]), float(cols[2])))
    return histo


if mpi.is_master_node():
    arch = HDFArchive('asymm_bath.h5', 'w')

# Set hybridization function
for e in epsilon:
    delta_w = GfImFreq(indices=[0], beta=beta)
    delta_w << (V**2) * inverse(iOmega_n - e)

    S.G0_iw["up"] << inverse(iOmega_n - ed - delta_w)
    S.G0_iw["dn"] << inverse(iOmega_n - ed - delta_w)

    S.solve(h_int=H, **p)

    if mpi.is_master_node():
        arch.create_group('epsilon_' + str(e))
        gr = arch['epsilon_' + str(e)]
        gr['G_tau'] = S.G_tau
        gr['beta'] = beta
        gr['U'] = U
        gr['ed'] = ed
        gr['V'] = V
        gr['e'] = e
        gr['perturbation_order'] = S.perturbation_order
        gr['perturbation_order_total'] = S.perturbation_order_total
        gr['performance_analysis'] = S.performance_analysis
beta = 10
n_iw = 50
g = GfImFreq(indices = [0], beta = beta, n_points = n_iw, statistic = 'Boson')
g.data[iw_, 0, 0] = ... # TRIQS uses twice n_iw: the first n_iw frequencies are negative!

g_w = GfReFreq(window = run_params['energy_window'], n_points = n_w, indices = indices)
s = g.copy()
g_rec = g.copy()
s.data[:] = 1.0 # either s = const. or s = g

if mpi.is_master_node():
    arch = HDFArchive(name+'.h5','w')
    arch['pytriqs_hash'] = pytriqs_hash
    arch['cthyb_hash'] = cthyb_hash
    arch['som_hash'] = som_hash
    arch.create_group('run_params')
    archpar = arch['run_params']
    for key, val in run_params.items():
        archpar[key] = val
    arch['beta'] = beta
    arch['n_iw'] = n_iw

start = time.clock()
cont = Som(g, s, kind = 'BosonAutoCorr', norms = np.array([ --- ])) # enter norm!
cont.run(**run_params)
exec_time = time.clock() - start
g_rec << cont
g_w << cont
if mpi.is_master_node():
    arch['exec_time'] = exec_time
    arch['g'] = g
Beispiel #6
0
    def run_dmft_loops(self, n_dmft_loops = 1):
        """runs the DMFT calculation"""
        clp = p = CleanLoopParameters(self.get_parameters())
        report = Reporter(**clp)
        report('Parameters:', clp)
        scheme = Scheme(**clp)
        dmft = DMFTObjects(**clp)
        raw_dmft = DMFTObjects(**clp)
        g_0_c_iw, g_c_iw, sigma_c_iw, dmu = dmft.get_dmft_objs() # ref, ref, ref, value

        report('Initializing...')
        if clp['nambu']:
            transf = NambuTransformation(**clp)
            scheme.set_pretransf(transf.pretransformation(), transf.pretransformation_inverse())
            raw_transf = NambuTransformation(**clp)
        else:
            transf = ClustersiteTransformation(g_loc = scheme.g_local(sigma_c_iw, dmu), **clp)
            clp.update({'g_transf_struct': transf.get_g_struct()})
            raw_transf = ClustersiteTransformation(**clp)
        
        transf.set_hamiltonian(**clp)
        report('Transformation ready')
        report('New basis:', transf.get_g_struct())
        impurity = Solver(beta = clp['beta'], gf_struct = dict(transf.get_g_struct()), 
                          n_tau = clp['n_tau'], n_iw = clp['n_iw'], n_l = clp['n_legendre'])
        impurity.Delta_tau.name = '$\\tilde{\\Delta}_c$'
        rnames = random_generator_names_list()
        report('H = ', transf.hamiltonian)
        report('Impurity solver ready')
        report('')

        for loop_nr in range(self.next_loop(), self.next_loop() + n_dmft_loops):
            report('DMFT-loop nr. %s'%loop_nr)
            if mpi.is_master_node(): duration = time()

            report('Calculating dmu...')
            dmft.find_dmu(scheme, **clp)
            g_0_c_iw, g_c_iw, sigma_c_iw, dmu = dmft.get_dmft_objs()
            report('dmu = %s'%dmu)

            report('Calculating local Greenfunction...')
            g_c_iw << scheme.g_local(sigma_c_iw, dmu)
            g_c_iw << addExtField(g_c_iw, p['ext_field'])
            if mpi.is_master_node() and p['verbosity'] > 1: checksym_plot(g_c_iw, p['archive'][0:-3] + 'Gchecksym' + str(loop_nr) + '.pdf')
            report('Calculating Weiss-field...')
            g_0_c_iw << inverse(inverse(g_c_iw) + sigma_c_iw)

            dmft.make_g_0_iw_with_delta_tau_real()

            report('Changing basis...')
            transf.set_dmft_objs(*dmft.get_dmft_objs())
            if mpi.is_master_node() and p['verbosity'] > 1: 
                checktransf_plot(transf.get_g_iw(), p['archive'][0:-3] + 'Gchecktransf' + str(loop_nr) + '.pdf')
                checktransf_plot(g_0_c_iw, p['archive'][0:-3] + 'Gweisscheck' + str(loop_nr) + '.pdf')
                checksym_plot(inverse(transf.g_0_iw), p['archive'][0:-3] + 'invGweisscheckconst' + str(loop_nr) + '.pdf')
                #checksym_plot(inverse(transf.get_g_iw()), p['archive'][0:-3] + 'invGsymcheckconst' + str(loop_nr) + '.pdf')

            if not clp['random_name']: clp.update({'random_name': rnames[int((loop_nr + mpi.rank) % len(rnames))]}) # TODO move
            if not clp['random_seed']: clp.update({'random_seed': 862379 * mpi.rank + 12563 * self.next_loop()})
            impurity.G0_iw << transf.get_g_0_iw()
            report('Solving impurity problem...')
            mpi.barrier()
            impurity.solve(h_int = transf.get_hamiltonian(), **clp.get_cthyb_parameters())

            if mpi.is_master_node() and p['verbosity'] > 1:
                checksym_plot(inverse(impurity.G0_iw), p['archive'][0:-3] + 'invGweisscheckconstsolver' + str(loop_nr) + '.pdf')
            report('Postprocessing measurements...')
            if clp['measure_g_l']:
                for ind, g in transf.get_g_iw(): g  << LegendreToMatsubara(impurity.G_l[ind])
            else:
                for ind, g in transf.get_g_iw(): g.set_from_fourier(impurity.G_tau[ind])
            raw_transf.set_dmft_objs(transf.get_g_0_iw(),
                                     transf.get_g_iw(),
                                     inverse(transf.get_g_0_iw()) - inverse(transf.get_g_iw()))
            if clp['measure_g_tau'] and clp['fit_tail']:
                for ind, g in transf.get_g_iw():
                    for tind in transf.get_g_struct():
                        if tind[0] == ind: block_inds = tind[1]
                    fixed_moments = TailGf(len(block_inds), len(block_inds), 1, 1)
                    fixed_moments[1] = identity(len(block_inds))
                    g.fit_tail(fixed_moments, 3, clp['tail_start'], clp['n_iw'] - 1)
            if mpi.is_master_node() and p['verbosity'] > 1: checksym_plot(inverse(transf.get_g_iw()), p['archive'][0:-3] + 'invGsymcheckconstsolver' + str(loop_nr) + '.pdf')
            report('Backtransforming...')
            transf.set_sigma_iw(inverse(transf.get_g_0_iw()) - inverse(transf.get_g_iw()))
            dmft.set_dmft_objs(*transf.get_backtransformed_dmft_objs())
            dmft.set_dmu(dmu)
            raw_dmft.set_dmft_objs(*raw_transf.get_backtransformed_dmft_objs())
            raw_dmft.set_dmu(dmu)

            if clp['mix']: dmft.mix()
            if clp['impose_paramagnetism']: dmft.paramagnetic()
            if clp['impose_afm']: dmft.afm()
            if clp['site_symmetries']: dmft.site_symmetric(clp['site_symmetries'])
            density = scheme.apply_pretransf_inv(dmft.get_g_iw(), True).total_density()

            report('Saving results...')
            if mpi.is_master_node():
                a = HDFArchive(p['archive'], 'a')
                if not a.is_group('results'):
                    a.create_group('results')
                a_r = a['results']
                a_r.create_group(str(loop_nr))
                a_l = a_r[str(loop_nr)]
                a_l['g_c_iw'] = dmft.get_g_iw()
                a_l['g_c_iw_raw'] = raw_dmft.get_g_iw()
                a_l['g_transf_iw'] = transf.get_g_iw()
                a_l['g_transf_iw_raw'] = raw_transf.get_g_iw()
                a_l['sigma_c_iw'] = dmft.get_sigma_iw()
                a_l['sigma_c_iw_raw'] = raw_dmft.get_sigma_iw()
                a_l['sigma_transf_iw'] = transf.get_sigma_iw()
                a_l['sigma_transf_iw_raw'] = raw_transf.get_sigma_iw()
                a_l['g_0_c_iw'] = dmft.get_g_0_iw()
                a_l['g_0_c_iw_raw'] = raw_dmft.get_g_0_iw()
                a_l['g_0_transf_iw'] = transf.get_g_0_iw()
                a_l['g_0_transf_iw_raw'] = raw_transf.get_g_0_iw()
                a_l['dmu'] = dmft.get_dmu()
                a_l['density'] = density
                a_l['loop_time'] = {'seconds': time() - duration,
                                    'hours': (time() - duration)/3600., 
                                    'days': (time() - duration)/3600./24.}
                a_l['n_cpu'] = mpi.size
                a_l['cdmft_code_version'] = CDmft._version
                clp_dict = dict()
                clp_dict.update(clp)
                a_l['parameters'] = clp_dict
                a_l['triqs_code_version'] = version

                a_l['delta_transf_tau'] = impurity.Delta_tau
                if clp['measure_g_l']: a_l['g_transf_l'] = impurity.G_l
                if clp['measure_g_tau']: a_l['g_transf_tau'] = impurity.G_tau
                a_l['sign'] = impurity.average_sign
                if clp['measure_density_matrix']: a_l['density_matrix'] = impurity.density_matrix
                a_l['g_atomic_tau'] = impurity.atomic_gf
                a_l['h_loc_diagonalization'] = impurity.h_loc_diagonalization
                if a_r.is_data('n_dmft_loops'):
                    a_r['n_dmft_loops'] += 1
                else:
                    a_r['n_dmft_loops'] = 1
                del a_l, a_r, a
            report('Loop done')
            report('')
            mpi.barrier()
Beispiel #7
0
    arch['beta'] = beta
    arch['move_global_prob'] = move_global_prob

static_observables = {"N1_up" : n(*mkind("up",1)), "N1_dn" : n(*mkind("dn",1)),
                      "N2_up" : n(*mkind("up",2)), "N2_dn" : n(*mkind("dn",2))}

global_moves = [('none',{}),
                ('flip_spins_1',gm_flip_spins_1),
                ('flip_spins_all',gm_flip_spins_all),
                ('swap_atoms',gm_swap_atoms),
                ('swap_and_flip',dict(gm_flip_spins_all,**gm_swap_atoms))]

for gm_name, gm in global_moves:
    mpi.report("Running with global moves set '%s'" % gm_name)
    if gm_name != 'none':
        p["move_global"] = gm
        p["move_global_prob"] = move_global_prob

    # Solve the problem
    S.solve(h_int=H, **p)

    if mpi.is_master_node():
        # Save the results
        arch.create_group(gm_name)
        arch[gm_name]['G_tau'] = S.G_tau

        dm = S.density_matrix
        for on, o in static_observables.items():
            arch[gm_name][on] = trace_rho_op(dm,o,S.h_loc_diagonalization)

Beispiel #8
0
#from pytriqs.applications.dft.converters.wien2k_converter import *
#Converter = Wien2kConverter(filename=dft_filename, repacking=True)
#Converter.convert_dft_input()
#mpi.barrier()

previous_runs = 0
previous_present = False
if mpi.is_master_node():
    f = HDFArchive(dft_filename+'.h5','a')
    if 'dmft_output' in f:
        ar = f['dmft_output']
        if 'iterations' in ar:
            previous_present = True
            previous_runs = ar['iterations']
    else:
        f.create_group('dmft_output')
    del f
previous_runs    = mpi.bcast(previous_runs)
previous_present = mpi.bcast(previous_present)

SK=SumkDFT(hdf_file=dft_filename+'.h5',use_dft_blocks=use_blocks,h_field=h_field)

n_orb = SK.corr_shells[0]['dim']
l = SK.corr_shells[0]['l']
spin_names = ["up","down"]
orb_names = [i for i in range(n_orb)]

# Use GF structure determined by DFT blocks
gf_struct = SK.gf_struct_solver[0]

# Construct Slater U matrix 
Beispiel #9
0
    G_w = arch_ed['G_w'].copy()
    histograms = {}
    for bn, g_block in G:
        # Construct a SOM object
        cont = Som(g_block, kind = kind)
        # Run!
        cont.run(**som_params)

        G_w[bn] << cont
        G_rec[bn] << cont
        histograms[bn] = cont.histograms

    if mpi.is_master_node():
        with HDFArchive(som_filename,'a') as arch_som:
            gr = 'G_'+mesh_suffix
            if gr not in arch_som: arch_som.create_group(gr)
            arch_som[gr]['G'] = G
            arch_som[gr]['G_rec'] = G_rec
            arch_som[gr]['G_w'] = G_w
            arch_som[gr]['histograms'] = histograms
else:
    chi_rec = chi.copy()
    chi_w = arch_ed['chi_w'].copy()

    chi_iw = arch['chi_iw']
    norms = np.pi * np.array([chi_iw.data[n_iw-1,0,0].real,
                              chi_iw.data[n_iw-1,1,1].real])
    if kind == "BosonAutoCorr": norms = norms / 2

    # Construct a SOM object
    cont = Som(chi, kind = kind, norms = norms)
Beispiel #10
0
    for line in f:
        cols = filter(lambda s: s, line.split(' '))
        histo.append((type_of_col_1(cols[0]),float(cols[1]),float(cols[2])))
    return histo

if mpi.is_master_node():
    arch = HDFArchive('asymm_bath.h5','w')

# Set hybridization function
for e in epsilon:
    delta_w = GfImFreq(indices = [0], beta=beta)
    delta_w << (V**2) * inverse(iOmega_n - e)

    S.G0_iw["up"] << inverse(iOmega_n - ed - delta_w)
    S.G0_iw["dn"] << inverse(iOmega_n - ed - delta_w)

    S.solve(h_int=H, **p)

    if mpi.is_master_node():
        arch.create_group('epsilon_' + str(e))
        gr = arch['epsilon_' + str(e)]
        gr['G_tau'] = S.G_tau
        gr['beta'] = beta
        gr['U'] = U
        gr['ed'] = ed
        gr['V'] = V
        gr['e'] = e
        gr['perturbation_order'] = S.perturbation_order
        gr['perturbation_order_total'] = S.perturbation_order_total
        gr['performance_analysis'] = S.performance_analysis
Beispiel #11
0
    tau = tau.real
    kern = lambda e: -np.exp(-tau * e) / (1 + np.exp(-beta*e))
    return np.diag(chi_norms) * quad(lambda e: dos(e, 1) * kern(e), -1, 3, points = [0])[0].real
g_tau = GfImTime(beta = beta, statistic = "Fermion", n_points = n_tau, indices = indices)
g_tau << Function(g_tau_model)

def g_l_model(l):
    l = int(l.real)
    kern = lambda e: -beta * sqrt(2*l+1) *((-np.sign(e)) ** l) * \
                     spherical_in(l, np.abs(e)*beta/2) / (2 * np.cosh(e*beta/2))
    return np.diag(chi_norms) * quad(lambda e: dos(e, 1) * kern(e), -1, 3, points = [0])[0].real
g_l = GfLegendre(beta = beta, statistic = "Fermion", n_points = n_l, indices = indices)
g_l << Function(g_l_model)

if mpi.is_master_node():
    arch.create_group("FermionGf")
    arch["FermionGf"]["norms"] = g_norms

for mesh, g in (("imfreq", g_iw),
                ("imtime", g_tau),
                ("legendre", g_l)):
    print_master("-"*len(mesh))
    print_master(mesh)
    print_master("-"*len(mesh))
    S = g.copy()
    if mesh == "legendre": S.data[:] = 1.0
    run_som_and_save("FermionGf", mesh, g, S, g_norms, (-5,5))

print_master("=================")
print_master("BosonCorr kernels")
print_master("=================")
Beispiel #12
0
static_observables = {
    "N1_up": n(*mkind("up", 1)),
    "N1_dn": n(*mkind("dn", 1)),
    "N2_up": n(*mkind("up", 2)),
    "N2_dn": n(*mkind("dn", 2))
}

global_moves = [('none', {}), ('flip_spins_1', gm_flip_spins_1),
                ('flip_spins_all', gm_flip_spins_all),
                ('swap_atoms', gm_swap_atoms),
                ('swap_and_flip', dict(gm_flip_spins_all, **gm_swap_atoms))]

for gm_name, gm in global_moves:
    mpi.report("Running with global moves set '%s'" % gm_name)
    if gm_name != 'none':
        p["move_global"] = gm
        p["move_global_prob"] = move_global_prob

    # Solve the problem
    S.solve(h_int=H, **p)

    if mpi.is_master_node():
        # Save the results
        arch.create_group(gm_name)
        arch[gm_name]['G_tau'] = S.G_tau

        dm = S.density_matrix
        for on, o in static_observables.items():
            arch[gm_name][on] = trace_rho_op(dm, o, S.h_loc_diagonalization)
Beispiel #13
0
    # Dump Delta parameters
    if Delta_dump:
        Delta_dump_file.write(bn + '\t')
        Delta_dump_file.write(str(V) + '\t')
        Delta_dump_file.write(str(e) + '\n')

mpi.report("Running the simulation...")

# Solve the problem
S.solve(**p)

# Save the results
if mpi.is_master_node():
    Results = HDFArchive(results_file_name, 'w')
    Results['G_tau'] = S.G_tau
    Results['use_interaction'] = use_interaction
    Results['delta_params'] = delta_params
    Results['spin_names'] = spin_names
    Results['orb_names'] = orb_names

    import pytriqs.applications.impurity_solvers.cthyb.version as version
    import inspect
    import __main__
    Results.create_group("log")
    log = Results["log"]
    log["version"] = version.version
    log["release"] = version.release
    log["triqs_hash"] = version.triqs_hash
    log["cthyb_hash"] = version.cthyb_hash
    log["script"] = inspect.getsource(__main__)
Beispiel #14
0
def dmft_cycle(general_parameters, solver_parameters, observables):
    """
    main dmft cycle that works for one shot and CSC equally

    Parameters
    ----------
    general_parameters : dict
        general parameters as a dict
    solver_parameters : dict
        solver parameters as a dict
    observables : dict
        current observable array for calculation

    __Returns:__
    observables : dict
        updated observable array for calculation
    """

    # create Sumk object
    if general_parameters['csc']:
        SK = SumkDFT(hdf_file=general_parameters['seedname'] + '.h5',
                     use_dft_blocks=False,
                     h_field=general_parameters['h_field'])
    else:
        SK = SumkDFT(hdf_file=general_parameters['jobname'] + '/' +
                     general_parameters['seedname'] + '.h5',
                     use_dft_blocks=False,
                     h_field=general_parameters['h_field'])

    iteration_offset = 0
    dft_mu = 0.0

    # determine chemical potential for bare DFT SK object
    if mpi.is_master_node():
        ar = HDFArchive(
            general_parameters['jobname'] + '/' +
            general_parameters['seedname'] + '.h5', 'a')
        if not 'DMFT_results' in ar: ar.create_group('DMFT_results')
        if not 'last_iter' in ar['DMFT_results']:
            ar['DMFT_results'].create_group('last_iter')
        if not 'DMFT_input' in ar: ar.create_group('DMFT_input')
        if 'iteration_count' in ar['DMFT_results']:
            iteration_offset = ar['DMFT_results']['iteration_count']
            SK.chemical_potential = ar['DMFT_results']['last_iter'][
                'chemical_potential']
        if general_parameters['dft_mu'] != 0.0:
            dft_mu = general_parameters['dft_mu']
    # cast everything to other nodes
    SK.chemical_potential = mpi.bcast(SK.chemical_potential)
    dft_mu = mpi.bcast(dft_mu)

    iteration_offset = mpi.bcast(iteration_offset)

    mpi.barrier()

    # determine block structure for solver
    det_blocks = True
    shell_multiplicity = []
    # load previous block_structure if possible
    if mpi.is_master_node():
        if 'block_structure' in ar['DMFT_input']:
            det_blocks = False
            shell_multiplicity = ar['DMFT_input']['shell_multiplicity']
    det_blocks = mpi.bcast(det_blocks)
    shell_multiplicity = mpi.bcast(shell_multiplicity)

    # if we are not doing a CSC calculation we need to have a DFT mu value
    # if CSC we are using the VASP converter which subtracts mu already
    # if we are at iteration offset 0 we should determine it anyway for safety!
    if (dft_mu == 0.0
            and not general_parameters['csc']) or iteration_offset == 0:
        dft_mu = SK.calc_mu(precision=general_parameters['prec_mu'])

    # determine block structure for GF and Hyb function
    if det_blocks:
        SK, shell_multiplicity = toolset.determine_block_structure(
            SK, general_parameters)
    else:
        SK.read_input_from_hdf(subgrp='DMFT_input',
                               things_to_read=['block_structure', 'rot_mat'])
        toolset.print_block_sym(SK, shell_multiplicity)

    # if we do AFM calculation we can use symmetry to copy self-energies from
    # one imp to another by exchanging up/down channels for speed up and accuracy
    afm_mapping = []
    if mpi.is_master_node():
        if (general_parameters['magnetic']
                and len(general_parameters['magmom']) == SK.n_inequiv_shells
                and general_parameters['afm_order']
                and not 'afm_mapping' in ar['DMFT_input']):

            # find equal or opposite spin imps, where we use the magmom array to
            # identity those with equal numbers or opposite
            # [copy Yes/False, from where, switch up/down channel]
            afm_mapping.append([False, 0, False])

            abs_moms = map(abs, general_parameters['magmom'])

            for icrsh in range(1, SK.n_inequiv_shells):
                # if the moment was seen before ...
                if abs_moms[icrsh] in abs_moms[0:icrsh]:
                    copy = True
                    # find the source imp to copy from
                    source = abs_moms[0:icrsh].index(abs_moms[icrsh])

                    # determine if we need to switch up and down channel
                    if general_parameters['magmom'][
                            icrsh] == general_parameters['magmom'][source]:
                        switch = False
                    elif general_parameters['magmom'][
                            icrsh] == -1 * general_parameters['magmom'][source]:
                        switch = True
                    # double check if the moment where not the same and then don't copy
                    else:
                        switch = False
                        copy = False

                    afm_mapping.append([copy, source, switch])
                else:
                    afm_mapping.append([False, icrsh, False])

            print 'AFM calculation selected, mapping self energies as follows:'
            print 'imp  [copy sigma, source imp, switch up/down]'
            print '---------------------------------------------'
            for i, elem in enumerate(afm_mapping):
                print str(i) + ' ', elem
            print ''

            ar['DMFT_input']['afm_mapping'] = afm_mapping

        # else if mapping is already in h5 archive
        elif 'afm_mapping' in ar['DMFT_input']:
            afm_mapping = ar['DMFT_input']['afm_mapping']

        # if anything did not work set afm_order false
        else:
            general_parameters['afm_order'] = False

    general_parameters['afm_order'] = mpi.bcast(
        general_parameters['afm_order'])
    afm_mapping = mpi.bcast(afm_mapping)

    # build interacting local hamiltonain
    h_int = []
    S = []
    # extract U and J
    mpi.report('*** interaction parameters ***')
    if len(general_parameters['U']) == 1:
        mpi.report("Assuming %s=%.2f for all correlated shells" %
                   ('U', general_parameters['U'][0]))
        general_parameters['U'] = general_parameters['U'] * SK.n_inequiv_shells
    elif len(general_parameters['U']) == SK.n_inequiv_shells:
        mpi.report('U list for correlated shells: ' +
                   str(general_parameters['U']))
    else:
        raise IndexError(
            "Property list %s must have length 1 or n_inequiv_shells" %
            (str(general_parameters['U'])))

    # now J
    if len(general_parameters['J']) == 1:
        mpi.report("Assuming %s=%.2f for all correlated shells" %
                   ('J', general_parameters['J'][0]))
        general_parameters['J'] = general_parameters['J'] * SK.n_inequiv_shells
    elif len(general_parameters['J']) == SK.n_inequiv_shells:
        mpi.report('J list for correlated shells: ' +
                   str(general_parameters['J']))
    else:
        raise IndexError(
            "Property list %s must have length 1 or n_inequiv_shells" %
            (str(general_parameters['J'])))

    ## Initialise the Hamiltonian and Solver
    for icrsh in range(SK.n_inequiv_shells):
        # ish points to the shell representative of the current group
        ish = SK.inequiv_to_corr[icrsh]
        n_orb = SK.corr_shells[ish]['dim']
        l = SK.corr_shells[ish]['l']
        orb_names = [i for i in range(n_orb)]

        # Construct U matrix of general kanamori type calculations
        if n_orb == 2 or n_orb == 3:  # e_g or t_2g cases
            Umat, Upmat = U_matrix_kanamori(
                n_orb=n_orb,
                U_int=general_parameters['U'][icrsh],
                J_hund=general_parameters['J'][icrsh])
        elif n_orb == 5:
            R = 0.63  # SumkDFT value for F4/F2
            F2 = 49.0 / (3.0 + 20.0 / 9.0 * R) * general_parameters['J'][icrsh]
            F4 = R * F2
            Javg = (F2 + F4) / 14.0
            Uavg = general_parameters['U'][icrsh] - 8.0 / 7.0 * Javg
            F0 = Uavg
            Umat_full = U_matrix(l=2,
                                 U_int=Uavg,
                                 J_hund=Javg,
                                 basis='other',
                                 T=T)
            # reduce full 4-index interaction matrix to 2-index
            Umat, Upmat = reduce_4index_to_2index(Umat_full)
            fmt = '{:9.5f}' * n_orb
            if mpi.is_master_node():
                print '\nUav =%9.4f, Jav =%9.4f, F4/F2 =%9.4f' % (Uavg, Javg,
                                                                  R)
                print 'F0  =%9.4f, F2  =%9.4f, F4    =%9.4f' % (F0, F2, F4)
                print 'Transformation matrix from [Y_lm (l=2, m=-2,...,2)] to ' + str(
                    orb_names_d)
                print '       ' + 'real part'.center(
                    9 * n_orb) + '  ' + 'imaginary part'.center(9 * n_orb)
                for irow in range(n_orb):
                    row = [orb_names_d[irow]] + numpy.real(
                        T[irow, :]).tolist() + numpy.imag(T[irow, :]).tolist()
                    print('{:7s}' + fmt + '  ' + fmt).format(*row)
        else:
            mpi.report('\n*** Hamiltonian for n_orb = %s NOT supported' %
                       (n_orb))
            quit()

        # Construct Hamiltonian
        mpi.report('Constructing the interaction Hamiltonian for shell %s ' %
                   (icrsh))
        if general_parameters['h_int_type'] == 1:
            # 1. density-density
            mpi.report('Using the density-density Hamiltonian ')
            h_int.append(
                h_int_density(general_parameters['spin_names'],
                              orb_names,
                              map_operator_structure=SK.sumk_to_solver[icrsh],
                              U=Umat,
                              Uprime=Upmat,
                              H_dump=general_parameters['jobname'] + '/' +
                              "H.txt"))
        elif general_parameters['h_int_type'] == 2:
            # 2. Kanamori Hamiltonian
            mpi.report(
                'Using the Kanamori Hamiltonian (with spin-flip and pair-hopping) '
            )
            h_int.append(
                h_int_kanamori(general_parameters['spin_names'],
                               orb_names,
                               map_operator_structure=SK.sumk_to_solver[icrsh],
                               off_diag=True,
                               U=Umat,
                               Uprime=Upmat,
                               J_hund=general_parameters['J'][icrsh],
                               H_dump=general_parameters['jobname'] + '/' +
                               "H.txt"))
        elif general_parameters['h_int_type'] == 3:
            # 3. Rotationally-invariant Slater Hamiltonian (4-index)
            h_int.append(
                h_int_slater(general_parameters['spin_names'],
                             orb_names_all,
                             map_operator_structure=map_all,
                             off_diag=True,
                             U_matrix=Umat_full,
                             H_dump=general_parameters['jobname'] + '/' +
                             "H_full.txt"))

        ####################################
        # hotfix for new triqs 2.0 gf_struct_solver is still a dict
        # but cthyb 2.0 expects a list of pairs ####
        if legacy_mode:
            gf_struct = SK.gf_struct_solver[icrsh]
        else:
            gf_struct = [[k, v]
                         for k, v in SK.gf_struct_solver[icrsh].iteritems()]
        ####################################
        # Construct the Solver instances
        if solver_parameters["measure_G_l"]:
            S.append(
                Solver(beta=general_parameters['beta'],
                       gf_struct=gf_struct,
                       n_l=general_parameters["n_LegCoeff"]))
        else:
            S.append(
                Solver(beta=general_parameters['beta'], gf_struct=gf_struct))

    # if Sigma is loaded, mu needs to be calculated again
    calc_mu = False

    # Prepare hdf file and and check for previous iterations
    if mpi.is_master_node():
        obs_prev = []
        if 'iteration_count' in ar['DMFT_results']:
            print '\n *** loading previous self energies ***'
            SK.dc_imp = ar['DMFT_results']['last_iter']['DC_pot']
            SK.dc_energ = ar['DMFT_results']['last_iter']['DC_energ']
            if 'observables' in ar['DMFT_results']:
                obs_prev = ar['DMFT_results']['observables']
            for icrsh in range(SK.n_inequiv_shells):
                print 'loading Sigma_imp' + str(
                    icrsh) + ' from previous calculation'
                S[icrsh].Sigma_iw = ar['DMFT_results']['last_iter']['Sigma_iw_'
                                                                    +
                                                                    str(icrsh)]
            calc_mu = True
        else:
            # calculation from scratch:
            ## write some input parameters to the archive
            ar['DMFT_input']['general_parameters'] = general_parameters
            ar['DMFT_input']['solver_parameters'] = solver_parameters
            ## and also the SumK <--> Solver mapping (used for restarting)
            for item in ['block_structure', 'deg_shells']:
                ar['DMFT_input'][item] = getattr(SK, item)
            # and the shell_multiplicity
            ar['DMFT_input']['shell_multiplicity'] = shell_multiplicity

            start_sigma = []
            # load now sigma from other calculation if wanted
            if general_parameters['load_sigma'] == True and general_parameters[
                    'previous_file'] == 'none':
                start_sigma, SK.dc_imp, SK.dc_energ = toolset.load_sigma_from_h5(
                    general_parameters['path_to_sigma'],
                    general_parameters['load_sigma_iter'])

            # if this is a series of calculation load previous sigma
            elif general_parameters['previous_file'] != 'none':
                start_sigma, SK.dc_imp, SK.dc_energ = toolset.load_sigma_from_h5(
                    general_parameters['previous_file'], -1)

            # load everything now to the solver
            if start_sigma:
                calc_mu = True
                for icrsh in range(SK.n_inequiv_shells):
                    S[icrsh].Sigma_iw = start_sigma[icrsh]

    # bcast everything to other nodes
    for icrsh in range(SK.n_inequiv_shells):
        S[icrsh].Sigma_iw = mpi.bcast(S[icrsh].Sigma_iw)
        S[icrsh].G_iw = mpi.bcast(S[icrsh].G_iw)
    SK.dc_imp = mpi.bcast(SK.dc_imp)
    SK.dc_energ = mpi.bcast(SK.dc_energ)
    SK.set_dc(SK.dc_imp, SK.dc_energ)
    calc_mu = mpi.bcast(calc_mu)

    # symmetrise Sigma
    for icrsh in range(SK.n_inequiv_shells):
        SK.symm_deg_gf(S[icrsh].Sigma_iw, orb=icrsh)

    SK.put_Sigma([S[icrsh].Sigma_iw for icrsh in range(SK.n_inequiv_shells)])
    if calc_mu:
        # determine chemical potential
        SK.calc_mu(precision=general_parameters['prec_mu'])

    #############################
    # extract G local
    G_loc_all = SK.extract_G_loc()
    #############################

    if general_parameters['occ_conv_crit'] > 0.0:
        conv_file = open(
            general_parameters['jobname'] + '/' + 'convergence.dat', 'a')

    if mpi.is_master_node():
        # print other system information
        print "\nInverse temperature beta = %s" % (general_parameters['beta'])
        if solver_parameters["measure_G_l"]:
            print "\nSampling G(iw) in Legendre space with %s coefficients" % (
                general_parameters["n_LegCoeff"])

    # extract free lattice greens function
    G_loc_all_dft = SK.extract_G_loc(with_Sigma=False, mu=dft_mu)
    density_shell_dft = np.zeros(SK.n_inequiv_shells)
    density_mat_dft = []
    for icrsh in range(SK.n_inequiv_shells):
        density_mat_dft.append([])
        density_mat_dft[icrsh] = G_loc_all_dft[icrsh].density()
        density_shell_dft[icrsh] = G_loc_all_dft[icrsh].total_density()
        mpi.report('total density for imp ' + str(icrsh) + ' from DFT: ' +
                   str(density_shell_dft[icrsh]))

    # extracting new rotation matrices from density_mat or local Hamiltonian
    if (general_parameters['set_rot'] == 'hloc' or
            general_parameters['set_rot'] == 'den') and iteration_offset == 0:
        if general_parameters['set_rot'] == 'hloc':
            q_diag = SK.eff_atomic_levels()
            chnl = 'up'
        elif general_parameters['set_rot'] == 'den':
            q_diag = density_mat_dft
            chnl = 'up_0'

        rot_mat = []
        for icrsh in range(SK.n_corr_shells):
            ish = SK.corr_to_inequiv[icrsh]
            eigval, eigvec = numpy.linalg.eigh(np.real(q_diag[ish][chnl]))
            rot_mat_local = numpy.array(eigvec) + 0.j

            rot_mat.append(rot_mat_local)

        SK.rot_mat = rot_mat
        mpi.report(
            'Updating rotation matrices using dft %s eigenbasis to maximise sign'
            % (general_parameters['set_rot']))

        if mpi.is_master_node():
            print "\n new rotation matrices "
            # rotation matrices
            for icrsh in range(SK.n_corr_shells):
                n_orb = SK.corr_shells[icrsh]['dim']
                print 'rot_mat[%2d] ' % (icrsh) + 'real part'.center(
                    9 * n_orb) + '  ' + 'imaginary part'.center(9 * n_orb)
                rot = np.matrix(SK.rot_mat[icrsh])
                for irow in range(n_orb):
                    fmt = '{:9.5f}' * n_orb
                    row = np.real(rot[irow, :]).tolist()[0] + np.imag(
                        rot[irow, :]).tolist()[0]
                    print('           ' + fmt + '  ' + fmt).format(*row)

            print '\n'

    # saving rot mat to h5 archive:
    if mpi.is_master_node() and iteration_offset == 0:
        ar['DMFT_input']['rot_mat'] = SK.rot_mat

    #Double Counting if first iteration or if CSC calculation with DFTDC
    if ((iteration_offset == 0 and general_parameters['dc']
         and not general_parameters['load_sigma'])
            or (general_parameters['csc'] and general_parameters['dc']
                and not general_parameters['dc_dmft'])):
        mpi.report('\n *** DC determination ***')

        for icrsh in range(SK.n_inequiv_shells):
            ###################################################################
            SK.calc_dc(density_mat_dft[icrsh],
                       U_interact=general_parameters['U'][icrsh],
                       J_hund=general_parameters['J'][icrsh],
                       orb=icrsh,
                       use_dc_formula=general_parameters['dc_type'])
            ###################################################################

    # initialise sigma if first iteration
    if (iteration_offset == 0 and general_parameters['previous_file'] == 'none'
            and general_parameters['load_sigma'] == False
            and general_parameters['dc']):
        for icrsh in range(SK.n_inequiv_shells):
            # if we are doing a mangetic calculation and initial magnetic moments
            # are set, manipulate the initial sigma accordingly
            if general_parameters['magnetic'] and general_parameters['magmom']:
                fac = abs(general_parameters['magmom'][icrsh])

                # init self energy according to factors in magmoms
                if general_parameters['magmom'][icrsh] > 0.0:
                    # if larger 1 the up channel will be favored
                    for spin_channel, elem in SK.gf_struct_solver[
                            icrsh].iteritems():
                        if 'up' in spin_channel:
                            S[icrsh].Sigma_iw[spin_channel] << (
                                1 + fac) * SK.dc_imp[
                                    SK.inequiv_to_corr[icrsh]]['up'][0, 0]
                        else:
                            S[icrsh].Sigma_iw[spin_channel] << (
                                1 - fac) * SK.dc_imp[
                                    SK.inequiv_to_corr[icrsh]]['down'][0, 0]
                else:
                    for spin_channel, elem in SK.gf_struct_solver[
                            icrsh].iteritems():
                        if 'down' in spin_channel:
                            S[icrsh].Sigma_iw[spin_channel] << (
                                1 + fac) * SK.dc_imp[
                                    SK.inequiv_to_corr[icrsh]]['up'][0, 0]
                        else:
                            S[icrsh].Sigma_iw[spin_channel] << (
                                1 - fac) * SK.dc_imp[
                                    SK.inequiv_to_corr[icrsh]]['down'][0, 0]
            else:
                S[icrsh].Sigma_iw << SK.dc_imp[
                    SK.inequiv_to_corr[icrsh]]['up'][0, 0]

        # set DC as Sigma and extract the new Gloc with DC potential
        SK.put_Sigma(
            [S[icrsh].Sigma_iw for icrsh in range(SK.n_inequiv_shells)])
        G_loc_all = SK.extract_G_loc()

    if ((general_parameters['load_sigma'] == True
         or general_parameters['previous_file'] != 'none')
            and iteration_offset == 0):
        SK.calc_mu(precision=general_parameters['prec_mu'])
        G_loc_all = SK.extract_G_loc()

    # if CSC we use the first and per params for the number of iterations
    if general_parameters['csc'] and iteration_offset == 0:
        # for CSC calculations converge first to a better Sigma
        n_iter = general_parameters['n_iter_dmft_first']

    # if CSC and not the first iteration we do n_iter_dmft_per iterations per DMFT step
    if general_parameters['csc'] and iteration_offset != 0:
        n_iter = general_parameters['n_iter_dmft_per']

    # if no csc calculation is done the number of dmft iterations is n_iter_dmft
    if not general_parameters['csc'] and iteration_offset == 0:
        n_iter = general_parameters['n_iter_dmft']

    mpi.report('\n%s DMFT cycles requested. Starting with iteration %s. \n' %
               (n_iter, iteration_offset + 1))
    # make sure a last time that every node as the same number of iterations
    n_iter = mpi.bcast(n_iter)

    # calculate E_kin_dft for one shot calculations
    if not general_parameters['csc'] and general_parameters['calc_energies']:
        E_kin_dft = calc_dft_kin_en(general_parameters, SK, dft_mu)

    sampling = False
    dmft_looping = True
    it = iteration_offset + 1
    # The infamous DMFT self consistency cycle
    while (dmft_looping == True):
        mpi.report("#" * 80)
        mpi.report('Running iteration: ' + str(it) + ' / ' +
                   str(iteration_offset + n_iter))

        # init local density matrices for observables
        density_tot = 0.0
        density_shell = np.zeros(SK.n_inequiv_shells)
        density_mat = []
        for icrsh in range(SK.n_inequiv_shells):
            density_mat.append([])
        density_shell_pre = np.zeros(SK.n_inequiv_shells)
        density_mat_pre = []
        for icrsh in range(SK.n_inequiv_shells):
            density_mat_pre.append([])

        mpi.barrier()
        for icrsh in range(SK.n_inequiv_shells):
            SK.symm_deg_gf(S[icrsh].Sigma_iw, orb=icrsh)

        # looping over inequiv shells and solving for each site seperately
        for icrsh in range(SK.n_inequiv_shells):

            S[icrsh].G_iw << G_loc_all[icrsh]

            density_shell_pre[icrsh] = S[icrsh].G_iw.total_density()
            mpi.report("\n *** Correlated Shell type #%3d : " % (icrsh) +
                       "Total charge of impurity problem = %.6f" %
                       (density_shell_pre[icrsh]))
            density_mat_pre[icrsh] = S[icrsh].G_iw.density()
            mpi.report("Density matrix:")
            for key, value in density_mat_pre[icrsh].iteritems():
                mpi.report(key)
                mpi.report(np.real(value))

            # dyson equation to extract G0_iw
            S[icrsh].G0_iw << inverse(S[icrsh].Sigma_iw +
                                      inverse(S[icrsh].G_iw))
            SK.symm_deg_gf(S[icrsh].G0_iw, orb=icrsh)

            # prepare our G_tau and G_l used to save the 'good' G_tau
            glist_tau = []
            if solver_parameters["measure_G_l"]:
                glist_l = []
            for name, g in S[icrsh].G0_iw:
                glist_tau.append(
                    GfImTime(indices=g.indices,
                             beta=general_parameters['beta'],
                             n_points=S[icrsh].n_tau))
                if solver_parameters["measure_G_l"]:
                    glist_l.append(
                        GfLegendre(indices=g.indices,
                                   beta=general_parameters['beta'],
                                   n_points=general_parameters['n_LegCoeff']))

            # we will call it G_tau_man for a manual build G_tau
            S[icrsh].G_tau_man = BlockGf(
                name_list=SK.gf_struct_solver[icrsh].keys(),
                block_list=glist_tau,
                make_copies=True)
            if solver_parameters["measure_G_l"]:
                S[icrsh].G_l_man = BlockGf(
                    name_list=SK.gf_struct_solver[icrsh].keys(),
                    block_list=glist_l,
                    make_copies=True)

            # atm small complex parts can numerical increase and cause trouble
            # at some point in iterations, this is a fix to remove those off
            # diagonal parts.
            if general_parameters['rm_complex']:
                for name, g in S[icrsh].G0_iw:
                    G0_tau = GfImTime(indices=g.indices,
                                      beta=general_parameters['beta'])
                    G0_tau << InverseFourier(g)
                    G0_tau.data[:, :, :] = np.real(G0_tau.data[:, :, :])
                    S[icrsh].G0_iw[name] << Fourier(G0_tau)

            # if we do a AFM calculation we can use the init magnetic moments to
            # copy the self energy instead of solving it explicitly
            if general_parameters['afm_order'] and afm_mapping[icrsh][
                    0] == True:
                imp_source = afm_mapping[icrsh][1]
                invert_spin = afm_mapping[icrsh][2]
                mpi.report(
                    "\ncopying the self-energy for shell %d from shell %d" %
                    (icrsh, imp_source))
                mpi.report("inverting spin channels: " + str(invert_spin))

                if invert_spin:
                    for spin_channel, elem in SK.gf_struct_solver[
                            icrsh].iteritems():
                        if 'up' in spin_channel:
                            target_channel = 'down' + spin_channel.replace(
                                'up', '')
                        else:
                            target_channel = 'up' + spin_channel.replace(
                                'down', '')

                        S[icrsh].Sigma_iw[spin_channel] << S[
                            imp_source].Sigma_iw[target_channel]
                        S[icrsh].G_tau_man[spin_channel] << S[
                            imp_source].G_tau_man[target_channel]
                        S[icrsh].G_iw[spin_channel] << S[imp_source].G_iw[
                            target_channel]
                        S[icrsh].G0_iw[spin_channel] << S[imp_source].G0_iw[
                            target_channel]
                        if solver_parameters["measure_G_l"]:
                            S[icrsh].G_l_man[spin_channel] << S[
                                imp_source].G_l_man[target_channel]

                else:
                    S[icrsh].Sigma_iw << S[imp_source].Sigma_iw
                    S[icrsh].G_tau_man << S[imp_source].G_tau_man
                    S[icrsh].G_iw << S[imp_source].G_iw
                    S[icrsh].G0_iw << S[imp_source].G0_iw
                    if solver_parameters["measure_G_l"]:
                        S[icrsh].G_l_man << S[imp_source].G_l_man

            else:
                # ugly workaround for triqs 1.4
                if legacy_mode:
                    solver_parameters["measure_g_l"] = solver_parameters[
                        "measure_G_l"]
                    del solver_parameters["measure_G_l"]
                    solver_parameters["measure_g_tau"] = solver_parameters[
                        "measure_G_tau"]
                    del solver_parameters["measure_G_tau"]

                ####################################################################
                # Solve the impurity problem for this shell
                mpi.report("\nSolving the impurity problem for shell %d ..." %
                           (icrsh))
                # *************************************
                S[icrsh].solve(h_int=h_int[icrsh], **solver_parameters)
                # *************************************
                ####################################################################

                # revert the changes:
                if legacy_mode:
                    solver_parameters["measure_G_l"] = solver_parameters[
                        "measure_g_l"]
                    del solver_parameters["measure_g_l"]
                    solver_parameters["measure_G_tau"] = solver_parameters[
                        "measure_g_tau"]
                    del solver_parameters["measure_g_tau"]

                # use Legendre for next G and Sigma instead of matsubara, less noisy!
                if solver_parameters["measure_G_l"]:
                    S[icrsh].Sigma_iw_orig = S[icrsh].Sigma_iw.copy()
                    S[icrsh].G_iw_from_leg = S[icrsh].G_iw.copy()
                    S[icrsh].G_l_man << S[icrsh].G_l
                    if mpi.is_master_node():
                        for i, g in S[icrsh].G_l:
                            g.enforce_discontinuity(
                                numpy.identity(g.target_shape[0]))
                            S[icrsh].G_iw[i].set_from_legendre(g)
                            # update G_tau as well:
                            S[icrsh].G_tau_man[i] << InverseFourier(
                                S[icrsh].G_iw[i])
                            # set Sigma and G_iw from G_l
                            S[icrsh].Sigma_iw << inverse(
                                S[icrsh].G0_iw) - inverse(S[icrsh].G_iw)

                        if legacy_mode:
                            # bad ass trick to avoid non asymptotic behavior of Sigma
                            # if legendre is used  with triqs 1.4
                            for key, value in S[icrsh].Sigma_iw:
                                S[icrsh].Sigma_iw[key].tail[-1] = S[
                                    icrsh].G_iw[key].tail[-1]

                    # broadcast new G, Sigmas to all other nodes
                    S[icrsh].Sigma_iw_orig << mpi.bcast(S[icrsh].Sigma_iw_orig)
                    S[icrsh].Sigma_iw << mpi.bcast(S[icrsh].Sigma_iw)
                    S[icrsh].G_iw << mpi.bcast(S[icrsh].G_iw)
                    S[icrsh].G_tau_man << mpi.bcast(S[icrsh].G_tau_man)
                else:
                    S[icrsh].G_tau_man << S[icrsh].G_tau

            # some printout of the obtained density matrices and some basic checks
            density_shell[icrsh] = S[icrsh].G_iw.total_density()
            density_tot += density_shell[icrsh] * shell_multiplicity[icrsh]
            density_mat[icrsh] = S[icrsh].G_iw.density()
            if mpi.is_master_node():
                print "\nTotal charge of impurity problem : " + "{:7.5f}".format(
                    density_shell[icrsh])
                print "Total charge convergency of impurity problem : " + "{:7.5f}".format(
                    density_shell[icrsh] - density_shell_pre[icrsh])
                print "\nDensity matrix:"
                for key, value in density_mat[icrsh].iteritems():
                    print key
                    print np.real(value)
                    eige, eigv = np.linalg.eigh(value)
                    print 'eigenvalues: ', eige
                    # check for large off-diagonal elements and write out a warning
                    i = 0
                    j = 0
                    size = len(np.real(value)[0, :])
                    pr_warning = False
                    for i in range(0, size):
                        for j in range(0, size):
                            if i != j and np.real(value)[i, j] >= 0.1:
                                pr_warning = True
                    if pr_warning:
                        print '\n!!! WARNING !!!'
                        print '!!! large off diagonal elements in density matrix detected! I hope you know what you are doing !!!'
                        print '\n!!! WARNING !!!'

        # Done with loop over impurities

        if mpi.is_master_node():
            # Done. Now do post-processing:
            print "\n *** Post-processing the solver output ***"
            print "Total charge of all correlated shells : %.6f \n" % density_tot

        # mixing Sigma
        if mpi.is_master_node():
            if it > 1:
                print "mixing sigma with previous iteration by factor " + str(
                    general_parameters['sigma_mix']) + '\n'
                for icrsh in range(SK.n_inequiv_shells):
                    S[icrsh].Sigma_iw << (
                        general_parameters['sigma_mix'] * S[icrsh].Sigma_iw +
                        (1 - general_parameters['sigma_mix']) *
                        ar['DMFT_results']['last_iter']['Sigma_iw_' +
                                                        str(icrsh)])
                    S[icrsh].G_iw << (
                        general_parameters['sigma_mix'] * S[icrsh].G_iw +
                        (1 - general_parameters['sigma_mix']) *
                        ar['DMFT_results']['last_iter']['Gimp_iw_' +
                                                        str(icrsh)])

        for icrsh in range(SK.n_inequiv_shells):
            S[icrsh].Sigma_iw << mpi.bcast(S[icrsh].Sigma_iw)
            S[icrsh].G_iw << mpi.bcast(S[icrsh].G_iw)
        mpi.barrier()

        # calculate new DC
        if general_parameters['dc_dmft'] and general_parameters['dc']:
            for icrsh in range(SK.n_inequiv_shells):
                dm = S[icrsh].G_iw.density()
                # if DC should be build differently on the sites for first iterations
                SK.calc_dc(dm,
                           U_interact=general_parameters['U'][icrsh],
                           J_hund=general_parameters['J'][icrsh],
                           orb=icrsh,
                           use_dc_formula=general_parameters['dc_type'])

        # symmetrise Sigma
        for icrsh in range(SK.n_inequiv_shells):
            SK.symm_deg_gf(S[icrsh].Sigma_iw, orb=icrsh)

        # doing the dmft loop and set new sigma into sumk
        SK.put_Sigma(
            [S[icrsh].Sigma_iw for icrsh in range(SK.n_inequiv_shells)])

        if general_parameters['fixed_mu']:
            SK.set_mu(general_parameters['fixed_mu_value'])
            previous_mu = SK.chemical_potential
            mpi.report("+++ Keeping the  chemical potential fixed  at: " +
                       str(general_parameters['fixed_mu_value']) + " +++ ")
        else:
            # saving previous mu for writing to observables file
            previous_mu = SK.chemical_potential
            SK.calc_mu(precision=general_parameters['prec_mu'])

        G_loc_all = SK.extract_G_loc()

        for icrsh in range(SK.n_inequiv_shells):
            # copy the block of G_loc into the corresponding instance of the impurity solver
            S[icrsh].G_iw << G_loc_all[icrsh]

        # saving results to h5 archive
        if mpi.is_master_node():
            ar['DMFT_results']['iteration_count'] = it
            ar['DMFT_results']['last_iter'][
                'chemical_potential'] = SK.chemical_potential
            ar['DMFT_results']['last_iter']['DC_pot'] = SK.dc_imp
            ar['DMFT_results']['last_iter']['DC_energ'] = SK.dc_energ
            ar['DMFT_results']['last_iter']['dens_mat_pre'] = density_mat_pre
            ar['DMFT_results']['last_iter']['dens_mat_post'] = density_mat
            for icrsh in range(SK.n_inequiv_shells):
                ar['DMFT_results']['last_iter']['G0_iw' +
                                                str(icrsh)] = S[icrsh].G0_iw
                ar['DMFT_results']['last_iter'][
                    'Gimp_tau_' + str(icrsh)] = S[icrsh].G_tau_man
                if solver_parameters["measure_G_l"]:
                    ar['DMFT_results']['last_iter'][
                        'Gimp_l_' + str(icrsh)] = S[icrsh].G_l_man
                ar['DMFT_results']['last_iter']['Gimp_iw_' +
                                                str(icrsh)] = S[icrsh].G_iw
                ar['DMFT_results']['last_iter']['Sigma_iw_' +
                                                str(icrsh)] = S[icrsh].Sigma_iw

            # save to h5 archive every h5_save_freq iterations
            if (it % general_parameters['h5_save_freq'] == 0):
                ar['DMFT_results'].create_group('it_' + str(it))
                ar['DMFT_results'][
                    'it_' +
                    str(it)]['chemical_potential'] = SK.chemical_potential
                ar['DMFT_results']['it_' + str(it)]['DC_pot'] = SK.dc_imp
                ar['DMFT_results']['it_' + str(it)]['DC_energ'] = SK.dc_energ
                ar['DMFT_results']['it_' +
                                   str(it)]['dens_mat_pre'] = density_mat_pre
                ar['DMFT_results']['it_' +
                                   str(it)]['dens_mat_post'] = density_mat
                for icrsh in range(SK.n_inequiv_shells):
                    ar['DMFT_results']['it_' +
                                       str(it)]['G0_iw' +
                                                str(icrsh)] = S[icrsh].G0_iw
                    ar['DMFT_results']['it_' + str(it)][
                        'Gimp_tau_' + str(icrsh)] = S[icrsh].G_tau_man
                    if solver_parameters["measure_G_l"]:
                        ar['DMFT_results']['it_' + str(it)][
                            'Gimp_l_' + str(icrsh)] = S[icrsh].G_l_man
                    ar['DMFT_results']['it_' +
                                       str(it)]['Gimp_iw_' +
                                                str(icrsh)] = S[icrsh].G_iw
                    ar['DMFT_results']['it_' +
                                       str(it)]['Sigma_iw_' +
                                                str(icrsh)] = S[icrsh].Sigma_iw

        mpi.barrier()

        # calculate energies now if wanted

        # calculate interaction energy
        E_int = np.zeros(SK.n_inequiv_shells)
        E_corr_en = 0.0
        e_int_shell = 0.0
        E_bandcorr = 0.0

        if general_parameters['calc_energies']:
            # dmft interaction energy with E_int = 0.5 * Tr[Sigma * G]
            if mpi.is_master_node():
                for icrsh in range(SK.n_inequiv_shells):
                    #calc energy for given S and G
                    E_int[icrsh] = 0.5 * (S[icrsh].G_iw *
                                          S[icrsh].Sigma_iw).total_density()
                    E_corr_en += shell_multiplicity[icrsh] * E_int[
                        icrsh] - shell_multiplicity[icrsh] * SK.dc_energ[
                            SK.inequiv_to_corr[icrsh]]
            mpi.barrier()
            E_int = mpi.bcast(E_int)
            E_corr_en = mpi.bcast(E_corr_en)

        # for a one shot calculation we are using our own method
        if not general_parameters['csc'] and general_parameters[
                'calc_energies'] == True:
            E_bandcorr = calc_bandcorr_man(general_parameters, SK, E_kin_dft)

        # if we do a CSC calculation we need always an updated GAMMA file
        if general_parameters['csc']:
            # handling the density correction for fcsc calculations
            dN, d, E_bandcorr = SK.calc_density_correction(filename='GAMMA',
                                                           dm_type='vasp')

        # DFT energy
        E_dft = 0.0
        if mpi.is_master_node() and general_parameters['csc']:
            # Read energy from OSZICAR
            E_dft = toolset.get_dft_energy()
        E_dft = mpi.bcast(E_dft)

        # calculate observables and write them to file
        if mpi.is_master_node():
            '\n *** calculation of observables ***'
            observables = calc_obs(observables, general_parameters, it, S,
                                   dft_mu, previous_mu, SK, G_loc_all_dft,
                                   density_mat_dft, density_mat,
                                   shell_multiplicity, E_dft, E_bandcorr,
                                   E_int, E_corr_en)

            write_obs(observables, SK, general_parameters)

            # write the new observable array to h5 archive
            ar['DMFT_results']['observables'] = observables

            print '*** iteration finished ***'

            # print out of the energies
            if general_parameters['calc_energies']:
                print
                print "=" * 60
                print 'summary of energetics:'
                print "total energy: ", observables['E_tot'][-1]
                print "DFT energy: ", observables['E_dft'][-1]
                print "correllation energy: ", observables['E_corr_en'][-1]
                print "DFT band correction: ", observables['E_bandcorr'][-1]
                print "=" * 60
                print

            # print out summary of occupations per impurity
            print "=" * 60
            print 'summary of occupations: '
            for icrsh in range(SK.n_inequiv_shells):
                print 'total occupany of impurity ' + str(
                    icrsh) + ':' + "{:7.4f}".format(
                        observables['imp_occ'][icrsh]['up'][-1] +
                        observables['imp_occ'][icrsh]['down'][-1])
            for icrsh in range(SK.n_inequiv_shells):
                print 'G(beta/2) occ of impurity ' + str(
                    icrsh) + ':' + "{:8.4f}".format(
                        observables['imp_gb2'][icrsh]['up'][-1] +
                        observables['imp_gb2'][icrsh]['down'][-1])
            print "=" * 60
            print

            # if a magnetic calculation is done print out a summary of up/down occ
            if general_parameters['magnetic']:
                occ = {}
                occ['up'] = 0.0
                occ['down'] = 0.0
                print
                print "=" * 60
                print '\n *** summary of magnetic occupations: ***'
                for icrsh in range(SK.n_inequiv_shells):
                    for spin in ['up', 'down']:
                        temp = observables['imp_occ'][icrsh][spin][-1]
                        print 'imp ' + str(
                            icrsh) + ' spin ' + spin + ': ' + "{:6.4f}".format(
                                temp)
                        occ[spin] += temp

                print 'total spin up   occ: ' + "{:6.4f}".format(occ['up'])
                print 'total spin down occ: ' + "{:6.4f}".format(occ['down'])
                print "=" * 60
                print

        # check for convergency and stop if criteria is reached
        if it == 1 or it == iteration_offset + 1:
            converged = False
        std_dev = 0.0
        if it == 1 and general_parameters[
                'occ_conv_crit'] > 0.0 and mpi.is_master_node():
            conv_file.write('std_dev occ for each impurity \n')
        if it >= general_parameters['occ_conv_it'] and general_parameters[
                'occ_conv_crit'] > 0.0:
            if mpi.is_master_node():
                converged, std_dev = toolset.check_convergence(
                    SK, general_parameters, observables)
                conv_file.write("{:3d}".format(it))
                for icrsh in range(SK.n_inequiv_shells):
                    conv_file.write("{:10.6f}".format(std_dev[icrsh]))
                conv_file.write('\n')
                conv_file.flush()
            converged = mpi.bcast(converged)
            std_dev = mpi.bcast(std_dev)

        # check for convergency and if wanted do the sampling dmft iterations.
        if converged == True and sampling == False:
            if general_parameters['sampling_iterations'] > 0:
                mpi.report(
                    '*** required convergence reached and sampling now for ' +
                    str(general_parameters['sampling_iterations']) +
                    ' iterations ***')
                n_iter = (it - iteration_offset
                          ) + general_parameters['sampling_iterations']
                sampling = True
            else:
                mpi.report('*** required convergence reached stopping now ***')
                break

        # finishing the dmft loop if the maximum number of iterations is reached
        if it == (iteration_offset + n_iter):
            mpi.report('all requested iterations finished')
            mpi.report("#" * 80)
            dmft_looping = False

        # iteration counter
        it += 1

    if converged and general_parameters['csc']:
        # is there a smoother way to stop both vasp and triqs from running after convergency is reached?
        if mpi.is_master_node():
            f_stop = open('STOPCAR', 'wt')
            f_stop.write("LABORT = .TRUE.\n")
            f_stop.close()
            del ar
        mpi.MPI.COMM_WORLD.Abort(1)

    if mpi.is_master_node():
        if general_parameters['occ_conv_crit'] > 0.0:
            conv_file.close()
    mpi.barrier()

    # close the h5 archive
    if mpi.is_master_node():
        if 'h5_archive' in locals():
            del h5_archive

    return observables
Beispiel #15
0
def five_plus_five(use_interaction=True):

    results_file_name = "5_plus_5." + ("int."
                                       if use_interaction else "") + "h5"

    # Block structure of GF
    L = 2  # d-orbital
    spin_names = ("up", "dn")
    orb_names = cubic_names(L)

    # Input parameters
    beta = 40.
    mu = 26

    U = 4.0
    J = 0.7
    F0 = U
    F2 = J * (14.0 / (1.0 + 0.63))
    F4 = F2 * 0.63

    # Dump the local Hamiltonian to a text file (set to None to disable dumping)
    H_dump = "H.txt"
    # Dump Delta parameters to a text file (set to None to disable dumping)
    Delta_dump = "Delta_params.txt"

    # Hybridization function parameters
    # Delta(\tau) is diagonal in the basis of cubic harmonics
    # Each component of Delta(\tau) is represented as a list of single-particle
    # terms parametrized by pairs (V_k,\epsilon_k).
    delta_params = {
        "xy": {
            'V': 0.2,
            'e': -0.2
        },
        "yz": {
            'V': 0.2,
            'e': -0.15
        },
        "z^2": {
            'V': 0.2,
            'e': -0.1
        },
        "xz": {
            'V': 0.2,
            'e': 0.05
        },
        "x^2-y^2": {
            'V': 0.2,
            'e': 0.4
        }
    }

    atomic_levels = {
        ('up_xy', 0): -0.2,
        ('dn_xy', 0): -0.2,
        ('up_yz', 0): -0.15,
        ('dn_yz', 0): -0.15,
        ('up_z^2', 0): -0.1,
        ('dn_z^2', 0): -0.1,
        ('up_xz', 0): 0.05,
        ('dn_xz', 0): 0.05,
        ('up_x^2-y^2', 0): 0.4,
        ('dn_x^2-y^2', 0): 0.4
    }

    n_iw = 1025
    n_tau = 10001

    p = {}
    p["max_time"] = -1
    p["random_name"] = ""
    p["random_seed"] = 123 * mpi.rank + 567
    p["length_cycle"] = 50
    #p["n_warmup_cycles"] = 5000
    p["n_warmup_cycles"] = 500
    p["n_cycles"] = int(1.e1 / mpi.size)
    #p["n_cycles"] = int(5.e5 / mpi.size)
    #p["n_cycles"] = int(5.e6 / mpi.size)
    p["partition_method"] = "autopartition"
    p["measure_G_tau"] = True
    p["move_shift"] = True
    p["move_double"] = True
    p["measure_pert_order"] = False
    p["performance_analysis"] = False
    p["use_trace_estimator"] = False

    mpi.report("Welcome to 5+5 (5 orbitals + 5 bath sites) test.")

    gf_struct = set_operator_structure(spin_names, orb_names, False)
    mkind = get_mkind(False, None)

    H = Operator()

    if use_interaction:
        # Local Hamiltonian
        U_mat = U_matrix(L, [F0, F2, F4], basis='cubic')
        H += h_int_slater(spin_names, orb_names, U_mat, False, H_dump=H_dump)
    else:
        mu = 0.

    p["h_int"] = H

    # Quantum numbers (N_up and N_down)
    QN = [Operator(), Operator()]
    for cn in orb_names:
        for i, sn in enumerate(spin_names):
            QN[i] += n(*mkind(sn, cn))
    if p["partition_method"] == "quantum_numbers": p["quantum_numbers"] = QN

    mpi.report("Constructing the solver...")

    # Construct the solver
    S = SolverCore(beta=beta, gf_struct=gf_struct, n_tau=n_tau, n_iw=n_iw)

    mpi.report("Preparing the hybridization function...")

    H_hyb = Operator()

    # Set hybridization function
    if Delta_dump: Delta_dump_file = open(Delta_dump, 'w')
    for sn, cn in product(spin_names, orb_names):
        bn, i = mkind(sn, cn)
        V = delta_params[cn]['V']
        e = delta_params[cn]['e']

        delta_w = Gf(mesh=MeshImFreq(beta, 'Fermion', n_iw), target_shape=[])
        delta_w << (V**2) * inverse(iOmega_n - e)

        S.G0_iw[bn][i, i] << inverse(iOmega_n + mu - atomic_levels[(bn, i)] -
                                     delta_w)

        cnb = cn + '_b'  # bath level
        a = sn + '_' + cn
        b = sn + '_' + cn + '_b'

        H_hyb += ( atomic_levels[(bn,i)] - mu ) * n(a, 0) + \
            n(b,0) * e + V * ( c(a,0) * c_dag(b,0) + c(b,0) * c_dag(a,0) )

        # Dump Delta parameters
        if Delta_dump:
            Delta_dump_file.write(bn + '\t')
            Delta_dump_file.write(str(V) + '\t')
            Delta_dump_file.write(str(e) + '\n')

    if mpi.is_master_node():
        filename_ham = 'data_Ham%s.h5' % ('_int' if use_interaction else '')
        with HDFArchive(filename_ham, 'w') as arch:
            arch['H'] = H_hyb + H
            arch['gf_struct'] = gf_struct
            arch['beta'] = beta

    mpi.report("Running the simulation...")

    # Solve the problem
    S.solve(**p)

    # Save the results
    if mpi.is_master_node():
        Results = HDFArchive(results_file_name, 'w')
        Results['G_tau'] = S.G_tau
        Results['G0_iw'] = S.G0_iw
        Results['use_interaction'] = use_interaction
        Results['delta_params'] = delta_params
        Results['spin_names'] = spin_names
        Results['orb_names'] = orb_names

        import __main__
        Results.create_group("log")
        log = Results["log"]
        log["version"] = version.version
        log["triqs_hash"] = version.triqs_hash
        log["cthyb_hash"] = version.cthyb_hash
        log["script"] = inspect.getsource(__main__)
Beispiel #16
0
if mpi.is_master_node():
    arch = HDFArchive('triangles.h5','w')
    arch['abs_errors'] = abs_error

for s in abs_error:
    if mpi.is_master_node():
        make_g_tau(g_tau)
        g_tau.data[:] += s * 2*(np.random.rand(*g_tau.data.shape) - 0.5)

    g_tau = mpi.bcast(g_tau)
    S_tau.data[:] = 1.0

    if mpi.is_master_node():
        gr_name = 'abs_error_%.4f' % s
        arch.create_group(gr_name)
        abs_err_gr = arch[gr_name]

    for name, g, S, g_rec in (('g_tau',g_tau,S_tau,g_tau_rec),):

        start = time.clock()
        cont = Som(g, S)
        cont.run(**run_params)
        exec_time = time.clock() - start

        g_rec << cont
        g_w << cont

        if mpi.is_master_node():
            abs_err_gr.create_group(name)
            gr = abs_err_gr[name]
Beispiel #17
0
        g_iw.data[:] = 0.5 * (g_iw.data[:, :, :] +
                              np.conj(g_iw.data[::-1, :, :]))
        g_tau.data[:] += s * 2 * (np.random.rand(*g_tau.data.shape) - 0.5)
        g_l.data[:] += s * 2 * (np.random.rand(*g_l.data.shape) - 0.5)

    g_iw = mpi.bcast(g_iw)
    g_tau = mpi.bcast(g_tau)
    g_l = mpi.bcast(g_l)

    S_iw.data[:] = 1.0
    S_tau.data[:] = 1.0
    S_l.data[:] = 1.0

    if mpi.is_master_node():
        gr_name = 'abs_error_%.4f' % s
        arch.create_group(gr_name)
        abs_err_gr = arch[gr_name]

    for name, g, S, g_rec in (('g_iw', g_iw, S_iw,
                               g_iw_rec), ('g_tau', g_tau, S_tau, g_tau_rec),
                              ('g_l', g_l, S_l, g_l_rec)):

        start = time.clock()
        cont = Som(g, S)
        cont.run(**run_params)
        exec_time = time.clock() - start

        g_rec << cont
        g_w << cont

        if mpi.is_master_node():
Beispiel #18
0
Converter = Wien2kConverter(filename=dft_filename, repacking=True)
Converter.convert_dft_input()
mpi.barrier()

previous_runs = 0
previous_present = False
if mpi.is_master_node():
    f = HDFArchive(dft_filename+'.h5','a')
    if 'dmft_output' in f:
        ar = f['dmft_output']
        if 'iterations' in ar:
            previous_present = True
            previous_runs = ar['iterations']
    else:
        f.create_group('dmft_output')
    del f
previous_runs    = mpi.bcast(previous_runs)
previous_present = mpi.bcast(previous_present)

SK=SumkDFT(hdf_file=dft_filename+'.h5',use_dft_blocks=use_blocks,h_field=h_field)

n_orb = SK.corr_shells[0]['dim']
l = SK.corr_shells[0]['l']
spin_names = ["up","down"]
orb_names = [i for i in range(n_orb)]

# Use GF structure determined by DFT blocks
gf_struct = [(block, indices) for block, indices in SK.gf_struct_solver[0].iteritems()]
# Construct U matrix for density-density calculations
Umat, Upmat = U_matrix_kanamori(n_orb=n_orb, U_int=U, J_hund=J)
Beispiel #19
0
                    general_parameters['config_file'])
            else:
                print '#' * 80 + '\n WARNING! specified job folder already exists continuing previous job! \n' + '#' * 80 + '\n'

        mpi.report("#" * 80)
        mpi.report('starting the DMFT calculation for ' +
                   str(general_parameters['seedname']))
        mpi.report("#" * 80)

        # basic H5 archive checks and setup
        if mpi.is_master_node():
            h5_archive = HDFArchive(
                general_parameters['jobname'] + '/' +
                general_parameters['seedname'] + '.h5', 'a')
            if not 'DMFT_results' in h5_archive:
                h5_archive.create_group('DMFT_results')
            if not 'last_iter' in h5_archive['DMFT_results']:
                h5_archive['DMFT_results'].create_group('last_iter')
            if not 'DMFT_input' in h5_archive:
                h5_archive.create_group('DMFT_input')

        # prepare observable dicts and files, which is stored on the master node
        observables = dict()
        if mpi.is_master_node():
            observables = prep_observables(general_parameters, h5_archive)
        observables = mpi.bcast(observables)

        ############################################################
        # run the dmft_cycle
        observables = dmft_cycle(general_parameters, solver_parameters,
                                 observables)