Esempio 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
Esempio 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 range(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 list(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
    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
Esempio n. 4
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)))
Esempio n. 5
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
Esempio n. 6
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 range(U.shape[0]):
            op_idx = op_idx_map[l]
            ret += U[k, l] * c(*op_idx)

        return ret
Esempio n. 7
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 = list(zip(*t))
        o1, o2, o3, o4 = ops
        o1, o2 = dagger(o1), dagger(o2)

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

    return H
Esempio n. 8
0
import unittest

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))
Esempio 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
Esempio 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