Hi all,

I am trying to implement a DMRG calculation using the spin_nnn model with the coupling term being different on different sites. To my understanding, we can do this for magnetic fields by defining a list with the different magnetic fields for different sites and passing the list as the model parameters. However, when I do the same for the coupling, I get a vector length issue. It would seem this is because the array length for the onsite terms are N and N-1 for the coupling terms. Hence, I would like to ask what is the way to go about implementing non-homogeneous couplings.

Sorry if this is the wrong place to post this. Please move it to the correct section if it is wrong.

Edit: I would also like to ask what is the reason that there is onsite terms in spin_nnn.py but not in spin.py for the couplings.

## Different coupling terms on different sites

### Re: Different coupling terms on different sites

To answer first in general (That's the perfect place to ask this ):

If you give the

You are right, for onsite terms in

Now what is the "correct" size in

That depends on the

For open boundary conditions, it's

for a mix of open and periodic it's the straightforward generalization.

(For the MultiCouplingModel, it's a bit more complicated, but again the answer to how much you can shift the "box" of couplings around without violating the boundary conditions.)

Now in your case of the

You have a simple

If you look into the model code, you see that it uses the same parameters for couplings with

The

If you're interested in DMRG and not in time evolution, I strongly advise you to take the code of the usual SpinChain instead and extend it by a next-nearest neighbor coupling instead, without making it a

I've just added the according code in the

With that model, it should be clear which array sizes you can give to the model parameters, right?

For open boundary conditions,

If you give the

`strength`

parameter to `add_coupling`

, it is tiled to the "correct" size of the couplings.You are right, for onsite terms in

`add_onsite`

, this is simply the `Ls`

of the lattice.Now what is the "correct" size in

`add_coupling`

?That depends on the

`dx`

and the `bc_coupling`

.For open boundary conditions, it's

`(Ls[0] - |dx[0]|, Ls[1] - |dx[1]|, ...)`

, for periodic boundary conditions it's simply the `Ls`

again,for a mix of open and periodic it's the straightforward generalization.

(For the MultiCouplingModel, it's a bit more complicated, but again the answer to how much you can shift the "box" of couplings around without violating the boundary conditions.)

Now in your case of the

`SpinChainNNN`

, it actually doesn't work for open/finite boundaries You have a simple

`Chain`

with `L` `DoubleSite`

, so `2*L` usual sites in total (!).If you look into the model code, you see that it uses the same parameters for couplings with

`dx=0`

and `dx=1`

. For that reason, your array shape is always wrong - except if you just give a single number...The

`DoubleSite`

is anyways just a kind of hack to allow a time evolution of a next-nearest neighbor model with TEBD, as long as we don't have time evolution from an MPO. This is only a temporary solution and also makes code run slowlier.If you're interested in DMRG and not in time evolution, I strongly advise you to take the code of the usual SpinChain instead and extend it by a next-nearest neighbor coupling instead, without making it a

`NearestNeighborModel`

(which a next-nearest neighbor model usualy isn't...).I've just added the according code in the

`spin_nnn.py`

as the `SpinChainNNN2`

in the newest git commit.With that model, it should be clear which array sizes you can give to the model parameters, right?

For open boundary conditions,

`hz`

gets `L`, `Jz`

gets `L-1` and `Jzp`

gets `L-2` entries ### Re: Different coupling terms on different sites

Thank you so much for the swift reply!

I have pulled the latest git commit and am able to run the code using spinChainNNN2. However, as not it is not a nearest neighbour model, I am not able to to use the method of

to calculate the energies. I have tried fiddling around the code and one way I can come up with is to directly read the energies from the dmrg run by

but I think that it is quite "brute force" like and not really the way it should be done. I was thinking of directly calculating the expectation value by using the MPS psi and the MPO of the Hamiltonian but I cannot really figure it out. Sorry if this is a really trivial question but how should I calculate energies now?

I have pulled the latest git commit and am able to run the code using spinChainNNN2. However, as not it is not a nearest neighbour model, I am not able to to use the method of

Python: Select all

`E = np.sum(psi.expectation_value(M.H_bond[1:]))`

Python: Select all

`E, shelve, bond, sweep = dmrg.run(psi, M, dmrg_params)`

### Re: Different coupling terms on different sites

Taking the energy as returned by the DMRG code is a perfectly reasonable thing And it's what I would recommend you for now.

In general, you could still try to get the energy from local expectation values and/or correlation functions, but you would need to carefully figure all the terms out and sum them up.

The best way would be to have a method

Unfortunately, such a method is not yet implemented, since calculating the expectation values for a

In fact, for finite systems, you can just use

Do you consider finite or infinite systems?

In general, you could still try to get the energy from local expectation values and/or correlation functions, but you would need to carefully figure all the terms out and sum them up.

The best way would be to have a method

`MPO.expectation_value(psi)`

.Unfortunately, such a method is not yet implemented, since calculating the expectation values for a

*general*MPO with respect to a general MPS is very non-trivial for infinite boundary conditions. But using the`MPOEnvironment`

, it should not be too hard to implement it for a finite-range Hamiltonian/MPO and/or finite systems, which would do the job for most cases...In fact, for finite systems, you can just use

`MPOEnvironment(psi, H, psi).full_contraction()`

.Do you consider finite or infinite systems?

### Re: Different coupling terms on different sites

Yes, this was what I was wondering how it can be done. I see in the method of full contraction that there is a need to specify a site index. As we are contracting the entire MPS to calculate for energy, is my understanding correct in saying that it does not matter which site we choose in this case?

For now, we are considering a finite system. Based on what I understand, iDMRG can still be calculated for such a system but the only way to obtain the energy is directly from the iDMRG output?

### Re: Different coupling terms on different sites

Yes, that's correct!As we are contracting the entire MPS to calculate for energy, is my understanding correct in saying that it does not matter which site we choose in this case?

For the moment, yes, until someone implements a function for it.Based on what I understand, iDMRG can still be calculated for such a system but the only way to obtain the energy is directly from the iDMRG output?

### Re: Different coupling terms on different sites

Hi!

How can we include site-dependent coefficients for 2d lattices, using a square lattice? The size of coupling seems to be (L-1), but i would like to have 2*(L-1)**2 different coefficients (so all different).

Thank you!!

How can we include site-dependent coefficients for 2d lattices, using a square lattice? The size of coupling seems to be (L-1), but i would like to have 2*(L-1)**2 different coefficients (so all different).

Thank you!!

### Re: Different coupling terms on different sites

As documented, the

`strength`

argumente of add_coupling can be a numpy array - for a square lattice with Lx by Ly sites, for nearest-neighbor hopping/interaction in y -direction, it could be of shape (Lx, Ly-1), or for the one in x-direction (Lx-1, Ly), respectively.