Ejemplo n.º 1
0
def relabel_operators(op, from_list, to_list):
    """ Transform the operator op according to the single particle 
    transform matrix U defined in the subspace of operators listed in 
    fundamental_operators. """

    op_idx_map = get_operator_index_map(from_list, include_dag=True)
    op_idx_set = set(op_idx_map)

    from_list, to_list = list(from_list), list(to_list)

    # -- Loop over given operator and substitute operators
    # -- in from_list to to_list

    op_trans = Operator()

    for term in op:
        op_factor = Operator(1.)
        for factor in term:
            if type(factor) is list:
                for dag, idxs in factor:
                    tup = (dag, tuple(idxs))
                    if tup in op_idx_set:
                        op_factor *= to_list[op_idx_map.index(tup)]
                    else:
                        op_factor *= {False: c, True: c_dag}[dag](*idxs)

            else:  # constant prefactor
                op_factor *= factor

        op_trans += op_factor

    return op_trans
Ejemplo n.º 2
0
def operator_single_particle_transform(op, U, fundamental_operators):
    
    """ Transform the operator op according to the single particle 
    transform matrix U defined in the subspace of operators listed in 
    fundamental_operators. """

    # -- Convert fundamental operators back and forth from index

    op_idx_map = get_operator_index_map(fundamental_operators)
    op_idx_set = set(op_idx_map)

    # -- Transformed creation operator

    def c_transf(s, i):
        if (s, i) not in op_idx_set:
            return c(s, i)

        k = op_idx_map.index((s, i))
        
        ret = Operator()
        for l in xrange(U.shape[0]):
            op_idx = op_idx_map[l]
            ret += U[k, l] * c(*op_idx)

        return ret

    # -- Precompute transformed operators
    
    op_trans_dict = {}
    for fop in fundamental_operators:
        dag, idxs = op_serialize_fundamental(fop)
        op_trans_dict[(dag, idxs)] = c_transf(*idxs)
        op_trans_dict[(not dag, idxs)] = dagger(c_transf(*idxs))
            
    # -- Loop over given operator and substitute operators
    # -- fundamental_operators with the transformed operators
    
    op_trans = Operator()
    
    for term in op:
        op_factor = Operator(1.)
        for factor in term:
            if type(factor) is list:
                for dag, idxs in factor:
                    tup = (dag, tuple(idxs))
                    if tup in op_trans_dict.keys():
                        op_factor *= op_trans_dict[tup]
                    else:
                        op_factor *= {False:c, True:c_dag}[dag](*idxs)
                    
            else: # constant prefactor
                op_factor *= factor

        op_trans += op_factor

    return op_trans
Ejemplo n.º 3
0
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)) )
Ejemplo n.º 4
0
def get_quadratic_operator(h, fundamental_operators):

    # -- Check Hermicity
    np.testing.assert_array_almost_equal(h, h.T.conj())

    H = Operator(0.)
    for idx1, o1 in enumerate(fundamental_operators):
        o1 = dagger(o1)
        for idx2, o2 in enumerate(fundamental_operators):
            H += h[idx1, idx2] * o1 * o2

    return H
Ejemplo n.º 5
0
    def c_transf(s, i):
        if (s, i) not in op_idx_set:
            return c(s, i)

        k = op_idx_map.index((s, i))

        ret = Operator()
        for l in xrange(U.shape[0]):
            op_idx = op_idx_map[l]
            ret += U[k, l] * c(*op_idx)

        return ret
Ejemplo n.º 6
0
def operator_from_quartic_tensor(h_quart, fundamental_operators):

    # -- Convert fundamental operators back and forth from index

    op_idx_map = get_operator_index_map(fundamental_operators)
    op_idx_set = set(op_idx_map)

    nop = len(fundamental_operators)

    H = Operator(0.)

    for t in itertools.product(enumerate(fundamental_operators), repeat=4):
        idx, ops = zip(*t)
        o1, o2, o3, o4 = ops
        o1, o2 = dagger(o1), dagger(o2)

        H += h_quart[idx] * o1 * o2 * o3 * o4

    return H
Ejemplo n.º 7
0
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)

# Number of particles on the impurity
H_loc = -mu * (n('up', 0) + n('dn', 0)) + U * n('up', 0) * n('dn', 0)

# Bath Hamiltonian
H_bath = sum(eps * n("B%i_%s" % (k, sn), 0)
             for sn, (k, eps) in product(spin_names, enumerate(epsilon)))

# Hybridization Hamiltonian
H_hyb = Operator()
for k, v in enumerate(V):
    H_hyb += sum(v * c_dag("B%i_%s" % (k, sn), 0) * c(sn, 0) +
                 np.conj(v) * c_dag(sn, 0) * c("B%i_%s" % (k, sn), 0)
                 for sn in spin_names)

# Complete Hamiltonian
H = H_loc + H_hyb + H_bath

# Diagonalize H
ed.diagonalize(H)

###########
# G^{(2)} #
###########
Ejemplo n.º 8
0
    results_file_name = "kanamori" + (".qn" if use_qn else "") + ".h5"

    mpi.report("Welcome to Kanamori benchmark.")

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

    ## Hamiltonian
    H = h_int_kanamori(spin_names,orb_names,
                       np.array([[0,U-3*J],[U-3*J,0]]),
                       np.array([[U,U-2*J],[U-2*J,U]]),
                       J,False)

    if use_qn:
        QN = [sum([n(*mkind("up",o)) for o in orb_names],Operator()),
              sum([n(*mkind("dn",o)) for o in orb_names],Operator())]
        for o in orb_names:
            dn = n(*mkind("up",o)) - n(*mkind("dn",o))
            QN.append(dn*dn)
        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...")

    # Set hybridization function
