issp-center-dev / TeNeS

Massively parallel tensor network solver
http://www.pasums.issp.u-tokyo.ac.jp/tenes/en
GNU General Public License v3.0
46 stars 11 forks source link

Inconsistent results for the magnetization #44

Closed HamidArianZad closed 1 year ago

HamidArianZad commented 2 years ago

Dear TeNeS group,

I have simulated the magnetization of my favorite 2D spin-1/2 model (below figure) by using TeNeS. I also simulated the same magnetization by using other method that could reproduced nicely the ground-state phase diagram of the model. By comparing obtained results from the both methods, I found that the TeNeS results do not reproduce the ground-state phase diagram of my model and they are not compatible with that of obtained from the other method. The model is:

MartiniLattice1

As you recommended me, I made the simple.toml file for this model as:

[parameter] [parameter.general]

[parameter.simple_update] num_step = 1000 tau = 0.01

[parameter.full_update] num_step = 0 tau = 0.01

[lattice] type = "kagome lattice" L = 2 W = 2 initial = "ferro" virtual_dim = 2

[model] type = "spin" J = 1.0

However, my model is antiferromagnetic, hence I changed the term 'ferro' to 'antiferro'. I added ctm parameters to the simple.toml as well.

[parameter.ctm] iteration_max = 100 dimension = 10

Also, according to your advisement I used the kagome lattice for introducing my model to TeNeS. I tested both model in below figure:

Martini1_kagometype

In fact, I changed the lattice class of kagome lattice in tenes_simple as:


class KagomeLattice(Lattice): def init(self, param: Dict[str, Any]): super().init(param) self.type = "kagome lattice" self.z = 4

    self.L *= 2
    self.W *= 2

    L, W = self.L, self.W

    self.latticevector = np.array([[1.0, 0.0], [0.5, np.sqrt(3.0) / 2]])
    self.latticevector *= np.array([[L], [W]])

    a0 = np.array([1.0, 0.0])
    a1 = np.array([0.5, np.sqrt(3.0) / 2])

    vd = self.vdim
    self.sublattice.append(SubLattice([vd, vd, vd, vd], is_vacancy=False))
    self.sublattice.append(SubLattice([vd, vd, vd, vd], is_vacancy=False))
    self.sublattice.append(SubLattice([vd, vd, vd, vd], is_vacancy=False))
    self.sublattice.append(SubLattice([vd, vd, vd, vd], is_vacancy=False))

    # My favorite lattice: 
    for index in range(L * W):
        x, y = index2coord(index, L)

        if x % 2 == 0 and y % 2 == 0:
            #
            # sublattice A
            #
            self.sublattice[0].add_site(index)
            self.coords.append(a0 * x + a1 * y)

            # 1st neighbors
            self.bonds[0][0].append(Bond(index, 1, 0))
            self.bonds[0][0].append(Bond(index, 0, 1))

            # 2nd neighbors
            self.bonds[1][0].append(Bond(index, -1, 2))
            self.bonds[1][0].append(Bond(index, -2, 1))

            # 3rd neighbors
            self.bonds[2][0].append(Bond(index, 2, 0))
            self.bonds[2][0].append(Bond(index, 0, 2))
            self.bonds[2][1].append(Bond(index, -2, 2))
        elif x % 2 == 1 and y % 2 == 0:
            #
            # sublattice B
            #
            self.sublattice[1].add_site(index)
            self.coords.append(a0 * x + a1 * y)

            # 1st neighbors
            self.bonds[0][1].append(Bond(index, 0, 1))
            self.bonds[0][0].append(Bond(index, -1, 1))

            # 2nd neighbors
            self.bonds[1][0].append(Bond(index, 1, 1))
            self.bonds[1][0].append(Bond(index, -1, 2))

            # 3rd neighbors
            self.bonds[2][0].append(Bond(index, 2, 0))
            self.bonds[2][0].append(Bond(index, -2, 2))
            self.bonds[2][1].append(Bond(index, 0, 2))
        elif x % 2 == 0 and y % 2 == 1:
            #
            # sublattice C
            #
            self.sublattice[2].add_site(index)
            self.coords.append(a0 * x + a1 * y)

            # 1st neighbors
            self.bonds[0][1].append(Bond(index, -1, 0))
            # self.bonds[0][1].append(Bond(index, -1, 1))

            # 2nd neighbors
            self.bonds[1][0].append(Bond(index, 1, 1))
            self.bonds[1][0].append(Bond(index, -2, 1))

            # 3rd neighbors
            self.bonds[2][0].append(Bond(index, 0, 2))
            self.bonds[2][0].append(Bond(index, -2, 2))
            self.bonds[2][1].append(Bond(index, 2, 0))

        elif x % 2 == 1 and y % 2 == 1:
            #
            # sublattice D
            #
            self.sublattice[3].add_site(index)
            self.coords.append(a0 * x + a1 * y)

            # 1st neighbors
            # self.bonds[0][1].append(Bond(index, 1, 0))
            self.bonds[0][1].append(Bond(index, 1, 1))

            # 2nd neighbors
            self.bonds[1][0].append(Bond(index, 1, 1))
            self.bonds[1][0].append(Bond(index, -2, 1))

            # 3rd neighbors
            self.bonds[2][0].append(Bond(index, 0, 2))
            self.bonds[2][0].append(Bond(index, -2, 2))
            self.bonds[2][1].append(Bond(index, 2, 0))

