Spin-Boson MPO

How do I use this algorithm? What does that parameter do?
Post Reply
Posts: 1
Joined: 24 Jun 2022, 15:56

Spin-Boson MPO

Post by FJSchmid »

Hello all

I'm trying to build an MPO for a spin-boson system, coupling a single spin-half to a chain of bosonic sites. To make it simple, I thought I'd try to set up an MPO for a single spin-half and a single site that can host a few bosons.

Code: Select all

import tenpy.networks as tpn
import tenpy.linalg.np_conserved as npc

spin_site = tpn.site.SpinHalfSite(conserve=None)
boson_site = tpn.site.BosonSite(Nmax=4, conserve='N')
tpn.site.set_common_charges([spin_site, boson_site])

""" This works """
spin_zx = tpn.mpo.grid_insert_ops(spin_site, [[spin_site.Sz, spin_site.Sx]])
bos_n = tpn.mpo.grid_insert_ops(boson_site, [[boson_site.N], [boson_site.NN]])
mpo = tpn.mpo.MPO.from_grids([spin_site, boson_site], [spin_zx, bos_n])

""" This does not work """
spin_zx = tpn.mpo.grid_insert_ops(spin_site, [[spin_site.Sz, None]])
bos_n = tpn.mpo.grid_insert_ops(boson_site, [[boson_site.N], [boson_site.NN]])
mpo = tpn.mpo.MPO.from_grids([spin_site, boson_site], [spin_zx, bos_n])

""" This however does work """
spin_zx = tpn.mpo.grid_insert_ops(spin_site, [[spin_site.Sz, spin_site.Sx]])
bos_middle = tpn.mpo.grid_insert_ops(boson_site, [[boson_site.N, None], [boson_site.NN, boson_site.NN]])
bos_n = tpn.mpo.grid_insert_ops(boson_site, [[boson_site.N], [boson_site.NN]])
mpo = tpn.mpo.MPO.from_grids([spin_site, boson_site, boson_site], [spin_zx, bos_middle, bos_n])
I do not understand why the second part does not work. At first I thought that the function cannot handle 'None' properly, but the third example does work nicely.
I then wondered whether the function does not like it when the last (or first) Superoperator in an MPO has 'None' values, and I do not have a conclusive answer to this. I only get an error if the spin_zx operator has a 'None' value. The MPO manages to get built if the bos_n operator has a 'None' value.

I get the following error in detect_grid_outer_legcharge
ValueError: can't derive flat charge for all indices:[array([0]), None]

I guess there would be a possibility to manually construct the MPO via the grid_outer function as is written in the example there https://tenpy.readthedocs.io/en/v0.8.2/ ... outer.html, but I tried to avoid that since I thought I'd rather have the charge-conservation and everything being taken care of by the functions instead of me manually plugging things in via LegCharge.

Would it be a viable hack to substitute 'None' with 0*spin_site.Id?
If not, why not?
User avatar
Site Admin
Posts: 337
Joined: 21 Jul 2018, 12:52
Location: TU Munich

Re: Spin-Boson MPO

Post by Johannes »

Hi, and sorry for the slow response; I hope it's still useful, given that I added extensive examples and further functions!

Let me first explain why your examples do or don't work:
When you write the MPO grid as \(W_0 = (S^z, S^x); W_1 = (N, N^2)^T\) or as in the last example,
The [tenpyclass=tenpy.networks.mpo.MPO]from_grids[/tenpy] function evaluate the charges for each index of the virtual legs by starting with a trivial charge on the left and the checking the total charge of entries in each column of W_0. For your first and last example, this works, since each column has an operator which is not None (=0), but fails in the second example.
The error message is basically an indicator that you can drop that particular MPO index completely, since it's not contributing anything to the terms of the MPO. On the other hand, if you really want to keep it, yes, you can do that hack that you add a zero on-site operator. Note that in general you can get different charges on the corresponding index depending on whether you add 0*spin_site.Sx or 0*spin_site.Id (at least if you would turn on parity conservation of the spin, such that the Sx operator actually has non-trivial qtotal).

That being said, you actually don't have to construct the MPO by hand, just because you use different sites - the model construction in TeNPy fully supports this! I've added a simple example for a combination of spins and fermions in this example notebook.
Furhter, I've implemented the new tenpy.models.lattice.MultiSpeciesLattice to make it even simpler to add multiple species per site into an exisiting lattice.
You can also look at the code of the tenpy.models.hubbard.FermiHubbardModel for another new example using the MultiSpeciesLattice.

Let me know if you have any further questions!

Edit: the documentation build failed, so links don't work yet. The notebook is here as well.
Edit2: doc builds work again
Post Reply