Quantum Numbers with dipole/'spatially modulated' symmetries: Multi-Site Generalization

Hi,

Supposing we want to study a conserved “dipole” moment of a U(1) charge, i.e. instead of just having \sum_{j=1}^N S_j^z conserved we wish to conserve the “dipole moment” \sum_{j=1}^N jS_j^z as well. Then the following site definition accomplishes this:

using ITensors, ITensorMPS
using ITensorInfiniteMPS
function ITensors.space(::SiteType"spin1dipole", pos::Int;
                        conserve_qns = true)
  if conserve_qns
    return [QN(("Sz",1),("dipole",1*pos))=>1,QN(("Sz",0),("dipole",0*pos))=>1,
            QN(("Sz",-1),("dipole",-1*pos))=>1]
  end
  return 3
  
end

where Sz and other definitions are left implicit. This will allow us to perform DMRG with this “modulated” symmetry conserved. (Note that I did not define an operator called “dipole”.) (Note also that I’ve only tested this for finite DMRG.)

Now, suppose I wish to generalize the above site-definition to a new on-site Hilbert space consisting of two of the above site types; i.e. the on-site degree of freedom consists of two unit cells. (This approach is one way to trick the DMRG code into doing a multi-site update). The conserved quantities are rewritten as \sum_{j=1}^{N/2}(S_{2j-1}^z+S^z_{2j}) (charge) and \sum_{j=1}^{N/2}((2j-1)S_{2j-1}^z+2jS^z_{2j}) (dipole).

But now there is no simple way to implement this as detailed above, because the on-site “dipole density” is no longer proportional to the on-site “charge density”. What is true is that we can rewrite the dipole moment as:

\sum_{j=1}^{N/2}((2j-1)S_{2j-1}^z+2jS^z_{2j}) = \sum_j (2j-\frac12)(S_{2j-1}^z+S^z_{2j}) + \frac12\sum_j (S^z_{2j} - S^z_{2j-1})

i.e. a sum of a dipole moment whose “dipole density” is proportional to the on-site charge density, and another piece which is a normal abelian charge density without any modulated piece (I call this density SzDiff. Then I could define a site type like:

using ITensors, ITensorMPS
using ITensorInfiniteMPS
function ITensors.space(::SiteType"spin1dipole", pos::Int;
                        conserve_qns = true)
  if conserve_qns
    return [QN(("Sz",x),("SzDiff",y)("dipole",y+(2*pos-1/2)*x))=>????,...]
  end
  return 9
  
end

with three conserved quantum numbers, and conserve the same exact dipole moment and charge that I conserved in the last example. The problem with this is that I’m also conserving an extra quantum number SzDiff, which wasn’t conserved initially and thus is an unwanted constraint.

The other approach is to define an operator called "dipole" that acts on my on-site Hilbert space (here consisting of two spin-one’s) and takes pos as an argument, just like the ITensors.space function did. However, I’m not sure how to do this—trying this exactly as I described didn’t work for me:

ITensors.op(::OpName"dipole",::SiteType"4ssdipole",pos::Int) = operator_definition_here

leading to:
ArgumentError: Overload of "op" or "op!" functions not found for operator name "dipole" and Index tags: ("spin1dipole,Site,n=1",).

Thus, is there any way I can implement this kind of dipole symmetry as described in my two-spin unit cell example? Would definitely appreciate some pointers. (Maybe it would also help to see where I should dig around in the Quantum Numbers code to see which things I could tweak myself, but the closest example to what I’m looking at here is actually only an example of the first type of dipole symmetry I described which is easy to implement.)

Thanks very much;

Sincerely,

Amogh A