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.

M_vs_H.cc 3.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. /**********************************************************
  2. This software is part of J.-S. Caux's ABACUS library.
  3. Copyright (c) J.-S. Caux.
  4. -----------------------------------------------------------
  5. File: M_vs_H.cc
  6. Purpose: field to and from magnetization for Heisenberg
  7. ***********************************************************/
  8. #include "ABACUS.h"
  9. using namespace std;
  10. namespace ABACUS {
  11. DP Ezero (DP Delta, int N, int M)
  12. {
  13. // Returns the energy of the ground state with M down spins
  14. if (M < 0 || M > N/2) ABACUSerror("M out of bounds in Ezero.");
  15. DP E = -1.0; // sentinel value
  16. if (M == 0) E = N * Delta/4.0;
  17. else {
  18. Heis_Chain BD1(1.0, Delta, 0.0, N);
  19. Vect_INT Nrapidities_groundstate(0, BD1.Nstrings);
  20. Nrapidities_groundstate[0] = M;
  21. Heis_Base baseconfig_groundstate(BD1, Nrapidities_groundstate);
  22. if ((Delta > 0.0) && (Delta < 1.0)) {
  23. XXZ_Bethe_State groundstate(BD1, baseconfig_groundstate);
  24. groundstate.Compute_All(true);
  25. E = groundstate.E;
  26. }
  27. else if (Delta == 1.0) {
  28. XXX_Bethe_State groundstate(BD1, baseconfig_groundstate);
  29. groundstate.Compute_All(true);
  30. E = groundstate.E;
  31. }
  32. else if (Delta > 1.0) {
  33. XXZ_gpd_Bethe_State groundstate(BD1, baseconfig_groundstate);
  34. groundstate.Compute_All(true);
  35. E = groundstate.E;
  36. }
  37. else ABACUSerror("Anisotropy out of bounds in Ezero.");
  38. }
  39. return(E);
  40. }
  41. DP H_vs_M (DP Delta, int N, int M)
  42. {
  43. // Assumes dE/dM = 0 = dE_0/dM + h, with dE_0/dM = E_0(M) - E_0 (M - 1)
  44. DP H = 0.0;
  45. if (2*M == N) H = 0.0;
  46. else if (Delta <= 1.0) H = Ezero (Delta, N, M - 1) - Ezero (Delta, N, M);
  47. return(H);
  48. }
  49. DP HZmin (DP Delta, int N, int M, Vect_DP& Ezero_ref)
  50. {
  51. if (M < 0 || M > N/2 - 1) {
  52. cout << "M = " << M << endl;
  53. ABACUSerror("M out of bounds in HZmin.");
  54. }
  55. if (Ezero_ref[M] == -1.0) Ezero_ref[M] = Ezero(Delta, N, M);
  56. if (Ezero_ref[M + 1] == -1.0) Ezero_ref[M + 1] = Ezero(Delta, N, M + 1);
  57. return(Ezero_ref[M] - Ezero_ref[M + 1]);
  58. }
  59. int M_vs_H (DP Delta, int N, DP HZ)
  60. {
  61. // Returns the value of M for given field HZ
  62. if (HZ < 0.0) ABACUSerror("Please use a positive field in M_vs_H.");
  63. else if (HZ == 0.0) return(N/2);
  64. // Here, -1.0 is a sentinel value.
  65. Vect_DP Ezero(-1.0, N/2 + 1); // contains the GSE[M].
  66. // We look for M s.t. HZmin[M] < HZ <= HZmin[M + 1]
  67. int M_actual = N/4; // start somewhere in middle
  68. int M_step = N/8 - 1; // step
  69. DP HZmin_actual = 0.0;
  70. DP HZmax_actual = 0.0;
  71. bool M_found = false;
  72. if (HZ >= 1.0 + Delta) M_actual = 0; // saturation
  73. else {
  74. HZmin_actual = HZmin (Delta, N, M_actual, Ezero);
  75. HZmax_actual = HZmin (Delta, N, M_actual - 1, Ezero);
  76. while (!M_found) {
  77. if (HZmin_actual > HZ) M_actual += M_step;
  78. else if (HZmax_actual <= HZ) M_actual -= M_step;
  79. M_step = (M_step + 1)/2;
  80. HZmin_actual = HZmin (Delta, N, M_actual, Ezero);
  81. HZmax_actual = HZmin (Delta, N, M_actual - 1, Ezero);
  82. M_found = (HZmin_actual < HZ && HZ <= HZmax_actual);
  83. //cout << "M_actual = " << M_actual << "\tM_step = " << M_step
  84. // << "\tHZmin_actual = " << HZmin_actual << "\tHZmax_actual = " << HZmax_actual << "\tHZ = " << HZ << "\t" << M_found << endl;
  85. }
  86. }
  87. //cout << "M found = " << M_actual << "\tHZmax = " << Ezero[M_actual] - Ezero[M_actual + 1] << "\tHZmin = " << Ezero[M_actual - 1] - Ezero[M_actual] << endl;
  88. return(M_actual);
  89. }
  90. }