The results obtained from TeNeS simulations for J = 1 (and Delta = 1) is as following figure for 16 sites (also for 24 sites is very similar):

mag_martini1_16site_JHm1JIm1

While the results obtained from other method is as:

mag_martini lattice1_JHm1JIm1

in which magnetization jumps and plateaus of total magnetization m_T (black curves) occur at different magnetic fields and different incommensurate values M/M_s. I would be thankful to you if help me to fix this problem.

All the best,

yomichi commented 2 years ago
yomichi commented 2 years ago

TeNeS represents the total Hamiltonian by the sum of two-site local Hamiltonians, and hence the one-site terms like Zeeman term are split into two-site terms on the adjacent bonds: H_{ij} = J S_i S_j + h/z (S_i^z + S_j^z), where z is the coordinate number. While z of the kagome lattice is 4, z of your lattice is 3. Did you fix this difference? I guess this is the reason why the transition field is too high in TeNeS result (please check by multiplying the magnetic field by 3/4 in your plot).

HamidArianZad commented 2 years ago

While I used periodic boundary conditions in Lanczos algorithm. Can I switch open boundary conditions to periodic boundary conditions in tenes_simple?

yomichi commented 2 years ago

This code snippet calculates the matrix element of a local Hamiltonian on a bond, and so this does not relate with the boundary condition. TeNeS treats an infinite lattice by using the CTMRG method (of course, some periodicity (translational symmetry) is assumed). https://issp-center-dev.github.io/TeNeS/manual/master/en/html/algorithm/algorithms.html#contraction-of-itps

HamidArianZad commented 2 years ago

Dear TeNeS group,

I would like to obtain a stright results for the magnetization of a special lattice (see attached figure) by means of TeNeS.

Martini2_K_Lattice

The shaded region is a unit block including 56 S-1/2 sites that repeats throughout the lattice. Unfortunately I obtain inconsistent results for the magnetization that are quite different from exact results. I checked all bonds written in input files. All of them reproduced correctly according to the above lattice structure. To consider empty circles as dummy sites, I considered just one bond between them and their +x neighbor sites as J2 and then in simple.toml file I supposed J2 = 0. Is this consideration correct?

In this model, some of sites have 6 exchange interactions with their neighboring sites (red lines) while others have 3 interactions with their adjacent sites. Does TeNeS support this kind of model? Or, for geting correct results from TeNeS package all connections between all sites of the introduced lattice should have the same nubmer?

yomichi commented 2 years ago

To consider empty circles as dummy sites, I considered just one bond between them and their +x neighbor sites as J2 and then in simple.toml file I supposed J2 = 0. Is this consideration correct?

Yes, and you need not add bonds (interaction) to dummy sites.

In this model, some of sites have 6 exchange interactions with their neighboring sites (red lines) while others have 3 interactions with their adjacent sites. Does TeNeS support this kind of model?

TeNeS (strictly speaking, tenes_std) can deal with such a lattice (the coordinate number is not uniform). Please split the full Hamiltonian into a summation of bond Hamiltonians. In this splitting, one-site terms such as Zeeman terms are absorbed into adjacent two-site terms (Heisenberg term). To avoid double-counting, the value of the magnetic field in one-site terms should be divided by the coordinate number, z.

From the experience of one of the developers, to use only bond-ITE operators converges faster than to use both bond-iTE and site-ITE, it is why the current version of tenes accepts only bond-ITE operators. From the viewpoint of usability, I think that it would be better to make tenes_std accept site hamiltonian and tenes accept site-ITE operators, and so I will implement it in the (near) future.

yomichi commented 1 year ago

I close this because it has been one year since the last comment.