You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

ODSLF_Sumrules.cc 6.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. /**********************************************************
  2. This software is part of J.-S. Caux's ABACUS library.
  3. Copyright (c) J.-S. Caux.
  4. -----------------------------------------------------------
  5. File: src/ODSLF/ODSLF_Sumrules.cc
  6. Purpose: defines sumrule factors for spinless fermions related to Heisenberg
  7. ***********************************************************/
  8. #include "ABACUS.h"
  9. using namespace ABACUS;
  10. using namespace std;
  11. namespace ABACUS {
  12. DP ODSLF_X_avg (char xyorz, DP Delta, int N, int M)
  13. {
  14. // Calculates \sum_j < S_j^a S_{j+1}^a >, a = x, y or z.
  15. DP eps_Delta = 0.00000001;
  16. // Define the chain: J, Delta, h, Nsites
  17. Heis_Chain chain(1.0, Delta, 0.0, N);
  18. // Define the base: chain, Mdown
  19. ODSLF_Base gbase(chain, M);
  20. // Define the chain: J, Delta, h, Nsites
  21. Heis_Chain chain2(1.0, Delta + eps_Delta, 0.0, N);
  22. // Define the base: chain, Mdown
  23. ODSLF_Base gbase2(chain2, M);
  24. DP E0_Delta = 0.0;
  25. DP E0_Delta_eps = 0.0;
  26. if (Delta > 0.0 && Delta < 1.0) {
  27. // Define the ground state
  28. ODSLF_XXZ_Bethe_State gstate(chain, gbase);
  29. // Compute everything about the ground state
  30. gstate.Compute_All(true);
  31. E0_Delta = gstate.E;
  32. // Define the ground state
  33. ODSLF_XXZ_Bethe_State gstate2(chain2, gbase2);
  34. // Compute everything about the ground state
  35. gstate2.Compute_All(true);
  36. E0_Delta_eps = gstate2.E;
  37. }
  38. else ABACUSerror("Wrong anisotropy in ODSLF_S1_sumrule_factor.");
  39. DP answer = 0.0;
  40. if (xyorz == 'x' || xyorz == 'y') answer = 0.5 * (E0_Delta - Delta * (E0_Delta_eps - E0_Delta)/eps_Delta);
  41. // Careful for z ! Hamiltonian defined as S^z S^z - 1/4, so add back N/4:
  42. else if (xyorz == 'z') answer = (E0_Delta_eps - E0_Delta)/eps_Delta + 0.25 * N;
  43. else ABACUSerror("option not implemented in ODSLF_X_avg.");
  44. return(answer);
  45. }
  46. DP ODSLF_S1_sumrule_factor (char mporz, DP Delta, int N, int M, int iK)
  47. {
  48. DP X_x = ODSLF_X_avg ('x', Delta, N, M);
  49. DP X_z = ODSLF_X_avg ('z', Delta, N, M);
  50. DP sumrule = 0.0;
  51. if (mporz == 'm' || mporz == 'p')
  52. sumrule = - 2.0 * ((1.0 - Delta * cos((twoPI * iK)/N)) * X_x + (Delta - cos((twoPI * iK)/N)) * X_z)/N;
  53. else if (mporz == 'z') sumrule = iK == 0 ? 1.0 : -2.0 * X_x * (1.0 - cos((twoPI * iK)/N))/N;
  54. else if (mporz == 'a') sumrule = 1.0;
  55. else if (mporz == 'b') sumrule = 1.0;
  56. else ABACUSerror("option not implemented in ODSLF_S1_sumrule_factor.");
  57. return(1.0/(sumrule + 1.0e-32)); // sumrule is 0 for iK == 0 or N
  58. }
  59. DP ODSLF_S1_sumrule_factor (char mporz, DP Delta, int N, DP X_x, DP X_z, int iK)
  60. {
  61. DP sumrule = 0.0;
  62. if (mporz == 'm' || mporz == 'p')
  63. sumrule = - 2.0 * ((1.0 - Delta * cos((twoPI * iK)/N)) * X_x + (Delta - cos((twoPI * iK)/N)) * X_z)/N;
  64. else if (mporz == 'z') sumrule = -2.0 * X_x * (1.0 - cos((twoPI * iK)/N))/N;
  65. else if (mporz == 'a') sumrule = 1.0;
  66. else if (mporz == 'b') sumrule = 1.0;
  67. else ABACUSerror("option not implemented in ODSLF_S1_sumrule_factor.");
  68. return(1.0/(sumrule + 1.0e-32)); // sumrule is 0 for iK == 0 or N
  69. }
  70. DP Sumrule_Factor (char whichDSF, ODSLF_Bethe_State& RefState, DP Chem_Pot, int iKmin, int iKmax)
  71. {
  72. DP sumrule_factor = 1.0;
  73. if (iKmin != iKmax) {
  74. if (whichDSF == 'Z') sumrule_factor = 1.0;
  75. else if (whichDSF == 'm')
  76. sumrule_factor = 1.0/RefState.base.Mdown;
  77. else if (whichDSF == 'z') sumrule_factor = 1.0/(0.25 * RefState.chain.Nsites);
  78. else if (whichDSF == 'p') sumrule_factor = 1.0/(RefState.chain.Nsites - RefState.base.Mdown);
  79. else if (whichDSF == 'a') sumrule_factor = 1.0;
  80. else if (whichDSF == 'b') sumrule_factor = 1.0;
  81. else if (whichDSF == 'q') sumrule_factor = 1.0;
  82. else ABACUSerror("whichDSF option not consistent in Sumrule_Factor");
  83. }
  84. else if (iKmin == iKmax) {
  85. if (whichDSF == 'Z') sumrule_factor = 1.0;
  86. else if (whichDSF == 'm' || whichDSF == 'z' || whichDSF == 'p')
  87. sumrule_factor = ODSLF_S1_sumrule_factor (whichDSF, RefState.chain.Delta, RefState.chain.Nsites,
  88. RefState.base.Mdown, iKmax);
  89. else if (whichDSF == 'a') sumrule_factor = 1.0;
  90. else if (whichDSF == 'b') sumrule_factor = 1.0;
  91. else if (whichDSF == 'q') sumrule_factor = 1.0;
  92. else ABACUSerror("whichDSF option not consistent in Sumrule_Factor");
  93. }
  94. return(sumrule_factor);
  95. }
  96. void Evaluate_F_Sumrule (string prefix, char whichDSF, const ODSLF_Bethe_State& RefState,
  97. DP Chem_Pot, int iKmin, int iKmax)
  98. {
  99. stringstream RAW_stringstream; string RAW_string;
  100. RAW_stringstream << prefix << ".raw";
  101. RAW_string = RAW_stringstream.str(); const char* RAW_Cstr = RAW_string.c_str();
  102. stringstream FSR_stringstream; string FSR_string;
  103. FSR_stringstream << prefix << ".fsr";
  104. FSR_string = FSR_stringstream.str(); const char* FSR_Cstr = FSR_string.c_str();
  105. ifstream infile;
  106. infile.open(RAW_Cstr);
  107. if(infile.fail()) ABACUSerror("Could not open input file in Evaluate_F_Sumrule(ODSLF...).");
  108. // We run through the data file to chech the f sumrule at each positive momenta:
  109. Vect<DP> Sum_omega_FFsq(0.0, iKmax - iKmin + 1); //
  110. DP omega, FF;
  111. int iK, conv;
  112. long long int base_id, type_id, id;
  113. while (infile.peek() != EOF) {
  114. infile >> omega >> iK >> FF >> conv >> base_id >> type_id >> id;
  115. if (iK >= iKmin && iK <= iKmax) Sum_omega_FFsq[iK - iKmin] += omega * FF * FF;
  116. }
  117. infile.close();
  118. ofstream outfile;
  119. outfile.open(FSR_Cstr);
  120. outfile.precision(16);
  121. DP X_x = X_avg ('x', RefState.chain.Delta, RefState.chain.Nsites, RefState.base.Mdown);
  122. DP X_z = X_avg ('z', RefState.chain.Delta, RefState.chain.Nsites, RefState.base.Mdown);
  123. for (int i = iKmin; i <= iKmax; ++i) {
  124. if (i > iKmin) outfile << endl;
  125. outfile << i << "\t" << Sum_omega_FFsq[i] * ODSLF_S1_sumrule_factor (whichDSF, RefState.chain.Delta,
  126. RefState.chain.Nsites, X_x, X_z, i);
  127. }
  128. outfile.close();
  129. }
  130. } // namespace ABACUS