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(beta=2.0, h_field=0.0): # ------------------------------------------------------------------ # -- Hubbard atom with two bath sites, Hamiltonian p = ParameterCollection( beta = beta, h_field = h_field, U = 5.0, ntau = 40, niw = 15, ) p.mu = 0.5*p.U # ------------------------------------------------------------------ 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) p.H = -p.mu * nA + p.U * docc + p.h_field * mA # ------------------------------------------------------------------ fundamental_operators = [c(up,0), c(do,0)] ed = TriqsExactDiagonalization(p.H, fundamental_operators, p.beta) g_tau = GfImTime(beta=beta, statistic='Fermion', n_points=40, indices=[0]) g_iw = GfImFreq(beta=beta, statistic='Fermion', n_points=10, indices=[0]) p.G_tau = BlockGf(name_list=[up,do], block_list=[g_tau]*2, make_copies=True) p.G_iw = BlockGf(name_list=[up,do], block_list=[g_iw]*2, make_copies=True) ed.set_g2_tau(p.G_tau[up], c(up,0), c_dag(up,0)) ed.set_g2_tau(p.G_tau[do], c(do,0), c_dag(do,0)) ed.set_g2_iwn(p.G_iw[up], c(up,0), c_dag(up,0)) ed.set_g2_iwn(p.G_iw[do], c(do,0), c_dag(do,0)) p.magnetization = ed.get_expectation_value(0.5 * mA) p.magnetization2 = ed.get_expectation_value(0.25 * mA * mA) # ------------------------------------------------------------------ # -- Store to hdf5 filename = 'data_pyed_h_field_%4.4f.h5' % h_field with HDFArchive(filename,'w') as res: res['p'] = p
def test_fundamental(): assert (op_is_fundamental(c(0, 0)) is True) assert (op_is_fundamental(c_dag(0, 0)) is True) assert (op_is_fundamental(c_dag(0, 0) * c(0, 0)) is False) assert (op_is_fundamental(Operator(1.0)) is False) assert (op_serialize_fundamental(c(0, 0)) == (False, (0, 0))) assert (op_serialize_fundamental(c_dag(0, 0)) == (True, (0, 0))) assert (op_serialize_fundamental(c(2, 4)) == (False, (2, 4))) assert (op_serialize_fundamental(c_dag(4, 3)) == (True, (4, 3)))
def test_single_particle_transform(verbose=False): if verbose: print('--> test_single_particle_transform') h_loc = np.array([ [1.0, 0.0], [0.0, -1.0], ]) op_imp = [c(0, 0), c(0, 1)] H_loc = get_quadratic_operator(h_loc, op_imp) H_loc_ref = c_dag(0, 0) * c(0, 0) - c_dag(0, 1) * c(0, 1) assert ((H_loc - H_loc_ref).is_zero()) h_loc_ref = quadratic_matrix_from_operator(H_loc, op_imp) np.testing.assert_array_almost_equal(h_loc, h_loc_ref) if verbose: print('h_loc =\n', h_loc) print('h_loc_ref =\n', h_loc_ref) print('H_loc =', H_loc) T_ab = np.array([ [1., 1.], [1., -1.], ]) / np.sqrt(2.) Ht_loc = operator_single_particle_transform(H_loc, T_ab, op_imp) ht_loc = quadratic_matrix_from_operator(Ht_loc, op_imp) ht_loc_ref = np.array([ [0., 1.], [1., 0.], ]) Ht_loc_ref = c_dag(0, 0) * c(0, 1) + c_dag(0, 1) * c(0, 0) if verbose: print('ht_loc =\n', ht_loc) print('ht_loc_ref =\n', ht_loc_ref) print('Ht_loc =', Ht_loc) print('Ht_loc_ref =', Ht_loc_ref) assert ((Ht_loc - Ht_loc_ref).is_zero())
def test_sparse_matrix_representation(): up, do = 0, 1 fundamental_operators = [c(up, 0), c(do, 0)] rep = SparseMatrixRepresentation(fundamental_operators) # -- Test an operator O_mat = rep.sparse_matrix(c(up, 0)) O_ref = rep.sparse_operators.c_dag[0].getH() compare_sparse_matrices(O_mat, O_ref) # -- Test O_mat = rep.sparse_matrix(c(do, 0)) O_ref = rep.sparse_operators.c_dag[1].getH() compare_sparse_matrices(O_mat, O_ref) # -- Test expression H_expr = c(up, 0) * c(do, 0) * c_dag(up, 0) * c_dag(do, 0) H_mat = rep.sparse_matrix(H_expr) c_dag0, c_dag1 = rep.sparse_operators.c_dag c_0, c_1 = c_dag0.getH(), c_dag1.getH() H_ref = c_0 * c_1 * c_dag0 * c_dag1 compare_sparse_matrices(H_mat, H_ref)
def convert_operator(self, O, ish=0): """ Converts a second-quantization operator from sumk structure to solver structure. Parameters ---------- O : triqs.operators.Operator Operator in sumk structure ish : int shell index on which the operator acts """ from triqs.operators import Operator, c, c_dag T = self.transformation[ish] sk2s = self.sumk_to_solver[ish] O_out = Operator(0) for monomial in O: coefficient = monomial[-1] new_monomial = Operator(1) #if coefficient > 1e-10: for single_operator in monomial[0]: new_single_operator = Operator(0) daggered = single_operator[0] blockname = single_operator[1][0] i = single_operator[1][1] for j in range(len(T[blockname])): if sk2s[(blockname, j)] != (None, None): if daggered: new_single_operator += ( T[blockname][j, i] * c_dag(*sk2s[(blockname, j)])) else: new_single_operator += ( T[blockname][j, i].conjugate() * c(*sk2s[(blockname, j)])) new_monomial *= new_single_operator O_out += new_monomial * coefficient return O_out
def test_two_particle_greens_function(): # ------------------------------------------------------------------ # -- Hubbard atom with two bath sites, Hamiltonian beta = 2.0 V1 = 2.0 V2 = 5.0 epsilon1 = 0.00 epsilon2 = 4.00 mu = 2.0 U = 0.0 up, do = 0, 1 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) 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 fundamental_operators = [ c(up, 0), c(do, 0), c(up, 1), c(do, 1), c(up, 2), c(do, 2) ] ed = TriqsExactDiagonalization(H, fundamental_operators, beta) # ------------------------------------------------------------------ # -- single particle Green's functions g_tau = GfImTime(name=r'$g$', beta=beta, statistic='Fermion', n_points=100, target_shape=(1, 1)) ed.set_g2_tau(g_tau[0, 0], c(up, 0), c_dag(up, 0)) # ------------------------------------------------------------------ # -- Two particle Green's functions ntau = 10 imtime = MeshImTime(beta, 'Fermion', ntau) prodmesh = MeshProduct(imtime, imtime, imtime) g40_tau = Gf(name='g40_tau', mesh=prodmesh, target_shape=(1, 1, 1, 1)) g4_tau = Gf(name='g4_tau', mesh=prodmesh, target_shape=(1, 1, 1, 1)) ed.set_g40_tau_matrix(g40_tau, g_tau) ed.set_g4_tau(g4_tau[0, 0, 0, 0], c(up, 0), c_dag(up, 0), c(up, 0), c_dag(up, 0)) # ------------------------------------------------------------------ # -- compare zero_outer_planes_and_equal_times(g4_tau) zero_outer_planes_and_equal_times(g40_tau) np.testing.assert_array_almost_equal(g4_tau.data, g40_tau.data)
n_orb_bath = len(eps_bath) # Non-interacting impurity hamiltonian in matrix representation h_0_mat = diag(eps - mu) - matrix([[0, t + a, 0, a], [t - a, 0, -a, 0], [0, a, 0, t + a], [-a, 0, t - a, 0]]) # Bath hamiltonian in matrix representation h_bath_mat = diag(eps_bath) - matrix([[0, t_bath, 0, 0], [t_bath, 0, 0, 0], [0, 0, 0, t_bath], [0, 0, t_bath, 0]]) # Coupling matrix V_mat = matrix([[1., 0., 0, 0], [0., 1., 0, 0], [0., 0., 1, 0], [0., 0., 0, 1]]) # ==== Local Hamiltonian ==== c_dag_vec = matrix([[c_dag('bl', o) for o in range(n_orb)]]) c_vec = matrix([[c('bl', o)] for o in range(n_orb)]) h_0 = (c_dag_vec * h_0_mat * c_vec)[0, 0] h_int = U * n('bl', up_0) * n('bl', dn_0) + \ U * n('bl', up_1) * n('bl', dn_1) + \ U * n('bl', up_0) * n('bl', dn_1) + \ U * n('bl', up_1) * n('bl', dn_0) + \ Up * n('bl', up_0) * n('bl', up_1) + \ Up * n('bl', dn_0) * n('bl', dn_1) h_imp = h_0 + h_int # ==== Bath & Coupling hamiltonian ==== c_dag_bath_vec = matrix(
n_orb = len(eps) n_orb_bath = len(eps_bath) # Non-interacting impurity hamiltonian in matrix representation h_0_mat = diag(eps - mu) - matrix([[0, t, t], [t, 0, t], [t, t, 0]]) # Bath hamiltonian in matrix representation h_bath_mat = diag(eps_bath) - matrix([[0, t_bath, t_bath], [t_bath, 0, t_bath], [t_bath, t_bath, 0]]) # Coupling matrix V_mat = matrix([[1., 1., 1.], [1., 1., 1.], [1., 1., 1.]]) # ==== Local Hamiltonian ==== c_dag_vec = { s: matrix([[c_dag(s, o) for o in range(n_orb)]]) for s in block_names } c_vec = {s: matrix([[c(s, o)] for o in range(n_orb)]) for s in block_names} h_0 = sum(c_dag_vec[s] * h_0_mat * c_vec[s] for s in block_names)[0, 0] Umat, Upmat = U_matrix_kanamori(n_orb, U_int=U, J_hund=J) h_int = h_int_kanamori(block_names, range(n_orb), Umat, Upmat, J, off_diag=True) h_imp = h_0 + h_int
def test_cf_G_tau_and_G_iw_nonint(verbose=False): beta = 3.22 eps = 1.234 niw = 64 ntau = 2 * niw + 1 H = eps * c_dag(0, 0) * c(0, 0) fundamental_operators = [c(0, 0)] ed = TriqsExactDiagonalization(H, fundamental_operators, beta) # ------------------------------------------------------------------ # -- Single-particle Green's functions G_tau = GfImTime(beta=beta, statistic='Fermion', n_points=ntau, target_shape=(1, 1)) G_iw = GfImFreq(beta=beta, statistic='Fermion', n_points=niw, target_shape=(1, 1)) G_iw << inverse(iOmega_n - eps) G_tau << Fourier(G_iw) G_tau_ed = GfImTime(beta=beta, statistic='Fermion', n_points=ntau, target_shape=(1, 1)) G_iw_ed = GfImFreq(beta=beta, statistic='Fermion', n_points=niw, target_shape=(1, 1)) ed.set_g2_tau(G_tau_ed[0, 0], c(0, 0), c_dag(0, 0)) ed.set_g2_iwn(G_iw_ed[0, 0], c(0, 0), c_dag(0, 0)) # ------------------------------------------------------------------ # -- Compare gfs from triqs.utility.comparison_tests import assert_gfs_are_close assert_gfs_are_close(G_tau, G_tau_ed) assert_gfs_are_close(G_iw, G_iw_ed) # ------------------------------------------------------------------ # -- Plotting if verbose: from triqs.plot.mpl_interface import oplot, plt subp = [3, 1, 1] plt.subplot(*subp) subp[-1] += 1 oplot(G_tau.real) oplot(G_tau_ed.real) plt.subplot(*subp) subp[-1] += 1 diff = G_tau - G_tau_ed oplot(diff.real) oplot(diff.imag) plt.subplot(*subp) subp[-1] += 1 oplot(G_iw) oplot(G_iw_ed) plt.show()
from triqs.operators import c, c_dag, Operator from triqs.atom_diag import * from itertools import product import numpy as np orbs = (1, 2, 3) spins = ("dn", "up") # Construct a sum of the pair hopping and spin flip terms from a 3-orbital Kanamori interaction Hamiltonian H_p = Operator() H_J = Operator() for o1, o2 in product(orbs, repeat=2): if o1 == o2: continue H_p += c_dag("dn", o1) * c_dag("up", o1) * c("up", o2) * c("dn", o2) H_J += c_dag("dn", o1) * c("up", o1) * c_dag("up", o2) * c("dn", o2) H = H_p + H_J fops1 = [(s, o) for (s, o) in product(spins, orbs)] fops2 = [(s, o) for (o, s) in product(orbs, spins)] ad1 = AtomDiag(H, fops1) ad2 = AtomDiag(H, fops2) # for e1, e2 in zip(ad1.energies, ad2.energies): # print(e1.round(5), e2.round(5)) # Check that subspace energies are identical up to ordering assert len(ad1.energies) == len(ad2.energies)
if __name__ == '__main__': # ------------------------------------------------------------------ # -- Hubbard atom with two bath sites, Hamiltonian beta = 10.0 V1 = 1.0 V2 = 1.0 epsilon1 = +2.30 epsilon2 = -2.30 t = 0.1 mu = 1.0 U = 2.0 up, do = 0, 1 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) hopA = c_dag(up, 0) * c(do, 0) + c_dag(do, 0) * c(up, 0) hopB = c_dag(up, 1) * c(do, 1) + c_dag(do, 1) * c(up, 1) hopC = c_dag(up, 2) * c(do, 2) + c_dag(do, 2) * c(up, 2) 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) ) + \ -t * (hopA + hopB + hopC)
U = 2.3 # Density-density interaction J = 0.4 # Hunds coupling n_iw = int(10 * beta) # The number of positive Matsubara frequencies n_k = 16 # The number of k-points per dimension block_names = ['up', 'dn'] # The spins n_orb = 3 TBL = tight_binding_model(lambda_soc=0.) # The Tight-Binding Lattice TBL.bz = BrillouinZone(TBL.bl) # ==== Local Hamiltonian ==== c_dag_vec = { s: matrix([[c_dag(s,o) for o in range(n_orb)]]) for s in block_names } c_vec = { s: matrix([[c(s,o)] for o in range(n_orb)]) for s in block_names } h_0_mat = TBL.hoppings[(0,0,0)][0:n_orb,0:n_orb] h_0 = sum(c_dag_vec[s] * h_0_mat * c_vec[s] for s in block_names)[0,0] Umat, Upmat = U_matrix_kanamori(n_orb, U_int=U, J_hund=J) h_int = h_int_kanamori(block_names, range(n_orb), Umat, Upmat, J, off_diag=True) h_imp = h_0 + h_int # ==== Non-Interacting Impurity Green function ==== gf_struct = [ (s,n_orb) for s in block_names ] iw_mesh = MeshImFreq(beta, 'Fermion', n_iw)
orb_names = [up_0, up_1, dn_0, dn_1] # Non-interacting impurity hamiltonian in matrix representation h_0_mat = diag(eps - mu) - matrix([[0, t + a, 0, a], [t - a, 0, -a, 0], [0, a, 0, t + a], [-a, 0, t - a, 0]]) # Bath hamiltonian in matrix representation h_bath_mat = diag(eps_bath) - matrix([[0, t_bath, 0, 0], [t_bath, 0, 0, 0], [0, 0, 0, t_bath], [0, 0, t_bath, 0]]) # Coupling matrix V_mat = matrix([[1., 0., 0, 0], [0., 1., 0, 0], [0., 0., 1, 0], [0., 0., 0, 1]]) # ==== Local Hamiltonian ==== c_dag_vec = matrix([[c_dag('bl', o) for o in orb_names]]) c_vec = matrix([[c('bl', o)] for o in orb_names]) h_0 = (c_dag_vec * h_0_mat * c_vec)[0, 0] h_int = U * n('bl', up_0) * n('bl', dn_0) + \ U * n('bl', up_1) * n('bl', dn_1) + \ U * n('bl', up_0) * n('bl', dn_1) + \ U * n('bl', up_1) * n('bl', dn_0) + \ Up * n('bl', up_0) * n('bl', up_1) + \ Up * n('bl', dn_0) * n('bl', dn_1) h_imp = h_0 + h_int # ==== Bath & Coupling hamiltonian ==== orb_bath_names = ['b_' + str(o) for o in orb_names]
SOC = 0.1 # Spin-orbit coupling n_iw = int(10 * beta) # The number of positive Matsubara frequencies n_k = 16 # The number of k-points per dimension block_names = ['up', 'dn'] # The spins orb_names = [0, 1, 2] # The orbitals idx_lst = list(range(len(block_names) * len(orb_names))) gf_struct = [('bl', idx_lst)] TBL = tight_binding_model(lambda_soc=SOC) # The Tight-Binding Lattice TBL.bz = BrillouinZone(TBL.bl) n_idx = len(idx_lst) # ==== Local Hamiltonian ==== c_dag_vec = matrix([[c_dag('bl', idx) for idx in idx_lst]]) c_vec = matrix([[c('bl', idx)] for idx in idx_lst]) h_0_mat = TBL._hop[(0, 0, 0)] h_0 = (c_dag_vec * h_0_mat * c_vec)[0, 0] Umat, Upmat = U_matrix_kanamori(len(orb_names), U_int=U, J_hund=J) op_map = {(s, o): ('bl', i) for i, (s, o) in enumerate(product(block_names, orb_names))} h_int = h_int_kanamori(block_names, orb_names, Umat, Upmat, J, off_diag=True, map_operator_structure=op_map)
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)
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')
# ---------------------------------------------------------------------- if __name__ == '__main__': # ------------------------------------------------------------------ # -- Hubbard atom with two bath sites, Hamiltonian beta = 2.0 V1 = 2.0 V2 = 5.0 epsilon1 = 0.00 epsilon2 = 4.00 mu = 2.0 U = 0.0 up, do = 0, 1 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) 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 fundamental_operators = [ c(up,0), c(do,0), c(up,1), c(do,1), c(up,2), c(do,2)]
Hk=Hk, n_iw=parms['n_iw'], n_iw2=parms["measure_G2_n_fermionic"], n_iW=parms["measure_G2_n_bosonic"]) if haspomerol: 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)} # 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 = (parms["Ua"] * (ops.n('up', '0') * ops.n('dn', '0')) + parms["Ub"] * (ops.n('up', '1') * ops.n('dn', '1')) + parms['t0'] * (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'] * N) ##### # # 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'])] ref_gf_struct = op.set_operator_structure(spin_names, ref_orbs, off_diag=off_diag)
def test_trimer_hamiltonian(): # ------------------------------------------------------------------ # -- Hubbard atom with two bath sites, Hamiltonian beta = 2.0 V1 = 2.0 V2 = 5.0 epsilon1 = 0.00 epsilon2 = 4.00 mu = 2.0 U = 1.0 # -- construction using triqs operators up, do = 0, 1 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) H_expr = -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)) # ------------------------------------------------------------------ fundamental_operators = [ c(up, 0), c(do, 0), c(up, 1), c(do, 1), c(up, 2), c(do, 2) ] rep = SparseMatrixRepresentation(fundamental_operators) H_mat = rep.sparse_matrix(H_expr) # -- explicit construction class Dummy(object): def __init__(self): pass op = Dummy() op.cdagger = rep.sparse_operators.c_dag op.c = np.array([cdag.getH() for cdag in op.cdagger]) op.n = np.array([cdag * cop for cop, cdag in zip(op.c, op.cdagger)]) H_ref = -mu * (op.n[0] + op.n[1]) + \ epsilon1 * (op.n[2] + op.n[3]) + \ epsilon2 * (op.n[4] + op.n[5]) + \ U * op.n[0] * op.n[1] + \ V1 * (op.cdagger[0] * op.c[2] + op.cdagger[2] * op.c[0] + op.cdagger[1] * op.c[3] + op.cdagger[3] * op.c[1]) + \ V2 * (op.cdagger[0] * op.c[4] + op.cdagger[4] * op.c[0] + op.cdagger[1] * op.c[5] + op.cdagger[5] * op.c[1]) # ------------------------------------------------------------------ # -- compare compare_sparse_matrices(H_mat, H_ref)
V = [ 2.0, 5.0 ] # Couplings to Bath-sites spin_names = ['up', 'dn'] orb_names = [0] # ==== Local Hamiltonian ==== h_0 = - mu*( n('up',0) + n('dn',0) ) - h*( n('up',0) - n('dn',0) ) h_int = U * n('up',0) * n('dn',0) h_imp = h_0 + h_int # ==== Bath & Coupling Hamiltonian ==== h_bath, h_coup = 0, 0 for i, E_i, V_i in zip([0, 1], E, V): for sig in ['up','dn']: h_bath += E_i * n(sig,'b_' + str(i)) h_coup += V_i * (c_dag(sig,0) * c(sig,'b_' + str(i)) + c_dag(sig,'b_' + str(i)) * c(sig,0)) # ==== Total impurity hamiltonian and fundamental operators ==== h_tot = h_imp + h_coup + h_bath # ==== Green function structure ==== gf_struct = [ [s, orb_names] for s in spin_names ] # ==== Hybridization Function ==== n_iw = int(10 * beta) iw_mesh = MeshImFreq(beta, 'Fermion', n_iw) Delta = BlockGf(mesh=iw_mesh, gf_struct=gf_struct) Delta << sum([V_i*V_i * inverse(iOmega_n - E_i) for V_i,E_i in zip(V, E)]); # ==== Non-Interacting Impurity Green function ==== G0_iw = BlockGf(mesh=iw_mesh, gf_struct=gf_struct)
spin_names = ['up', 'dn'] orb_names = [0, 1] orb_bath_names = [0, 1, 2, 3] # Non-interacting impurity hamiltonian in matrix representation h_0_mat = diag(eps - mu) - matrix([[0, t], [t, 0]]) # Bath hamiltonian in matrix representation h_bath_mat = diag(eps_bath) # Coupling matrix V_mat = matrix([[1., 1., 0.2, 0.2], [0.2, 0.2, 1, 1]]) # ==== Local Hamiltonian ==== c_dag_vec = {s: matrix([[c_dag(s, o) for o in orb_names]]) for s in spin_names} c_vec = {s: matrix([[c(s, o)] for o in orb_names]) for s in spin_names} h_0 = sum(c_dag_vec[s] * h_0_mat * c_vec[s] for s in spin_names)[0, 0] h_int = h_int_kanamori( spin_names, orb_names, array([[0, V - J], [V - J, 0]]), # Interaction for equal spins array([[U, V], [V, U]]), # Interaction for opposite spins J, True) h_loc = h_0 + h_int # ==== Bath & Coupling hamiltonian ====
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