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.

Smoothen_RAW_into_SF_LiebLin_Scaled.cc 5.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. /**********************************************************
  2. This software is part of J.-S. Caux's ABACUS library.
  3. Copyright (c) J.-S. Caux.
  4. -----------------------------------------------------------
  5. File: Smoothen_RAW_into_SF_LiebLin_Scaled.cc
  6. Purpose: from a .raw file, produces .dsf (dynamical sf) file
  7. with gaussian width a function of momentum, and a .ssf (static sf) file.
  8. ***********************************************************/
  9. #include "ABACUS.h"
  10. using namespace std;
  11. using namespace ABACUS;
  12. namespace ABACUS {
  13. DP Smoothen_RAW_into_SF_LiebLin_Scaled (string prefix, DP L, int N, int iKmin, int iKmax, int DiK,
  14. DP ommin, DP ommax, int Nom, DP width, DP normalization)
  15. {
  16. // DiK is the (half-)window in iK which is averaged over. A single iK means DiK == 0.
  17. // ommax is omega max for .dsf file, Nom is the number of omega slots used.
  18. // width is measured in units of the level spacing (for each momentum independently).
  19. // gwidth is the width of the smoothing Gaussian, defined as
  20. // exp(-omega^2/(2 * gwidth^2))
  21. // Open the original raw file:
  22. stringstream RAW_stringstream; string RAW_string;
  23. RAW_stringstream << prefix << ".raw";
  24. RAW_string = RAW_stringstream.str(); const char* RAW_Cstr = RAW_string.c_str();
  25. ifstream RAW_infile;
  26. RAW_infile.open(RAW_Cstr);
  27. if (RAW_infile.fail()) {
  28. cout << RAW_Cstr << endl;
  29. ABACUSerror("Could not open RAW_infile... ");
  30. }
  31. if (iKmax - iKmin + 1 < 0) ABACUSerror("Improper iKmin, iKmax in Smoothen_RAW_into_SF_LiebLin_Scaled");
  32. RecMat<DP> DSFS(Nom, iKmax - iKmin + 1);
  33. Vect_DP SSF(0.0, iKmax - iKmin + 1);
  34. DP omega;
  35. int iK;
  36. DP FF;
  37. DP dev;
  38. string label;
  39. // Momenta: average over 2*DiK + 1 entries. Weigh them linearly decreasing away from central one.
  40. // Setting central one to value 1 + DiK,
  41. // total weight is 1 + DiK + 2* \sum_1^DiK n = 1 + DiK + DiK (DiK + 1) = (DiK + 1)^2.
  42. // Weight given is thus abs(DiK + 1 - (iK - iK'))/(DiK + 1)^2 for abs(iK - iK') <= DiK.
  43. Vect_DP Kweight(DiK + 1);
  44. for (int i = 0; i < DiK + 1; ++i) Kweight[i] = (DiK + 1.0 - i)/pow(DiK + 1.0, 2);
  45. Vect_DP omegaout (Nom);
  46. for (int i = 0; i < Nom; ++i) omegaout[i] = ommin + (0.5 + i) * (ommax - ommin)/Nom;
  47. DP d_omega;
  48. Vect_DP gwidth (iKmax - iKmin + 1);
  49. // At fixed momentum k, we take the bandwidth as bw = e_1 (k) - e_2 (k) calculated in TG limit,
  50. // i.e. bw = k^2 + 2\pi \rho k - (-k^2 + 2\pi\rho k) = 2 k^2 for 0 < k < 2k_F = 2\pi \rho
  51. // and bw = 2 * (2\pi \rho)^2 for 2k_F < k.
  52. // For iK <= N, there are iK states in bw.
  53. // For iK > N, there are N states.
  54. for (iK = iKmin; iK <= iKmax; ++iK)
  55. // Make sure the width does not become lower than the omegaout raster:
  56. gwidth[iK - iKmin] = ABACUS::max(2.0 * (ommax - ommin)/Nom, width * 2.0
  57. * ABACUS::min( pow(twoPI * ABACUS::max(abs(iK),1)/L, 2.0),
  58. pow(twoPI * N/L, 2.0))/ABACUS::min(N, ABACUS::max(abs(iK), 1)));
  59. Vect_DP big_gwidth_used (iKmax - iKmin + 1);
  60. for (iK = iKmin; iK <= iKmax; ++iK)
  61. big_gwidth_used[iK - iKmin] = 10.0 * gwidth[iK - iKmin]; // neglect terms having gaussian < exp(-50)
  62. Vect_DP oneovertwowidthsq (iKmax - iKmin + 1);
  63. for (iK = iKmin; iK <= iKmax; ++iK)
  64. oneovertwowidthsq[iK - iKmin] = 1.0/(2.0 * gwidth[iK - iKmin] * gwidth[iK - iKmin]);
  65. // Reset proper normalization:
  66. Vect_DP normalization_used (iKmax - iKmin + 1);
  67. for (iK = iKmin; iK <= iKmax; ++iK)
  68. normalization_used[iK - iKmin] = normalization * 1.0/(sqrt(twoPI) * gwidth[iK - iKmin]); // Gaussian factor
  69. DP FFsq = 0.0;
  70. while (RAW_infile.peek() != EOF) {
  71. RAW_infile >> omega >> iK >> FF >> dev >> label;
  72. if (iK >= iKmin && iK <= iKmax && fabs(omega) > 1.0e-8) { // remove connected part of DSF
  73. FFsq = FF * FF;
  74. SSF[iK - iKmin] += FFsq;
  75. for (int iomega = 0; iomega < Nom; ++iomega)
  76. if (big_gwidth_used[iK - iKmin] > (d_omega = fabs(omegaout[iomega] - omega)))
  77. for (int deltaiK = -DiK; deltaiK <= DiK; ++deltaiK)
  78. if (iK + deltaiK >= iKmin && iK + deltaiK <= iKmax)
  79. DSFS[iomega][iK + deltaiK - iKmin] += Kweight[abs(deltaiK)] * FFsq * normalization_used[iK + deltaiK - iKmin]
  80. * exp(-d_omega*d_omega * oneovertwowidthsq[iK + deltaiK - iKmin]);
  81. }
  82. }
  83. RAW_infile.close();
  84. // Reset proper normalization:
  85. for (int iK = 0; iK < iKmax - iKmin + 1; ++iK) {
  86. SSF[iK] *= normalization/twoPI;
  87. }
  88. // Output to .dsfs and .ssf files
  89. stringstream DSFS_stringstream; string DSFS_string;
  90. DSFS_stringstream << prefix;
  91. if (DiK > 0) DSFS_stringstream << "_DiK_" << DiK;
  92. DSFS_stringstream << "_ommin_"<< ommin << "_ommax_" << ommax << "_Nom_" << Nom << "_w_" << width << ".dsfs";
  93. DSFS_string = DSFS_stringstream.str(); const char* DSFS_Cstr = DSFS_string.c_str();
  94. ofstream DSFS_outfile;
  95. DSFS_outfile.open(DSFS_Cstr);
  96. DSFS_outfile.precision(12);
  97. for (int iomega = 0; iomega < Nom; ++iomega) {
  98. if (iomega > 0) DSFS_outfile << endl;
  99. for (int iK = 0; iK < iKmax - iKmin + 1; ++iK)
  100. DSFS_outfile << DSFS[iomega][iK] << "\t";
  101. }
  102. DSFS_outfile.close();
  103. stringstream SSF_stringstream; string SSF_string;
  104. SSF_stringstream << prefix;
  105. SSF_stringstream << ".ssf";
  106. SSF_string = SSF_stringstream.str(); const char* SSF_Cstr = SSF_string.c_str();
  107. ofstream SSF_outfile;
  108. SSF_outfile.open(SSF_Cstr);
  109. SSF_outfile.precision(12);
  110. for (int iK = 0; iK < iKmax - iKmin + 1; ++iK) {
  111. SSF_outfile << iK + iKmin << "\t" << SSF[iK] << endl;
  112. }
  113. SSF_outfile.close();
  114. // Check sums:
  115. DP sumdsf = 0.0;
  116. for (int iK = 0; iK < iKmax - iKmin + 1; ++iK) {
  117. for (int iomega = 0; iomega < Nom; ++iomega)
  118. sumdsf += DSFS[iomega][iK];
  119. }
  120. sumdsf /= (iKmax - iKmin + 1) * Nom;
  121. return(sumdsf);
  122. }
  123. } // namespace ABACUS