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.

General_Scan.cc 49KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259
  1. /**********************************************************
  2. This software is part of J.-S. Caux's ABACUS library.
  3. Copyright (c) J.-S. Caux.
  4. -----------------------------------------------------------
  5. File: src/SCAN/General_Scan.cc
  6. Purpose: universal implementation of state scanning:
  7. functions to descend down hierarchy of intermediate states.
  8. NOTE: since templated functions have to be in the same file,
  9. we put all scanning functions here. The externally-accessible
  10. functions are defined at the end of this file.
  11. ***********************************************************/
  12. #include <omp.h>
  13. #include "ABACUS.h"
  14. using namespace std;
  15. using namespace ABACUS;
  16. string LABEL_TO_CHECK = "bla";
  17. //string LABEL_TO_CHECK = "6_0_";
  18. //string LABEL_TO_CHECK = "6_2_22y32";
  19. namespace ABACUS {
  20. // Types of descendents:
  21. // 14 == iK stepped up, leading exc one step further (can lead to ph recombination)
  22. // 13 == iK up, next exc (nr of ph preserved, not taking possible ph recombination into account)
  23. // 12 == iK up, next ext (nr ph increased, not taking possible ph recombination into account)
  24. // 11 == iK down, leading exc one step further (can lead to ph recombination)
  25. // 10 == iK down, next exc (nr of ph preserved, not taking possible ph recombination into account)
  26. // 9 == iK down, next exc (nr ph increased, not taking possible ph recombination into account)
  27. // 8 == iK preserved, 14 and 11 (up to 2 ph recombinations)
  28. // 7 == iK preserved, 14 and 10
  29. // 6 == iK preserved, 14 and 9
  30. // 5 == iK preserved, 13 and 11
  31. // 4 == iK preserved, 13 and 10
  32. // 3 == iK preserved, 13 and 9
  33. // 2 == iK preserved, 12 and 11
  34. // 1 == iK preserved, 12 and 10
  35. // 0 == iK preserved, 12 and 9
  36. // For scanning over symmetric states, the interpretation is slightly different.
  37. // Types 14, 13 and 12 step iK up using the Ix2 on the right only,
  38. // and mirrors the change on the left Ix2.
  39. // Types 11, 10 and 9 step iK down using the Ix2 on the right only,
  40. // and mirrors the change on the left Ix2.
  41. // There is then no need of scanning over types 0 - 8.
  42. // By convention, types 9, 10 and 11 can call types 9 - 14; types 12-14 can only call types 12-14.
  43. bool Expect_ph_Recombination_iK_Up (string ScanIx2_label, const Vect<Vect<int> >& OriginIx2,
  44. const Vect<Vect<int> >& BaseScanIx2)
  45. {
  46. // This function returns true if descending further can lead to a particle-hole recombination.
  47. // The criteria which are used are:
  48. // - the active excitation has moved at least one step (so it has already created its p-h pair)
  49. // - there exists an OriginIx2 between the active Ix2 and the next Ix2
  50. // (to right or left depending on type of descendent)
  51. Vect<Vect<int> > ScanIx2 = Return_Ix2_from_Label (ScanIx2_label, OriginIx2);
  52. // Determine the level and index of the bottom-most left-most right-moving quantum number sits:
  53. int exclevel = -1;
  54. int excindex = 0;
  55. bool excfound = false;
  56. do {
  57. exclevel++;
  58. if (exclevel == ScanIx2.size()) { // there is no right-moving quantum number in ScanIx2
  59. break;
  60. }
  61. for (int alpha = 0; alpha < ScanIx2[exclevel].size(); ++alpha)
  62. if (ScanIx2[exclevel][alpha] > BaseScanIx2[exclevel][alpha]) {
  63. excindex = alpha;
  64. excfound = true;
  65. break;
  66. }
  67. } while (!excfound);
  68. // If we haven't found an excitation, then exclevel == ScanIx2.size() and excindex = 0;
  69. if (excfound && !BaseScanIx2[exclevel].includes(ScanIx2[exclevel][excindex])) {
  70. // there exists an already dispersing excitation which isn't in Origin
  71. // Is there a possible recombination?
  72. if (excindex < ScanIx2[exclevel].size() - 1) {
  73. // a particle to the right of excitation has already move right, so there is a hole
  74. // check that there exists an occupied Ix2 in Origin sitting between the excitation
  75. // and the next Ix2 to its right in ScanIx2
  76. for (int alpha = BaseScanIx2[exclevel].size() - 1; alpha >= 0; --alpha)
  77. if (BaseScanIx2[exclevel][alpha] > ScanIx2[exclevel][excindex]
  78. && BaseScanIx2[exclevel][alpha] < ScanIx2[exclevel][excindex + 1]) {
  79. return(true);
  80. }
  81. }
  82. } // if (excfound)
  83. return(false);
  84. }
  85. // Specialization for Lieb-Liniger:
  86. bool Expect_ph_Recombination_iK_Up (string ScanIx2_label, const LiebLin_Bethe_State& OriginState)
  87. {
  88. Vect<Vect<int> > OriginIx2here(1);
  89. OriginIx2here[0] = OriginState.Ix2;
  90. Vect<Vect<int> > BaseScanIx2here(1);
  91. BaseScanIx2here[0] = OriginState.Ix2;
  92. return(Expect_ph_Recombination_iK_Up (ScanIx2_label, OriginIx2here, BaseScanIx2here));
  93. }
  94. // Specialization for Heis
  95. bool Expect_ph_Recombination_iK_Up (string ScanIx2_label, const Heis_Bethe_State& OriginState)
  96. {
  97. return(Expect_ph_Recombination_iK_Up (ScanIx2_label, OriginState.Ix2, OriginState.Ix2));
  98. }
  99. bool Expect_ph_Recombination_iK_Down (string ScanIx2_label, const Vect<Vect<int> >& OriginIx2,
  100. const Vect<Vect<int> >& BaseScanIx2)
  101. {
  102. // This function returns true if descending further can lead to a particle-hole recombination.
  103. // The criteria which are used are:
  104. // - the active excitation has moved at least one step (so it has already created its p-h pair)
  105. // - there exists an OriginIx2 between the active Ix2 and the next Ix2
  106. // (to right or left depending on type of descendent)
  107. Vect<Vect<int> > ScanIx2 = Return_Ix2_from_Label (ScanIx2_label, OriginIx2);
  108. // Determine the level and index of the bottom-most right-most left-moving quantum number sits:
  109. int exclevel = -1;
  110. int excindex = 0;
  111. bool excfound = false;
  112. do {
  113. exclevel++;
  114. if (exclevel == ScanIx2.size()) { // there isn't a single left-moving quantum number in ScanIx2
  115. break;
  116. }
  117. for (int alpha = ScanIx2[exclevel].size() - 1; alpha >= 0; --alpha) {
  118. if (ScanIx2[exclevel][alpha] < BaseScanIx2[exclevel][alpha]) {
  119. excindex = alpha;
  120. excfound = true;
  121. break;
  122. }
  123. }
  124. } while (!excfound);
  125. // If we haven't found an excitation, then exclevel == ScanIx2.size() and excindex = 0;
  126. if (!excfound) excindex = ScanIx2[exclevel].size() - 1;
  127. if (excfound && !BaseScanIx2[exclevel].includes(ScanIx2[exclevel][excindex])) {
  128. // there exists an already dispersing excitation which isn't in Origin
  129. // Is there a possible recombination?
  130. if (excindex > 0) {
  131. // a particle to the left of excitation has already moved left, so there is a hole
  132. // check that there exists an occupied Ix2 in Origin sitting between the excitation
  133. // and the next Ix2 to its left in ScanIx2
  134. for (int alpha = 0; alpha < BaseScanIx2[exclevel].size(); ++alpha)
  135. if (BaseScanIx2[exclevel][alpha] > ScanIx2[exclevel][excindex - 1]
  136. && BaseScanIx2[exclevel][alpha] < ScanIx2[exclevel][excindex]) {
  137. return(true);
  138. }
  139. }
  140. } // if (excfound)
  141. return(false);
  142. }
  143. // Specialization for Lieb-Liniger:
  144. bool Expect_ph_Recombination_iK_Down (string ScanIx2_label, const LiebLin_Bethe_State& OriginState)
  145. {
  146. Vect<Vect<int> > OriginIx2here(1);
  147. OriginIx2here[0] = OriginState.Ix2;
  148. Vect<Vect<int> > BaseScanIx2here(1);
  149. BaseScanIx2here[0] = OriginState.Ix2;
  150. return(Expect_ph_Recombination_iK_Down (ScanIx2_label, OriginIx2here, BaseScanIx2here));
  151. }
  152. // Specialization for Heis
  153. bool Expect_ph_Recombination_iK_Down (string ScanIx2_label, const Heis_Bethe_State& OriginState)
  154. {
  155. return(Expect_ph_Recombination_iK_Down (ScanIx2_label, OriginState.Ix2, OriginState.Ix2));
  156. }
  157. template<class Tstate>
  158. Scan_Info General_Scan (char whichDSF, int iKmin, int iKmax, int iKmod, DP kBT,
  159. Tstate& AveragingState, Tstate& SeedScanState, string defaultScanStatename,
  160. int Max_Secs, DP target_sumrule, bool refine,
  161. int paralevel, Vect<int> rank, Vect<int> nr_processors)
  162. {
  163. // Performs the scan over excited states, writing data to file.
  164. // AveragingState is the state on which the correlations are calculated.
  165. // SeedScanState is the originator of all scan states.
  166. // This distinction is kept to allow for quenches and finite temperatures.
  167. // This function is also called by the parallel implementation of ABACUS.
  168. // In this case, file names carry a rank and nr_processors suffix.
  169. // In fact, the parallelization can be done in incremental levels.
  170. // If paralevel == 0, the run is serial.
  171. // If paralevel == n, the run is parallelized in a tree with n levels of branching.
  172. // A paralevel == 1 branching's files have a suffix of the form "_3_8", meaning that this
  173. // is the rank 3 out of 8 processors.
  174. // A paralevel == 2 branching's files have a suffix of the form "_3_8_2_8", meaning that this
  175. // is the rank 2 out of 8 subscan of the _3_8 scan.
  176. bool in_parallel = (paralevel > 0);
  177. if (in_parallel && (rank.size() != paralevel || nr_processors.size() != paralevel)) {
  178. cout << "paralevel = " << paralevel << "\trank.size() = " << rank.size()
  179. << "\tnr_processors.size() = " << nr_processors.size() << endl;
  180. cout << "rank = " << rank << endl;
  181. cout << "nr_processors = " << nr_processors << endl;
  182. ABACUSerror("Inconsistent paralevel, rank or nr_processors in General_Scan.");
  183. }
  184. if (in_parallel && !refine) ABACUSerror("Must refine when using parallel ABACUS");
  185. // expected cost on data_value of adding a particle-hole excitation.
  186. DP ph_cost = Particle_Hole_Excitation_Cost (whichDSF, AveragingState);
  187. int Max_Secs_used = int(0.9 * Max_Secs); // we don't start any new ithread loop beyond this point
  188. int Max_Secs_alert = int(0.95 * Max_Secs); // we break any ongoing ithread loop beyond this point
  189. /* TO_STR
  190. stringstream filenameprefix;
  191. Data_File_Name (filenameprefix, whichDSF, iKmin, iKmax, kBT,
  192. AveragingState, SeedScanState, defaultScanStatename);
  193. if (in_parallel)
  194. for (int r = 0; r < paralevel; ++r)
  195. filenameprefix << "_" << rank[r] << "_" << nr_processors[r];
  196. string prefix = filenameprefix.str();
  197. */
  198. string prefix = Data_Filename(whichDSF, iKmin, iKmax, kBT,
  199. AveragingState, SeedScanState, defaultScanStatename);
  200. if (in_parallel)
  201. for (int r = 0; r < paralevel; ++r)
  202. prefix += "_" + to_string(rank[r]) + "_" + to_string(nr_processors[r]);
  203. /* TO_STR
  204. stringstream filenameprefix_prevparalevel;
  205. // without the rank and nr_processors of the highest paralevel
  206. Data_File_Name (filenameprefix_prevparalevel, whichDSF, iKmin, iKmax, kBT,
  207. AveragingState, SeedScanState, defaultScanStatename);
  208. if (in_parallel) for (int r = 0; r < paralevel - 1; ++r)
  209. filenameprefix << "_" << rank[r] << "_" << nr_processors[r];
  210. string prefix_prevparalevel = filenameprefix_prevparalevel.str();
  211. */
  212. // without the rank and nr_processors of the highest paralevel
  213. string prefix_prevparalevel = Data_Filename(whichDSF, iKmin, iKmax, kBT,
  214. AveragingState, SeedScanState, defaultScanStatename);
  215. if (in_parallel)
  216. for (int r = 0; r < paralevel - 1; ++r)
  217. prefix_prevparalevel += "_" + to_string(rank[r]) + "_" + to_string(nr_processors[r]);
  218. /* TO_STR
  219. stringstream RAW_stringstream; string RAW_string;
  220. stringstream INADM_stringstream; string INADM_string;
  221. stringstream CONV0_stringstream; string CONV0_string;
  222. stringstream STAT_stringstream; string STAT_string;
  223. stringstream LOG_stringstream; string LOG_string;
  224. stringstream THR_stringstream; string THR_string;
  225. stringstream THRDIR_stringstream; string THRDIR_string;
  226. stringstream SRC_stringstream; string SRC_string;
  227. stringstream SUM_stringstream; string SUM_string;
  228. RAW_stringstream << prefix << ".raw";
  229. INADM_stringstream << prefix << ".inadm";
  230. CONV0_stringstream << prefix << ".conv0";
  231. STAT_stringstream << prefix << ".stat";
  232. LOG_stringstream << prefix << ".log";
  233. THR_stringstream << prefix << ".thr";
  234. THRDIR_stringstream << prefix << "_thrdir";
  235. SRC_stringstream << prefix << ".src";
  236. SUM_stringstream << prefix << ".sum";
  237. RAW_string = RAW_stringstream.str(); const char* RAW_Cstr = RAW_string.c_str();
  238. INADM_string = INADM_stringstream.str(); const char* INADM_Cstr = INADM_string.c_str();
  239. CONV0_string = CONV0_stringstream.str(); const char* CONV0_Cstr = CONV0_string.c_str();
  240. STAT_string = STAT_stringstream.str(); const char* STAT_Cstr = STAT_string.c_str();
  241. LOG_string = LOG_stringstream.str(); const char* LOG_Cstr = LOG_string.c_str();
  242. THR_string = THR_stringstream.str(); const char* THR_Cstr = THR_string.c_str();
  243. SRC_string = SRC_stringstream.str(); const char* SRC_Cstr = SRC_string.c_str();
  244. SUM_string = SUM_stringstream.str(); const char* SUM_Cstr = SUM_string.c_str();
  245. THRDIR_string = THRDIR_stringstream.str();
  246. */
  247. string RAW_str = prefix + ".raw";
  248. string INADM_str = prefix + ".inadm";
  249. string CONV0_str = prefix + ".conv0";
  250. string STAT_str = prefix + ".stat";
  251. string LOG_str = prefix + ".log";
  252. string THR_str = prefix + ".thr";
  253. string THRDIR_str = prefix + "_thrdir";
  254. string SRC_str = prefix + ".src";
  255. string SUM_str = prefix + ".sum";
  256. fstream RAW_outfile;
  257. if (!refine || in_parallel) RAW_outfile.open(RAW_str, fstream::out | fstream::trunc);
  258. else RAW_outfile.open(RAW_str, fstream::out | fstream::app);
  259. if (RAW_outfile.fail()) {
  260. cout << RAW_str << endl;
  261. ABACUSerror("Could not open RAW_outfile... ");
  262. }
  263. RAW_outfile.precision(16);
  264. fstream INADM_outfile;
  265. if (!refine || in_parallel) INADM_outfile.open(INADM_str, fstream::out | fstream::trunc);
  266. else INADM_outfile.open(INADM_str, fstream::out | fstream::app);
  267. if (INADM_outfile.fail()) ABACUSerror("Could not open INADM_outfile... ");
  268. INADM_outfile.precision(16);
  269. fstream CONV0_outfile;
  270. if (!refine || in_parallel) CONV0_outfile.open(CONV0_str, fstream::out | fstream::trunc);
  271. else CONV0_outfile.open(CONV0_str, fstream::out | fstream::app);
  272. if (CONV0_outfile.fail()) ABACUSerror("Could not open CONV0_outfile... ");
  273. CONV0_outfile.precision(16);
  274. fstream STAT_outfile;
  275. if (!refine || in_parallel) STAT_outfile.open(STAT_str, fstream::out | fstream::trunc);
  276. else STAT_outfile.open(STAT_str, fstream::out | fstream::app);
  277. if (STAT_outfile.fail()) ABACUSerror("Could not open STAT_outfile... ");
  278. STAT_outfile.precision(8);
  279. ofstream LOG_outfile;
  280. if (!in_parallel) {
  281. if (!refine) LOG_outfile.open(LOG_str, fstream::out | fstream::trunc);
  282. else LOG_outfile.open(LOG_str, fstream::out | fstream::app);
  283. if (LOG_outfile.fail()) ABACUSerror("Could not open LOG_outfile... ");
  284. LOG_outfile.precision(16);
  285. }
  286. else { // in_parallel
  287. LOG_outfile.open(LOG_str, fstream::out | fstream::trunc);
  288. if (LOG_outfile.fail()) ABACUSerror("Could not open LOG_outfile... ");
  289. LOG_outfile.precision(16);
  290. }
  291. Scan_Info scan_info;
  292. if (!refine) mkdir(THRDIR_str.c_str(), S_IRWXU | S_IRWXG | S_IRWXO);
  293. Scan_Thread_Data paused_thread_data (THRDIR_str, refine);
  294. if (refine) {
  295. paused_thread_data.Load();
  296. if (!in_parallel) scan_info.Load(SRC_str);
  297. }
  298. Scan_Info scan_info_before = scan_info; // for LOG file
  299. Scan_Info scan_info_before_descent;
  300. Scan_Info scan_info_obtained_in_descent;
  301. Scan_State_List<Tstate> ScanStateList (whichDSF, SeedScanState);
  302. ScanStateList.Populate_List(whichDSF, SeedScanState);
  303. if (refine && !in_parallel) ScanStateList.Load_Info (SUM_str);
  304. else if (in_parallel && rank.sum() == 0) {}; // do nothing, keep info in the higher .sum file!
  305. DP Chem_Pot = Chemical_Potential (AveragingState);
  306. DP sumrule_factor = Sumrule_Factor (whichDSF, AveragingState, Chem_Pot, iKmin, iKmax);
  307. // Now go for it !
  308. bool at_least_one_new_flag_raised = false;
  309. int Ndata_previous_cycle = 0;
  310. int ninadm = 0; // nr of inadm states for which we save info in .inadm file. Save first 1000.
  311. int nconv0 = 0; // nr of unconv states for which we save info in .conv0 file. Save first 1000.
  312. double start_time_omp = omp_get_wtime();
  313. double current_time_omp = omp_get_wtime();
  314. #pragma omp parallel
  315. do {
  316. int omp_thread_nr = omp_get_thread_num();
  317. if ((paused_thread_data.lowest_il_with_nthreads_neq_0 == paused_thread_data.nlists - 1)
  318. && omp_thread_nr > 0) {
  319. double start_time_wait = omp_get_wtime();
  320. double stop_time_wait;
  321. do {
  322. for (int i = 0; i < 100000; ++i) { }
  323. stop_time_wait = omp_get_wtime();
  324. } while (stop_time_wait - start_time_wait < 5.0);
  325. }
  326. double start_time_cycle_omp = omp_get_wtime();
  327. at_least_one_new_flag_raised = false;
  328. #pragma omp master
  329. {
  330. double start_time_flags = omp_get_wtime();
  331. // First flag the new base/type 's that we need to include:
  332. ScanStateList.Raise_Scanning_Flags
  333. (exp(-paused_thread_data.logscale * paused_thread_data.lowest_il_with_nthreads_neq_0));
  334. // Get these base/type started:
  335. for (int i = 0; i < ScanStateList.ndef; ++i) {
  336. if (ScanStateList.flag_for_scan[i] && ScanStateList.info[i].Ndata == 0
  337. && !ScanStateList.scan_attempted[i]) {
  338. Scan_Info scan_info_flags;
  339. at_least_one_new_flag_raised = true;
  340. ScanStateList.scan_attempted[i] = true;
  341. Tstate ScanState;
  342. ScanState = ScanStateList.State[i];
  343. DP data_value = -1.0;
  344. bool admissible = ScanState.Check_Admissibility(whichDSF);
  345. if (admissible) {
  346. ScanState.Compute_All(true);
  347. if (ScanState.conv) {
  348. // Put momentum in fundamental window, if possible:
  349. int iKexc = ScanState.iK - AveragingState.iK;
  350. while (iKexc > iKmax && iKexc - iKmod >= iKmin) iKexc -= iKmod;
  351. while (iKexc < iKmin && iKexc + iKmod <= iKmax) iKexc += iKmod;
  352. stringstream rawfile_entry;
  353. data_value = Compute_Matrix_Element_Contrib (whichDSF, iKmin, iKmax, ScanState, AveragingState, Chem_Pot, rawfile_entry);
  354. {
  355. #pragma omp critical
  356. RAW_outfile << rawfile_entry.str();
  357. }
  358. {
  359. #pragma omp critical
  360. if (iKexc >= iKmin && iKexc <= iKmax) {
  361. scan_info_flags.Ndata++;
  362. scan_info_flags.Ndata_conv++;
  363. scan_info_flags.sumrule_obtained += data_value*sumrule_factor;
  364. }
  365. }
  366. // If we force descent: modify data_value by hand so that descent is forced on next scanning pass
  367. for (int itype = 0; itype < 15; ++itype) {
  368. DP data_value_used = 0.1* exp(-paused_thread_data.logscale * ABACUS::min(0, paused_thread_data.lowest_il_with_nthreads_neq_0));
  369. if (Force_Descent(whichDSF, ScanState, AveragingState, itype, iKmod, Chem_Pot))
  370. data_value = data_value_used;
  371. }
  372. Vect<bool> allowed(false, 15);
  373. if (whichDSF == 'B') { // symmetric state scanning
  374. allowed[9] = true; allowed[10] = true; allowed[11] = true;
  375. allowed[12] = true; allowed[13] = true; allowed[14] = true;
  376. }
  377. else {
  378. allowed[0] = (iKexc >= iKmin && iKexc <= iKmax);
  379. allowed[1] = allowed[0]; allowed[2] = allowed[0];
  380. allowed[3] = allowed[0]; allowed[4] = allowed[0];
  381. allowed[5] = allowed[0]; allowed[6] = allowed[0];
  382. allowed[7] = allowed[0]; allowed[8] = allowed[0];
  383. allowed[9] = (iKexc > iKmin);
  384. allowed[10] = allowed[9]; allowed[11] = allowed[9];
  385. allowed[12] = (iKexc < iKmax);
  386. allowed[13] = allowed[12]; allowed[14] = allowed[12];
  387. }
  388. for (int type_required_here = 0; type_required_here < 15; ++type_required_here) {
  389. if (!allowed[type_required_here]) continue;
  390. // All cases here are such that the ScanState hasn't been descended yet,
  391. // so we simply use data_value as expected data value:
  392. {
  393. #pragma omp critical
  394. paused_thread_data.Include_Thread (abs(data_value), ScanState.label, type_required_here);
  395. }
  396. }
  397. } // if (ScanState.conv)
  398. else {
  399. if (nconv0++ < 1000)
  400. CONV0_outfile << setw(25) << ScanState.label << setw(25) << ScanState.diffsq
  401. << setw(5) << ScanState.Check_Rapidities()
  402. << setw(25) << ScanState.String_delta() << endl;
  403. scan_info_flags.Ndata++;
  404. scan_info_flags.Ndata_conv0++;
  405. }
  406. } // if admissible
  407. else { // if inadmissible, modify data_value by hand so that descent is forced on next scanning pass
  408. if (ninadm++ < 10000000) INADM_outfile << ScanState.label << endl;
  409. scan_info_flags.Ndata++;
  410. scan_info_flags.Ninadm++;
  411. // Put momentum in fundamental window, if possible:
  412. int iKexc = ScanState.iK - AveragingState.iK;
  413. while (iKexc > iKmax && iKexc - iKmod >= iKmin) iKexc -= iKmod;
  414. while (iKexc < iKmin && iKexc + iKmod <= iKmax) iKexc += iKmod;
  415. DP data_value = 1.0e-32;
  416. for (int itype = 0; itype < 15; ++itype)
  417. if (Force_Descent(whichDSF, ScanState, AveragingState, itype, iKmod, Chem_Pot))
  418. data_value = 0.1* exp(-paused_thread_data.logscale * paused_thread_data.lowest_il_with_nthreads_neq_0);
  419. Vect<bool> allowed(false, 15);
  420. if (whichDSF == 'B') {
  421. // We scan over symmetric states. Only types 14 down to 9 are allowed.
  422. allowed[9] = true; allowed[10] = true; allowed[11] = true;
  423. allowed[12] = true; allowed[13] = true; allowed[14] = true;
  424. }
  425. else {
  426. allowed[0] = (iKexc >= iKmin && iKexc <= iKmax);
  427. allowed[1] = allowed[0]; allowed[2] = allowed[0];
  428. allowed[3] = allowed[0]; allowed[4] = allowed[0];
  429. allowed[5] = allowed[0]; allowed[6] = allowed[0];
  430. allowed[7] = allowed[0]; allowed[8] = allowed[0];
  431. allowed[9] = (iKexc > iKmin);
  432. allowed[10] = allowed[9]; allowed[11] = allowed[9];
  433. allowed[12] = (iKexc < iKmax);
  434. allowed[13] = allowed[12]; allowed[14] = allowed[12];
  435. }
  436. for (int type_required_here = 0; type_required_here < 15; ++type_required_here) {
  437. if (!allowed[type_required_here]) continue;
  438. {
  439. #pragma omp critical
  440. paused_thread_data.Include_Thread (abs(data_value), ScanState.label, type_required_here);
  441. }
  442. }
  443. } // inadmissible
  444. scan_info_flags.TT += omp_get_wtime() - start_time_flags;
  445. // Put this info into the appropriate ScanStateList.info
  446. {
  447. #pragma omp critical
  448. ScanStateList.Include_Info(scan_info_flags, ScanStateList.base_label[i]);
  449. scan_info += scan_info_flags;
  450. }
  451. } // if flag_for_scan
  452. } // for i
  453. } // #pragma omp master
  454. // Now we deal with the previously existing paused threads:
  455. Vect<Scan_Thread> threads_to_do;
  456. int il_to_do = paused_thread_data.lowest_il_with_nthreads_neq_0; // for resaving threads in case we're out of time
  457. DP current_threshold = exp(-paused_thread_data.logscale * il_to_do);
  458. {
  459. #pragma omp critical
  460. threads_to_do = paused_thread_data.Extract_Next_Scan_Threads();
  461. }
  462. int ithread;
  463. {
  464. for (ithread = 0; ithread < threads_to_do.size(); ++ithread) {
  465. Scan_Info scan_info_this_ithread;
  466. double start_time_this_ithread = omp_get_wtime();
  467. // If we don't have time anymore, resave the threads instead of computing them:
  468. if (start_time_this_ithread - start_time_omp > Max_Secs_alert) {
  469. for (int ith = ithread; ith < threads_to_do.size(); ++ith) {
  470. #pragma omp critical
  471. paused_thread_data.Include_Thread (il_to_do, threads_to_do[ith].label, threads_to_do[ith].type);
  472. }
  473. break; // jump out of ithread loop
  474. }
  475. Tstate ScanState;
  476. {
  477. #pragma omp critical
  478. ScanState = ScanStateList.Return_State(Extract_Base_Label(threads_to_do[ithread].label));
  479. }
  480. Tstate BaseScanState; BaseScanState = ScanState;
  481. ScanState.Set_to_Label(threads_to_do[ithread].label, BaseScanState.Ix2);
  482. Tstate ScanStateBeingDescended = ScanState;
  483. // STARTING Descend_and_Compute block:
  484. int type_required = threads_to_do[ithread].type;
  485. ScanState.Compute_Momentum();
  486. Vect<string> desc_label;
  487. bool disperse_only_current_exc_up = false;
  488. if (type_required == 14 || type_required == 8 || type_required == 7 || type_required == 6)
  489. disperse_only_current_exc_up = true;
  490. bool preserve_nexc_up = false;
  491. if (type_required == 13 || type_required == 5 || type_required == 4 || type_required == 3)
  492. preserve_nexc_up = true;
  493. bool disperse_only_current_exc_down = false;
  494. if (type_required == 11 || type_required == 8 || type_required == 5 || type_required == 2)
  495. disperse_only_current_exc_down = true;
  496. bool preserve_nexc_down = false;
  497. if (type_required == 10 || type_required == 7 || type_required == 4 || type_required == 1)
  498. preserve_nexc_down = true;
  499. if (whichDSF == 'B') { // symmetric state scanning
  500. if (type_required >= 9 && type_required <= 11)
  501. desc_label = Descendent_States_with_iK_Stepped_Down_rightIx2only
  502. (ScanState.label, BaseScanState, disperse_only_current_exc_down, preserve_nexc_down);
  503. else if (type_required >= 12 && type_required <= 14)
  504. desc_label = Descendent_States_with_iK_Stepped_Up_rightIx2only
  505. (ScanState.label, BaseScanState, disperse_only_current_exc_up, preserve_nexc_up);
  506. }
  507. else {
  508. if (type_required >= 0 && type_required <= 8) {
  509. desc_label = Descendent_States_with_iK_Preserved
  510. (ScanState.label, BaseScanState, disperse_only_current_exc_up, preserve_nexc_up,
  511. disperse_only_current_exc_down, preserve_nexc_down);
  512. }
  513. else if (type_required >= 9 && type_required <= 11)
  514. desc_label = Descendent_States_with_iK_Stepped_Down
  515. (ScanState.label, BaseScanState, disperse_only_current_exc_down, preserve_nexc_down);
  516. else if (type_required >= 12 && type_required <= 14)
  517. desc_label = Descendent_States_with_iK_Stepped_Up
  518. (ScanState.label, BaseScanState, disperse_only_current_exc_up, preserve_nexc_up);
  519. }
  520. string label_here = ScanState.label;
  521. for (int idesc = 0; idesc < desc_label.size(); ++idesc) {
  522. ScanState.Set_to_Label (desc_label[idesc], BaseScanState.Ix2);
  523. bool admissible = ScanState.Check_Admissibility(whichDSF);
  524. DP data_value = 0.0;
  525. ScanState.conv = false;
  526. ScanState.Compute_Momentum(); // since momentum is used as forced descent criterion
  527. if (admissible) {
  528. ScanState.Compute_All (idesc == 0);
  529. if (ScanState.conv) {
  530. // Put momentum in fundamental window, if possible:
  531. int iKexc = ScanState.iK - AveragingState.iK;
  532. while (iKexc > iKmax && iKexc - iKmod >= iKmin) iKexc -= iKmod;
  533. while (iKexc < iKmin && iKexc + iKmod <= iKmax) iKexc += iKmod;
  534. stringstream rawfile_entry;
  535. data_value = Compute_Matrix_Element_Contrib (whichDSF, iKmin, iKmax, ScanState, AveragingState,
  536. Chem_Pot, rawfile_entry);
  537. {
  538. #pragma omp critical
  539. RAW_outfile << rawfile_entry.str();
  540. if (iKexc >= iKmin && iKexc <= iKmax) {
  541. scan_info_this_ithread.Ndata++;
  542. scan_info_this_ithread.Ndata_conv++;
  543. scan_info_this_ithread.sumrule_obtained += data_value*sumrule_factor;
  544. }
  545. }
  546. // Uncomment line below if .stat file is desired:
  547. // STAT_outfile << setw(20) << label_here << "\t" << setw(5) << type_required
  548. // << "\t" << setw(16) << std::scientific
  549. // << exp(-paused_thread_data.logscale * il_to_do)
  550. // << "\t" << setw(20) << ScanState.label << "\t" << setw(16) << data_value
  551. // << "\t" << setw(16) << std::fixed << setprecision(8)
  552. // << data_value/exp(-paused_thread_data.logscale * il_to_do) << endl;
  553. // Uncomment below if alerts for unexpectedly high data_value (as compared to threshold) are desired
  554. // if (fabs(data_value) > 10.0* current_threshold) {
  555. // cout << "\nAlert: data_value > 10* threshold, " << data_value << "\t" << current_threshold << endl;
  556. // cout << " for state " << ScanState.label << " descendent of type " << type_required
  557. // << " of state " << ScanStateBeingDescended.label << endl;
  558. // cout << AveragingState.Ix2 << endl;
  559. // cout << ScanStateBeingDescended.Ix2 << endl;
  560. // cout << ScanState.Ix2 << endl;
  561. // }
  562. } // if (ScanState.conv)
  563. else {
  564. if (nconv0++ < 1000)
  565. CONV0_outfile << setw(25) << ScanState.label << setw(25)
  566. << ScanState.diffsq << setw(5) << ScanState.Check_Rapidities()
  567. << setw(25) << ScanState.String_delta() << endl;
  568. scan_info_this_ithread.Ndata++;
  569. scan_info_this_ithread.Ndata_conv0++;
  570. }
  571. } // if (admissible)
  572. else {
  573. if (ninadm++ < 1000000) INADM_outfile << ScanState.label << endl;
  574. scan_info_this_ithread.Ndata++;
  575. scan_info_this_ithread.Ninadm++;
  576. }
  577. Tstate state_to_descend; state_to_descend = ScanState; // for checking
  578. ScanState.Compute_Momentum();
  579. // Put momentum in fundamental window, if possible:
  580. int iKexc = ScanState.iK - AveragingState.iK;
  581. while (iKexc > iKmax && iKexc - iKmod >= iKmin) iKexc -= iKmod;
  582. while (iKexc < iKmin && iKexc + iKmod <= iKmax) iKexc += iKmod;
  583. // Momentum-preserving are only descended to momentum-preserving.
  584. // Momentum-increasing are only descended to momentum-preserving and momentum-increasing.
  585. // Momentum-decreasing are only descended to momentum-preserving and momentum-decreasing.
  586. Vect<bool> allowed(false, 15);
  587. if (whichDSF == 'B') {
  588. // We scan over symmetric states. Only types 14 down to 9 are allowed.
  589. if (type_required >= 9 && type_required <= 11) { // iK stepped down on rightIx2; step further up or down
  590. allowed[9] = true; allowed[10] = true; allowed[11] = true;
  591. allowed[12] = true; allowed[13] = true; allowed[14] = true;
  592. }
  593. else if (type_required >= 12 && type_required <= 14) { // iK stepped up on rightIx2; only step further up
  594. allowed[12] = true; allowed[13] = true; allowed[14] = true;
  595. }
  596. }
  597. else {
  598. if (type_required >= 0 && type_required <= 8) { // momentum-preserving
  599. allowed[0] = (iKexc >= iKmin && iKexc <= iKmax);
  600. allowed[9] = false;
  601. allowed[12] = false;
  602. }
  603. if (type_required >= 9 && type_required <= 11) { // momentum-decreasing
  604. allowed[0] = (iKexc >= iKmin && iKexc <= iKmax);
  605. allowed[9] = (iKexc > iKmin);
  606. allowed[12] = false;
  607. }
  608. if (type_required >= 12 && type_required <= 14) { // momentum-increasing
  609. allowed[0] = (iKexc >= iKmin && iKexc <= iKmax);
  610. allowed[9] = false;
  611. allowed[12] = (iKexc < iKmax);
  612. }
  613. // The others are just copies of the ones above:
  614. allowed[1] = allowed[0]; allowed[2] = allowed[0]; allowed[3] = allowed[0]; allowed[4] = allowed[0]; allowed[5] = allowed[0]; allowed[6] = allowed[0]; allowed[7] = allowed[0]; allowed[8] = allowed[0];
  615. allowed[10] = allowed[9]; allowed[11] = allowed[9];
  616. allowed[13] = allowed[12]; allowed[14] = allowed[12];
  617. }
  618. for (int type_required_here = 0; type_required_here < 15; ++type_required_here) {
  619. if (!allowed[type_required_here]) continue;
  620. // Reset ScanState to what it was, if change on first pass
  621. if (type_required_here > 0) ScanState = state_to_descend;
  622. // We determine if we carry on scanning based on the data_value obtained, or forcing conditions:
  623. DP expected_abs_data_value = abs(data_value);
  624. //++G_7 logic
  625. if ((type_required_here == 14 || type_required_here == 8
  626. || type_required_here == 7 || type_required_here == 6)
  627. && Expect_ph_Recombination_iK_Up (ScanState.label, BaseScanState))
  628. expected_abs_data_value /= ph_cost;
  629. if (type_required_here == 12 || type_required_here == 2
  630. || type_required_here == 1 || type_required_here == 0)
  631. expected_abs_data_value *= ph_cost;
  632. if ((type_required_here == 11 || type_required_here == 8
  633. || type_required_here == 5 || type_required_here == 2)
  634. && Expect_ph_Recombination_iK_Down (ScanState.label, BaseScanState))
  635. expected_abs_data_value /= ph_cost;
  636. if (type_required_here == 9 || type_required_here == 6
  637. || type_required_here == 3 || type_required_here == 0)
  638. expected_abs_data_value *= ph_cost;
  639. {
  640. #pragma omp critical
  641. paused_thread_data.Include_Thread (expected_abs_data_value, ScanState.label, type_required_here);
  642. }
  643. } // for type_required_here
  644. } // for idesc
  645. // FINISHED Descend_and_Compute block
  646. scan_info_this_ithread.TT += omp_get_wtime() - start_time_this_ithread;
  647. #pragma omp critical
  648. {
  649. scan_info += scan_info_this_ithread;
  650. ScanStateList.Include_Info(scan_info_this_ithread, Extract_Base_Label(threads_to_do[ithread].label));
  651. }
  652. } // for ithread
  653. } // omp parallel region
  654. #pragma omp master
  655. {
  656. if (!in_parallel)
  657. LOG_outfile << "Master cycling. Ndata_conv " << scan_info.Ndata_conv
  658. << ". Threshold " << paused_thread_data.lowest_il_with_nthreads_neq_0 << " "
  659. << setw(9) << setprecision(3)
  660. << exp(-paused_thread_data.logscale * paused_thread_data.lowest_il_with_nthreads_neq_0)
  661. << ". " << setw(12) << scan_info.Ndata - Ndata_previous_cycle << " new data. Nr of threads: "
  662. << setw(14) << paused_thread_data.nthreads_total.sum()
  663. << ". Saturation: " << setprecision(12) << scan_info.sumrule_obtained << endl;
  664. Ndata_previous_cycle = scan_info.Ndata;
  665. }
  666. current_time_omp = omp_get_wtime();
  667. } while (current_time_omp - start_time_omp < Max_Secs_used
  668. && scan_info.sumrule_obtained < target_sumrule
  669. );
  670. // This closes the #pragram omp parallel block
  671. RAW_outfile.close();
  672. INADM_outfile.close();
  673. CONV0_outfile.close();
  674. STAT_outfile.close();
  675. scan_info.Save(SRC_str);
  676. Scan_Info scan_info_refine = scan_info;
  677. scan_info_refine -= scan_info_before;
  678. if (!in_parallel) {
  679. if (scan_info.sumrule_obtained >= target_sumrule)
  680. LOG_outfile << endl << "Achieved sumrule saturation of " << scan_info.sumrule_obtained
  681. << "\t(target was " << target_sumrule << ")." << endl << endl;
  682. if (!refine) {
  683. LOG_outfile << "Main run info: " << scan_info << endl;
  684. LOG_outfile << "Latest threshold level " << paused_thread_data.lowest_il_with_nthreads_neq_0
  685. << " " << std::scientific << setprecision(3)
  686. << exp(-paused_thread_data.logscale * paused_thread_data.lowest_il_with_nthreads_neq_0) << endl;
  687. }
  688. else if (refine) {
  689. LOG_outfile << "Refining info: " << scan_info_refine << endl;
  690. LOG_outfile << "Latest threshold level " << paused_thread_data.lowest_il_with_nthreads_neq_0
  691. << " " << std::scientific << setprecision(3)
  692. << exp(-paused_thread_data.logscale * paused_thread_data.lowest_il_with_nthreads_neq_0) << endl;
  693. LOG_outfile << "Resulting info: " << scan_info << endl;
  694. }
  695. time_t current_time = time(nullptr);
  696. char timestr[100];
  697. strftime(timestr, sizeof(timestr), "%Y-%m-%d %H:%M:%S", gmtime(&current_time));
  698. LOG_outfile << "Run completion timestamp: " << timestr << " UTC" << endl;
  699. LOG_outfile << "ABACUS version " << ABACUS_VERSION << ", copyright J.-S. Caux." << endl << endl;
  700. LOG_outfile.close();
  701. }
  702. else { // in_parallel
  703. LOG_outfile << "rank " << rank << " out of " << nr_processors << " processors: "
  704. << "run info: " << scan_info << endl << "Latest threshold = "
  705. << exp(-paused_thread_data.logscale * paused_thread_data.lowest_il_with_nthreads_neq_0) << endl;
  706. }
  707. paused_thread_data.Save();
  708. ScanStateList.Order_in_SRC ();
  709. ScanStateList.Save_Info (SUM_str);
  710. // Evaluate f-sumrule:
  711. if (!in_parallel ) if (whichDSF != 'q')
  712. Evaluate_F_Sumrule (prefix_prevparalevel, whichDSF, AveragingState, Chem_Pot, iKmin, iKmax);
  713. return(scan_info);
  714. }
  715. //******************************************************
  716. // Functions to initiate scans:
  717. // General version for equilibrium correlators at generic (possibly finite) temperature:
  718. Scan_Info Scan_LiebLin (char whichDSF, DP c_int, DP L, int N, int iKmin, int iKmax, DP kBT,
  719. int Max_Secs, DP target_sumrule, bool refine,
  720. int paralevel, Vect<int> rank, Vect<int> nr_processors)
  721. {
  722. // This function scans the Hilbert space of the LiebLin gas,
  723. // for the function identified by whichDSF.
  724. // whichDSF == 'Z': canonical partition function
  725. // whichDSF == 'd': density-density correlation function
  726. // whichDSF == 'g': Green's function < \Psi \Psi^{\dagger}>
  727. // whichDSF == 'o': one-body function < \Psi^{\dagger} \Psi >
  728. // Delta is the number of sites involved in the smoothing of the entropy
  729. //int Delta = int(sqrt(N))/2;//6;//N/20;
  730. //DP epsilon = log(L)/L; // using Gaussian for density in entropy.
  731. //DP epsilon = 1.0/L; // using Lorentzian for density in entropy.
  732. // Construct the finite-size saddle-point state:
  733. // if we refine, read the quantum numbers of the saddle point state (and seed sps) from the sps file:
  734. /* TO_STR
  735. stringstream SPS_stringstream; string SPS_string;
  736. Data_File_Name (SPS_stringstream, whichDSF, c_int, L, N, iKmin, iKmax, kBT, 0.0, "");
  737. SPS_stringstream << ".sps";
  738. SPS_string = SPS_stringstream.str(); const char* SPS_Cstr = SPS_string.c_str();
  739. */
  740. string SPS_str = Data_Filename (whichDSF, c_int, L, N, iKmin, iKmax, kBT, 0.0, "") + ".sps";
  741. fstream spsfile;
  742. if (refine) spsfile.open(SPS_str, fstream::in);
  743. else spsfile.open(SPS_str, fstream::out | fstream::trunc);
  744. if (spsfile.fail()) {
  745. cout << SPS_str << endl; ABACUSerror("Could not open spsfile.");
  746. }
  747. LiebLin_Bethe_State spstate;
  748. if (!refine) { // obtain the sps from discretized TBA
  749. //spstate = Canonical_Saddle_Point_State (c_int, L, N, whichDSF == 'Z' ? 0.0 : kBT);
  750. spstate = Canonical_Saddle_Point_State (c_int, L, N, kBT);
  751. }
  752. else { // read it from the sps file
  753. // Check that the sps has the right number of Ix2:
  754. int Nspsread;
  755. spsfile >> Nspsread;
  756. if (Nspsread != N) {
  757. cout << Nspsread << "\t" << N << endl;
  758. ABACUSerror("Wrong number of Ix2 in saddle-point state.");
  759. }
  760. spstate = LiebLin_Bethe_State (c_int, L, N);
  761. for (int i = 0; i < N; ++i) spsfile >> spstate.Ix2[i];
  762. }
  763. spstate.Compute_All(true);
  764. int Nscan = N;
  765. if (whichDSF == 'o') Nscan = N - 1;
  766. if (whichDSF == 'g') Nscan = N + 1;
  767. // Now construct or read off the seed scan state:
  768. // TO MODIFY: this is not a good idea, since this might construct a state with many p-h w/r to the AveragingState.
  769. LiebLin_Bethe_State SeedScanState;
  770. if (whichDSF != 'o' && whichDSF != 'g') SeedScanState = spstate;
  771. else if (whichDSF == 'o' || whichDSF == 'g') {
  772. if (!refine) {
  773. if (whichDSF == 'o') SeedScanState = Remove_Particle_at_Center (spstate);
  774. else SeedScanState = Add_Particle_at_Center (spstate);
  775. }
  776. else { // read it from the sps file
  777. // Check that the sps has the right number of Ix2:
  778. int Nsspsread;
  779. spsfile >> Nsspsread;
  780. if (Nsspsread != Nscan) {
  781. cout << Nsspsread << "\t" << Nscan << endl;
  782. ABACUSerror("Wrong number of Ix2 in scan saddle-point state.");
  783. }
  784. SeedScanState = LiebLin_Bethe_State (c_int, L, Nscan);
  785. for (int i = 0; i < Nscan; ++i) spsfile >> SeedScanState.Ix2[i];
  786. }
  787. } // if one-body or Green's function
  788. SeedScanState.Compute_All(true);
  789. LiebLin_Bethe_State ScanState = SeedScanState;
  790. DP delta = sqrt(DP(N)) * (spstate.lambdaoc[N-1] - spstate.lambdaoc[0])/N;
  791. if (!refine) { // we write data to the sps file
  792. spsfile << N << endl;
  793. spsfile << spstate.Ix2 << endl;
  794. spsfile << Nscan << endl;
  795. spsfile << SeedScanState.Ix2 << endl;
  796. spsfile << endl << spstate << endl << endl;
  797. for (int i = 1; i < spstate.N - 2; ++i)
  798. spsfile << 0.5 * (spstate.lambdaoc[i] + spstate.lambdaoc[i+1])
  799. << "\t" << 1.0/spstate.L * (0.25/(spstate.lambdaoc[i] - spstate.lambdaoc[i-1])
  800. + 0.5/(spstate.lambdaoc[i+1] - spstate.lambdaoc[i])
  801. + 0.25/(spstate.lambdaoc[i+2] - spstate.lambdaoc[i+1]))
  802. << "\t" << rho_of_lambdaoc_1 (spstate, 0.5 * (spstate.lambdaoc[i] + spstate.lambdaoc[i+1]), delta)
  803. << "\t" << rho_of_lambdaoc_2 (spstate, 0.5 * (spstate.lambdaoc[i] + spstate.lambdaoc[i+1]), delta)
  804. << endl;
  805. }
  806. spsfile.close();
  807. // Perform the scan:
  808. return General_Scan (whichDSF, iKmin, iKmax, 100000000, kBT, spstate, SeedScanState, "",
  809. Max_Secs, target_sumrule, refine, paralevel, rank, nr_processors);
  810. }
  811. Scan_Info Scan_LiebLin (char whichDSF, DP c_int, DP L, int N, int iKmin, int iKmax, DP kBT,
  812. int Max_Secs, DP target_sumrule, bool refine)
  813. {
  814. int paralevel = 0;
  815. Vect<int> rank(0,1);
  816. Vect<int> nr_processors(0,1);
  817. return Scan_LiebLin (whichDSF, c_int, L, N, iKmin, iKmax, kBT, Max_Secs, target_sumrule,
  818. refine, paralevel, rank, nr_processors);
  819. }
  820. // Scanning on an excited state defined by a set of Ix2:
  821. Scan_Info Scan_LiebLin (char whichDSF, LiebLin_Bethe_State AveragingState, string defaultScanStatename,
  822. int iKmin, int iKmax, int Max_Secs, DP target_sumrule, bool refine,
  823. int paralevel, Vect<int> rank, Vect<int> nr_processors)
  824. {
  825. // This function is as Scan_LiebLin for generic T defined above, except that the
  826. // averaging is now done on a state defined by AveragingStateIx2
  827. // PRECONDITIONS:
  828. // - the Ix2 of AveragingState are properly set.
  829. DP c_int = AveragingState.c_int;
  830. DP L = AveragingState.L;
  831. int N = AveragingState.N;
  832. // The label of the Averaging State is by definition the `empty' label
  833. AveragingState.Set_Label_from_Ix2 (AveragingState.Ix2);
  834. AveragingState.Compute_All(true);
  835. int Nscan = N;
  836. if (whichDSF == 'o') Nscan = N - 1;
  837. if (whichDSF == 'g') Nscan = N + 1;
  838. LiebLin_Bethe_State SeedScanState (c_int, L, Nscan);
  839. if (whichDSF == 'd' || whichDSF == 'B') SeedScanState.Ix2 = AveragingState.Ix2;
  840. // If 'o', remove midmost and shift quantum numbers by half-integer towards removed one:
  841. if (whichDSF == 'o') {
  842. for (int i = 0; i < N-1; ++i)
  843. SeedScanState.Ix2[i] = AveragingState.Ix2[i + (i >= N/2)] + 1 - 2*(i >= N/2);
  844. }
  845. // If 'g', add a quantum number in middle (explicitly: to right of index N/2)
  846. // and shift quantum numbers by half-integer away from added one:
  847. if (whichDSF == 'g') {
  848. SeedScanState.Ix2[N/2] = AveragingState.Ix2[N/2] - 1;
  849. for (int i = 0; i < N+1; ++i)
  850. SeedScanState.Ix2[i + (i >= N/2)] = AveragingState.Ix2[i] - 1 + 2*(i >= N/2);
  851. }
  852. SeedScanState.Compute_All(true);
  853. SeedScanState.Set_Label_from_Ix2 (SeedScanState.Ix2);
  854. DP kBT = 0.0;
  855. // Perform the scan:
  856. return General_Scan (whichDSF, iKmin, iKmax, 100000000, kBT,
  857. AveragingState, SeedScanState, defaultScanStatename,
  858. Max_Secs, target_sumrule, refine, paralevel, rank, nr_processors);
  859. }
  860. // Simplified function call of the above:
  861. Scan_Info Scan_LiebLin (char whichDSF, LiebLin_Bethe_State AveragingState, string defaultScanStatename,
  862. int iKmin, int iKmax, int Max_Secs, DP target_sumrule, bool refine)
  863. {
  864. int paralevel = 0;
  865. Vect<int> rank(0,1);
  866. Vect<int> nr_processors(0,1);
  867. return Scan_LiebLin (whichDSF, AveragingState, defaultScanStatename, iKmin, iKmax, Max_Secs,
  868. target_sumrule, refine, paralevel, rank, nr_processors);
  869. }
  870. // Scanning on a previously-defined AveragingState
  871. Scan_Info Scan_Heis (char whichDSF, XXZ_Bethe_State& AveragingState, string defaultScanStatename,
  872. int iKmin, int iKmax,
  873. int Max_Secs, DP target_sumrule, bool refine,
  874. int paralevel, Vect<int> rank, Vect<int> nr_processors)
  875. {
  876. // General state scanning for Heisenberg chains
  877. // PRECONDITIONS:
  878. // - the Ix2 of AveragingState are properly set.
  879. // Prepare the AveragingState:
  880. AveragingState.Compute_All(true);
  881. XXZ_Bethe_State SeedScanState;
  882. if (whichDSF == 'Z' || whichDSF == 'z') SeedScanState = AveragingState;
  883. else if (whichDSF == 'm') SeedScanState = Remove_Particle_at_Center (AveragingState);
  884. else if (whichDSF == 'p') SeedScanState = Add_Particle_at_Center (AveragingState);
  885. else ABACUSerror("Unknown whichDSF in Scan_Heis.");
  886. // Now the scan itself
  887. General_Scan (whichDSF, iKmin, iKmax, AveragingState.chain.Nsites, 0.0, AveragingState, SeedScanState,
  888. defaultScanStatename, Max_Secs, target_sumrule, refine, paralevel, rank, nr_processors);
  889. }
  890. // Scanning on a previously-defined AveragingState
  891. Scan_Info Scan_Heis (char whichDSF, XXX_Bethe_State& AveragingState, string defaultScanStatename,
  892. int iKmin, int iKmax,
  893. int Max_Secs, DP target_sumrule, bool refine,
  894. int paralevel, Vect<int> rank, Vect<int> nr_processors)
  895. {
  896. // General state scanning for Heisenberg chains
  897. // PRECONDITIONS:
  898. // - the Ix2 of AveragingState are properly set.
  899. // Prepare the AveragingState:
  900. AveragingState.Compute_All(true);
  901. XXX_Bethe_State SeedScanState;
  902. if (whichDSF == 'Z' || whichDSF == 'z') SeedScanState = AveragingState;
  903. else if (whichDSF == 'm') SeedScanState = Remove_Particle_at_Center (AveragingState);
  904. else if (whichDSF == 'p') SeedScanState = Add_Particle_at_Center (AveragingState);
  905. else ABACUSerror("Unknown whichDSF in Scan_Heis.");
  906. // Now the scan itself
  907. return General_Scan (whichDSF, iKmin, iKmax, AveragingState.chain.Nsites, 0.0, AveragingState, SeedScanState,
  908. defaultScanStatename, Max_Secs, target_sumrule, refine, paralevel, rank, nr_processors);
  909. }
  910. // Scanning on a previously-defined AveragingState
  911. Scan_Info Scan_Heis (char whichDSF, XXZ_gpd_Bethe_State& AveragingState, string defaultScanStatename,
  912. int iKmin, int iKmax,
  913. int Max_Secs, DP target_sumrule, bool refine,
  914. int paralevel, Vect<int> rank, Vect<int> nr_processors)
  915. {
  916. // General state scanning for Heisenberg chains
  917. // PRECONDITIONS:
  918. // - the Ix2 of AveragingState are properly set.
  919. // Prepare the AveragingState:
  920. AveragingState.Compute_All(true);
  921. XXZ_gpd_Bethe_State SeedScanState;
  922. if (whichDSF == 'Z' || whichDSF == 'z') SeedScanState = AveragingState;
  923. else if (whichDSF == 'm') SeedScanState = Remove_Particle_at_Center (AveragingState);
  924. else if (whichDSF == 'p') SeedScanState = Add_Particle_at_Center (AveragingState);
  925. else ABACUSerror("Unknown whichDSF in Scan_Heis.");
  926. // Now the scan itself
  927. return General_Scan (whichDSF, iKmin, iKmax, AveragingState.chain.Nsites, 0.0, AveragingState, SeedScanState,
  928. defaultScanStatename, Max_Secs, target_sumrule, refine, paralevel, rank, nr_processors);
  929. }
  930. Scan_Info Scan_Heis (char whichDSF, DP Delta, int N, int M, int iKmin, int iKmax,
  931. int Max_Secs, DP target_sumrule, bool refine,
  932. int paralevel, Vect<int> rank, Vect<int> nr_processors)
  933. {
  934. // This function scans the Hilbert space of the Heisenberg spin-1/2 chain
  935. // for the function identified by whichDSF.
  936. // whichDSF == 'Z': canonical partition function
  937. // whichDSF == 'm': S^{-+}
  938. // whichDSF == 'z': S^{zz}
  939. // whichDSF == 'p': S^{+-}
  940. // whichDSF == 'a': < S^z_j S^z_{j+1} S^z_l S^z_{l+1} > for RIXS
  941. // whichDSF == 'b': < S^z_j S^-_{j+1} S^-_l S^z_{l+1} > + (m <-> z) for RIXS
  942. // whichDSF == 'c': < S^-_j S^-_{j+1} S^-_l S^-_{l+1} > for RIXS
  943. Heis_Chain BD1(1.0, Delta, 0.0, N);
  944. Vect_INT Nrapidities_groundstate(0, BD1.Nstrings);
  945. Nrapidities_groundstate[0] = M;
  946. Heis_Base baseconfig_groundstate(BD1, Nrapidities_groundstate);
  947. if ((Delta > 0.0) && (Delta < 1.0)) {
  948. XXZ_Bethe_State GroundState(BD1, baseconfig_groundstate);
  949. GroundState.Compute_All(true);
  950. // The ground state is now fully defined.
  951. XXZ_Bethe_State SeedScanState;
  952. if (whichDSF == 'Z' || whichDSF == 'z') SeedScanState = GroundState;
  953. else if (whichDSF == 'm') SeedScanState = XXZ_Bethe_State(GroundState.chain, M - 1);
  954. else if (whichDSF == 'p') SeedScanState = XXZ_Bethe_State(GroundState.chain, M + 1);
  955. else ABACUSerror("Unknown whichDSF in Scan_Heis.");
  956. // Now the scan itself
  957. General_Scan (whichDSF, iKmin, iKmax, N, 0.0, GroundState, SeedScanState, "",
  958. Max_Secs, target_sumrule, refine, paralevel, rank, nr_processors);
  959. }
  960. else if (Delta == 1.0) {
  961. XXX_Bethe_State GroundState(BD1, baseconfig_groundstate);
  962. GroundState.Compute_All(true);
  963. // The ground state is now fully defined.
  964. XXX_Bethe_State SeedScanState;
  965. if (whichDSF == 'Z' || whichDSF == 'z' || whichDSF == 'a' || whichDSF == 'q') SeedScanState = GroundState;
  966. else if (whichDSF == 'm') SeedScanState = XXX_Bethe_State(GroundState.chain, M - 1);
  967. else if (whichDSF == 'p') SeedScanState = XXX_Bethe_State(GroundState.chain, M + 1);
  968. else if (whichDSF == 'c') SeedScanState = XXX_Bethe_State(GroundState.chain, M - 2);
  969. else ABACUSerror("Unknown whichDSF in Scan_Heis.");
  970. // Now the scan itself
  971. General_Scan (whichDSF, iKmin, iKmax, N, 0.0, GroundState, SeedScanState, "",
  972. Max_Secs, target_sumrule, refine, paralevel, rank, nr_processors);
  973. }
  974. else if (Delta > 1.0) {
  975. XXZ_gpd_Bethe_State GroundState(BD1, baseconfig_groundstate);
  976. GroundState.Compute_All(true);
  977. // The ground state is now fully defined.
  978. XXZ_gpd_Bethe_State SeedScanState;
  979. if (whichDSF == 'Z' || whichDSF == 'z') SeedScanState = GroundState;
  980. else if (whichDSF == 'm') SeedScanState = XXZ_gpd_Bethe_State(GroundState.chain, M - 1);
  981. else if (whichDSF == 'p') SeedScanState = XXZ_gpd_Bethe_State(GroundState.chain, M + 1);
  982. else ABACUSerror("Unknown whichDSF in Scan_Heis.");
  983. // Now the scan itself
  984. return General_Scan (whichDSF, iKmin, iKmax, N, 0.0, GroundState, SeedScanState, "",
  985. Max_Secs, target_sumrule, refine, paralevel, rank, nr_processors);
  986. }
  987. else ABACUSerror("Delta out of range in Heis_Structure_Factor");
  988. return Scan_Info();
  989. }
  990. Scan_Info Scan_Heis (char whichDSF, DP Delta, int N, int M, int iKmin, int iKmax,
  991. int Max_Secs, DP target_sumrule, bool refine)
  992. {
  993. int paralevel = 0;
  994. Vect<int> rank(0,1);
  995. Vect<int> nr_processors(0,1);
  996. return Scan_Heis (whichDSF, Delta, N, M, iKmin, iKmax,
  997. Max_Secs, target_sumrule, refine, paralevel, rank, nr_processors);
  998. }
  999. } // namespace ABACUS