How Do I Define New Operators in TenPy

How do I use this algorithm? What does that parameter do?
Post Reply
dm_Physics
Posts: 7
Joined: 05 Dec 2021, 20:23

How Do I Define New Operators in TenPy

Post by dm_Physics »

I am currently studying the Bose Hubbard model that has been implemented in TenPy. Here the specific part of the code that I am studying:

Code: Select all

def init_terms(self, model_params):
        # 0) Read and set parameters.
        t = get_parameter(model_params, 't', 1., self.name, True)
        U = get_parameter(model_params, 'U', 0., self.name, True)
        V = get_parameter(model_params, 'V', 0., self.name, True)
        mu = get_parameter(model_params, 'mu', 0, self.name, True)
        for u in range(len(self.lat.unit_cell)):
            self.add_onsite(-mu - U / 2., u, 'N')
            self.add_onsite(U / 2., u, 'NN')
        for u1, u2, dx in self.lat.pairs['nearest_neighbors']:
            self.add_coupling(-t, u1, 'Bd', u2, 'B', dx)
            self.add_coupling(-np.conj(t), u2, 'Bd', u1, 'B', -dx)  # h.c.
            self.add_coupling(V, u1, 'N', u2, 'N', dx)
For instance the code

Code: Select all

 self.add_coupling(-t, u1, 'Bd', u2, 'B', dx)
basically implements the term \(-t\sum_{\langle i, j \rangle}b^\dagger_i b_j\). Now suppose I want to implement the term \(-t\sum_{\langle i, j \rangle}k^\dagger_i k_j\) where \(k_i^\dagger = b_i^\dagger \sigma_i^-\). I want to replace the line

Code: Select all

self.add_coupling(-t, u1, 'Bd', u2, 'B', dx)
with

Code: Select all

self.add_coupling(-t, u1, 'Kd', u2, 'K', dx)
.

Question: Is there a way to implement the operator \(k_i^\dagger = b_i^\dagger \sigma_i^-\) such that TenPy understand the string "Kd"? I was initially thinking to use

Code: Select all

kron("Bd", "Sp")
, but that would not return a string. How do I incorporate this operator.
Jirawat S
Posts: 8
Joined: 01 Mar 2022, 14:12

Re: How Do I Define New Operators in TenPy

Post by Jirawat S »

Hi!
If you know matrix representation (op) of the desired operator, I think you can manually add it through your Site with add_op() function. for example if your Site is BosonSite then you can use

Code: Select all

BosonSite.add_op(name, op)
.
dm_Physics
Posts: 7
Joined: 05 Dec 2021, 20:23

Re: How Do I Define New Operators in TenPy

Post by dm_Physics »

Hello Jirawat,

Thank you very much for your response. In the example I gave on \(k_i^\dagger = b_i^\dagger \sigma_i^-\) would I just write

Code: Select all

BosonSite.add_op('Kd', kron("Bd", "Sp"))
?

Please kindly let me know.
Jirawat S
Posts: 8
Joined: 01 Mar 2022, 14:12

Re: How Do I Define New Operators in TenPy

Post by Jirawat S »

Since I never work with BH model so I don't know if the way you define the new operator using kron() is really what you want or not.

But this is how I did when I define MPO to work with SpinSite, but it should work as well for other Site. Let say, for whatever reason, I want to use the operator S_0m defined as

Code: Select all

S_0m = np.array([ [0., 0.5, 0.], [0.5, 0., 0.], [0., 0., 0. ] ])
The operator is added after defining Site

Code: Select all

self.spin = SpinSite(S=self.S, conserve="None")
self.lattice = Chain(self.L, self.spin, bc="open", bc_MPS="finite")
self.spin.add_op("S_0m", S_0m)
After this I am free to add a term into Hamiltonian with S_0m.

Code: Select all

CouplingModel.__init__(self, self.lattice)
self.add_onsite(t, 0, 'S_0m')
MPOModel.__init__(self, self.lattice, self.calc_H_MPO())
Note that in this case I have set conserve="None". If you are going to use symmetry then please makes sure that the operator satisfies it.
User avatar
Johannes
Site Admin
Posts: 413
Joined: 21 Jul 2018, 12:52
Location: TU Munich

Re: How Do I Define New Operators in TenPy

Post by Johannes »

Thanks for the reply Jirawat! Your answer nicely explains how to add an onsite operator (given as a matrix) to a local site.
Expanding on this, let me just mention that for a CouplingMPOModel it should often be enough to overwrite the init_sites method.
A non-trivial example adding an operator P0 projecting onto the local vacuum would look like this:

Code: Select all

class ModifiedBoseHubbard(BoseHubbardModel):
    def init_sites(self, model_params):
        site = super().init_sites(model_params)
        # add projector onto vacuum
        vac = site.state_labels['vac']
        P0 = np.zeros([site.leg.ind_len, site.leg.ind_len])
        P0[vac, vac] = 1.
        site.add_op('P0', P0)
        return site
    ...
@dm_Physics I think there is still a conceptual confusion here, as to what the local Hilbert space structure is.
TenPy's BoseHubbardModel considers spin-less bosons on a lattice, i.e. there is no spin operators like \(\sigma_-\). When you try to replace \(b_i^\dagger \rightarrow k_i^\dagger := b_i^\dagger \sigma_i^-\), what is the spin operator here? Do you add an extra spin degree of freedom next to each boson site? In that case you need to add a whole extra site, not just an extra operator! Is it a Spin-1/2?
Or do you rather want to add the spin on the "bonds" of the original boson lattice (presumably for a gauge theory picture)? That's not the same as replacing all b with k, though...
Post Reply