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.

LiebLin_Sumrules.cc 9.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. /**********************************************************
  2. This software is part of J.-S. Caux's ABACUS library.
  3. Copyright (c) J.-S. Caux.
  4. -----------------------------------------------------------
  5. File: src/LIEBLIN/LiebLin_Sumrules.cc
  6. Purpose: provides functions evaluating various sumrule factors
  7. for Lieb-Liniger.
  8. ***********************************************************/
  9. #include "ABACUS.h"
  10. using namespace std;
  11. using namespace ABACUS;
  12. namespace ABACUS {
  13. DP Sumrule_Factor (char whichDSF, LiebLin_Bethe_State& RefState, DP Chem_Pot, int iKmin, int iKmax)
  14. {
  15. DP sumrule_factor = 1.0;
  16. if (iKmin != iKmax) {
  17. if (whichDSF == 'Z') sumrule_factor = 1.0;
  18. else if (whichDSF == 'd' || whichDSF == '1') {
  19. // Here, we use a measure decreasing in K with K^2.
  20. // We sum up omega * MEsq/(iK^2) for all values of iKmin <= iK <= iKmax, discounting iK == 0 (where DSF vanishes)
  21. // We therefore have (N/L) x L^{-1} x (2\pi/L)^2 x (iKmax - iKmin + 1) = 4 \pi^2 x N x (iKmax - iKmin + 1)/L^4
  22. // Discounting iK == 0 (where DSF vanishes),
  23. // if iKmin <= 0 && iKmax >= 0 (in which case 0 is containted in [iKmin, iKmax])
  24. sumrule_factor = (iKmin <= 0 && iKmax >= 0) ?
  25. (RefState.L * RefState.L * RefState.L * RefState.L)/(4.0 * PI * PI * RefState.N * (iKmax - iKmin))
  26. : (RefState.L * RefState.L * RefState.L * RefState.L)/(4.0 * PI * PI * RefState.N * (iKmax - iKmin + 1));
  27. }
  28. // For the Green's function, it's the delta function \delta(x = 0) plus the density:
  29. else if (whichDSF == 'g')
  30. sumrule_factor = 1.0/((abs(iKmax - iKmin) + 1.0)/RefState.L + RefState.N/RefState.L);
  31. // For the one-body function, it's just the density:
  32. else if (whichDSF == 'o') sumrule_factor = RefState.L/RefState.N;
  33. else if (whichDSF == 'q') sumrule_factor = 1.0;
  34. else if (whichDSF == 'B') sumrule_factor = 1.0;
  35. else if (whichDSF == 'C') sumrule_factor = 1.0;
  36. else ABACUSerror("whichDSF option not consistent in Sumrule_Factor");
  37. }
  38. else if (iKmin == iKmax) {
  39. if (whichDSF == 'Z') sumrule_factor = 1.0;
  40. else if (whichDSF == 'd' || whichDSF == '1')
  41. // We sum up omega * MEsq
  42. sumrule_factor = pow(RefState.L, 4.0)/(4.0 * PI * PI * iKmax * iKmax * RefState.N);
  43. else if (whichDSF == 'g' || whichDSF == 'o') {
  44. // We sum up omega * MEsq
  45. sumrule_factor = 1.0/((pow(twoPI * iKmax/RefState.L, 2.0) - Chem_Pot
  46. + 4.0 * RefState.c_int * RefState.N/RefState.L)/RefState.L);
  47. }
  48. else if (whichDSF == 'q') sumrule_factor = 1.0;
  49. else if (whichDSF == 'B') sumrule_factor = 1.0;
  50. else if (whichDSF == 'C') sumrule_factor = 1.0;
  51. else ABACUSerror("whichDSF option not consistent in Sumrule_Factor");
  52. }
  53. return(sumrule_factor);
  54. }
  55. void Evaluate_F_Sumrule (char whichDSF, const LiebLin_Bethe_State& RefState, DP Chem_Pot,
  56. int iKmin, int iKmax, const char* RAW_Cstr, const char* FSR_Cstr)
  57. {
  58. ifstream infile;
  59. infile.open(RAW_Cstr);
  60. if(infile.fail()) {
  61. cout << "Filename RAW_Cstr = " << RAW_Cstr << endl;
  62. ABACUSerror("Could not open input file in Evaluate_F_Sumrule(LiebLin...).");
  63. }
  64. // We run through the data file to check the f sumrule at each positive momenta:
  65. Vect_DP Sum_omega_MEsq (0.0, iKmax - iKmin + 1);
  66. Vect_DP Sum_abs_omega_MEsq (0.0, iKmax - iKmin + 1);
  67. DP Sum_MEsq = 0.0;
  68. DP omega, ME;
  69. int iK;
  70. DP dev;
  71. string label;
  72. int nr, nl;
  73. int nraw = 0;
  74. while (infile.peek() != EOF) {
  75. nraw++;
  76. infile >> omega >> iK >> ME >> dev >> label;
  77. if (whichDSF == '1') infile >> nr >> nl;
  78. if (iK >= iKmin && iK <= iKmax) Sum_omega_MEsq[iK - iKmin] += omega * ME * ME;
  79. if (iK >= iKmin && iK <= iKmax) Sum_abs_omega_MEsq[iK - iKmin] += fabs(omega * ME * ME);
  80. Sum_MEsq += ME * ME;
  81. }
  82. infile.close();
  83. ofstream outfile;
  84. outfile.open(FSR_Cstr);
  85. outfile.precision(16);
  86. if (whichDSF == 'd' || whichDSF == '1') {
  87. for (int i = iKmin; i <= iKmax; ++i) {
  88. if (i > iKmin) outfile << endl;
  89. outfile << i << "\t" << Sum_omega_MEsq[i - iKmin] * pow(RefState.L, 4.0)
  90. /(pow(2.0 * PI * ABACUS::max(abs(i), 1), 2.0) * RefState.N)
  91. // Include average of result at +iK and -iK in a third column: iK is at index index(iK) = iK - iKmin
  92. // so -iK is at index index(-iK) = -iK - iKmin
  93. // We can only use this index if it is >= 0 and < iKmax - iKmin + 1, otherwise third column is copy of second:
  94. << "\t" << ((i + iKmin <= 0 && -i < iKmax + 1) ?
  95. 0.5 * (Sum_omega_MEsq[i - iKmin] + Sum_omega_MEsq[-i - iKmin])
  96. : Sum_omega_MEsq[i - iKmin])
  97. * pow(RefState.L, 4.0)/(pow(2.0 * PI * ABACUS::max(abs(i), 1), 2.0) * RefState.N);
  98. }
  99. }
  100. else if (whichDSF == 'g' || whichDSF == 'o') {
  101. for (int i = iKmin; i <= iKmax; ++i) {
  102. if (i > iKmin) outfile << endl;
  103. outfile << i << "\t" << Sum_omega_MEsq[i - iKmin] * RefState.L
  104. /((4.0 * PI * PI * i * i)/(RefState.L * RefState.L) - Chem_Pot + 4.0 * RefState.c_int * RefState.N/RefState.L)
  105. << "\t" << ((i + iKmin <= 0 && -i < iKmax + 1) ?
  106. 0.5 * (Sum_omega_MEsq[i - iKmin] + Sum_omega_MEsq[-i - iKmin]) : Sum_omega_MEsq[i - iKmin])
  107. * RefState.L/((4.0 * PI * PI * i * i)/(RefState.L * RefState.L) - Chem_Pot + 4.0 * RefState.c_int * RefState.N/RefState.L);
  108. }
  109. }
  110. outfile.close();
  111. }
  112. void Evaluate_F_Sumrule (string prefix, char whichDSF, const LiebLin_Bethe_State& RefState,
  113. DP Chem_Pot, int iKmin, int iKmax)
  114. {
  115. stringstream RAW_stringstream; string RAW_string;
  116. RAW_stringstream << prefix << ".raw";
  117. RAW_string = RAW_stringstream.str(); const char* RAW_Cstr = RAW_string.c_str();
  118. stringstream FSR_stringstream; string FSR_string;
  119. FSR_stringstream << prefix << ".fsr";
  120. FSR_string = FSR_stringstream.str(); const char* FSR_Cstr = FSR_string.c_str();
  121. Evaluate_F_Sumrule (whichDSF, RefState, Chem_Pot, iKmin, iKmax, RAW_Cstr, FSR_Cstr);
  122. }
  123. // Using diagonal state ensemble:
  124. void Evaluate_F_Sumrule (char whichDSF, DP c_int, DP L, int N, DP kBT, int nstates_req,
  125. DP Chem_Pot, int iKmin, int iKmax, const char* FSR_Cstr)
  126. {
  127. // We run through the data file to check the f sumrule at each positive momenta:
  128. Vect_DP Sum_omega_MEsq (0.0, iKmax - iKmin + 1);
  129. DP Sum_MEsq = 0.0;
  130. DP omega, ME;
  131. int iK;
  132. DP dev;
  133. string label;
  134. int nr, nl;
  135. // Read the weights from the ensembles file:
  136. LiebLin_Diagonal_State_Ensemble ensemble;
  137. stringstream ensfilestrstream;
  138. ensfilestrstream << "LiebLin_c_int_" << c_int << "_L_" << L << "_N_" << N << "_kBT_" << kBT << ".ens";
  139. string ensfilestr = ensfilestrstream.str();
  140. const char* ensfile_Cstr = ensfilestr.c_str();
  141. ensemble.Load(c_int, L, N, ensfile_Cstr);
  142. for (int ns = 0; ns < ensemble.nstates; ++ns) {
  143. // Define the raw input file name:
  144. stringstream filenameprefix;
  145. Data_File_Name (filenameprefix, whichDSF, iKmin, iKmax, 0.0, ensemble.state[ns],
  146. ensemble.state[ns], ensemble.state[ns].label);
  147. string prefix = filenameprefix.str();
  148. stringstream RAW_stringstream; string RAW_string;
  149. RAW_stringstream << prefix << ".raw";
  150. RAW_string = RAW_stringstream.str(); const char* RAW_Cstr = RAW_string.c_str();
  151. ifstream infile;
  152. infile.open(RAW_Cstr);
  153. if(infile.fail()) {
  154. cout << "Filename RAW_Cstr = " << RAW_Cstr << endl;
  155. ABACUSerror("Could not open input file in Evaluate_F_Sumrule(LiebLin...).");
  156. }
  157. while (infile.peek() != EOF) {
  158. infile >> omega >> iK >> ME >> dev >> label;
  159. if (whichDSF == '1') infile >> nr >> nl;
  160. if (iK >= iKmin && iK <= iKmax) Sum_omega_MEsq[iK - iKmin] += ensemble.weight[ns] * omega * ME * ME;
  161. Sum_MEsq += ensemble.weight[ns] * ME * ME;
  162. }
  163. infile.close();
  164. }
  165. LiebLin_Bethe_State RefState = ensemble.state[0]; // to use the code below, which comes from earlier Evaluate_F_Sumrule
  166. ofstream outfile;
  167. outfile.open(FSR_Cstr);
  168. outfile.precision(16);
  169. if (whichDSF == 'd' || whichDSF == '1') {
  170. for (int i = iKmin; i <= iKmax; ++i) {
  171. if (i > iKmin) outfile << endl;
  172. outfile << i << "\t" << Sum_omega_MEsq[i - iKmin] * pow(RefState.L, 4.0)
  173. /(pow(2.0 * PI * ABACUS::max(abs(i), 1), 2.0) * RefState.N)
  174. // Include average of result at +iK and -iK in a third column: iK is at index index(iK) = iK - iKmin
  175. // so -iK is at index index(-iK) = -iK - iKmin
  176. // We can only use this index if it is >= 0 and < iKmax - iKmin + 1, otherwise third column is copy of second:
  177. << "\t" << ((i + iKmin <= 0 && -i < iKmax + 1) ?
  178. 0.5 * (Sum_omega_MEsq[i - iKmin] + Sum_omega_MEsq[-i - iKmin])
  179. : Sum_omega_MEsq[i - iKmin])
  180. * pow(RefState.L, 4.0)/(pow(2.0 * PI * ABACUS::max(abs(i), 1), 2.0) * RefState.N);
  181. }
  182. }
  183. else if (whichDSF == 'g' || whichDSF == 'o') {
  184. for (int i = iKmin; i <= iKmax; ++i) {
  185. if (i > iKmin) outfile << endl;
  186. outfile << i << "\t" << Sum_omega_MEsq[i - iKmin] * RefState.L
  187. /((4.0 * PI * PI * i * i)/(RefState.L * RefState.L) - Chem_Pot + 4.0 * RefState.c_int * RefState.N/RefState.L)
  188. << "\t" << ((i + iKmin <= 0 && -i < iKmax + 1) ?
  189. 0.5 * (Sum_omega_MEsq[i - iKmin] + Sum_omega_MEsq[-i - iKmin])
  190. : Sum_omega_MEsq[i - iKmin]) * RefState.L
  191. /((4.0 * PI * PI * i * i)/(RefState.L * RefState.L) - Chem_Pot + 4.0 * RefState.c_int * RefState.N/RefState.L);
  192. }
  193. }
  194. outfile.close();
  195. }
  196. } // namespace ABACUS