Browse Source

Update Discretized_LiebLin_Bethe_State (copy from abacus-dev)

master
Jean-Sébastien Caux 1 year ago
parent
commit
28f3db1979
1 changed files with 35 additions and 14 deletions
  1. 35
    14
      src/TBA/TBA_LiebLin.cc

+ 35
- 14
src/TBA/TBA_LiebLin.cc View File

@@ -643,37 +643,55 @@ namespace ABACUS {
643 643
     return(sbar);
644 644
   }
645 645
 
646
+
646 647
   LiebLin_Bethe_State Discretized_LiebLin_Bethe_State (DP c_int, DP L, int N, const Root_Density& rho)
647 648
   {
648 649
     // This function returns the Bethe state at finite size which is
649 650
     // the closest approximation to the continuum density rho(lambda)
650 651
 
651
-    // Each time N \int_{-\infty}^\lambda d\lambda' \rho(\lambda') crosses a half integer, add a particle:
652
+    // Check that the provided rho has the expected filling
653
+    DP rho_check = 0.0;
654
+    for (int i = 0; i < rho.Npts; ++i) rho_check += L * rho.value[i] * rho.dlambda[i];
655
+    // The integral of rho should be between N - 0.5 and N + 0.5 for the algorithm to work
656
+    if (fabs(rho_check - N) > 0.5)
657
+      cout << "WARNING: integral of rho != N in Discretized_LiebLin_Bethe_State, "
658
+	   << "consistent discretization is impossible. \int rho dlambda = "
659
+	   << rho_check << ", N = " << N << ", L = " << L << ", N/L = " << N/L << endl;
660
+
661
+    // Using the counting function
662
+    // c(\lambda) \equiv L \int_{-\infty}^\lambda d\lambda' \rho(\lambda'),
663
+    // we seek to find lambda[i] such that c(lambda[i]) = i + 0.5, i = 0...N-1
652 664
     DP integral = 0.0;
653 665
     DP integral_prev = 0.0;
654 666
     int Nfound = 0;
655
-    Vect<DP> lambda_found(0.0, 2*N);
667
+    Vect<DP> lambda_found(0.0, N);
668
+    int nr_to_set = 0;
656 669
 
657 670
     for (int i = 0; i < rho.Npts; ++i) {
671
+      // Note: integral_prev is the counting function
672
+      // at rapidity rho.lambda[i-1] + 0.5* rho.dlambda[i-1]
673
+      // which equals rho.lambda[i] - 0.5* rho.dlambda[i]
658 674
       integral_prev = integral;
675
+      // Note: integral gives the value of the counting function
676
+      // at rapidity rho.lambda[i] + 0.5* rho.dlambda[i]
659 677
       integral += L * rho.value[i] * rho.dlambda[i];
660
-      if (integral > Nfound + 0.5) {
661
-	// Subtle error: if the rho is too discontinuous, i.e. if more than one rapidity is found, must correct for this.
662
-	if (integral > Nfound + 1.5 && integral < Nfound + 2.5) { // found two rapidities
663
-	  lambda_found[Nfound++] = 0.25 * (3.0 * rho.lambda[i-1] + rho.lambda[i]);
664
-	  lambda_found[Nfound++] = 0.25 * (rho.lambda[i-1] + 3.0 * rho.lambda[i]);
665
-	}
666
-	else {
667
-	  // Better: center the lambda_found between these points:
668
-	  lambda_found[Nfound] = 0.5 * (rho.lambda[i-1] + rho.lambda[i]);
669
-	  Nfound++;
670
-	}
678
+      // We already have filled the RHS of the counting equation up to Nfound - 0.5.
679
+      // Therefore, the additional number found is
680
+      nr_to_set = floor(integral + 0.5 - Nfound);
681
+      // if (nr_to_set > 1)
682
+      // 	cout << "WARNING: setting " << nr_to_set << " rapidities in one step in Discretized_LiebLin_Bethe_State" << endl;
683
+      for (int n = 1; n <= nr_to_set; ++n) {
684
+	// Solve c(lambda[Nfound]) = Nfound + 0.5 for lambda[Nfound],
685
+	// namely (using linear interpolation)
686
+	// integral_prev + (lambda - rho.lambda[i-1] - 0.5*rho.dlambda[i-1]) * (integral - integra_prev)/rho.dlambda[i] = Nfound + 0.5
687
+	lambda_found[Nfound] = rho.lambda[i-1] + 0.5*rho.dlambda[i-1] + (Nfound + 0.5 - integral_prev) * rho.dlambda[i]/(integral - integral_prev);
688
+	Nfound++;
671 689
       }
672 690
     }
673 691
 
674 692
     Vect<DP> lambda(N);
675 693
     // Fill up the found rapidities:
676
-    for (int il = 0; il < ABACUS::min(N, Nfound); ++il) lambda[il] = lambda_found[il];
694
+    for (int il = 0; il < abacus::min(N, Nfound); ++il) lambda[il] = lambda_found[il];
677 695
     // If there are missing ones, put them at the end; ideally, this should never be called
678 696
     for (int il = Nfound; il < N; ++il) lambda[il] = lambda_found[Nfound-1] + (il - Nfound + 1) * (lambda_found[Nfound-1] - lambda_found[Nfound-2]);
679 697
 
@@ -687,6 +705,9 @@ namespace ABACUS {
687 705
       Ix2[i] = 2.0 * floor((L* lambda[i] + sum)/twoPI + 0.5 * (N%2 ? 1 : 2)) + (N%2) - 1;
688 706
     }
689 707
 
708
+    // Check that the Ix2 are all ordered
709
+    for (int i = 0; i < N-1; ++i) if (Ix2[i] >= Ix2[i+1]) cout << "Alert: Ix2 not ordered around index i = " << i << ": Ix2[i] = " << Ix2[i] << "\tIx2[i+1] = " << Ix2[i+1] << endl;
710
+
690 711
     // Check that the quantum numbers are all distinct:
691 712
     bool allOK = false;
692 713
     while (!allOK) {

Loading…
Cancel
Save