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.cc 14KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398
  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.cc
  6. Purpose: from a .raw file, produces .dsf (dynamical sf) and .ssf (static sf) files.
  7. ***********************************************************/
  8. #include "ABACUS.h"
  9. using namespace std;
  10. using namespace ABACUS;
  11. namespace ABACUS {
  12. DP Smoothen_RAW_into_SF (string prefix, int iKmin, int iKmax, int DiK,
  13. DP ommin, DP ommax, int Nom, DP gwidth, DP normalization, DP denom_sum_K)
  14. {
  15. // ommax is omega max for .dsf file, Nom is the number of omega slots used.
  16. // gwidth is the width of the smoothing Gaussian, defined as
  17. // exp(-omega^2/(2 * gwidth^2))
  18. // DiK is the (half-)window in iK which is averaged over. Averaging over a single iK means DiK == 0.
  19. // Open the original raw file:
  20. stringstream RAW_stringstream; string RAW_string;
  21. RAW_stringstream << prefix << ".raw";
  22. RAW_string = RAW_stringstream.str(); const char* RAW_Cstr = RAW_string.c_str();
  23. ifstream RAW_infile;
  24. RAW_infile.open(RAW_Cstr);
  25. if (RAW_infile.fail()) {
  26. cout << RAW_Cstr << endl;
  27. ABACUSerror("Could not open RAW_infile... ");
  28. }
  29. if (iKmax - iKmin + 1 < 0) ABACUSerror("Improper iKmin, iKmax in Smoothen_RAW_into_SF");
  30. RecMat<DP> DSF(Nom, iKmax - iKmin + 1);
  31. Vect_DP SSF(0.0, iKmax - iKmin + 1);
  32. Vect_DP ASF(0.0, Nom);
  33. DP omega;
  34. int iK;
  35. DP FF;
  36. DP dev;
  37. string label;
  38. // Momenta: average over 2*DiK + 1 entries. Weigh them linearly decreasing away from central one.
  39. // Setting central one to value 1 + DiK,
  40. // total weight is 1 + DiK + 2* \sum_1^DiK n = 1 + DiK + DiK (DiK + 1) = (DiK + 1)^2.
  41. // Weight given is thus abs(DiK + 1 - (iK - iK'))/(DiK + 1)^2 for abs(iK - iK') <= DiK.
  42. Vect_DP Kweight(DiK + 1);
  43. for (int i = 0; i < DiK + 1; ++i) Kweight[i] = (DiK + 1.0 - i)/pow(DiK + 1.0, 2);
  44. Vect_DP omegaout (Nom);
  45. for (int i = 0; i < Nom; ++i) omegaout[i] = ommin + (0.5 + i) * (ommax - ommin)/Nom;
  46. DP d_omega;
  47. DP big_gwidth_used = 10.0 * gwidth; // neglect terms having gaussian < exp(-50)
  48. DP oneovertwowidthsq = 1.0/(2.0 * gwidth * gwidth);
  49. DP SFfactor = 1.0;
  50. while (RAW_infile.peek() != EOF) {
  51. RAW_infile >> omega >> iK >> FF >> dev >> label;
  52. if (iK >= iKmin && iK <= iKmax && fabs(omega) > 1.0e-8) { // remove connected part of DSF
  53. for (int deltaiK = -DiK; deltaiK <= DiK; ++deltaiK)
  54. if (iK + deltaiK >= iKmin && iK + deltaiK <= iKmax)
  55. SSF[iK + deltaiK - iKmin] += Kweight[abs(deltaiK)] * FF * FF;
  56. for (int iomega = 0; iomega < Nom; ++iomega)
  57. if (big_gwidth_used > (d_omega = fabs(omegaout[iomega] - omega))) {
  58. SFfactor = FF * FF * exp(-d_omega*d_omega * oneovertwowidthsq);
  59. ASF[iomega] += SFfactor;
  60. if (fabs(omega) > 1.0e-12) // exclude the delta function contribution coming from diagonal term, if present
  61. for (int deltaiK = -DiK; deltaiK <= DiK; ++deltaiK)
  62. if (iK + deltaiK >= iKmin && iK + deltaiK <= iKmax)
  63. DSF[iomega][iK + deltaiK - iKmin] += Kweight[abs(deltaiK)] * SFfactor;
  64. }
  65. }
  66. }
  67. RAW_infile.close();
  68. // Reset proper normalization:
  69. DP normalization_used = normalization * 1.0/(sqrt(twoPI) * gwidth); // Gaussian factor
  70. for (int iK = 0; iK < iKmax - iKmin + 1; ++iK) {
  71. SSF[iK] *= normalization/twoPI; // twoPI from integral over omega: \int d\omega/2\pi
  72. for (int iomega = 0; iomega < Nom; ++iomega)
  73. DSF[iomega][iK] *= normalization_used;
  74. }
  75. DP ASFnormalization = normalization_used/denom_sum_K;
  76. for (int iomega = 0; iomega < Nom; ++iomega) ASF[iomega] *= ASFnormalization;
  77. // Output to .dsf, .ssf and .asf files
  78. stringstream DSF_stringstream; string DSF_string;
  79. DSF_stringstream << prefix;
  80. if (DiK > 0) DSF_stringstream << "_DiK_" << DiK;
  81. DSF_stringstream << "_ommin_"<< ommin << "_ommax_" << ommax << "_Nom_" << Nom << "_w_" << gwidth << ".dsf";
  82. DSF_string = DSF_stringstream.str(); const char* DSF_Cstr = DSF_string.c_str();
  83. ofstream DSF_outfile;
  84. DSF_outfile.open(DSF_Cstr);
  85. DSF_outfile.precision(12);
  86. for (int iomega = 0; iomega < Nom; ++iomega) {
  87. if (iomega > 0) DSF_outfile << endl;
  88. for (int iK = 0; iK < iKmax - iKmin + 1; ++iK)
  89. DSF_outfile << DSF[iomega][iK] << "\t";
  90. }
  91. DSF_outfile.close();
  92. stringstream SSF_stringstream; string SSF_string;
  93. SSF_stringstream << prefix;
  94. if (DiK > 0) SSF_stringstream << "_DiK_" << DiK;
  95. SSF_stringstream << ".ssf";
  96. SSF_string = SSF_stringstream.str(); const char* SSF_Cstr = SSF_string.c_str();
  97. ofstream SSF_outfile;
  98. SSF_outfile.open(SSF_Cstr);
  99. SSF_outfile.precision(12);
  100. for (int iK = 0; iK < iKmax - iKmin + 1; ++iK) {
  101. if (iK > 0) SSF_outfile << endl;
  102. SSF_outfile << iK + iKmin << "\t" << SSF[iK];
  103. }
  104. SSF_outfile.close();
  105. stringstream ASF_stringstream; string ASF_string;
  106. ASF_stringstream << prefix;
  107. ASF_stringstream << "_ommin_"<< ommin << "_ommax_" << ommax << "_Nom_" << Nom << "_w_" << gwidth << ".asf";
  108. ASF_string = ASF_stringstream.str(); const char* ASF_Cstr = ASF_string.c_str();
  109. ofstream ASF_outfile;
  110. ASF_outfile.open(ASF_Cstr);
  111. ASF_outfile.precision(12);
  112. for (int iomega = 0; iomega < Nom; ++iomega) {
  113. if (iomega > 0) ASF_outfile << endl;
  114. ASF_outfile << omegaout[iomega] << "\t" << ASF[iomega];
  115. }
  116. ASF_outfile.close();
  117. // Check sums:
  118. DP sumdsf = 0.0;
  119. DP sumssf = 0.0;
  120. for (int iK = 0; iK < iKmax - iKmin + 1; ++iK) {
  121. sumssf += SSF[iK];
  122. for (int iomega = 0; iomega < Nom; ++iomega)
  123. sumdsf += DSF[iomega][iK];
  124. }
  125. sumssf /= (iKmax - iKmin + 1);
  126. sumdsf /= (iKmax - iKmin + 1) * Nom;
  127. return(sumdsf);
  128. }
  129. // This is the same function as above, but now using data for a diagonal ensemble of states
  130. DP Smoothen_RAW_into_SF (string prefix, Vect<string> rawfilename, Vect<DP> weight, int iKmin, int iKmax, int DiK,
  131. DP ommin, DP ommax, int Nom, DP gwidth, DP normalization, DP denom_sum_K)
  132. {
  133. // ommax is omega max for .dsf file, Nom is the number of omega slots used.
  134. // gwidth is the width of the smoothing Gaussian, defined as
  135. // exp(-omega^2/(2 * gwidth^2))
  136. // DiK is the (half-)window in iK which is averaged over. Averaging over a single iK means DiK == 0.
  137. if (iKmax - iKmin + 1 < 0) ABACUSerror("Improper iKmin, iKmax in Smoothen_RAW_into_SF");
  138. RecMat<DP> DSF(Nom, iKmax - iKmin + 1);
  139. Vect_DP SSF(0.0, iKmax - iKmin + 1);
  140. Vect_DP ASF(0.0, Nom);
  141. DP omega;
  142. int iK;
  143. DP FF;
  144. DP dev;
  145. string label;
  146. // Momenta: average over 2*DiK + 1 entries. Weigh them linearly decreasing away from central one.
  147. // Setting central one to value 1 + DiK,
  148. // total weight is 1 + DiK + 2* \sum_1^DiK n = 1 + DiK + DiK (DiK + 1) = (DiK + 1)^2.
  149. // Weight given is thus abs(DiK + 1 - (iK - iK'))/(DiK + 1)^2 for abs(iK - iK') <= DiK.
  150. Vect_DP Kweight(DiK + 1);
  151. for (int i = 0; i < DiK + 1; ++i) Kweight[i] = (DiK + 1.0 - i)/pow(DiK + 1.0, 2);
  152. Vect_DP omegaout (Nom);
  153. for (int i = 0; i < Nom; ++i) omegaout[i] = ommin + (0.5 + i) * (ommax - ommin)/Nom;
  154. DP d_omega;
  155. DP big_gwidth_used = 10.0 * gwidth; // neglect terms having gaussian < exp(-50)
  156. DP oneovertwowidthsq = 1.0/(2.0 * gwidth * gwidth);
  157. DP SFfactor = 1.0;
  158. for (int ns = 0; ns < weight.size(); ++ns) {
  159. // Open the original raw file:
  160. const char* RAW_Cstr = rawfilename[ns].c_str();
  161. ifstream RAW_infile;
  162. RAW_infile.open(RAW_Cstr);
  163. if (RAW_infile.fail()) {
  164. cout << RAW_Cstr << endl;
  165. ABACUSerror("Could not open RAW_infile... ");
  166. }
  167. while (RAW_infile.peek() != EOF) {
  168. RAW_infile >> omega >> iK >> FF >> dev >> label;
  169. if (iK >= iKmin && iK <= iKmax && fabs(omega) > 1.0e-8) { // remove connected part of DSF)
  170. SSF[iK - iKmin] += weight[ns] * FF * FF;
  171. for (int iomega = 0; iomega < Nom; ++iomega)
  172. if (big_gwidth_used > (d_omega = fabs(omegaout[iomega] - omega))) {
  173. SFfactor = weight[ns] * FF * FF * exp(-d_omega*d_omega * oneovertwowidthsq);
  174. ASF[iomega] += SFfactor;
  175. if (fabs(omega) > 1.0e-12) // exclude the delta function contribution coming from diagonal term, if present
  176. for (int deltaiK = -DiK; deltaiK <= DiK; ++deltaiK)
  177. if (iK + deltaiK >= iKmin && iK + deltaiK <= iKmax)
  178. DSF[iomega][iK + deltaiK - iKmin] += Kweight[abs(deltaiK)] * SFfactor;
  179. }
  180. }
  181. }
  182. RAW_infile.close();
  183. } // for ns
  184. // Reset proper normalization:
  185. DP normalization_used = normalization * 1.0/(sqrt(twoPI) * gwidth); // Gaussian factor
  186. for (int iK = 0; iK < iKmax - iKmin + 1; ++iK) {
  187. SSF[iK] *= normalization/twoPI; // twoPI from integral over omega: \int d\omega/2\pi
  188. for (int iomega = 0; iomega < Nom; ++iomega)
  189. DSF[iomega][iK] *= normalization_used;
  190. }
  191. DP ASFnormalization = normalization_used/denom_sum_K;
  192. for (int iomega = 0; iomega < Nom; ++iomega) ASF[iomega] *= ASFnormalization;
  193. // Output to .dsf, .ssf and .asf files
  194. stringstream DSF_stringstream; string DSF_string;
  195. DSF_stringstream << prefix;
  196. DSF_stringstream << "_ns_" << weight.size();
  197. if (DiK > 0) DSF_stringstream << "_DiK_" << DiK;
  198. DSF_stringstream << "_ommin_"<< ommin << "_ommax_" << ommax << "_Nom_" << Nom << "_w_" << gwidth << ".dsf";
  199. DSF_string = DSF_stringstream.str(); const char* DSF_Cstr = DSF_string.c_str();
  200. ofstream DSF_outfile;
  201. DSF_outfile.open(DSF_Cstr);
  202. DSF_outfile.precision(12);
  203. for (int iomega = 0; iomega < Nom; ++iomega) {
  204. if (iomega > 0) DSF_outfile << endl;
  205. for (int iK = 0; iK < iKmax - iKmin + 1; ++iK)
  206. DSF_outfile << DSF[iomega][iK] << "\t";
  207. }
  208. DSF_outfile.close();
  209. stringstream SSF_stringstream; string SSF_string;
  210. SSF_stringstream << prefix;
  211. SSF_stringstream << "_ns_" << weight.size();
  212. SSF_stringstream << ".ssf";
  213. SSF_string = SSF_stringstream.str(); const char* SSF_Cstr = SSF_string.c_str();
  214. ofstream SSF_outfile;
  215. SSF_outfile.open(SSF_Cstr);
  216. SSF_outfile.precision(12);
  217. for (int iK = 0; iK < iKmax - iKmin + 1; ++iK) {
  218. if (iK > 0) SSF_outfile << endl;
  219. SSF_outfile << iK + iKmin << "\t" << SSF[iK];
  220. }
  221. SSF_outfile.close();
  222. stringstream ASF_stringstream; string ASF_string;
  223. ASF_stringstream << prefix;
  224. ASF_stringstream << "_ns_" << weight.size();
  225. ASF_stringstream << "_ommin_"<< ommin << "_ommax_" << ommax << "_Nom_" << Nom << "_w_" << gwidth << ".asf";
  226. ASF_string = ASF_stringstream.str(); const char* ASF_Cstr = ASF_string.c_str();
  227. ofstream ASF_outfile;
  228. ASF_outfile.open(ASF_Cstr);
  229. ASF_outfile.precision(12);
  230. for (int iomega = 0; iomega < Nom; ++iomega) {
  231. if (iomega > 0) ASF_outfile << endl;
  232. ASF_outfile << omegaout[iomega] << "\t" << ASF[iomega];
  233. }
  234. ASF_outfile.close();
  235. // Check sums:
  236. DP sumdsf = 0.0;
  237. DP sumssf = 0.0;
  238. for (int iK = 0; iK < iKmax - iKmin + 1; ++iK) {
  239. sumssf += SSF[iK];
  240. for (int iomega = 0; iomega < Nom; ++iomega)
  241. sumdsf += DSF[iomega][iK];
  242. }
  243. sumssf /= (iKmax - iKmin + 1);
  244. sumdsf /= (iKmax - iKmin + 1) * Nom;
  245. return(sumdsf);
  246. }
  247. DP Smoothen_RAW_into_ASF (string prefix, int iKmin, int iKmax, DP ommin, DP ommax, int Nom, DP gwidth,
  248. DP normalization, DP denom_sum_K)
  249. {
  250. // ommax is omega max for .asf file, Nom is the number of omega slots used.
  251. // gwidth is the width of the smoothing Gaussian, defined as
  252. // exp(-omega^2/(2 * gwidth^2))
  253. // Open the original raw file:
  254. stringstream RAW_stringstream; string RAW_string;
  255. RAW_stringstream << prefix << ".raw";
  256. RAW_string = RAW_stringstream.str(); const char* RAW_Cstr = RAW_string.c_str();
  257. ifstream RAW_infile;
  258. RAW_infile.open(RAW_Cstr);
  259. if (RAW_infile.fail()) {
  260. cout << RAW_Cstr << endl;
  261. ABACUSerror("Could not open RAW_infile... ");
  262. }
  263. if (iKmax - iKmin + 1 < 0) ABACUSerror("Improper iKmin, iKmax in Smoothen_RAW_into_ASF");
  264. Vect_DP ASF(Nom);
  265. DP omega;
  266. int iK;
  267. DP FF;
  268. DP dev;
  269. string label;
  270. Vect_DP omegaout (Nom);
  271. for (int i = 0; i < Nom; ++i) omegaout[i] = ommin + (0.5 + i) * (ommax - ommin)/Nom;
  272. DP d_omega;
  273. DP big_gwidth_used = 10.0 * gwidth; // neglect terms having gaussian < exp(-50)
  274. DP oneovertwowidthsq = 1.0/(2.0 * gwidth * gwidth);
  275. while (RAW_infile.peek() != EOF) {
  276. RAW_infile >> omega >> iK >> FF >> dev >> label;
  277. if (iK >= iKmin && iK <= iKmax && fabs(omega) > 1.0e-8) { // remove connected part of DSF)
  278. for (int iomega = 0; iomega < Nom; ++iomega)
  279. if (big_gwidth_used > (d_omega = fabs(omegaout[iomega] - omega)))
  280. ASF[iomega] += FF * FF * exp(-d_omega*d_omega * oneovertwowidthsq);
  281. }
  282. }
  283. RAW_infile.close();
  284. // Reset proper normalization:
  285. DP normalization_used = normalization * 1.0/(sqrt(twoPI) * gwidth); // Gaussian factor
  286. normalization_used /= denom_sum_K;
  287. for (int iomega = 0; iomega < Nom; ++iomega)
  288. ASF[iomega] *= normalization_used;
  289. // Output to .asf file
  290. stringstream ASF_stringstream; string ASF_string;
  291. ASF_stringstream << prefix;
  292. //if (iKmax != iKmin) DSF_stringstream << "_iKmin_" << iKmin << "_iKmax_" << iKmax;
  293. ASF_stringstream << "_ommin_"<< ommin << "_ommax_" << ommax << "_Nom_" << Nom << "_w_" << gwidth << ".asf";
  294. ASF_string = ASF_stringstream.str(); const char* ASF_Cstr = ASF_string.c_str();
  295. ofstream ASF_outfile;
  296. ASF_outfile.open(ASF_Cstr);
  297. ASF_outfile.precision(12);
  298. for (int iomega = 0; iomega < Nom; ++iomega) {
  299. if (iomega > 0) ASF_outfile << endl;
  300. ASF_outfile << ASF[iomega] << "\t";
  301. }
  302. ASF_outfile.close();
  303. DP sumasf = 0.0;
  304. for (int iomega = 0; iomega < Nom; ++iomega)
  305. sumasf += ASF[iomega];
  306. sumasf /= Nom;
  307. return(sumasf);
  308. }
  309. } // namespace ABACUS