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 46KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209
  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. stringstream filenameprefix;
  190. Data_File_Name (filenameprefix, whichDSF, iKmin, iKmax, kBT,
  191. AveragingState, SeedScanState, defaultScanStatename);
  192. if (in_parallel)
  193. for (int r = 0; r < paralevel; ++r)
  194. filenameprefix << "_" << rank[r] << "_" << nr_processors[r];
  195. string prefix = filenameprefix.str();
  196. stringstream filenameprefix_prevparalevel;
  197. // without the rank and nr_processors of the highest paralevel
  198. Data_File_Name (filenameprefix_prevparalevel, whichDSF, iKmin, iKmax, kBT,
  199. AveragingState, SeedScanState, defaultScanStatename);
  200. if (in_parallel) for (int r = 0; r < paralevel - 1; ++r)
  201. filenameprefix << "_" << rank[r] << "_" << nr_processors[r];
  202. string prefix_prevparalevel = filenameprefix_prevparalevel.str();
  203. stringstream RAW_stringstream; string RAW_string;
  204. stringstream INADM_stringstream; string INADM_string;
  205. stringstream CONV0_stringstream; string CONV0_string;
  206. stringstream STAT_stringstream; string STAT_string;
  207. stringstream LOG_stringstream; string LOG_string;
  208. stringstream THR_stringstream; string THR_string;
  209. stringstream THRDIR_stringstream; string THRDIR_string;
  210. stringstream SRC_stringstream; string SRC_string;
  211. stringstream SUM_stringstream; string SUM_string;
  212. RAW_stringstream << prefix << ".raw";
  213. INADM_stringstream << prefix << ".inadm";
  214. CONV0_stringstream << prefix << ".conv0";
  215. STAT_stringstream << prefix << ".stat";
  216. LOG_stringstream << prefix << ".log";
  217. THR_stringstream << prefix << ".thr";
  218. THRDIR_stringstream << prefix << "_thrdir";
  219. SRC_stringstream << prefix << ".src";
  220. SUM_stringstream << prefix << ".sum";
  221. RAW_string = RAW_stringstream.str(); const char* RAW_Cstr = RAW_string.c_str();
  222. INADM_string = INADM_stringstream.str(); const char* INADM_Cstr = INADM_string.c_str();
  223. CONV0_string = CONV0_stringstream.str(); const char* CONV0_Cstr = CONV0_string.c_str();
  224. STAT_string = STAT_stringstream.str(); const char* STAT_Cstr = STAT_string.c_str();
  225. LOG_string = LOG_stringstream.str(); const char* LOG_Cstr = LOG_string.c_str();
  226. THR_string = THR_stringstream.str(); const char* THR_Cstr = THR_string.c_str();
  227. SRC_string = SRC_stringstream.str(); const char* SRC_Cstr = SRC_string.c_str();
  228. SUM_string = SUM_stringstream.str(); const char* SUM_Cstr = SUM_string.c_str();
  229. THRDIR_string = THRDIR_stringstream.str();
  230. fstream RAW_outfile;
  231. if (!refine || in_parallel) RAW_outfile.open(RAW_Cstr, fstream::out | fstream::trunc);
  232. else RAW_outfile.open(RAW_Cstr, fstream::out | fstream::app);
  233. if (RAW_outfile.fail()) {
  234. cout << RAW_Cstr << endl;
  235. ABACUSerror("Could not open RAW_outfile... ");
  236. }
  237. RAW_outfile.precision(16);
  238. fstream INADM_outfile;
  239. if (!refine || in_parallel) INADM_outfile.open(INADM_Cstr, fstream::out | fstream::trunc);
  240. else INADM_outfile.open(INADM_Cstr, fstream::out | fstream::app);
  241. if (INADM_outfile.fail()) ABACUSerror("Could not open INADM_outfile... ");
  242. INADM_outfile.precision(16);
  243. fstream CONV0_outfile;
  244. if (!refine || in_parallel) CONV0_outfile.open(CONV0_Cstr, fstream::out | fstream::trunc);
  245. else CONV0_outfile.open(CONV0_Cstr, fstream::out | fstream::app);
  246. if (CONV0_outfile.fail()) ABACUSerror("Could not open CONV0_outfile... ");
  247. CONV0_outfile.precision(16);
  248. fstream STAT_outfile;
  249. if (!refine || in_parallel) STAT_outfile.open(STAT_Cstr, fstream::out | fstream::trunc);
  250. else STAT_outfile.open(STAT_Cstr, fstream::out | fstream::app);
  251. if (STAT_outfile.fail()) ABACUSerror("Could not open STAT_outfile... ");
  252. STAT_outfile.precision(8);
  253. ofstream LOG_outfile;
  254. if (!in_parallel) {
  255. if (!refine) LOG_outfile.open(LOG_Cstr, fstream::out | fstream::trunc);
  256. else LOG_outfile.open(LOG_Cstr, fstream::out | fstream::app);
  257. if (LOG_outfile.fail()) ABACUSerror("Could not open LOG_outfile... ");
  258. LOG_outfile.precision(16);
  259. }
  260. else { // in_parallel
  261. LOG_outfile.open(LOG_Cstr, fstream::out | fstream::trunc);
  262. if (LOG_outfile.fail()) ABACUSerror("Could not open LOG_outfile... ");
  263. LOG_outfile.precision(16);
  264. }
  265. Scan_Info scan_info;
  266. if (!refine) mkdir(THRDIR_string.c_str(), S_IRWXU | S_IRWXG | S_IRWXO);
  267. Scan_Thread_Data paused_thread_data (THRDIR_string, refine);
  268. if (refine) {
  269. paused_thread_data.Load();
  270. if (!in_parallel) scan_info.Load(SRC_Cstr);
  271. }
  272. Scan_Info scan_info_before = scan_info; // for LOG file
  273. Scan_Info scan_info_before_descent;
  274. Scan_Info scan_info_obtained_in_descent;
  275. Scan_State_List<Tstate> ScanStateList (whichDSF, SeedScanState);
  276. ScanStateList.Populate_List(whichDSF, SeedScanState);
  277. if (refine && !in_parallel) ScanStateList.Load_Info (SUM_Cstr);
  278. else if (in_parallel && rank.sum() == 0) {}; // do nothing, keep info in the higher .sum file!
  279. DP Chem_Pot = Chemical_Potential (AveragingState);
  280. DP sumrule_factor = Sumrule_Factor (whichDSF, AveragingState, Chem_Pot, iKmin, iKmax);
  281. // Now go for it !
  282. bool at_least_one_new_flag_raised = false;
  283. int Ndata_previous_cycle = 0;
  284. int ninadm = 0; // nr of inadm states for which we save info in .inadm file. Save first 1000.
  285. int nconv0 = 0; // nr of unconv states for which we save info in .conv0 file. Save first 1000.
  286. double start_time_omp = omp_get_wtime();
  287. double current_time_omp = omp_get_wtime();
  288. #pragma omp parallel
  289. do {
  290. int omp_thread_nr = omp_get_thread_num();
  291. if ((paused_thread_data.lowest_il_with_nthreads_neq_0 == paused_thread_data.nlists - 1)
  292. && omp_thread_nr > 0) {
  293. double start_time_wait = omp_get_wtime();
  294. double stop_time_wait;
  295. do {
  296. for (int i = 0; i < 100000; ++i) { }
  297. stop_time_wait = omp_get_wtime();
  298. } while (stop_time_wait - start_time_wait < 5.0);
  299. }
  300. double start_time_cycle_omp = omp_get_wtime();
  301. at_least_one_new_flag_raised = false;
  302. #pragma omp master
  303. {
  304. double start_time_flags = omp_get_wtime();
  305. // First flag the new base/type 's that we need to include:
  306. ScanStateList.Raise_Scanning_Flags
  307. (exp(-paused_thread_data.logscale * paused_thread_data.lowest_il_with_nthreads_neq_0));
  308. // Get these base/type started:
  309. for (int i = 0; i < ScanStateList.ndef; ++i) {
  310. if (ScanStateList.flag_for_scan[i] && ScanStateList.info[i].Ndata == 0
  311. && !ScanStateList.scan_attempted[i]) {
  312. Scan_Info scan_info_flags;
  313. at_least_one_new_flag_raised = true;
  314. ScanStateList.scan_attempted[i] = true;
  315. Tstate ScanState;
  316. ScanState = ScanStateList.State[i];
  317. DP data_value = -1.0;
  318. bool admissible = ScanState.Check_Admissibility(whichDSF);
  319. if (admissible) {
  320. ScanState.Compute_All(true);
  321. if (ScanState.conv) {
  322. // Put momentum in fundamental window, if possible:
  323. int iKexc = ScanState.iK - AveragingState.iK;
  324. while (iKexc > iKmax && iKexc - iKmod >= iKmin) iKexc -= iKmod;
  325. while (iKexc < iKmin && iKexc + iKmod <= iKmax) iKexc += iKmod;
  326. stringstream rawfile_entry;
  327. data_value = Compute_Matrix_Element_Contrib (whichDSF, iKmin, iKmax, ScanState, AveragingState, Chem_Pot, rawfile_entry);
  328. {
  329. #pragma omp critical
  330. RAW_outfile << rawfile_entry.str();
  331. }
  332. {
  333. #pragma omp critical
  334. if (iKexc >= iKmin && iKexc <= iKmax) {
  335. scan_info_flags.Ndata++;
  336. scan_info_flags.Ndata_conv++;
  337. scan_info_flags.sumrule_obtained += data_value*sumrule_factor;
  338. }
  339. }
  340. // If we force descent: modify data_value by hand so that descent is forced on next scanning pass
  341. for (int itype = 0; itype < 15; ++itype) {
  342. DP data_value_used = 0.1* exp(-paused_thread_data.logscale * ABACUS::min(0, paused_thread_data.lowest_il_with_nthreads_neq_0));
  343. if (Force_Descent(whichDSF, ScanState, AveragingState, itype, iKmod, Chem_Pot))
  344. data_value = data_value_used;
  345. }
  346. Vect<bool> allowed(false, 15);
  347. if (whichDSF == 'B') { // symmetric state scanning
  348. allowed[9] = true; allowed[10] = true; allowed[11] = true;
  349. allowed[12] = true; allowed[13] = true; allowed[14] = true;
  350. }
  351. else {
  352. allowed[0] = (iKexc >= iKmin && iKexc <= iKmax);
  353. allowed[1] = allowed[0]; allowed[2] = allowed[0];
  354. allowed[3] = allowed[0]; allowed[4] = allowed[0];
  355. allowed[5] = allowed[0]; allowed[6] = allowed[0];
  356. allowed[7] = allowed[0]; allowed[8] = allowed[0];
  357. allowed[9] = (iKexc > iKmin);
  358. allowed[10] = allowed[9]; allowed[11] = allowed[9];
  359. allowed[12] = (iKexc < iKmax);
  360. allowed[13] = allowed[12]; allowed[14] = allowed[12];
  361. }
  362. for (int type_required_here = 0; type_required_here < 15; ++type_required_here) {
  363. if (!allowed[type_required_here]) continue;
  364. // All cases here are such that the ScanState hasn't been descended yet,
  365. // so we simply use data_value as expected data value:
  366. {
  367. #pragma omp critical
  368. paused_thread_data.Include_Thread (abs(data_value), ScanState.label, type_required_here);
  369. }
  370. }
  371. } // if (ScanState.conv)
  372. else {
  373. if (nconv0++ < 1000)
  374. CONV0_outfile << setw(25) << ScanState.label << setw(25) << ScanState.diffsq
  375. << setw(5) << ScanState.Check_Rapidities()
  376. << setw(25) << ScanState.String_delta() << endl;
  377. scan_info_flags.Ndata++;
  378. scan_info_flags.Ndata_conv0++;
  379. }
  380. } // if admissible
  381. else { // if inadmissible, modify data_value by hand so that descent is forced on next scanning pass
  382. if (ninadm++ < 10000000) INADM_outfile << ScanState.label << endl;
  383. scan_info_flags.Ndata++;
  384. scan_info_flags.Ninadm++;
  385. // Put momentum in fundamental window, if possible:
  386. int iKexc = ScanState.iK - AveragingState.iK;
  387. while (iKexc > iKmax && iKexc - iKmod >= iKmin) iKexc -= iKmod;
  388. while (iKexc < iKmin && iKexc + iKmod <= iKmax) iKexc += iKmod;
  389. DP data_value = 1.0e-32;
  390. for (int itype = 0; itype < 15; ++itype)
  391. if (Force_Descent(whichDSF, ScanState, AveragingState, itype, iKmod, Chem_Pot))
  392. data_value = 0.1* exp(-paused_thread_data.logscale * paused_thread_data.lowest_il_with_nthreads_neq_0);
  393. Vect<bool> allowed(false, 15);
  394. if (whichDSF == 'B') {
  395. // We scan over symmetric states. Only types 14 down to 9 are allowed.
  396. allowed[9] = true; allowed[10] = true; allowed[11] = true;
  397. allowed[12] = true; allowed[13] = true; allowed[14] = true;
  398. }
  399. else {
  400. allowed[0] = (iKexc >= iKmin && iKexc <= iKmax);
  401. allowed[1] = allowed[0]; allowed[2] = allowed[0];
  402. allowed[3] = allowed[0]; allowed[4] = allowed[0];
  403. allowed[5] = allowed[0]; allowed[6] = allowed[0];
  404. allowed[7] = allowed[0]; allowed[8] = allowed[0];
  405. allowed[9] = (iKexc > iKmin);
  406. allowed[10] = allowed[9]; allowed[11] = allowed[9];
  407. allowed[12] = (iKexc < iKmax);
  408. allowed[13] = allowed[12]; allowed[14] = allowed[12];
  409. }
  410. for (int type_required_here = 0; type_required_here < 15; ++type_required_here) {
  411. if (!allowed[type_required_here]) continue;
  412. {
  413. #pragma omp critical
  414. paused_thread_data.Include_Thread (abs(data_value), ScanState.label, type_required_here);
  415. }
  416. }
  417. } // inadmissible
  418. scan_info_flags.TT += omp_get_wtime() - start_time_flags;
  419. // Put this info into the appropriate ScanStateList.info
  420. {
  421. #pragma omp critical
  422. ScanStateList.Include_Info(scan_info_flags, ScanStateList.base_label[i]);
  423. scan_info += scan_info_flags;
  424. }
  425. } // if flag_for_scan
  426. } // for i
  427. } // #pragma omp master
  428. // Now we deal with the previously existing paused threads:
  429. Vect<Scan_Thread> threads_to_do;
  430. int il_to_do = paused_thread_data.lowest_il_with_nthreads_neq_0; // for resaving threads in case we're out of time
  431. {
  432. #pragma omp critical
  433. threads_to_do = paused_thread_data.Extract_Next_Scan_Threads();
  434. }
  435. int ithread;
  436. {
  437. for (ithread = 0; ithread < threads_to_do.size(); ++ithread) {
  438. Scan_Info scan_info_this_ithread;
  439. double start_time_this_ithread = omp_get_wtime();
  440. // If we don't have time anymore, resave the threads instead of computing them:
  441. if (start_time_this_ithread - start_time_omp > Max_Secs_alert) {
  442. for (int ith = ithread; ith < threads_to_do.size(); ++ith) {
  443. #pragma omp critical
  444. paused_thread_data.Include_Thread (il_to_do, threads_to_do[ith].label, threads_to_do[ith].type);
  445. }
  446. break; // jump out of ithread loop
  447. }
  448. Tstate ScanState;
  449. {
  450. #pragma omp critical
  451. ScanState = ScanStateList.Return_State(Extract_Base_Label(threads_to_do[ithread].label));
  452. }
  453. Tstate BaseScanState; BaseScanState = ScanState;
  454. ScanState.Set_to_Label(threads_to_do[ithread].label, BaseScanState.Ix2);
  455. // STARTING Descend_and_Compute block:
  456. int type_required = threads_to_do[ithread].type;
  457. ScanState.Compute_Momentum();
  458. Vect<string> desc_label;
  459. bool disperse_only_current_exc_up = false;
  460. if (type_required == 14 || type_required == 8 || type_required == 7 || type_required == 6)
  461. disperse_only_current_exc_up = true;
  462. bool preserve_nexc_up = false;
  463. if (type_required == 13 || type_required == 5 || type_required == 4 || type_required == 3)
  464. preserve_nexc_up = true;
  465. bool disperse_only_current_exc_down = false;
  466. if (type_required == 11 || type_required == 8 || type_required == 5 || type_required == 2)
  467. disperse_only_current_exc_down = true;
  468. bool preserve_nexc_down = false;
  469. if (type_required == 10 || type_required == 7 || type_required == 4 || type_required == 1)
  470. preserve_nexc_down = true;
  471. if (whichDSF == 'B') { // symmetric state scanning
  472. if (type_required >= 9 && type_required <= 11)
  473. desc_label = Descendent_States_with_iK_Stepped_Down_rightIx2only
  474. (ScanState.label, BaseScanState, disperse_only_current_exc_down, preserve_nexc_down);
  475. else if (type_required >= 12 && type_required <= 14)
  476. desc_label = Descendent_States_with_iK_Stepped_Up_rightIx2only
  477. (ScanState.label, BaseScanState, disperse_only_current_exc_up, preserve_nexc_up);
  478. }
  479. else {
  480. if (type_required >= 0 && type_required <= 8) {
  481. desc_label = Descendent_States_with_iK_Preserved
  482. (ScanState.label, BaseScanState, disperse_only_current_exc_up, preserve_nexc_up,
  483. disperse_only_current_exc_down, preserve_nexc_down);
  484. }
  485. else if (type_required >= 9 && type_required <= 11)
  486. desc_label = Descendent_States_with_iK_Stepped_Down
  487. (ScanState.label, BaseScanState, disperse_only_current_exc_down, preserve_nexc_down);
  488. else if (type_required >= 12 && type_required <= 14)
  489. desc_label = Descendent_States_with_iK_Stepped_Up
  490. (ScanState.label, BaseScanState, disperse_only_current_exc_up, preserve_nexc_up);
  491. }
  492. string label_here = ScanState.label;
  493. for (int idesc = 0; idesc < desc_label.size(); ++idesc) {
  494. ScanState.Set_to_Label (desc_label[idesc], BaseScanState.Ix2);
  495. bool admissible = ScanState.Check_Admissibility(whichDSF);
  496. DP data_value = 0.0;
  497. ScanState.conv = false;
  498. ScanState.Compute_Momentum(); // since momentum is used as forced descent criterion
  499. if (admissible) {
  500. ScanState.Compute_All (idesc == 0);
  501. if (ScanState.conv) {
  502. // Put momentum in fundamental window, if possible:
  503. int iKexc = ScanState.iK - AveragingState.iK;
  504. while (iKexc > iKmax && iKexc - iKmod >= iKmin) iKexc -= iKmod;
  505. while (iKexc < iKmin && iKexc + iKmod <= iKmax) iKexc += iKmod;
  506. stringstream rawfile_entry;
  507. data_value = Compute_Matrix_Element_Contrib (whichDSF, iKmin, iKmax, ScanState, AveragingState,
  508. Chem_Pot, rawfile_entry);
  509. {
  510. #pragma omp critical
  511. RAW_outfile << rawfile_entry.str();
  512. if (iKexc >= iKmin && iKexc <= iKmax) {
  513. scan_info_this_ithread.Ndata++;
  514. scan_info_this_ithread.Ndata_conv++;
  515. scan_info_this_ithread.sumrule_obtained += data_value*sumrule_factor;
  516. }
  517. }
  518. // Uncomment line below if .stat file is desired:
  519. //STAT_outfile << setw(20) << label_here << "\t" << setw(5) << type_required << "\t" << setw(16) << std::scientific << running_scan_threshold << "\t" << setw(20) << ScanState.label << "\t" << setw(16) << data_value << "\t" << setw(16) << std::fixed << setprecision(8) << data_value/running_scan_threshold << endl;
  520. } // if (ScanState.conv)
  521. else {
  522. if (nconv0++ < 1000)
  523. CONV0_outfile << setw(25) << ScanState.label << setw(25)
  524. << ScanState.diffsq << setw(5) << ScanState.Check_Rapidities()
  525. << setw(25) << ScanState.String_delta() << endl;
  526. scan_info_this_ithread.Ndata++;
  527. scan_info_this_ithread.Ndata_conv0++;
  528. }
  529. } // if (admissible)
  530. else {
  531. if (ninadm++ < 1000000) INADM_outfile << ScanState.label << endl;
  532. scan_info_this_ithread.Ndata++;
  533. scan_info_this_ithread.Ninadm++;
  534. }
  535. Tstate state_to_descend; state_to_descend = ScanState; // for checking
  536. ScanState.Compute_Momentum();
  537. // Put momentum in fundamental window, if possible:
  538. int iKexc = ScanState.iK - AveragingState.iK;
  539. while (iKexc > iKmax && iKexc - iKmod >= iKmin) iKexc -= iKmod;
  540. while (iKexc < iKmin && iKexc + iKmod <= iKmax) iKexc += iKmod;
  541. // Momentum-preserving are only descended to momentum-preserving.
  542. // Momentum-increasing are only descended to momentum-preserving and momentum-increasing.
  543. // Momentum-decreasing are only descended to momentum-preserving and momentum-decreasing.
  544. Vect<bool> allowed(false, 15);
  545. if (whichDSF == 'B') {
  546. // We scan over symmetric states. Only types 14 down to 9 are allowed.
  547. if (type_required >= 9 && type_required <= 11) { // iK stepped down on rightIx2; step further up or down
  548. allowed[9] = true; allowed[10] = true; allowed[11] = true;
  549. allowed[12] = true; allowed[13] = true; allowed[14] = true;
  550. }
  551. else if (type_required >= 12 && type_required <= 14) { // iK stepped up on rightIx2; only step further up
  552. allowed[12] = true; allowed[13] = true; allowed[14] = true;
  553. }
  554. }
  555. else {
  556. if (type_required >= 0 && type_required <= 8) { // momentum-preserving
  557. allowed[0] = (iKexc >= iKmin && iKexc <= iKmax);
  558. allowed[9] = false;
  559. allowed[12] = false;
  560. }
  561. if (type_required >= 9 && type_required <= 11) { // momentum-decreasing
  562. allowed[0] = (iKexc >= iKmin && iKexc <= iKmax);
  563. allowed[9] = (iKexc > iKmin);
  564. allowed[12] = false;
  565. }
  566. if (type_required >= 12 && type_required <= 14) { // momentum-increasing
  567. allowed[0] = (iKexc >= iKmin && iKexc <= iKmax);
  568. allowed[9] = false;
  569. allowed[12] = (iKexc < iKmax);
  570. }
  571. // The others are just copies of the ones above:
  572. 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];
  573. allowed[10] = allowed[9]; allowed[11] = allowed[9];
  574. allowed[13] = allowed[12]; allowed[14] = allowed[12];
  575. }
  576. for (int type_required_here = 0; type_required_here < 15; ++type_required_here) {
  577. if (!allowed[type_required_here]) continue;
  578. // Reset ScanState to what it was, if change on first pass
  579. if (type_required_here > 0) ScanState = state_to_descend;
  580. // We determine if we carry on scanning based on the data_value obtained, or forcing conditions:
  581. DP expected_abs_data_value = abs(data_value);
  582. //++G_7 logic
  583. if ((type_required_here == 14 || type_required_here == 8
  584. || type_required_here == 7 || type_required_here == 6)
  585. && Expect_ph_Recombination_iK_Up (ScanState.label, BaseScanState))
  586. expected_abs_data_value /= ph_cost;
  587. if (type_required_here == 12 || type_required_here == 2
  588. || type_required_here == 1 || type_required_here == 0)
  589. expected_abs_data_value *= ph_cost;
  590. if ((type_required_here == 11 || type_required_here == 8
  591. || type_required_here == 5 || type_required_here == 2)
  592. && Expect_ph_Recombination_iK_Down (ScanState.label, BaseScanState))
  593. expected_abs_data_value /= ph_cost;
  594. if (type_required_here == 9 || type_required_here == 6
  595. || type_required_here == 3 || type_required_here == 0)
  596. expected_abs_data_value *= ph_cost;
  597. {
  598. #pragma omp critical
  599. paused_thread_data.Include_Thread (expected_abs_data_value, ScanState.label, type_required_here);
  600. }
  601. } // for type_required_here
  602. } // for idesc
  603. // FINISHED Descend_and_Compute block
  604. scan_info_this_ithread.TT += omp_get_wtime() - start_time_this_ithread;
  605. #pragma omp critical
  606. {
  607. scan_info += scan_info_this_ithread;
  608. ScanStateList.Include_Info(scan_info_this_ithread, Extract_Base_Label(threads_to_do[ithread].label));
  609. }
  610. } // for ithread
  611. } // omp parallel region
  612. #pragma omp master
  613. {
  614. if (!in_parallel)
  615. LOG_outfile << "Master cycling. Ndata_conv " << scan_info.Ndata_conv
  616. << ". Threshold " << paused_thread_data.lowest_il_with_nthreads_neq_0 << " "
  617. << setw(9) << setprecision(3)
  618. << exp(-paused_thread_data.logscale * paused_thread_data.lowest_il_with_nthreads_neq_0)
  619. << ". " << setw(12) << scan_info.Ndata - Ndata_previous_cycle << " new data. Nr of threads: "
  620. << setw(14) << paused_thread_data.nthreads_total.sum()
  621. << ". Saturation: " << setprecision(12) << scan_info.sumrule_obtained << endl;
  622. Ndata_previous_cycle = scan_info.Ndata;
  623. }
  624. current_time_omp = omp_get_wtime();
  625. } while (current_time_omp - start_time_omp < Max_Secs_used
  626. && scan_info.sumrule_obtained < target_sumrule
  627. );
  628. // This closes the #pragram omp parallel block
  629. RAW_outfile.close();
  630. INADM_outfile.close();
  631. CONV0_outfile.close();
  632. STAT_outfile.close();
  633. scan_info.Save(SRC_Cstr);
  634. Scan_Info scan_info_refine = scan_info;
  635. scan_info_refine -= scan_info_before;
  636. if (!in_parallel) {
  637. if (scan_info.sumrule_obtained >= target_sumrule)
  638. LOG_outfile << endl << "Achieved sumrule saturation of " << scan_info.sumrule_obtained
  639. << "\t(target was " << target_sumrule << ")." << endl << endl;
  640. if (!refine) {
  641. LOG_outfile << "Main run info: " << scan_info << endl;
  642. LOG_outfile << "Latest threshold level " << paused_thread_data.lowest_il_with_nthreads_neq_0
  643. << " " << std::scientific << setprecision(3)
  644. << exp(-paused_thread_data.logscale * paused_thread_data.lowest_il_with_nthreads_neq_0) << endl;
  645. }
  646. else if (refine) {
  647. LOG_outfile << "Refining info: " << scan_info_refine << endl;
  648. LOG_outfile << "Latest threshold level " << paused_thread_data.lowest_il_with_nthreads_neq_0
  649. << " " << std::scientific << setprecision(3)
  650. << exp(-paused_thread_data.logscale * paused_thread_data.lowest_il_with_nthreads_neq_0) << endl;
  651. LOG_outfile << "Resulting info: " << scan_info << endl;
  652. }
  653. LOG_outfile << "Code version " << ABACUS_VERSION << ", copyright J.-S. Caux." << endl << endl;
  654. LOG_outfile.close();
  655. }
  656. else { // in_parallel
  657. LOG_outfile << "rank " << rank << " out of " << nr_processors << " processors: "
  658. << "run info: " << scan_info << endl << "Latest threshold = "
  659. << exp(-paused_thread_data.logscale * paused_thread_data.lowest_il_with_nthreads_neq_0) << endl;
  660. }
  661. paused_thread_data.Save();
  662. ScanStateList.Order_in_SRC ();
  663. ScanStateList.Save_Info (SUM_Cstr);
  664. // Evaluate f-sumrule:
  665. if (!in_parallel ) if (whichDSF != 'q')
  666. Evaluate_F_Sumrule (prefix_prevparalevel, whichDSF, AveragingState, Chem_Pot, iKmin, iKmax);
  667. return(scan_info);
  668. }
  669. //******************************************************
  670. // Functions to initiate scans:
  671. // General version for equilibrium correlators at generic (possibly finite) temperature:
  672. void Scan_LiebLin (char whichDSF, DP c_int, DP L, int N, int iKmin, int iKmax, DP kBT,
  673. int Max_Secs, DP target_sumrule, bool refine,
  674. int paralevel, Vect<int> rank, Vect<int> nr_processors)
  675. {
  676. // This function scans the Hilbert space of the LiebLin gas,
  677. // for the function identified by whichDSF.
  678. // whichDSF == 'Z': canonical partition function
  679. // whichDSF == 'd': density-density correlation function
  680. // whichDSF == 'g': Green's function < \Psi \Psi^{\dagger}>
  681. // whichDSF == 'o': one-body function < \Psi^{\dagger} \Psi >
  682. // Delta is the number of sites involved in the smoothing of the entropy
  683. //int Delta = int(sqrt(N))/2;//6;//N/20;
  684. //DP epsilon = log(L)/L; // using Gaussian for density in entropy.
  685. //DP epsilon = 1.0/L; // using Lorentzian for density in entropy.
  686. // Construct the finite-size saddle-point state:
  687. // if we refine, read the quantum numbers of the saddle point state (and seed sps) from the sps file:
  688. stringstream SPS_stringstream; string SPS_string;
  689. Data_File_Name (SPS_stringstream, whichDSF, c_int, L, N, iKmin, iKmax, kBT, 0.0, "");
  690. SPS_stringstream << ".sps";
  691. SPS_string = SPS_stringstream.str(); const char* SPS_Cstr = SPS_string.c_str();
  692. fstream spsfile;
  693. if (refine) spsfile.open(SPS_Cstr, fstream::in);
  694. else spsfile.open(SPS_Cstr, fstream::out | fstream::trunc);
  695. if (spsfile.fail()) {
  696. cout << SPS_Cstr << endl; ABACUSerror("Could not open spsfile.");
  697. }
  698. LiebLin_Bethe_State spstate;
  699. if (!refine) { // obtain the sps from discretized TBA
  700. spstate = Canonical_Saddle_Point_State (c_int, L, N, whichDSF == 'Z' ? 0.0 : kBT);
  701. }
  702. else { // read it from the sps file
  703. // Check that the sps has the right number of Ix2:
  704. int Nspsread;
  705. spsfile >> Nspsread;
  706. if (Nspsread != N) {
  707. cout << Nspsread << "\t" << N << endl;
  708. ABACUSerror("Wrong number of Ix2 in saddle-point state.");
  709. }
  710. spstate = LiebLin_Bethe_State (c_int, L, N);
  711. for (int i = 0; i < N; ++i) spsfile >> spstate.Ix2[i];
  712. }
  713. spstate.Compute_All(true);
  714. int Nscan = N;
  715. if (whichDSF == 'o') Nscan = N - 1;
  716. if (whichDSF == 'g') Nscan = N + 1;
  717. // Now construct or read off the seed scan state:
  718. // TO MODIFY: this is not a good idea, since this might construct a state with many p-h w/r to the AveragingState.
  719. LiebLin_Bethe_State SeedScanState;
  720. if (whichDSF != 'o' && whichDSF != 'g') SeedScanState = spstate;
  721. else if (whichDSF == 'o' || whichDSF == 'g') {
  722. if (!refine) {
  723. if (whichDSF == 'o') SeedScanState = Remove_Particle_at_Center (spstate);
  724. else SeedScanState = Add_Particle_at_Center (spstate);
  725. }
  726. else { // read it from the sps file
  727. // Check that the sps has the right number of Ix2:
  728. int Nsspsread;
  729. spsfile >> Nsspsread;
  730. if (Nsspsread != Nscan) {
  731. cout << Nsspsread << "\t" << Nscan << endl;
  732. ABACUSerror("Wrong number of Ix2 in scan saddle-point state.");
  733. }
  734. SeedScanState = LiebLin_Bethe_State (c_int, L, Nscan);
  735. for (int i = 0; i < Nscan; ++i) spsfile >> SeedScanState.Ix2[i];
  736. }
  737. } // if one-body or Green's function
  738. SeedScanState.Compute_All(true);
  739. LiebLin_Bethe_State ScanState = SeedScanState;
  740. DP delta = sqrt(DP(N)) * (spstate.lambdaoc[N-1] - spstate.lambdaoc[0])/N;
  741. if (!refine) { // we write data to the sps file
  742. spsfile << N << endl;
  743. spsfile << spstate.Ix2 << endl;
  744. spsfile << Nscan << endl;
  745. spsfile << SeedScanState.Ix2 << endl;
  746. spsfile << endl << spstate << endl << endl;
  747. for (int i = 1; i < spstate.N - 2; ++i)
  748. spsfile << 0.5 * (spstate.lambdaoc[i] + spstate.lambdaoc[i+1])
  749. << "\t" << 1.0/spstate.L * (0.25/(spstate.lambdaoc[i] - spstate.lambdaoc[i-1])
  750. + 0.5/(spstate.lambdaoc[i+1] - spstate.lambdaoc[i])
  751. + 0.25/(spstate.lambdaoc[i+2] - spstate.lambdaoc[i+1]))
  752. << "\t" << rho_of_lambdaoc_1 (spstate, 0.5 * (spstate.lambdaoc[i] + spstate.lambdaoc[i+1]), delta)
  753. << "\t" << rho_of_lambdaoc_2 (spstate, 0.5 * (spstate.lambdaoc[i] + spstate.lambdaoc[i+1]), delta)
  754. << endl;
  755. }
  756. spsfile.close();
  757. // Perform the scan:
  758. General_Scan (whichDSF, iKmin, iKmax, 100000000, kBT, spstate, SeedScanState, "",
  759. Max_Secs, target_sumrule, refine, paralevel, rank, nr_processors);
  760. return;
  761. }
  762. void Scan_LiebLin (char whichDSF, DP c_int, DP L, int N, int iKmin, int iKmax, DP kBT,
  763. int Max_Secs, DP target_sumrule, bool refine)
  764. {
  765. int paralevel = 0;
  766. Vect<int> rank(0,1);
  767. Vect<int> nr_processors(0,1);
  768. Scan_LiebLin (whichDSF, c_int, L, N, iKmin, iKmax, kBT, Max_Secs, target_sumrule,
  769. refine, paralevel, rank, nr_processors);
  770. return;
  771. }
  772. // Scanning on an excited state defined by a set of Ix2:
  773. void Scan_LiebLin (char whichDSF, LiebLin_Bethe_State AveragingState, string defaultScanStatename,
  774. int iKmin, int iKmax, int Max_Secs, DP target_sumrule, bool refine,
  775. int paralevel, Vect<int> rank, Vect<int> nr_processors)
  776. {
  777. // This function is as Scan_LiebLin for generic T defined above, except that the
  778. // averaging is now done on a state defined by AveragingStateIx2
  779. // PRECONDITIONS:
  780. // - the Ix2 of AveragingState are properly set.
  781. DP c_int = AveragingState.c_int;
  782. DP L = AveragingState.L;
  783. int N = AveragingState.N;
  784. // The label of the Averaging State is by definition the `empty' label
  785. AveragingState.Set_Label_from_Ix2 (AveragingState.Ix2);
  786. AveragingState.Compute_All(true);
  787. int Nscan = N;
  788. if (whichDSF == 'o') Nscan = N - 1;
  789. if (whichDSF == 'g') Nscan = N + 1;
  790. LiebLin_Bethe_State SeedScanState (c_int, L, Nscan);
  791. if (whichDSF == 'd' || whichDSF == 'B') SeedScanState.Ix2 = AveragingState.Ix2;
  792. // If 'o', remove midmost and shift quantum numbers by half-integer towards removed one:
  793. if (whichDSF == 'o') {
  794. for (int i = 0; i < N-1; ++i)
  795. SeedScanState.Ix2[i] = AveragingState.Ix2[i + (i >= N/2)] + 1 - 2*(i >= N/2);
  796. }
  797. // If 'g', add a quantum number in middle (explicitly: to right of index N/2)
  798. // and shift quantum numbers by half-integer away from added one:
  799. if (whichDSF == 'g') {
  800. SeedScanState.Ix2[N/2] = AveragingState.Ix2[N/2] - 1;
  801. for (int i = 0; i < N+1; ++i)
  802. SeedScanState.Ix2[i + (i >= N/2)] = AveragingState.Ix2[i] - 1 + 2*(i >= N/2);
  803. }
  804. SeedScanState.Compute_All(true);
  805. SeedScanState.Set_Label_from_Ix2 (SeedScanState.Ix2);
  806. DP kBT = 0.0;
  807. // Perform the scan:
  808. General_Scan (whichDSF, iKmin, iKmax, 100000000, kBT, AveragingState, SeedScanState, defaultScanStatename,
  809. Max_Secs, target_sumrule, refine, paralevel, rank, nr_processors);
  810. return;
  811. }
  812. // Simplified function call of the above:
  813. void Scan_LiebLin (char whichDSF, LiebLin_Bethe_State AveragingState, string defaultScanStatename,
  814. int iKmin, int iKmax, int Max_Secs, DP target_sumrule, bool refine)
  815. {
  816. int paralevel = 0;
  817. Vect<int> rank(0,1);
  818. Vect<int> nr_processors(0,1);
  819. Scan_LiebLin (whichDSF, AveragingState, defaultScanStatename, iKmin, iKmax, Max_Secs,
  820. target_sumrule, refine, paralevel, rank, nr_processors);
  821. return;
  822. }
  823. // Scanning on a previously-defined AveragingState
  824. void Scan_Heis (char whichDSF, XXZ_Bethe_State& AveragingState, string defaultScanStatename, int iKmin, int iKmax,
  825. int Max_Secs, DP target_sumrule, bool refine, int paralevel, Vect<int> rank, Vect<int> nr_processors)
  826. {
  827. // General state scanning for Heisenberg chains
  828. // PRECONDITIONS:
  829. // - the Ix2 of AveragingState are properly set.
  830. // Prepare the AveragingState:
  831. AveragingState.Compute_All(true);
  832. XXZ_Bethe_State SeedScanState;
  833. if (whichDSF == 'Z' || whichDSF == 'z') SeedScanState = AveragingState;
  834. else if (whichDSF == 'm') SeedScanState = Remove_Particle_at_Center (AveragingState);
  835. else if (whichDSF == 'p') SeedScanState = Add_Particle_at_Center (AveragingState);
  836. else ABACUSerror("Unknown whichDSF in Scan_Heis.");
  837. // Now the scan itself
  838. General_Scan (whichDSF, iKmin, iKmax, AveragingState.chain.Nsites, 0.0, AveragingState, SeedScanState,
  839. defaultScanStatename, Max_Secs, target_sumrule, refine, paralevel, rank, nr_processors);
  840. }
  841. // Scanning on a previously-defined AveragingState
  842. void Scan_Heis (char whichDSF, XXX_Bethe_State& AveragingState, string defaultScanStatename, int iKmin, int iKmax,
  843. int Max_Secs, DP target_sumrule, bool refine, int paralevel, Vect<int> rank, Vect<int> nr_processors)
  844. {
  845. // General state scanning for Heisenberg chains
  846. // PRECONDITIONS:
  847. // - the Ix2 of AveragingState are properly set.
  848. // Prepare the AveragingState:
  849. AveragingState.Compute_All(true);
  850. XXX_Bethe_State SeedScanState;
  851. if (whichDSF == 'Z' || whichDSF == 'z') SeedScanState = AveragingState;
  852. else if (whichDSF == 'm') SeedScanState = Remove_Particle_at_Center (AveragingState);
  853. else if (whichDSF == 'p') SeedScanState = Add_Particle_at_Center (AveragingState);
  854. else ABACUSerror("Unknown whichDSF in Scan_Heis.");
  855. // Now the scan itself
  856. General_Scan (whichDSF, iKmin, iKmax, AveragingState.chain.Nsites, 0.0, AveragingState, SeedScanState,
  857. defaultScanStatename, Max_Secs, target_sumrule, refine, paralevel, rank, nr_processors);
  858. }
  859. // Scanning on a previously-defined AveragingState
  860. void Scan_Heis (char whichDSF, XXZ_gpd_Bethe_State& AveragingState, string defaultScanStatename, int iKmin, int iKmax,
  861. int Max_Secs, DP target_sumrule, bool refine, int paralevel, Vect<int> rank, Vect<int> nr_processors)
  862. {
  863. // General state scanning for Heisenberg chains
  864. // PRECONDITIONS:
  865. // - the Ix2 of AveragingState are properly set.
  866. // Prepare the AveragingState:
  867. AveragingState.Compute_All(true);
  868. XXZ_gpd_Bethe_State SeedScanState;
  869. if (whichDSF == 'Z' || whichDSF == 'z') SeedScanState = AveragingState;
  870. else if (whichDSF == 'm') SeedScanState = Remove_Particle_at_Center (AveragingState);
  871. else if (whichDSF == 'p') SeedScanState = Add_Particle_at_Center (AveragingState);
  872. else ABACUSerror("Unknown whichDSF in Scan_Heis.");
  873. // Now the scan itself
  874. General_Scan (whichDSF, iKmin, iKmax, AveragingState.chain.Nsites, 0.0, AveragingState, SeedScanState,
  875. defaultScanStatename, Max_Secs, target_sumrule, refine, paralevel, rank, nr_processors);
  876. }
  877. void Scan_Heis (char whichDSF, DP Delta, int N, int M, int iKmin, int iKmax,
  878. int Max_Secs, DP target_sumrule, bool refine, int paralevel, Vect<int> rank, Vect<int> nr_processors)
  879. {
  880. // This function scans the Hilbert space of the Heisenberg spin-1/2 chain
  881. // for the function identified by whichDSF.
  882. // whichDSF == 'Z': canonical partition function
  883. // whichDSF == 'm': S^{-+}
  884. // whichDSF == 'z': S^{zz}
  885. // whichDSF == 'p': S^{+-}
  886. // whichDSF == 'a': < S^z_j S^z_{j+1} S^z_l S^z_{l+1} > for RIXS
  887. // whichDSF == 'b': < S^z_j S^-_{j+1} S^-_l S^z_{l+1} > + (m <-> z) for RIXS
  888. // whichDSF == 'c': < S^-_j S^-_{j+1} S^-_l S^-_{l+1} > for RIXS
  889. Heis_Chain BD1(1.0, Delta, 0.0, N);
  890. Vect_INT Nrapidities_groundstate(0, BD1.Nstrings);
  891. Nrapidities_groundstate[0] = M;
  892. Heis_Base baseconfig_groundstate(BD1, Nrapidities_groundstate);
  893. if ((Delta > 0.0) && (Delta < 1.0)) {
  894. XXZ_Bethe_State GroundState(BD1, baseconfig_groundstate);
  895. GroundState.Compute_All(true);
  896. // The ground state is now fully defined.
  897. XXZ_Bethe_State SeedScanState;
  898. if (whichDSF == 'Z' || whichDSF == 'z') SeedScanState = GroundState;
  899. else if (whichDSF == 'm') SeedScanState = XXZ_Bethe_State(GroundState.chain, M - 1);
  900. else if (whichDSF == 'p') SeedScanState = XXZ_Bethe_State(GroundState.chain, M + 1);
  901. else ABACUSerror("Unknown whichDSF in Scan_Heis.");
  902. // Now the scan itself
  903. General_Scan (whichDSF, iKmin, iKmax, N, 0.0, GroundState, SeedScanState, "",
  904. Max_Secs, target_sumrule, refine, paralevel, rank, nr_processors);
  905. }
  906. else if (Delta == 1.0) {
  907. XXX_Bethe_State GroundState(BD1, baseconfig_groundstate);
  908. GroundState.Compute_All(true);
  909. // The ground state is now fully defined.
  910. XXX_Bethe_State SeedScanState;
  911. if (whichDSF == 'Z' || whichDSF == 'z' || whichDSF == 'a' || whichDSF == 'q') SeedScanState = GroundState;
  912. else if (whichDSF == 'm') SeedScanState = XXX_Bethe_State(GroundState.chain, M - 1);
  913. else if (whichDSF == 'p') SeedScanState = XXX_Bethe_State(GroundState.chain, M + 1);
  914. else if (whichDSF == 'c') SeedScanState = XXX_Bethe_State(GroundState.chain, M - 2);
  915. else ABACUSerror("Unknown whichDSF in Scan_Heis.");
  916. // Now the scan itself
  917. General_Scan (whichDSF, iKmin, iKmax, N, 0.0, GroundState, SeedScanState, "",
  918. Max_Secs, target_sumrule, refine, paralevel, rank, nr_processors);
  919. }
  920. else if (Delta > 1.0) {
  921. XXZ_gpd_Bethe_State GroundState(BD1, baseconfig_groundstate);
  922. GroundState.Compute_All(true);
  923. // The ground state is now fully defined.
  924. XXZ_gpd_Bethe_State SeedScanState;
  925. if (whichDSF == 'Z' || whichDSF == 'z') SeedScanState = GroundState;
  926. else if (whichDSF == 'm') SeedScanState = XXZ_gpd_Bethe_State(GroundState.chain, M - 1);
  927. else if (whichDSF == 'p') SeedScanState = XXZ_gpd_Bethe_State(GroundState.chain, M + 1);
  928. else ABACUSerror("Unknown whichDSF in Scan_Heis.");
  929. // Now the scan itself
  930. General_Scan (whichDSF, iKmin, iKmax, N, 0.0, GroundState, SeedScanState, "",
  931. Max_Secs, target_sumrule, refine, paralevel, rank, nr_processors);
  932. }
  933. else ABACUSerror("Delta out of range in Heis_Structure_Factor");
  934. return;
  935. }
  936. void Scan_Heis (char whichDSF, DP Delta, int N, int M, int iKmin, int iKmax,
  937. int Max_Secs, DP target_sumrule, bool refine)
  938. {
  939. int paralevel = 0;
  940. Vect<int> rank(0,1);
  941. Vect<int> nr_processors(0,1);
  942. Scan_Heis (whichDSF, Delta, N, M, iKmin, iKmax, Max_Secs, target_sumrule, refine, paralevel, rank, nr_processors);
  943. return;
  944. }
  945. } // namespace ABACUS