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.

NRG_DME_Matrix_Block_builder.cc 11KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  1. /**********************************************************
  2. This software is part of J.-S. Caux's ABACUS library.
  3. Copyright (c) J.-S. Caux.
  4. -----------------------------------------------------------
  5. File: NRG_DFF_Matrix_Block_builder.cc
  6. Purpose: calculate matrix elements of density operator between
  7. selected states in NRG for a selected block of the whole matrix.
  8. For collaboration with Robert Konik.
  9. ***********************************************************/
  10. #include "ABACUS.h"
  11. using namespace std;
  12. using namespace ABACUS;
  13. namespace ABACUS {
  14. void Build_DME_Matrix_Block_for_NRG (DP c_int, DP L, int N, int iKmin, int iKmax,
  15. int Nstates_required, bool symmetric_states, int iKmod,
  16. int weighing_option, int nrglabel_left_begin, int nrglabel_left_end,
  17. int nrglabel_right_begin, int nrglabel_right_end,
  18. int block_option, DP* DME_block_1, DP* DME_block_2, Vect_DP Kweight)
  19. {
  20. // Given a list of states produced by Select_States_for_NRG, this function
  21. // computes all the density form factors < lstate| \rho | rstate >
  22. // for all id_left_begin <= id_left <= id_left_end (similarly for right states).
  23. // The block_option flag determines what kind of data is written in the 2 DME blocks.
  24. // If !symmetric_states, then only block 1 is filled.
  25. // If symmetric_states, then
  26. // if block_option == 1, only block 1 is filled with the symmetric states ME.
  27. // if block_option == 2, both blocks 1 and 2 are filled with ME and ME (after parity) respectively.
  28. // ASSUMPTIONS:
  29. // We assume the DME_blocks are already reserved in memory.
  30. // If !symmetric states, DME_block_2 doesn't need to be allocated.
  31. if (nrglabel_left_begin < 0 || nrglabel_right_begin < 0)
  32. ABACUSerror("beginning nrglabels negative in Build_DME_Matrix_Block_for_NRG");
  33. if (nrglabel_left_end >= Nstates_required)
  34. ABACUSerror("nrglabel_left_end too large in Build_DME_Matric_Block_for_NRG");
  35. if (nrglabel_right_end >= Nstates_required)
  36. ABACUSerror("nrglabel_right_end too large in Build_DME_Matric_Block_for_NRG");
  37. if (nrglabel_left_begin > nrglabel_left_end)
  38. ABACUSerror("nrglabels of left states improperly chosen in DME block builder.");
  39. if (nrglabel_right_begin > nrglabel_right_end)
  40. ABACUSerror("nrglabels of right states improperly chosen in DME block builder.");
  41. // DME_block is a pointer of size row_l * col_l, where
  42. int block_row_length = nrglabel_right_end - nrglabel_right_begin + 1;
  43. int block_col_length = nrglabel_left_end - nrglabel_left_begin + 1;
  44. // iKmod is an integer specifying that we're only interested in momenta multiples of
  45. // a base unit. In other words, if the perturbation potential repeats itself iKmod times
  46. // on the periodic cycle on which the theory is defined, then we only need states such
  47. // that iKl - iKr = (integer) * iKmod. We impose this constraint at the same time as
  48. // the check on the weight of the state.
  49. // We start by reading off the list of selected states:
  50. stringstream NRG_stringstream;
  51. string NRG_string;
  52. NRG_stringstream << "States_";
  53. NRG_stringstream << "c_" << c_int << "_L_" << L << "_N_" << N
  54. << "_iKmin_" << iKmin << "_iKmax_" << iKmax << "_Nstates_" << Nstates_required
  55. << "_Sym_" << symmetric_states << "_iKmod_" << iKmod << "_wopt_" << weighing_option << ".nrg";
  56. NRG_string = NRG_stringstream.str();
  57. const char* NRG_Cstr = NRG_string.c_str();
  58. ifstream infile;
  59. infile.open(NRG_Cstr);
  60. if (infile.fail()) {
  61. cout << NRG_Cstr << endl;
  62. ABACUSerror("The input file was not opened successfully in Build_DME_Matrix_between_Selected_States_for_NRG. ");
  63. }
  64. // Read the whole data file:
  65. const int MAXDATA = ABACUS::max(nrglabel_left_end, nrglabel_right_end) + 10; // 10 for safety...
  66. int* nrglabel = new int[MAXDATA];
  67. DP* omega = new DP[MAXDATA];
  68. int* iK = new int[MAXDATA];
  69. string* label = new string[MAXDATA];
  70. bool* sym = new bool[MAXDATA];
  71. DP* weight = new DP[MAXDATA];
  72. int Ndata = 0;
  73. while (((infile.peek()) != EOF) && (Ndata < MAXDATA)) {
  74. infile >> nrglabel[Ndata];
  75. if (nrglabel[Ndata] != Ndata) ABACUSerror("reading states nrglabels wrong in NRG_DME_Matrix_Block_builder");
  76. infile >> omega[Ndata];
  77. infile >> iK[Ndata];
  78. infile >> label[Ndata];
  79. infile >> sym[Ndata];
  80. infile >> weight[Ndata];
  81. Ndata++;
  82. }
  83. infile.close();
  84. // We first reconstruct all the needed eigenstates:
  85. // Vector containing all the kept states:
  86. Vect<LiebLin_Bethe_State> Kept_States_left(block_col_length);
  87. Vect<LiebLin_Bethe_State> Kept_States_right(block_row_length);
  88. // Dummy state for calculations
  89. LiebLin_Bethe_State Scanstate (c_int, L, N);
  90. // State list containing all the types of states
  91. Scan_State_List<LiebLin_Bethe_State> List_of_Basic_States ('Z', Scanstate);
  92. for (int nrglabel_left = nrglabel_left_begin; nrglabel_left <= nrglabel_left_end; ++nrglabel_left) {
  93. Scanstate = List_of_Basic_States.Return_State (Extract_Base_Label(label[nrglabel_left]));
  94. Scanstate.Set_to_Label (label[nrglabel_left]);
  95. Scanstate.Compute_All(true);
  96. Kept_States_left[nrglabel_left - nrglabel_left_begin] = Scanstate;
  97. if (!Scanstate.conv)
  98. cout << "State of label " << label[nrglabel_left] << " did not converge after " << Scanstate.iter_Newton
  99. << " Newton step; diffsq = " << Scanstate.diffsq << endl;
  100. } // for nrglabel_left
  101. for (int nrglabel_right = nrglabel_right_begin; nrglabel_right <= nrglabel_right_end; ++nrglabel_right) {
  102. Scanstate = List_of_Basic_States.Return_State (Extract_Base_Label(label[nrglabel_right]));
  103. Scanstate.Set_to_Label (label[nrglabel_right]);
  104. Scanstate.Compute_All(true);
  105. Kept_States_right[nrglabel_right - nrglabel_right_begin] = Scanstate;
  106. if (!Scanstate.conv)
  107. cout << "State of label " << label[nrglabel_right] << " did not converge after " << Scanstate.iter_Newton
  108. << " Newton step; diffsq = " << Scanstate.diffsq << endl;
  109. } // for nrglabel_left
  110. // Now that we have all the states, we can do the full calculation of all cross form factors:
  111. for (int ll = 0; ll < block_col_length; ++ll) {
  112. for (int lr = 0; lr < block_row_length; ++lr) {
  113. if (Kept_States_left[ll].conv && Kept_States_right[lr].conv
  114. && abs(Kept_States_left[ll].iK) % iKmod == 0
  115. && abs(Kept_States_right[lr].iK) % iKmod == 0) {
  116. if (!symmetric_states) {
  117. DME_block_1[ll* block_row_length + lr] = // By convention, put the lowest energy state to the left
  118. Kweight[abs(Kept_States_left[ll].iK - Kept_States_right[lr].iK)]
  119. * (Kept_States_left[ll].E <= Kept_States_right[lr].E
  120. ? real(exp(ln_Density_ME (Kept_States_left[ll], Kept_States_right[lr])))
  121. : real(exp(ln_Density_ME (Kept_States_right[lr], Kept_States_left[ll]))));
  122. // We don't do anything with block 2, we don't even assume it's been allocated.
  123. }
  124. else if (symmetric_states) {
  125. // Check parity of both states:
  126. bool Lstate_parity_inv = Kept_States_left[ll].Check_Symmetry();
  127. bool Rstate_parity_inv = Kept_States_right[lr].Check_Symmetry();
  128. if (Lstate_parity_inv && Rstate_parity_inv) {
  129. DME_block_1[ll* block_row_length + lr] = Kweight[abs(Kept_States_left[ll].iK - Kept_States_right[lr].iK)]
  130. * real(exp(ln_Density_ME (Kept_States_left[ll], Kept_States_right[lr])));
  131. if (block_option == 2) DME_block_2[ll* block_row_length + lr] = 0.0;
  132. }
  133. else if (!Lstate_parity_inv && !Rstate_parity_inv) {
  134. LiebLin_Bethe_State PRstate = Kept_States_right[lr];
  135. PRstate.Parity_Flip();
  136. if (block_option == 1) {
  137. DME_block_1[ll* block_row_length + lr] =
  138. (Kweight[abs(Kept_States_left[ll].iK - Kept_States_right[lr].iK)]
  139. * real(exp(ln_Density_ME (Kept_States_left[ll], Kept_States_right[lr])))
  140. + Kweight[abs(Kept_States_left[ll].iK - PRstate.iK)]
  141. * real(exp(ln_Density_ME (Kept_States_left[ll], PRstate))));
  142. // We don't do anything with block 2, we don't even assume it's been allocated.
  143. }
  144. else if (block_option == 2) {
  145. DME_block_1[ll* block_row_length + lr] =
  146. Kweight[abs(Kept_States_left[ll].iK - Kept_States_right[lr].iK)]
  147. * real(exp(ln_Density_ME (Kept_States_left[ll], Kept_States_right[lr])));
  148. DME_block_2[ll* block_row_length + lr] =
  149. Kweight[abs(Kept_States_left[ll].iK - PRstate.iK)]
  150. * real(exp(ln_Density_ME (Kept_States_left[ll], PRstate)));
  151. }
  152. }
  153. else if (Lstate_parity_inv) {
  154. LiebLin_Bethe_State PRstate = Kept_States_right[lr];
  155. PRstate.Parity_Flip();
  156. if (block_option == 1) {
  157. DME_block_1[ll* block_row_length + lr] = sqrt(0.5) *
  158. (Kweight[abs(Kept_States_left[ll].iK - Kept_States_right[lr].iK)]
  159. * real(exp(ln_Density_ME (Kept_States_left[ll], Kept_States_right[lr])))
  160. + Kweight[abs(Kept_States_left[ll].iK - PRstate.iK)]
  161. * real(exp(ln_Density_ME (Kept_States_left[ll], PRstate))));
  162. // We don't do anything with block 2, we don't even assume it's been allocated.
  163. }
  164. else if (block_option == 2) {
  165. DME_block_1[ll* block_row_length + lr] = sqrt(0.5) *
  166. Kweight[abs(Kept_States_left[ll].iK - Kept_States_right[lr].iK)]
  167. * real(exp(ln_Density_ME (Kept_States_left[ll], Kept_States_right[lr])));
  168. DME_block_2[ll* block_row_length + lr] = sqrt(0.5) *
  169. Kweight[abs(Kept_States_left[ll].iK - PRstate.iK)]
  170. * real(exp(ln_Density_ME (Kept_States_left[ll], PRstate)));
  171. }
  172. }
  173. else { // only R state is parity invariant, flip left:
  174. LiebLin_Bethe_State PLstate = Kept_States_left[ll];
  175. PLstate.Parity_Flip();
  176. if (block_option == 1) {
  177. DME_block_1[ll* block_row_length + lr] = sqrt(0.5) *
  178. (Kweight[abs(Kept_States_left[ll].iK - Kept_States_right[lr].iK)]
  179. * real(exp(ln_Density_ME (Kept_States_left[ll], Kept_States_right[lr])))
  180. + Kweight[abs(PLstate.iK - Kept_States_right[lr].iK)]
  181. * real(exp(ln_Density_ME (PLstate, Kept_States_right[lr]))));
  182. // We don't do anything with block 2, we don't even assume it's been allocated.
  183. }
  184. else if (block_option == 2) {
  185. DME_block_1[ll* block_row_length + lr] = sqrt(0.5) *
  186. Kweight[abs(Kept_States_left[ll].iK - Kept_States_right[lr].iK)]
  187. * real(exp(ln_Density_ME (Kept_States_left[ll], Kept_States_right[lr])));
  188. DME_block_2[ll* block_row_length + lr] = sqrt(0.5) *
  189. Kweight[abs(PLstate.iK - Kept_States_right[lr].iK)]
  190. * real(exp(ln_Density_ME (PLstate, Kept_States_right[lr])));
  191. }
  192. }
  193. } // if (symmetric_states)
  194. } // if conv & iKmod condition fulfilled
  195. else {
  196. DME_block_1[ll* block_row_length + lr] = 0.0;
  197. // condition, to prevent segfault if DME_block_2 not allocated.
  198. if (symmetric_states && block_option == 2) DME_block_2[ll* block_row_length + lr] = 0.0;
  199. }
  200. } // for lr
  201. } // for ll
  202. return;
  203. }
  204. } // namespace ABACUS