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()
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)
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!
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
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()
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)
#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
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)
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
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("=================")
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)
# 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__)
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
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__)
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]
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():
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)
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)