Ejemplo n.º 9
0
def h_int_kanamori_d(spin_names,
                     orb_names,
                     U,
                     Uprime,
                     J_hund,
                     off_diag=None,
                     map_operator_structure=None,
                     H_dump=None,
                     d=None):
    r"""
    Create a Kanamori Hamiltonian using the density-density, spin-fip and pair-hopping interactions.

    .. math::
        H = \frac{1}{2} \sum_{(i \sigma) \neq (j \sigma')} U_{i j}^{\sigma \sigma'} n_{i \sigma} n_{j \sigma'}
            - \sum_{i \neq j} J a^\dagger_{i \uparrow} a_{i \downarrow} a^\dagger_{j \downarrow} a_{j \uparrow}
            + \sum_{i \neq j} J a^\dagger_{i \uparrow} a^\dagger_{i \downarrow} a_{j \downarrow} a_{j \uparrow}.

    Parameters
    ----------
    spin_names : list of strings
                 Names of the spins, e.g. ['up','down'].
    orb_names : list of strings or int
                Names of the orbitals, e.g. [0,1,2] or ['t2g','eg'].
    U : 2D matrix or array
        :math:`U_{ij}^{\sigma \sigma} (same spins)`
    Uprime : 2D matrix or array
             :math:`U_{ij}^{\sigma \bar{\sigma}} (opposite spins)`
    J_hund : scalar
             :math:`J`
    off_diag : boolean
               Do we have (orbital) off-diagonal elements?
               If yes, the operators and blocks are denoted by ('spin', 'orbital'),
               otherwise by ('spin_orbital',0).
    map_operator_structure : dict
                             Mapping of names of GF blocks names from one convention to another,
                             e.g. {('up', 0): ('up_0', 0), ('down', 0): ('down_0',0)}.
                             If provided, the operators and blocks are denoted by the mapping of ``('spin', 'orbital')``.
    H_dump : string
             Name of the file to which the Hamiltonian should be written.

    Returns
    -------
    H : Operator
        The Hamiltonian.

    """
    def d_dag(b, m):
        return dagger(d(b, m))

    if H_dump:
        H_dump_file = open(H_dump, 'w')
        H_dump_file.write("Kanamori Hamiltonian:" + '\n')

    H = Operator()
    mkind = get_mkind(off_diag, map_operator_structure)

    # density terms:
    if H_dump: H_dump_file.write("Density-density terms:" + '\n')
    for s1, s2 in product(spin_names, spin_names):
        for a1, a2 in product(orb_names, orb_names):
            if (s1 == s2):
                U_val = U[orb_names.index(a1), orb_names.index(a2)]
            else:
                U_val = Uprime[orb_names.index(a1), orb_names.index(a2)]

            H_term = 0.5 * U_val * d_dag(*mkind(s1, a1)) * d(
                *mkind(s1, a1)) * d_dag(*mkind(s2, a2)) * d(*mkind(s2, a2))
            H += H_term

            # Dump terms of H
            if H_dump and not H_term.is_zero():
                H_dump_file.write('%s' % (mkind(s1, a1), ) + '\t')
                H_dump_file.write('%s' % (mkind(s2, a2), ) + '\t')
                H_dump_file.write(str(U_val) + '\n')

    # spin-flip terms:
    if H_dump: H_dump_file.write("Spin-flip terms:" + '\n')
    for s1, s2 in product(spin_names, spin_names):
        if (s1 == s2):
            continue
        for a1, a2 in product(orb_names, orb_names):
            if (a1 == a2):
                continue
            H_term = -0.5 * J_hund * d_dag(*mkind(s1, a1)) * d(
                *mkind(s2, a1)) * d_dag(*mkind(s2, a2)) * d(*mkind(s1, a2))
            H += H_term

            # Dump terms of H
            if H_dump and not H_term.is_zero():
                H_dump_file.write('%s' % (mkind(s1, a1), ) + '\t')
                H_dump_file.write('%s' % (mkind(s2, a2), ) + '\t')
                H_dump_file.write(str(-J_hund) + '\n')

    # pair-hopping terms:
    if H_dump: H_dump_file.write("Pair-hopping terms:" + '\n')
    for s1, s2 in product(spin_names, spin_names):
        if (s1 == s2):
            continue
        for a1, a2 in product(orb_names, orb_names):
            if (a1 == a2):
                continue
            H_term = 0.5 * J_hund * d_dag(*mkind(s1, a1)) * d_dag(
                *mkind(s2, a1)) * d(*mkind(s2, a2)) * d(*mkind(s1, a2))
            H += H_term

            # Dump terms of H
            if H_dump and not H_term.is_zero():
                H_dump_file.write('%s' % (mkind(s1, a1), ) + '\t')
                H_dump_file.write('%s' % (mkind(s2, a2), ) + '\t')
                H_dump_file.write(str(-J_hund) + '\n')
    return H
Ejemplo n.º 10
0
 def d(b, m):
     ret = Operator()
     for i in range(len(v[b])):
         ret += v[b][m][i] * c(b, i)
     return ret
Ejemplo n.º 11
0
p["max_time"] = -1
p["random_name"] = ""
p["random_seed"] = 123 * mpi.rank + 567
p["length_cycle"] = 50
p["n_warmup_cycles"] = 50000
p["n_cycles"] = 1200000

for modes in range(1,N_max+1):
    V = [0.2]*modes
    e = [-0.2]*modes

    #gf_struct = {str(n):[0] for n in range(0,len(V))}
    gf_struct = [ [str(bidx), [0]] for bidx in range(0,len(V)) ]

    # Local Hamiltonian
    H = Operator()

    # Quantum numbers (N_up and N_down)
    QN = []
    for b, idxs in gf_struct: QN.append(n(b,0))
    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...")

    # Set hybridization function