def calc_reference(): ref_orbs = [ '%s' % i for i in range(n_orbs * parms['N_x'] * parms['N_y']) ] ref_gf_struct = op.set_operator_structure(spin_names, ref_orbs, off_diag=off_diag) ref_index_converter = {(sn, o): ("loc", int(o), "down" if sn == "dn" else "up") for sn, o in product(spin_names, ref_orbs)} #print ref_index_converter,ref_orbs ref_ed = PomerolED(ref_index_converter, verbose=True) ref_N = sum( ops.n(sn, o) for sn, o in product(spin_names, ref_orbs)) # 2 3 # 0 1 ref_H = (parms["U"] * (ops.n('up', '0') * ops.n('dn', '0') + ops.n('up', '1') * ops.n('dn', '1')) - 2. * parms['t1'] * (ops.c_dag('up', '0') * ops.c('up', '1') + ops.c_dag('up', '1') * ops.c('up', '0') + ops.c_dag('dn', '0') * ops.c('dn', '1') + ops.c_dag('dn', '1') * ops.c('dn', '0')) - parms['chemical_potential'] * ref_N) # Run the solver ref_ed.diagonalize(ref_H) # Compute G(i\omega) ref_G_iw = ref_ed.G_iw(ref_gf_struct, parms['beta'], parms['n_iw']) return ref_G_iw
def make_calc(): # ------------------------------------------------------------------ # -- Hamiltonian p = ParameterCollection( beta = 0.5, U = 0.5, nw = 1, nwf = 15, V = 1.0, eps = 0.2, ) p.nwf_gf = 4 * p.nwf p.mu = 0.5*p.U # ------------------------------------------------------------------ ca_up, cc_up = c('0', 0), c_dag('0', 0) ca_do, cc_do = c('0', 1), c_dag('0', 1) ca0_up, cc0_up = c('1', 0), c_dag('1', 0) ca0_do, cc0_do = c('1', 1), c_dag('1', 1) docc = cc_up * ca_up * cc_do * ca_do nA = cc_up * ca_up + cc_do * ca_do hybridiz = p.V * (cc0_up * ca_up + cc_up * ca0_up + cc0_do * ca_do + cc_do * ca0_do) bath_lvl = p.eps * (cc0_up * ca0_up + cc0_do * ca0_do) p.H_int = p.U * docc p.H = -p.mu * nA + p.H_int + hybridiz + bath_lvl # ------------------------------------------------------------------ # -- Exact diagonalization # Conversion from TRIQS to Pomerol notation for operator indices # TRIQS: block_name, inner_index # Pomerol: site_label, orbital_index, spin_name index_converter = { ('0', 0) : ('loc', 0, 'up'), ('0', 1) : ('loc', 0, 'down'), ('1', 0) : ('loc', 1, 'up'), ('1', 1) : ('loc', 1, 'down'), } # -- Create Exact Diagonalization instance ed = PomerolED(index_converter, verbose=True) ed.diagonalize(p.H) # -- Diagonalize H p.gf_struct = [['0', [0, 1]]] # -- Single-particle Green's functions p.G_iw = ed.G_iw(p.gf_struct, p.beta, n_iw=p.nwf_gf)['0'] # -- Particle-particle two-particle Matsubara frequency Green's function opt = dict( beta=p.beta, gf_struct=p.gf_struct, blocks=set([("0", "0")]), n_iw=p.nw, n_inu=p.nwf) p.G2_iw_ph = ed.G2_iw_inu_inup(channel='PH', **opt)[('0', '0')] filename = 'data_pomerol.h5' with HDFArchive(filename,'w') as res: res['p'] = p import os os.system('tar czvf data_pomerol.tar.gz data_pomerol.h5') os.remove('data_pomerol.h5')
H = H_int + get_quadratic_operator(T, fop) up, do = spin_names index_converter = { (up, 0): ('loc', 0, 'up'), (do, 0): ('loc', 0, 'down'), (up, 1): ('loc', 1, 'up'), (do, 1): ('loc', 1, 'down'), (up, 2): ('loc', 2, 'up'), (do, 2): ('loc', 2, 'down'), (up, 3): ('loc', 3, 'up'), (do, 3): ('loc', 3, 'down'), (up, 4): ('loc', 4, 'up'), (do, 4): ('loc', 4, 'down'), (up, 5): ('loc', 5, 'up'), (do, 5): ('loc', 5, 'down'), } ed = PomerolED(index_converter, verbose=True) ed.diagonalize(H) gf_struct_up = [[up, [0, 1]]] gf_struct_do = [[do, [0, 1]]] G_tau_up = ed.G_tau(gf_struct_up, beta, n_tau=100) G_tau_do = ed.G_tau(gf_struct_do, beta, n_tau=100) with HDFArchive('kanamori_offdiag.pomerol.h5', 'w') as Results: Results['up'] = G_tau_up Results['dn'] = G_tau_do
def run_test(t1, filename): dptkeys = [ 'verbosity', 'calculate_sigma', 'calculate_sigma1', 'calculate_sigma2' ] parms = { # Solver parameters 'n_iw': 100, # Physical parameters 'U': 0.5, 't1': t1, 'beta': 10, # DMFT loop control parameters 'calculate_sigma': True, 'calculate_sigma1': True, 'calculate_sigma2': True, 'measure_G2_iw_ph': True, "measure_G2_n_bosonic": 10, "measure_G2_n_fermionic": 10, "verbosity": 4, } parms["N_x"] = 2 parms["N_y"] = 1 parms["N_z"] = 1 parms["ksi_delta"] = 1.0 # Chemical potential depends on the definition of H(k) that is used parms['chemical_potential_bare'] = 0. parms['chemical_potential'] = parms['U'] / 2. + parms[ 'chemical_potential_bare'] n_orbs = 1 # Number of orbitals off_diag = True spin_names = ['up', 'dn'] # Outer (non-hybridizing) blocks orb_names = ['%s' % i for i in range(n_orbs)] # Orbital indices gf_struct = op.set_operator_structure(spin_names, orb_names, off_diag=off_diag) if haspomerol: ##### # # Reference: 4 site cluster, calculate only G, not G2 # ##### def calc_reference(): ref_orbs = [ '%s' % i for i in range(n_orbs * parms['N_x'] * parms['N_y']) ] ref_gf_struct = op.set_operator_structure(spin_names, ref_orbs, off_diag=off_diag) ref_index_converter = {(sn, o): ("loc", int(o), "down" if sn == "dn" else "up") for sn, o in product(spin_names, ref_orbs)} #print ref_index_converter,ref_orbs ref_ed = PomerolED(ref_index_converter, verbose=True) ref_N = sum( ops.n(sn, o) for sn, o in product(spin_names, ref_orbs)) # 2 3 # 0 1 ref_H = (parms["U"] * (ops.n('up', '0') * ops.n('dn', '0') + ops.n('up', '1') * ops.n('dn', '1')) - 2. * parms['t1'] * (ops.c_dag('up', '0') * ops.c('up', '1') + ops.c_dag('up', '1') * ops.c('up', '0') + ops.c_dag('dn', '0') * ops.c('dn', '1') + ops.c_dag('dn', '1') * ops.c('dn', '0')) - parms['chemical_potential'] * ref_N) # Run the solver ref_ed.diagonalize(ref_H) # Compute G(i\omega) ref_G_iw = ref_ed.G_iw(ref_gf_struct, parms['beta'], parms['n_iw']) return ref_G_iw ref_G_iw = calc_reference() ref = ref_G_iw[ref_spin] g2_blocks = set([("up", "up"), ("up", "dn"), ("dn", "up"), ("dn", "dn")]) index_converter = {(sn, o): ("loc", int(o), "down" if sn == "dn" else "up") for sn, o in product(spin_names, orb_names)} # 1 Bath degree of freedom # Level of the bath sites epsilon = [ -parms['chemical_potential_bare'], ] index_converter.update({ ("B%i_%s" % (k, sn), 0): ("bath" + str(k), 0, "down" if sn == "dn" else "up") for k, sn in product(range(len(epsilon)), spin_names) }) # Make PomerolED solver object ed = PomerolED(index_converter, verbose=True) N = sum(ops.n(sn, o) for sn, o in product(spin_names, orb_names)) H_loc = (parms["U"] * (ops.n('up', '0') * ops.n('dn', '0')) - parms['chemical_potential'] * N) # Bath Hamiltonian: levels H_bath = sum(eps * ops.n("B%i_%s" % (k, sn), 0) for sn, (k, eps) in product(spin_names, enumerate(epsilon))) # Hybridization Hamiltonian # Bath-impurity hybridization V = [ -2 * bath_prefactor * t1, ] H_hyb = ops.Operator() for k, v in enumerate(V): H_hyb += sum( v * ops.c_dag("B%i_%s" % (k, sn), 0) * ops.c(sn, '0') + np.conj(v) * ops.c_dag(sn, '0') * ops.c("B%i_%s" % (k, sn), 0) for sn in spin_names) # Obtain bath sites from Delta and create H_ED H_ED = H_loc + H_bath + H_hyb # Run the solver ed.diagonalize(H_ED) # Compute G(i\omega) G_iw = ed.G_iw(gf_struct, parms['beta'], parms['n_iw']) if parms["measure_G2_iw_ph"]: common_g2_params = { 'gf_struct': gf_struct, 'beta': parms['beta'], 'blocks': g2_blocks, 'n_iw': parms['measure_G2_n_bosonic'] } G2_iw = ed.G2_iw_inu_inup(channel="PH", block_order="AABB", n_inu=parms['measure_G2_n_fermionic'], **common_g2_params) if mpi.is_master_node(): with ar.HDFArchive(filename, 'w') as arch: arch["parms"] = parms arch["G_iw"] = G_iw arch["G2_iw"] = G2_iw arch["ref"] = ref else: # haspomerol is False with ar.HDFArchive(filename, 'r') as arch: ref = arch['ref'] G_iw = arch['G_iw'] G2_iw = arch['G2_iw'] BL = lattice.BravaisLattice(units=[ (1, 0, 0), ]) #linear lattice kmesh = gf.MeshBrillouinZone(lattice.BrillouinZone(BL), parms["N_x"]) Hk_blocks = [gf.Gf(indices=orb_names, mesh=kmesh) for spin in spin_names] Hk = gf.BlockGf(name_list=spin_names, block_list=Hk_blocks) def Hk_f(k): return -2 * parms['t1'] * (np.cos(k[0])) * np.eye(1) for spin, _ in Hk: for k in Hk.mesh: Hk[spin][k] = Hk_f(k.value) # Construct the DF2 program X = dualfermion.Dpt(beta=parms['beta'], gf_struct=gf_struct, Hk=Hk, n_iw=parms['n_iw'], n_iw2=parms["measure_G2_n_fermionic"], n_iW=parms["measure_G2_n_bosonic"]) for name, g0 in X.Delta: X.Delta[name] << gf.inverse( gf.iOmega_n + parms['chemical_potential_bare']) * bath_prefactor**2 * 4 * t1**2 X.G2_iw << G2_iw # Run the dual perturbation theory X.gimp << G_iw # Load G from impurity solver dpt_parms = {key: parms[key] for key in parms if key in dptkeys} X.run(**dpt_parms)
ops.c_dag('dn', '3') * ops.c('dn', '1')) - parms['chemical_potential'] * ref_N) # Run the solver ref_ed.diagonalize(ref_H) # Compute G(i\omega) ref_G_iw = ref_ed.G_iw(ref_gf_struct, parms['beta'], parms['n_iw']) return ref_G_iw ref_G_iw = calc_reference() ref = ref_G_iw[spin] # Obtain bath sites from Delta and create H_ED H_ED = H # Run the solver ed.diagonalize(H_ED) # Compute G(i\omega) G_iw = ed.G_iw(gf_struct, parms['beta'], parms['n_iw']) if parms["measure_G2_iw_ph"]: common_g2_params = { 'gf_struct': gf_struct, 'beta': parms['beta'], 'blocks': g2_blocks, 'n_iw': parms['measure_G2_n_bosonic'] } G2_iw = ed.G2_iw_inu_inup(channel="PH", block_order="AABB", n_inu=parms['measure_G2_n_fermionic'], **common_g2_params)
from pomerol2triqs import PomerolED # ---------------------------------------------------------------------- if __name__ == '__main__': if mpi.is_master_node(): with HDFArchive('data_model.h5', 'r') as A: p = A["p"] else: p = None p = mpi.bcast(p) p.convert_keys_from_string_to_python('index_converter') pom = PomerolED(p.index_converter, verbose=True) pom.diagonalize(p.H) p.g_iw = pom.G_iw(p.gf_struct, p.beta, n_iw=400) p.g_tau = pom.G_tau(p.gf_struct, p.beta, n_tau=200)['0'] p.tau = np.array([float(tau) for tau in p.g_tau.mesh]) opt = dict(block_order='AABB', beta=p.beta, gf_struct=p.gf_struct, blocks=set([('0', '0')]), n_iw=1, n_inu=10) p.g4_ph = pom.G2_iw_inu_inup(channel='PH', **opt)['0', '0'] if mpi.is_master_node():
class Solver: def __init__(self, beta, gf_struct, n_iw, spin_orbit=False, verbose=True): self.beta = beta self.gf_struct = gf_struct self.n_iw = n_iw self.spin_orbit = spin_orbit self.verbose = verbose if self.verbose and mpi.is_master_node(): print "\n*** Hubbard I solver using Pomerol library" print "*** gf_struct =", gf_struct print "*** n_iw =", n_iw # get spin_name and orb_names from gf_struct self.__analyze_gf_struct(gf_struct) if self.verbose and mpi.is_master_node(): print "*** spin_names =", self.spin_names print "*** orb_names =", self.orb_names # check spin_names for sn in self.spin_names: if not spin_orbit: assert sn in ('down', 'dn', 'up' ) # become either 'down' or 'up' if spin_orbit: assert sn in ('down', 'dn', 'ud') # all become 'down' # Conversion from TRIQS to Pomerol notation for operator indices # TRIQS: ('dn', '-2') --> Pomerol: ('atom', 0, 'down') # NOTE: When spin_orbit is true, only spin 'down' is used. mkind = get_mkind(True, None) index_converter = { mkind(sn, bn): ("atom", bi, "down" if sn == "dn" or sn == "ud" else sn) for sn, (bi, bn) in product(self.spin_names, enumerate(self.orb_names)) } self.__ed = PomerolED(index_converter, verbose, spin_orbit) # init G_iw glist = lambda: [ GfImFreq(indices=self.orb_names, beta=beta, n_points=n_iw) for block, inner in gf_struct.items() ] self.G_iw = BlockGf(name_list=self.spin_names, block_list=glist(), make_copies=False) self.G_iw.zero() self.G0_iw = self.G_iw.copy() self.Sigma_iw = self.G_iw.copy() def solve(self, H_int, E_levels, integrals_of_motion=None, density_matrix_cutoff=1e-10, file_quantum_numbers="", file_eigenvalues=""): self.__copy_E_levels(E_levels) H_0 = sum( self.E_levels[sn][oi1, oi2].real * c_dag(sn, on1) * c(sn, on2) for sn, (oi1, on1), ( oi2, on2) in product(self.spin_names, enumerate( self.orb_names), enumerate(self.orb_names))) if self.verbose and mpi.is_master_node(): print "\n*** compute G_iw and Sigma_iw" print "*** E_levels =", E_levels print "*** H_0 =", H_0 # print "*** integrals_of_motion =", integrals_of_motion N_op = sum( c_dag(sn, on) * c(sn, on) for sn, on in product(self.spin_names, self.orb_names)) if integrals_of_motion is None: if self.spin_orbit: # use only N op as integrals_of_motion when spin-orbit coupling is included self.__ed.diagonalize(H_0 + H_int, integrals_of_motion=[N_op]) else: # use N and S_z as integrals of motion by default self.__ed.diagonalize(H_0 + H_int) else: assert isinstance(integrals_of_motion, list) # check commutation relation in advance (just for test) if self.verbose and mpi.is_master_node(): print "*** Integrals of motion:" for i, op in enumerate(integrals_of_motion): print " op%d =" % i, op print "*** commutation relations:" is_commute = lambda h, op: h * op - op * h str_if_commute = lambda h, op: "== 0" if is_commute( h, op).is_zero() else "!= 0" for i, op in enumerate(integrals_of_motion): print " [H_0, op%d]" % i, str_if_commute( H_0, op), " [H_int, op%d]" % i, str_if_commute(H_int, op) self.__ed.diagonalize(H_0 + H_int, integrals_of_motion) # save data if file_quantum_numbers: self.__ed.save_quantum_numbers(file_quantum_numbers) if file_eigenvalues: self.__ed.save_eigenvalues(file_eigenvalues) # set density-matrix cutoff self.__ed.set_density_matrix_cutoff(density_matrix_cutoff) # Compute G(i\omega) self.G_iw << self.__ed.G_iw(self.gf_struct, self.beta, self.n_iw) # Compute G0 and Sigma E_list = [self.E_levels[sn] for sn in self.spin_names] # from dict to list self.G0_iw << iOmega_n self.G0_iw -= E_list self.Sigma_iw << self.G0_iw - inverse(self.G_iw) self.G0_iw.invert() # ********************************************************************* # TODO: tail # set tail of Sigma at all zero in the meantime, because tail of G is # not computed in pomerol solver. This part should be improved. # ********************************************************************* for s, sig in self.Sigma_iw: sig.tail.zero() def __copy_E_levels(self, E_levels): """Copy E_levels after checking the data structure""" # check data structure assert (isinstance(E_levels, dict)) for key, value in E_levels.items(): assert (isinstance(value, np.ndarray)) assert (value.shape == (len(self.orb_names), len(self.orb_names))) # copy self.E_levels = E_levels.copy() def __analyze_gf_struct(self, gf_struct): assert (isinstance(gf_struct, dict)) self.spin_names = gf_struct.keys() self.orb_names = gf_struct.values()[0] for value in gf_struct.values(): assert (self.orb_names == value ) # check if all spin blocks have the same orbitals
# z-component of angular momentum Lz = L_op('z', spin_names, orb_names, off_diag=False, basis='spherical') # Double check that we are actually using integrals of motion h_comm = lambda op: H * op - op * H assert h_comm(N).is_zero() assert h_comm(Sz).is_zero() assert h_comm(Lz).is_zero() # Diagonalize H # Do not split H into blocks (uncomment to generate reference data) #ed.diagonalize(H, True) ed.diagonalize(H, [N, Sz, Lz]) # Compute G(i\omega) G_iw = ed.G_iw(gf_struct, beta, n_iw) # Compute G(\tau) G_tau = ed.G_tau(gf_struct, beta, n_tau) if mpi.is_master_node(): with HDFArchive('slater_gf.out.h5', 'w') as ar: ar['H'] = H ar['G_iw'] = G_iw ar['G_tau'] = G_tau with HDFArchive("slater_gf.ref.h5", 'r') as ar: assert (ar['H'] - H).is_zero()
def make_calc(): # ------------------------------------------------------------------ # -- Hubbard atom with two bath sites, Hamiltonian p = ParameterCollection( beta=1.0, U=5.0, nw=1, nwf=20, ) p.nwf_gf = 4 * p.nwf p.mu = 0.5 * p.U # ------------------------------------------------------------------ ca_up, cc_up = c('0', 0), c_dag('0', 0) ca_do, cc_do = c('0', 1), c_dag('0', 1) docc = cc_up * ca_up * cc_do * ca_do nA = cc_up * ca_up + cc_do * ca_do p.H = -p.mu * nA + p.U * docc # ------------------------------------------------------------------ # -- Exact diagonalization # Conversion from TRIQS to Pomerol notation for operator indices # TRIQS: block_name, inner_index # Pomerol: site_label, orbital_index, spin_name index_converter = { ('0', 0): ('loc', 0, 'up'), ('0', 1): ('loc', 0, 'down'), } # -- Create Exact Diagonalization instance ed = PomerolED(index_converter, verbose=True) ed.diagonalize(p.H) # -- Diagonalize H gf_struct = [['0', [0, 1]]] # -- Single-particle Green's functions p.G_iw = ed.G_iw(gf_struct, p.beta, n_iw=p.nwf_gf)['0'] # -- Particle-particle two-particle Matsubara frequency Green's function opt = dict(beta=p.beta, gf_struct=gf_struct, blocks=set([("0", "0")]), n_iw=p.nw, n_inu=p.nwf) p.G2_iw_ph = ed.G2_iw_inu_inup(channel='PH', **opt)[('0', '0')] # ------------------------------------------------------------------ # -- Generalized susceptibility in magnetic PH channel p.chi_m = Gf(mesh=p.G2_iw_ph.mesh, target_shape=[1, 1, 1, 1]) p.chi_m[0, 0, 0, 0] = p.G2_iw_ph[0, 0, 0, 0] - p.G2_iw_ph[0, 0, 1, 1] p.chi0_m = chi0_from_gg2_PH(p.G_iw, p.chi_m) p.label = r'Pomerol' # ------------------------------------------------------------------ # -- Generalized susceptibility in PH channel p.chi = chi_from_gg2_PH(p.G_iw, p.G2_iw_ph) p.chi0 = chi0_from_gg2_PH(p.G_iw, p.G2_iw_ph) p.gamma = inverse_PH(p.chi0) - inverse_PH(p.chi) # ------------------------------------------------------------------ # -- Store to hdf5 filename = 'data_pomerol.h5' with HDFArchive(filename, 'w') as res: res['p'] = p
def make_calc(nw=10, beta=2.0, h_field=0.0): # ------------------------------------------------------------------ # -- Hubbard atom with two bath sites, Hamiltonian p = ParameterCollection( beta=beta, V1=2.0, V2=5.0, epsilon1=0.00, epsilon2=4.00, h_field=h_field, mu=2.0, U=5.0, ntau=40, niw=15, n_inu=nw, ) # ------------------------------------------------------------------ print '--> Solving SIAM with parameters' print p # ------------------------------------------------------------------ up, do = 'up', 'dn' docc = c_dag(up, 0) * c(up, 0) * c_dag(do, 0) * c(do, 0) mA = c_dag(up, 0) * c(up, 0) - c_dag(do, 0) * c(do, 0) nA = c_dag(up, 0) * c(up, 0) + c_dag(do, 0) * c(do, 0) nB = c_dag(up, 1) * c(up, 1) + c_dag(do, 1) * c(do, 1) nC = c_dag(up, 2) * c(up, 2) + c_dag(do, 2) * c(do, 2) p.H = -p.mu * nA + p.U * docc + p.h_field * mA + \ p.epsilon1 * nB + p.epsilon2 * nC + \ p.V1 * (c_dag(up,0)*c(up,1) + c_dag(up,1)*c(up,0) + \ c_dag(do,0)*c(do,1) + c_dag(do,1)*c(do,0) ) + \ p.V2 * (c_dag(up,0)*c(up,2) + c_dag(up,2)*c(up,0) + \ c_dag(do,0)*c(do,2) + c_dag(do,2)*c(do,0) ) # ------------------------------------------------------------------ # -- Exact diagonalization # Conversion from TRIQS to Pomerol notation for operator indices # TRIQS: block_name, inner_index # Pomerol: site_label, orbital_index, spin_name index_converter = { (up, 0): ('loc', 0, 'up'), (do, 0): ('loc', 0, 'down'), (up, 1): ('loc', 1, 'up'), (do, 1): ('loc', 1, 'down'), (up, 2): ('loc', 2, 'up'), (do, 2): ('loc', 2, 'down'), } # -- Create Exact Diagonalization instance ed = PomerolED(index_converter, verbose=True) ed.diagonalize(p.H) # -- Diagonalize H gf_struct = [[up, [0]], [do, [0]]] # -- Single-particle Green's functions p.G_iw = ed.G_iw(gf_struct, beta, n_iw=100) p.G_tau = ed.G_tau(gf_struct, beta, n_tau=400) # -- Particle-particle two-particle Matsubara frequency Green's function opt = dict(block_order='AABB', beta=beta, gf_struct=gf_struct, blocks=set([(up, up), (up, do)]), n_iw=1, n_inu=p.n_inu) p.G2_iw_ph = ed.G2_iw_inu_inup(channel='PH', **opt) # ------------------------------------------------------------------ # -- Store to hdf5 mpi.barrier() if mpi.is_master_node(): filename = 'data_pomerol_h_field_%4.4f.h5' % h_field with HDFArchive(filename, 'w') as res: res['p'] = p
def make_calc(): # ------------------------------------------------------------------ # -- Hubbard atom with two bath sites, Hamiltonian params = dict( beta=2.0, V1=2.0, V2=5.0, epsilon1=0.00, epsilon2=4.00, mu=2.0, U=5.0, ntau=40, niw=15, ) # ------------------------------------------------------------------ class Dummy(): def __init__(self): pass d = Dummy() # storage space d.params = params print '--> Solving SIAM with parameters' for key, value in params.items(): print '%10s = %-10s' % (key, str(value)) globals()[key] = value # populate global namespace # ------------------------------------------------------------------ up, do = 'up', 'dn' docc = c_dag(up, 0) * c(up, 0) * c_dag(do, 0) * c(do, 0) nA = c_dag(up, 0) * c(up, 0) + c_dag(do, 0) * c(do, 0) nB = c_dag(up, 1) * c(up, 1) + c_dag(do, 1) * c(do, 1) nC = c_dag(up, 2) * c(up, 2) + c_dag(do, 2) * c(do, 2) d.H = -mu * nA + epsilon1 * nB + epsilon2 * nC + U * docc + \ V1 * (c_dag(up,0)*c(up,1) + c_dag(up,1)*c(up,0) + \ c_dag(do,0)*c(do,1) + c_dag(do,1)*c(do,0) ) + \ V2 * (c_dag(up,0)*c(up,2) + c_dag(up,2)*c(up,0) + \ c_dag(do,0)*c(do,2) + c_dag(do,2)*c(do,0) ) # ------------------------------------------------------------------ # -- Exact diagonalization # Conversion from TRIQS to Pomerol notation for operator indices # TRIQS: block_name, inner_index # Pomerol: site_label, orbital_index, spin_name index_converter = { (up, 0): ('loc', 0, 'up'), (do, 0): ('loc', 0, 'down'), (up, 1): ('loc', 1, 'up'), (do, 1): ('loc', 1, 'down'), (up, 2): ('loc', 2, 'up'), (do, 2): ('loc', 2, 'down'), } # -- Create Exact Diagonalization instance ed = PomerolED(index_converter, verbose=True) ed.diagonalize(d.H) # -- Diagonalize H gf_struct = [[up, [0]], [do, [0]]] # -- Single-particle Green's functions G_iw = ed.G_iw(gf_struct, beta, n_iw=niw) G_tau = ed.G_tau(gf_struct, beta, n_tau=ntau) G_w = ed.G_w(gf_struct, beta, energy_window=(-2.5, 2.5), n_w=100, im_shift=0.01) d.G_iw = G_iw['up'] d.G_tau = G_tau['up'] d.G_w = G_w['up'] # -- Particle-particle two-particle Matsubara frequency Green's function opt = dict(block_order='AABB', beta=beta, gf_struct=gf_struct, blocks=set([("up", "dn")]), n_iw=niw, n_inu=niw) G2_iw = ed.G2_iw_inu_inup(channel='AllFermionic', **opt) d.G2_iw = G2_iw['up', 'dn'] G2_iw_pp = ed.G2_iw_inu_inup(channel='PP', **opt) d.G2_iw_pp = G2_iw_pp['up', 'dn'] G2_iw_ph = ed.G2_iw_inu_inup(channel='PH', **opt) d.G2_iw_ph = G2_iw_ph['up', 'dn'] # ------------------------------------------------------------------ # -- Store to hdf5 filename = 'data_pomerol.h5' with HDFArchive(filename, 'w') as res: for key, value in d.__dict__.items(): res[key] = value