HPhi++  3.1.0
expec_totalspin.cpp
Go to the documentation of this file.
1 /* HPhi - Quantum Lattice Model Simulator */
2 /* Copyright (C) 2015 The University of Tokyo */
3 
4 /* This program is free software: you can redistribute it and/or modify */
5 /* it under the terms of the GNU General Public License as published by */
6 /* the Free Software Foundation, either version 3 of the License, or */
7 /* (at your option) any later version. */
8 
9 /* This program is distributed in the hope that it will be useful, */
10 /* but WITHOUT ANY WARRANTY; without even the implied warranty of */
11 /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
12 /* GNU General Public License for more details. */
13 
14 /* You should have received a copy of the GNU General Public License */
15 /* along with this program. If not, see <http://www.gnu.org/licenses/>. */
16 #include <bitcalc.hpp>
17 #include "mltplyCommon.hpp"
18 #include "mltplySpinCore.hpp"
19 #include "wrapperMPI.hpp"
20 #include "mltplyMPISpin.hpp"
21 #include "mltplyMPISpinCore.hpp"
22 #include "expec_totalspin.hpp"
46  struct BindStruct *X,
47  int nstate,
48  std::complex<double> **vec
49 ) {
50  long int j;
51  long int irght, ilft, ihfbit;
52  long int isite1, isite2;
53  long int is1_up, is2_up, is1_down, is2_down;
54  long int iexchg, off;
55  int num1_up, num2_up, istate;
56  int num1_down, num2_down;
57  long int ibit1_up, ibit2_up, ibit1_down, ibit2_down;
58  std::complex<double> tmp_spn_z;
59  long i_max;
60  i_max = X->Check.idim_max;
61 
62  GetSplitBitByModel(X->Def.Nsite, X->Def.iCalcModel, &irght, &ilft, &ihfbit);
63  for (istate = 0; istate < nstate; istate++) {
64  X->Phys.s2[istate] = 0.0;
65  X->Phys.Sz[istate] = 0.0;
66  }
67  for (isite1 = 1; isite1 <= X->Def.NsiteMPI; isite1++) {
68  is1_up = X->Def.Tpow[2 * isite1 - 2];
69  is1_down = X->Def.Tpow[2 * isite1 - 1];
70 
71  for (isite2 = 1; isite2 <= X->Def.NsiteMPI; isite2++) {
72  is2_up = X->Def.Tpow[2 * isite2 - 2];
73  is2_down = X->Def.Tpow[2 * isite2 - 1];
74 
75  for (j = 1; j <= i_max; j++) {
76 
77  ibit1_up = list_1[j] & is1_up;
78  num1_up = ibit1_up / is1_up;
79  ibit2_up = list_1[j] & is2_up;
80  num2_up = ibit2_up / is2_up;
81 
82  ibit2_down = list_1[j] & is2_down;
83  num2_down = ibit2_down / is2_down;
84  ibit1_down = list_1[j] & is1_down;
85  num1_down = ibit1_down / is1_down;
86 
87  tmp_spn_z = (num1_up - num1_down) * (num2_up - num2_down);
88  for (istate = 0; istate < nstate; istate++)
89  X->Phys.s2[istate] += real(conj(vec[j][istate]) * vec[j][istate] * tmp_spn_z / 4.0);
90  if (isite1 == isite2) {
91  for (istate = 0; istate < nstate; istate++) {
92  X->Phys.s2[istate] += real(conj(vec[j][istate]) * vec[j][istate]) * (num1_up + num1_down - 2 * num1_up * num1_down) / 2.0;
93  X->Phys.Sz[istate] += real(conj(vec[j][istate]) * vec[j][istate]) * (num1_up - num1_down) / 2.0;
94  }
95  }
96  else {
97  if (ibit1_up != 0 && ibit1_down == 0 && ibit2_up == 0 && ibit2_down != 0) {
98  iexchg = list_1[j] - (is1_up + is2_down);
99  iexchg += (is2_up + is1_down);
100  GetOffComp(list_2_1, list_2_2, iexchg, irght, ilft, ihfbit, &off);
101  for (istate = 0; istate < nstate; istate++)
102  X->Phys.s2[istate] += real(conj(vec[j][istate]) * vec[off][istate]) / 2.0;
103  }
104  else if (ibit1_up == 0 && ibit1_down != 0 && ibit2_up != 0 && ibit2_down == 0) {
105  iexchg = list_1[j] - (is1_down + is2_up);
106  iexchg += (is2_down + is1_up);
107  GetOffComp(list_2_1, list_2_2, iexchg, irght, ilft, ihfbit, &off);
108  for (istate = 0; istate < nstate; istate++)
109  X->Phys.s2[istate] += real(conj(vec[j][istate]) * vec[off][istate]) / 2.0;
110  }
111  }
112  }
113  }
114  }
115  SumMPI_dv(nstate, X->Phys.s2);
116  SumMPI_dv(nstate, X->Phys.Sz);
117 }
128  struct BindStruct *X,
129  int nstate,
130  std::complex<double> **vec
131 ) {
132  long int j;
133  long int isite1, isite2;
134  long int is1_up, is2_up, is1_down, is2_down;
135  long int iexchg, off;
136  int num1_up, num2_up, istate;
137  int num1_down, num2_down;
138  long int ibit1_up, ibit2_up, ibit1_down, ibit2_down, list_1_j;
139  std::complex<double> tmp_spn_z;
140  long int i_max;
141 
142  i_max = X->Check.idim_max;
143 
144  for (istate = 0; istate < nstate; istate++) {
145  X->Phys.s2[istate] = 0.0;
146  X->Phys.Sz[istate] = 0.0;
147  }
148  for (isite1 = 1; isite1 <= X->Def.NsiteMPI; isite1++) {
149  for (isite2 = 1; isite2 <= X->Def.NsiteMPI; isite2++) {
150  is1_up = X->Def.Tpow[2 * isite1 - 2];
151  is1_down = X->Def.Tpow[2 * isite1 - 1];
152  is2_up = X->Def.Tpow[2 * isite2 - 2];
153  is2_down = X->Def.Tpow[2 * isite2 - 1];
154 
155  for (j = 1; j <= i_max; j++) {
156  list_1_j = j - 1;
157  ibit1_up = list_1_j & is1_up;
158  num1_up = ibit1_up / is1_up;
159  ibit2_up = list_1_j & is2_up;
160  num2_up = ibit2_up / is2_up;
161 
162  ibit1_down = list_1_j & is1_down;
163  num1_down = ibit1_down / is1_down;
164  ibit2_down = list_1_j & is2_down;
165  num2_down = ibit2_down / is2_down;
166 
167  tmp_spn_z = (num1_up - num1_down) * (num2_up - num2_down);
168  for (istate = 0; istate < nstate; istate++)
169  X->Phys.s2[istate] += real(conj(vec[j][istate]) * vec[j][istate] * tmp_spn_z / 4.0);
170  if (isite1 == isite2) {
171  X->Phys.s2[istate] += real(conj(vec[j][istate]) * vec[j][istate]) * (num1_up + num1_down - 2 * num1_up * num1_down) / 2.0;
172  X->Phys.Sz[istate] += real(conj(vec[j][istate]) * vec[j][istate]) * (num1_up - num1_down) / 2.0;
173  }
174  else {
175  if (ibit1_up != 0 && ibit1_down == 0 && ibit2_up == 0 && ibit2_down != 0) {
176  iexchg = list_1_j - (is1_up + is2_down);
177  iexchg += (is2_up + is1_down);
178  off = iexchg + 1;
179  for (istate = 0; istate < nstate; istate++)
180  X->Phys.s2[istate] += real(conj(vec[j][istate]) * vec[off][istate] / 2.0);
181  }
182  else if (ibit1_up == 0 && ibit1_down != 0 && ibit2_up != 0 && ibit2_down == 0) {
183  iexchg = list_1_j - (is1_down + is2_up);
184  iexchg += (is2_down + is1_up);
185  off = iexchg + 1;
186  for (istate = 0; istate < nstate; istate++)
187  X->Phys.s2[istate] += real(conj(vec[j][istate]) * vec[off][istate] / 2.0);
188  }
189  }
190  }
191  }
192  }
193  SumMPI_dv(nstate, X->Phys.s2);
194  SumMPI_dv(nstate, X->Phys.Sz);
195 }
208  struct BindStruct *X,
209  int nstate,
210  std::complex<double> **vec
211 ) {
212  long int j;
213  long int irght, ilft, ihfbit;
214  long int isite1, isite2;
215  long int tmp_isite1, tmp_isite2;
216 
217  long int is1_up, is2_up;
218  long int iexchg, off, off_2;
219 
220  int num1_up, num2_up;
221  int num1_down, num2_down;
222  int sigma_1, sigma_2, istate;
223  long int ibit1_up, ibit2_up, ibit_tmp, is_up;
224  std::complex<double> spn_z1, spn_z2;
225  long int i_max;
226  double spn_z;
227 
228  i_max = X->Check.idim_max;
229  for (istate = 0; istate < nstate; istate++) {
230  X->Phys.s2[istate] = 0.0;
231  X->Phys.Sz[istate] = 0.0;
232  }
233  if (X->Def.iFlgGeneralSpin == FALSE) {
234  GetSplitBitByModel(X->Def.Nsite, X->Def.iCalcModel, &irght, &ilft, &ihfbit);
235  for (isite1 = 1; isite1 <= X->Def.NsiteMPI; isite1++) {
236  for (isite2 = 1; isite2 <= X->Def.NsiteMPI; isite2++) {
237 
238  if (isite1 > X->Def.Nsite && isite2 > X->Def.Nsite) {
239 #ifdef __MPI
240  is1_up = X->Def.Tpow[isite1 - 1];
241  is2_up = X->Def.Tpow[isite2 - 1];
242  is_up = is1_up + is2_up;
243  num1_up = X_SpinGC_CisAis((long int) myrank + 1, is1_up, 1);
244  num1_down = 1 - num1_up;
245  num2_up = X_SpinGC_CisAis((long int) myrank + 1, is2_up, 1);
246  num2_down = 1 - num2_up;
247  spn_z = (num1_up - num1_down) * (num2_up - num2_down);
248 
249  for (j = 1; j <= i_max; j++) {
250  for (istate = 0; istate < nstate; istate++)
251  X->Phys.s2[istate] += real(conj(vec[j][istate]) * vec[j][istate] * spn_z) / 4.0;
252  }
253  if (isite1 == isite2) {
254  for (j = 1; j <= i_max; j++) {
255  for (istate = 0; istate < nstate; istate++)
256  X->Phys.s2[istate] += real(conj(vec[j][istate]) * vec[j][istate]) / 2.0;
257  }
258  }
259  else {//off diagonal
260  //debug spn += X_child_general_int_spin_TotalS_MPIdouble(isite1 - 1, isite2 - 1, X, nstate, vec, vec);
261  }
262 #endif
263  }
264  else if (isite1 > X->Def.Nsite || isite2 > X->Def.Nsite) {
265 #ifdef __MPI
266  if (isite1 < isite2) {
267  tmp_isite1 = isite1;
268  tmp_isite2 = isite2;
269  }
270  else {
271  tmp_isite1 = isite2;
272  tmp_isite2 = isite1;
273  }
274 
275  is1_up = X->Def.Tpow[tmp_isite1 - 1];
276  is2_up = X->Def.Tpow[tmp_isite2 - 1];
277  num2_up = X_SpinGC_CisAis((long int) myrank + 1, is2_up, 1);
278  num2_down = 1 - num2_up;
279 
280  //diagonal
281  for (j = 1; j <= i_max; j++) {
282  ibit1_up = list_1[j] & is1_up;
283  num1_up = ibit1_up / is1_up;
284  num1_down = 1 - num1_up;
285  spn_z = (num1_up - num1_down) * (num2_up - num2_down);
286  for (istate = 0; istate < nstate; istate++)
287  X->Phys.s2[istate] += real(conj(vec[j][istate]) * vec[j][istate] * spn_z) / 4.0;
288  }
289  if (isite1 < isite2) {
290  //debug spn += X_child_general_int_spin_MPIsingle(isite1 - 1, 0, 1, isite2 - 1, 1, 0, 1.0, X, nstate, vec, vec);
291  }
292  else {
293  //debug spn += conj(X_child_general_int_spin_MPIsingle(isite2 - 1, 1, 0, isite1 - 1, 0, 1, 1.0, X, nstate, vec, vec));
294  }
295 #endif
296  }//isite1 > Nsite || isite2 > Nsite
297  else {
298  is1_up = X->Def.Tpow[isite1 - 1];
299  is2_up = X->Def.Tpow[isite2 - 1];
300  is_up = is1_up + is2_up;
301 
302  for (j = 1; j <= i_max; j++) {
303  ibit1_up = list_1[j] & is1_up;
304  num1_up = ibit1_up / is1_up;
305  num1_down = 1 - num1_up;
306  ibit2_up = list_1[j] & is2_up;
307  num2_up = ibit2_up / is2_up;
308  num2_down = 1 - num2_up;
309 
310  spn_z = (num1_up - num1_down) * (num2_up - num2_down);
311  for (istate = 0; istate < nstate; istate++)
312  X->Phys.s2[istate] += real(conj(vec[j][istate]) * vec[j][istate] * spn_z) / 4.0;
313 
314  if (isite1 == isite2) {
315  for (istate = 0; istate < nstate; istate++)
316  X->Phys.s2[istate] += real(conj(vec[j][istate]) * vec[j][istate]) / 2.0;
317  }
318  else {
319  ibit_tmp = (num1_up) ^ (num2_up);
320  if (ibit_tmp != 0) {
321  iexchg = list_1[j] ^ (is_up);
322  GetOffComp(list_2_1, list_2_2, iexchg, irght, ilft, ihfbit, &off);
323  for (istate = 0; istate < nstate; istate++)
324  X->Phys.s2[istate] += real(conj(vec[j][istate]) * vec[off][istate]) / 2.0;
325  }
326  }
327  }// j
328  }
329  }//isite2
330  }//isite1
331  }//generalspin=FALSE
332  else {
333  double S1 = 0;
334  double S2 = 0;
335  for (isite1 = 1; isite1 <= X->Def.NsiteMPI; isite1++) {
336  for (isite2 = 1; isite2 <= X->Def.NsiteMPI; isite2++) {
337  S1 = 0.5 * (X->Def.SiteToBit[isite1 - 1] - 1);
338  S2 = 0.5 * (X->Def.SiteToBit[isite2 - 1] - 1);
339  if (isite1 == isite2) {
340  for (j = 1; j <= i_max; j++) {
341  spn_z1 = 0.5 * GetLocal2Sz(isite1, list_1[j], X->Def.SiteToBit, X->Def.Tpow);
342  for (istate = 0; istate < nstate; istate++) {
343  X->Phys.s2[istate] += real(conj(vec[j][istate]) * vec[j][istate]) * S1 * (S1 + 1.0);
344  X->Phys.Sz[istate] += real(conj(vec[j][istate]) * vec[j][istate] * spn_z1);
345  }
346  }
347  }
348  else {
349  for (j = 1; j <= i_max; j++) {
350  spn_z1 = 0.5 * GetLocal2Sz(isite1, list_1[j], X->Def.SiteToBit, X->Def.Tpow);
351  spn_z2 = 0.5 * GetLocal2Sz(isite2, list_1[j], X->Def.SiteToBit, X->Def.Tpow);
352  for (istate = 0; istate < nstate; istate++)
353  X->Phys.s2[istate] += real(conj(vec[j][istate]) * vec[j][istate] * spn_z1 * spn_z2);
354 
355  sigma_1 = GetBitGeneral(isite1, list_1[j], X->Def.SiteToBit, X->Def.Tpow);
356  sigma_2 = GetBitGeneral(isite2, list_1[j], X->Def.SiteToBit, X->Def.Tpow);
357 
358  ibit_tmp = GetOffCompGeneralSpin(list_1[j], isite2, sigma_2, sigma_2 + 1, &off, X->Def.SiteToBit,
359  X->Def.Tpow);
360  if (ibit_tmp == TRUE) {
361  ibit_tmp = GetOffCompGeneralSpin(off, isite1, sigma_1, sigma_1 - 1, &off_2, X->Def.SiteToBit,
362  X->Def.Tpow);
363  if (ibit_tmp == TRUE) {
364  ConvertToList1GeneralSpin(off_2, X->Check.sdim, &off);
365  for (istate = 0; istate < nstate; istate++)
366  X->Phys.s2[istate] += real(conj(vec[j][istate]) * vec[off][istate])
367  * sqrt(S2 * (S2 + 1) - real(spn_z2) * (real(spn_z2) + 1))
368  * sqrt(S1 * (S1 + 1) - real(spn_z1) * (real(spn_z1) - 1)) / 2.0;
369  }
370  }
371 
372  ibit_tmp = GetOffCompGeneralSpin(list_1[j], isite2, sigma_2, sigma_2 - 1, &off, X->Def.SiteToBit,
373  X->Def.Tpow);
374  if (ibit_tmp == TRUE) {
375  ibit_tmp = GetOffCompGeneralSpin(off, isite1, sigma_1, sigma_1 + 1, &off_2, X->Def.SiteToBit,
376  X->Def.Tpow);
377  if (ibit_tmp == TRUE) {
378  ConvertToList1GeneralSpin(off_2, X->Check.sdim, &off);
379  for (istate = 0; istate < nstate; istate++)
380  X->Phys.s2[istate] += real(conj(vec[j][istate]) * vec[off][istate])
381  * sqrt(S2 * (S2 + 1) - real(spn_z2) * (real(spn_z2) - 1.0))
382  * sqrt(S1 * (S1 + 1) - real(spn_z1) * (real(spn_z1) + 1)) / 2.0;
383  }
384  }
385  }
386  }
387  }
388  }
389  }
390  SumMPI_dv(nstate, X->Phys.s2);
391  SumMPI_dv(nstate, X->Phys.Sz);
392 }
406  struct BindStruct *X,
407  int nstate,
408  std::complex<double> **vec
409 ) {
410  long int j;
411  long int isite1, isite2, tmp_isite1, tmp_isite2;
412  long int is1_up, is2_up;
413  long int iexchg, off, off_2;
414  int num1_up, num2_up, istate;
415  int num1_down, num2_down;
416  int sigma_1, sigma_2;
417  long int ibit1_up, ibit2_up, ibit_tmp, is_up;
418  std::complex<double> spn_z1, spn_z2;
419  long int list_1_j;
420  long int i_max;
421 
422  i_max = X->Check.idim_max;
423  X->Large.mode = M_TOTALS;
424  for (istate = 0; istate < nstate; istate++) {
425  X->Phys.s2[istate] = 0.0;
426  X->Phys.Sz[istate] = 0.0;
427  }
428  if (X->Def.iFlgGeneralSpin == FALSE) {
429  for (isite1 = 1; isite1 <= X->Def.NsiteMPI; isite1++) {
430  if (isite1 > X->Def.Nsite) {
431  is1_up = X->Def.Tpow[isite1 - 1];
432  ibit1_up = myrank & is1_up;
433  num1_up = ibit1_up / is1_up;
434  num1_down = 1 - num1_up;
435  for (j = 1; j <= i_max; j++) {
436  for (istate = 0; istate < nstate; istate++)
437  X->Phys.Sz[istate] += real(conj(vec[j][istate])*vec[j][istate]) * (num1_up - num1_down) / 2.0;
438  }
439  }
440  else {
441  is1_up = X->Def.Tpow[isite1 - 1];
442  for (j = 1; j <= i_max; j++) {
443  list_1_j = j - 1;
444  ibit1_up = list_1_j & is1_up;
445  num1_up = ibit1_up / is1_up;
446  num1_down = 1 - num1_up;
447  for (istate = 0; istate < nstate; istate++)
448  X->Phys.Sz[istate] += real(conj(vec[j][istate])*vec[j][istate]) * (num1_up - num1_down) / 2.0;
449  }
450  }
451  for (isite2 = 1; isite2 <= X->Def.NsiteMPI; isite2++) {
452 
453  if (isite1 > X->Def.Nsite && isite2 > X->Def.Nsite) {
454  is1_up = X->Def.Tpow[isite1 - 1];
455  is2_up = X->Def.Tpow[isite2 - 1];
456  num1_up = X_SpinGC_CisAis((long int)myrank + 1, is1_up, 1);
457  num1_down = 1 - num1_up;
458  num2_up = X_SpinGC_CisAis((long int)myrank + 1, is2_up, 1);
459  num2_down = 1 - num2_up;
460  spn_z2 = (num1_up - num1_down)*(num2_up - num2_down) / 4.0;
461  for (j = 1; j <= i_max; j++) {
462  for (istate = 0; istate < nstate; istate++)
463  X->Phys.s2[istate] += real(conj(vec[j][istate])*vec[j][istate] * spn_z2);
464  }
465  if (isite1 == isite2) {
466  for (j = 1; j <= i_max; j++) {
467  for (istate = 0; istate < nstate; istate++)
468  X->Phys.s2[istate] += real(conj(vec[j][istate])*vec[j][istate]) / 2.0;
469  }
470  }//isite1 = isite2
471  else {//off diagonal
472  //debug spn += X_GC_child_CisAitCiuAiv_spin_MPIdouble(
473  //debug isite1 - 1, 0, 1, isite2 - 1, 1, 0, 1.0, X, nstate, vec, vec) / 2.0;
474  }
475  }
476  else if (isite1 > X->Def.Nsite || isite2 > X->Def.Nsite) {
477  if (isite1 < isite2) {
478  tmp_isite1 = isite1;
479  tmp_isite2 = isite2;
480  }
481  else {
482  tmp_isite1 = isite2;
483  tmp_isite2 = isite1;
484  }
485  is1_up = X->Def.Tpow[tmp_isite1 - 1];
486  is2_up = X->Def.Tpow[tmp_isite2 - 1];
487  num2_up = X_SpinGC_CisAis((long int)myrank + 1, is2_up, 1);
488  num2_down = 1 - num2_up;
489  //diagonal
490  for (j = 1; j <= i_max; j++) {
491  list_1_j = j - 1;
492  ibit1_up = list_1_j & is1_up;
493  num1_up = ibit1_up / is1_up;
494  num1_down = 1 - num1_up;
495  spn_z2 = (num1_up - num1_down)*(num2_up - num2_down);
496  for (istate = 0; istate < nstate; istate++)
497  X->Phys.s2[istate] += real(conj(vec[j][istate])*vec[j][istate] * spn_z2) / 4.0;
498  }
499  if (isite1 < isite2) {
500  //debug spn += X_GC_child_CisAitCiuAiv_spin_MPIsingle(isite1 - 1, 0, 1, isite2 - 1, 1, 0, 1.0, X, nstate, vec, vec) / 2.0;
501  }
502  else {
503  //debug spn += conj(X_GC_child_CisAitCiuAiv_spin_MPIsingle(isite2 - 1, 1, 0, isite1 - 1, 0, 1, 1.0, X, nstate, vec, vec)) / 2.0;
504  }
505  }
506  else {
507  is2_up = X->Def.Tpow[isite2 - 1];
508  is_up = is1_up + is2_up;
509  for (j = 1; j <= i_max; j++) {
510  list_1_j = j - 1;
511  ibit1_up = list_1_j & is1_up;
512  num1_up = ibit1_up / is1_up;
513  num1_down = 1 - num1_up;
514  ibit2_up = list_1_j & is2_up;
515  num2_up = ibit2_up / is2_up;
516  num2_down = 1 - num2_up;
517 
518  spn_z2 = (num1_up - num1_down)*(num2_up - num2_down);
519  for (istate = 0; istate < nstate; istate++)
520  X->Phys.s2[istate] += real(conj(vec[j][istate])*vec[j][istate] * spn_z2) / 4.0;
521 
522  if (isite1 == isite2) {
523  for (istate = 0; istate < nstate; istate++)
524  X->Phys.s2[istate] += real(conj(vec[j][istate])*vec[j][istate]) / 2.0;
525  }
526  else {
527  ibit_tmp = (num1_up) ^ (num2_up);
528  if (ibit_tmp != 0) {
529  iexchg = list_1_j ^ (is_up);
530  off = iexchg + 1;
531  for (istate = 0; istate < nstate; istate++)
532  X->Phys.s2[istate] += real(conj(vec[j][istate])*vec[off][istate]) / 2.0;
533  }
534  }
535  }//j
536  }//else
537  }
538  }
539  }
540  else {//general spin
541  double S1 = 0;
542  double S2 = 0;
543  for (isite1 = 1; isite1 <= X->Def.NsiteMPI; isite1++) {
544  S1 = 0.5*(X->Def.SiteToBit[isite1 - 1] - 1);
545  if (isite1 > X->Def.Nsite) {
546  spn_z1 = 0.5*GetLocal2Sz(isite1, (long int) myrank, X->Def.SiteToBit, X->Def.Tpow);
547  for (j = 1; j <= i_max; j++) {
548  for (istate = 0; istate < nstate; istate++) {
549  X->Phys.s2[istate] += real(conj(vec[j][istate])*vec[j][istate]) * S1*(S1 + 1.0);
550  X->Phys.Sz[istate] += real(conj(vec[j][istate])*vec[j][istate] * spn_z1);
551  }
552  }
553  }
554  else {
555  for (j = 1; j <= i_max; j++) {
556  spn_z1 = 0.5*GetLocal2Sz(isite1, j - 1, X->Def.SiteToBit, X->Def.Tpow);
557  for (istate = 0; istate < nstate; istate++) {
558  X->Phys.s2[istate] += real(conj(vec[j][istate])*vec[j][istate]) * S1*(S1 + 1.0);
559  X->Phys.Sz[istate] += real(conj(vec[j][istate])*vec[j][istate] * spn_z1);
560  }
561  }
562  }
563  for (isite2 = 1; isite2 <= X->Def.NsiteMPI; isite2++) {
564  if (isite1 == isite2) continue;
565  S2 = 0.5*(X->Def.SiteToBit[isite2 - 1] - 1);
566  if (isite1 > X->Def.Nsite && isite2 > X->Def.Nsite) {
567  }
568  else if (isite1 > X->Def.Nsite || isite2 > X->Def.Nsite) {
569  }
570  else { //inner-process
571  for (j = 1; j <= i_max; j++) {
572  spn_z1 = 0.5*GetLocal2Sz(isite1, j - 1, X->Def.SiteToBit, X->Def.Tpow);
573  spn_z2 = 0.5*GetLocal2Sz(isite2, j - 1, X->Def.SiteToBit, X->Def.Tpow);
574  for (istate = 0; istate < nstate; istate++)
575  X->Phys.s2[istate] += real(conj(vec[j][istate])*vec[j][istate] * spn_z1*spn_z2);
576 
577  sigma_1 = GetBitGeneral(isite1, j - 1, X->Def.SiteToBit, X->Def.Tpow);
578  sigma_2 = GetBitGeneral(isite2, j - 1, X->Def.SiteToBit, X->Def.Tpow);
579 
580  ibit_tmp = GetOffCompGeneralSpin(j - 1, isite2, sigma_2, sigma_2 + 1, &off, X->Def.SiteToBit, X->Def.Tpow);
581  if (ibit_tmp != 0) {
582  ibit_tmp = GetOffCompGeneralSpin(off, isite1, sigma_1, sigma_1 - 1, &off_2, X->Def.SiteToBit, X->Def.Tpow);
583  if (ibit_tmp != 0) {
584  for (istate = 0; istate < nstate; istate++)
585  X->Phys.s2[istate] += real(conj(vec[j][istate])*vec[off_2 + 1][istate])
586  * sqrt(S2*(S2 + 1) - real(spn_z2) * (real(spn_z2) + 1))
587  * sqrt(S1*(S1 + 1) - real(spn_z1) * (real(spn_z1) - 1)) / 2.0;
588  }
589  }
590  ibit_tmp = GetOffCompGeneralSpin(j - 1, isite2, sigma_2, sigma_2 - 1, &off, X->Def.SiteToBit, X->Def.Tpow);
591  if (ibit_tmp != 0) {
592  ibit_tmp = GetOffCompGeneralSpin(off, isite1, sigma_1, sigma_1 + 1, &off_2, X->Def.SiteToBit, X->Def.Tpow);
593  if (ibit_tmp != 0) {
594  for (istate = 0; istate < nstate; istate++)
595  X->Phys.s2[istate] += real(conj(vec[j][istate])*vec[off_2 + 1][istate])
596  * sqrt(S2*(S2 + 1) - real(spn_z2) * (real(spn_z2) - 1.0))
597  * sqrt(S1*(S1 + 1) - real(spn_z1) * (real(spn_z1) + 1)) / 2.0;
598  }
599  }
600  }//j
601  }//inner-process
602  }//isite2
603  }//isite1
604  }
605  SumMPI_dv(nstate, X->Phys.s2);
606  SumMPI_dv(nstate, X->Phys.Sz);
607 }
618 int expec_totalspin
619 (
620  struct BindStruct *X,
621  int nstate,
622  std::complex<double> **vec
623 )
624 {
625  int istate;
626 
627  X->Large.mode = M_TOTALS;
628  switch (X->Def.iCalcModel) {
629  case Spin:
630  totalspin_Spin(X, nstate, vec);
631  for (istate = 0; istate < nstate; istate++)
632  X->Phys.Sz[istate] = X->Def.Total2SzMPI / 2.;
633  break;
634  case SpinGC:
635  totalspin_SpinGC(X, nstate, vec);
636  break;
637  case Hubbard:
638  case Kondo:
639  totalspin_Hubbard(X, nstate, vec);
640  break;
641  case HubbardGC:
642  case KondoGC:
643  totalspin_HubbardGC(X, nstate, vec);
644  break;
645  default:
646  for (istate = 0; istate < nstate; istate++) {
647  X->Phys.s2[istate] = 0.0;
648  X->Phys.Sz[istate] = 0.0;
649  }
650  }
651  return 0;
652 }
struct DefineList Def
Definision of system (Hamiltonian) etc.
Definition: struct.hpp:395
int GetSplitBitByModel(const int Nsite, const int iCalcModel, long int *irght, long int *ilft, long int *ihfbit)
function of splitting original bit into right and left spaces.
Definition: bitcalc.cpp:78
long int * list_2_1
Definition: global.cpp:27
long int * list_2_2
Definition: global.cpp:28
void totalspin_Hubbard(struct BindStruct *X, int nstate, std::complex< double > **vec)
function of calculating totalspin for Hubbard model
double * s2
Expectation value of the square of the total S.
Definition: struct.hpp:365
int Nsite
Number of sites in the INTRA process region.
Definition: struct.hpp:56
void totalspin_Spin(struct BindStruct *X, int nstate, std::complex< double > **vec)
function of calculating totalspin for spin model
int X_SpinGC_CisAis(long int j, long int is1_spin, long int sigma1)
Compute the grandcanonical spin state with bit mask is1_spin.
struct LargeList Large
Variables for Matrix-Vector product.
Definition: struct.hpp:397
int ConvertToList1GeneralSpin(const long int org_ibit, const long int ihlfbit, long int *_ilist1Comp)
function of converting component to list_1
Definition: bitcalc.cpp:285
struct PhysList Phys
Physical quantities.
Definition: struct.hpp:398
int mode
multiply or expectation value.
Definition: struct.hpp:331
double * Sz
Expectation value of the Total Sz.
Definition: struct.hpp:361
int NsiteMPI
Total number of sites, differ from DefineList::Nsite.
Definition: struct.hpp:57
Bind.
Definition: struct.hpp:394
int GetOffCompGeneralSpin(const long int org_ibit, const int org_isite, const int org_ispin, const int off_ispin, long int *_ioffComp, const long int *SiteToBit, const long int *Tpow)
function of getting off-diagonal component for general spin
Definition: bitcalc.cpp:243
int GetOffComp(long int *_list_2_1, long int *_list_2_2, long int _ibit, const long int _irght, const long int _ilft, const long int _ihfbit, long int *_ioffComp)
function of getting off-diagonal component
Definition: bitcalc.cpp:195
int expec_totalspin(struct BindStruct *X, int nstate, std::complex< double > **vec)
Parent function of calculation of total spin.
int myrank
Process ID, defined in InitializeMPI()
Definition: global.cpp:73
int GetLocal2Sz(const int isite, const long int org_bit, const long int *SiteToBit, const long int *Tpow)
get 2sz at a site for general spin
Definition: bitcalc.cpp:448
int iFlgGeneralSpin
Flag for the general (Sz/=1/2) spin.
Definition: struct.hpp:86
void totalspin_HubbardGC(struct BindStruct *X, int nstate, std::complex< double > **vec)
function of calculating totalspin for Hubbard model in grand canonical ensemble
void SumMPI_dv(int nnorm, double *norm)
MPI wrapper function to obtain sum of Double array across processes.
Definition: wrapperMPI.cpp:238
void totalspin_SpinGC(struct BindStruct *X, int nstate, std::complex< double > **vec)
function of calculating totalspin for spin model in grand canonical ensemble
long int * SiteToBit
[DefineList::NsiteMPI] Similar to DefineList::Tpow. For general spin.
Definition: struct.hpp:94
long int * Tpow
[2 * DefineList::NsiteMPI] malloc in setmem_def().
Definition: struct.hpp:90
int iCalcModel
Switch for model. 0:Hubbard, 1:Spin, 2:Kondo, 3:HubbardGC, 4:SpinGC, 5:KondoGC, 6:HubbardNConserved.
Definition: struct.hpp:200
struct CheckList Check
Size of the Hilbert space.
Definition: struct.hpp:396
long int sdim
Dimension for Ogata-Lin ???
Definition: struct.hpp:309
long int * list_1
Definition: global.cpp:25
long int idim_max
The dimension of the Hilbert space of this process.
Definition: struct.hpp:305
int GetBitGeneral(const int isite, const long int org_bit, const long int *SiteToBit, const long int *Tpow)
get bit at a site for general spin
Definition: bitcalc.cpp:421
int Total2SzMPI
Total across processes.
Definition: struct.hpp:70