123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507 |
- /**********************************************************
-
- This software is part of J.-S. Caux's ABACUS library.
-
- Copyright (c) J.-S. Caux.
-
- -----------------------------------------------------------
-
- File: TBA_XXZ.cc
-
- Purpose: TBA for the gapless XXZ antiferromagnet.
-
- ***********************************************************/
-
- #include "ABACUS.h"
-
- using namespace std;
- using namespace ABACUS;
-
- namespace ABACUS {
-
- // First, define some useful kernels:
-
- DP XXZ_phi1_kernel (DP zeta, DP lambda)
- {
- return(2.0 * atan(tanh(lambda)/tan(0.5*zeta)));
- }
-
- DP XXZ_phi2_kernel (DP zeta, DP lambda)
- {
- return(2.0 * atan(tanh(lambda)/tan(zeta)));
- }
-
- DP XXZ_a1_kernel (DP sinzeta, DP coszeta, DP lambda)
- {
- DP expmin2abslambda = exp(-2.0 * fabs(lambda));
-
- DP answer = sinzeta * expmin2abslambda
- /(PI * (0.5 * (1.0 + expmin2abslambda * expmin2abslambda) - coszeta * expmin2abslambda));
-
- return(answer);
- }
-
- DP XXZ_da1dlambda_kernel (DP sinzeta, DP coszeta, DP lambda)
- {
- DP expmin2abslambda = exp(-2.0 * fabs(lambda));
- DP signlambda = lambda >= 0.0 ? 1.0 : -1.0;
- DP answer = -sinzeta * signlambda * expmin2abslambda * (1.0 - expmin2abslambda * expmin2abslambda)
- /(PI * pow((0.5 * (1.0 + expmin2abslambda * expmin2abslambda)
- - coszeta * expmin2abslambda), 2.0));
-
- return(answer);
- }
-
- DP XXZ_a2_kernel (DP sin2zeta, DP cos2zeta, DP lambda)
- {
- DP expmin2abslambda = exp(-2.0 * fabs(lambda));
-
- DP answer = sin2zeta * expmin2abslambda
- /(PI * (0.5 * (1.0 + expmin2abslambda * expmin2abslambda) - cos2zeta * expmin2abslambda));
-
- return(answer);
- }
-
- void Iterate_XXZ_rhotot_GS (DP zeta, DP B, Root_Density& rhotot_GS)
- {
- // Performs an iteration of the TBA equation for rhotot_GS:
-
- // First, copy the actual values into the previous ones:
- for (int i = 0; i < rhotot_GS.Npts; ++i) rhotot_GS.prev_value[i] = rhotot_GS.value[i];
-
- // Calculate the new values:
- DP conv = 0.0;
- DP sinzeta = sin(zeta);
- DP sin2zeta = sin(2.0*zeta);
- DP coszeta = cos(zeta);
- DP cos2zeta = cos(2.0*zeta);
- for (int i = 0; i < rhotot_GS.Npts; ++i) {
- // First, calculate the convolution
- conv = 0.0;
- for (int j = 0; j < rhotot_GS.Npts; ++j)
- conv += fabs(rhotot_GS.lambda[j]) > B ? 0.0 :
- XXZ_a2_kernel (sin2zeta, cos2zeta, rhotot_GS.lambda[i] - rhotot_GS.lambda[j])
- * rhotot_GS.prev_value[j] * rhotot_GS.dlambda[j];
- rhotot_GS.value[i] = XXZ_a1_kernel(sinzeta, coszeta, rhotot_GS.lambda[i]) - conv;
- }
-
- // Calculate the sum of differences:
- rhotot_GS.diff = 0.0;
- for (int i = 0; i < rhotot_GS.Npts; ++i)
- rhotot_GS.diff += fabs(rhotot_GS.value[i] - rhotot_GS.prev_value[i]);
-
- return;
- }
-
- Root_Density XXZ_rhotot_GS (DP Delta, DP B, DP lambdamax, int Npts, DP req_prec)
- {
-
- // This function returns a Root_Density object corresponding to the ground state
- // root distribution of the XXZ model.
-
- if (Delta >= 1.0 || Delta <= 0.0) ABACUSerror("Delta out of bounds in XXZ_rhotot_GS.");
-
- DP zeta = acos(Delta);
-
- Root_Density rhotot_GS(Npts, lambdamax);
-
- // We now attempt to find a solution...
-
- int niter = 0;
- do {
- Iterate_XXZ_rhotot_GS (zeta, B, rhotot_GS);
- niter ++;
- } while (rhotot_GS.diff > req_prec);
-
- return(rhotot_GS);
- }
-
- DP Return_GS_Sz_tot_value (DP B, Root_Density& rhotot_GS)
- {
- DP integral = 0.0;
- for (int i = 0; i < rhotot_GS.Npts; ++i)
- integral += fabs(rhotot_GS.lambda[i]) > B ? 0.0 : rhotot_GS.value[i] * rhotot_GS.dlambda[i];
-
- return(0.5 - integral);
- }
-
- void Iterate_XXZ_eps_GS (DP zeta, DP Hz, Root_Density& eps_GS)
- {
- // Performs an iteration of the TBA equation for eps_GS:
-
- // First, copy the actual values into the previous ones:
- for (int i = 0; i < eps_GS.Npts; ++i) eps_GS.prev_value[i] = eps_GS.value[i];
-
- // Calculate the new values:
- DP conv = 0.0;
- DP sinzeta = sin(zeta);
- DP sin2zeta = sin(2.0*zeta);
- DP coszeta = cos(zeta);
- DP cos2zeta = cos(2.0*zeta);
- for (int i = 0; i < eps_GS.Npts; ++i) {
- // First, calculate the convolution
- conv = 0.0;
- for (int j = 0; j < eps_GS.Npts; ++j)
- conv += eps_GS.prev_value[j] > 0.0 ? 0.0 :
- XXZ_a2_kernel (sin2zeta, cos2zeta, eps_GS.lambda[i] - eps_GS.lambda[j])
- * eps_GS.prev_value[j] * eps_GS.dlambda[j];
- eps_GS.value[i] = Hz - PI * sinzeta * XXZ_a1_kernel(sinzeta, coszeta, eps_GS.lambda[i]) - conv;
- }
-
- // Calculate the sum of differences:
- eps_GS.diff = 0.0;
- for (int i = 0; i < eps_GS.Npts; ++i)
- eps_GS.diff += fabs(eps_GS.value[i] - eps_GS.prev_value[i]);
-
- return;
- }
-
- Root_Density XXZ_eps_GS (DP Delta, DP Hz, DP lambdamax, int Npts, DP req_prec)
- {
-
- // This function returns a Root_Density object corresponding to the ground state
- // epsilon function of the XXZ model.
-
- if (Delta >= 1.0 || Delta <= 0.0) ABACUSerror("Delta out of bounds in XXZ_eps_GS.");
-
- DP zeta = acos(Delta);
-
- Root_Density eps_GS(Npts, lambdamax);
-
- // We now attempt to find a solution...
-
- int niter = 0;
- do {
- Iterate_XXZ_eps_GS (zeta, Hz, eps_GS);
- niter++;
- } while (eps_GS.diff > req_prec);
-
- return(eps_GS);
- }
-
- void Iterate_XXZ_depsdlambda_GS (DP zeta, DP B, Root_Density& depsdlambda_GS)
- {
- // Performs an iteration of the TBA equation for depsdlambda_GS:
-
- // First, copy the actual values into the previous ones:
- for (int i = 0; i < depsdlambda_GS.Npts; ++i) depsdlambda_GS.prev_value[i] = depsdlambda_GS.value[i];
-
- // Calculate the new values:
- DP conv = 0.0;
- DP sinzeta = sin(zeta);
- DP sin2zeta = sin(2.0*zeta);
- DP coszeta = cos(zeta);
- DP cos2zeta = cos(2.0*zeta);
- for (int i = 0; i < depsdlambda_GS.Npts; ++i) {
- // First, calculate the convolution
- conv = 0.0;
- for (int j = 0; j < depsdlambda_GS.Npts; ++j)
- conv += fabs(depsdlambda_GS.lambda[j]) > B ? 0.0 :
- XXZ_a2_kernel (sin2zeta, cos2zeta, depsdlambda_GS.lambda[i] - depsdlambda_GS.lambda[j])
- * depsdlambda_GS.prev_value[j] * depsdlambda_GS.dlambda[j];
- depsdlambda_GS.value[i] = -PI * sinzeta * XXZ_da1dlambda_kernel(sinzeta, coszeta, depsdlambda_GS.lambda[i]) - conv;
- }
-
- // Calculate the sum of differences:
- depsdlambda_GS.diff = 0.0;
- for (int i = 0; i < depsdlambda_GS.Npts; ++i)
- depsdlambda_GS.diff += fabs(depsdlambda_GS.value[i] - depsdlambda_GS.prev_value[i]);
-
- return;
- }
-
- Root_Density XXZ_depsdlambda_GS (DP Delta, DP B, DP lambdamax, int Npts, DP req_prec)
- {
-
- // This function returns a Root_Density object corresponding to the ground state
- // (d/d\lambda) epsilon function of the XXZ model.
-
- if (Delta >= 1.0 || Delta <= 0.0) ABACUSerror("Delta out of bounds in XXZ_rho_GS.");
-
- DP zeta = acos(Delta);
-
- Root_Density depsdlambda_GS(Npts, lambdamax);
-
- // We now attempt to find a solution...
-
- int niter = 0;
- do {
- Iterate_XXZ_depsdlambda_GS (zeta, B, depsdlambda_GS);
- niter++;
- } while (depsdlambda_GS.diff > req_prec);
-
- return(depsdlambda_GS);
- }
-
- void Iterate_XXZ_b2BB_lambda_B (DP zeta, DP B, Root_Density& b2BB)
- {
- // Calculates the vector corresponding to b2BB (lambda,B)
-
- // First, copy the actual values into the previous ones:
- for (int i = 0; i < b2BB.Npts; ++i) b2BB.prev_value[i] = b2BB.value[i];
-
- // Calculate the new values:
- DP conv = 0.0;
- DP sin2zeta = sin(2.0*zeta);
- DP cos2zeta = cos(2.0*zeta);
- for (int i = 0; i < b2BB.Npts; ++i) {
- if (fabs(b2BB.lambda[i]) > B) b2BB.value[i] = 0.0;
- else {
- // First, calculate the convolution
- conv = 0.0;
- for (int j = 0; j < b2BB.Npts; ++j)
- conv += fabs(b2BB.lambda[j]) > B ? 0.0 :
- XXZ_a2_kernel (sin2zeta, cos2zeta, b2BB.lambda[i] - b2BB.lambda[j])
- * b2BB.prev_value[j] * b2BB.dlambda[j];
- b2BB.value[i] = -XXZ_a2_kernel(sin2zeta, cos2zeta, b2BB.lambda[i] - B)
- - conv;
- }
- }
- // Calculate the sum of differences:
- b2BB.diff = 0.0;
- for (int i = 0; i < b2BB.Npts; ++i)
- b2BB.diff += fabs(b2BB.value[i] - b2BB.prev_value[i]);
-
- return;
- }
-
- Root_Density XXZ_b2BB_lambda_B (DP Delta, DP B, DP lambdamax, int Npts, DP req_prec)
- {
-
- // This function returns a Root_Density object corresponding to the inverse
- // kernel b2BB (lambda, B) used in Kbar function.
-
- if (Delta >= 1.0 || Delta <= 0.0) ABACUSerror("Delta out of bounds in XXZ_Kbackflow_GS.");
-
- DP zeta = acos(Delta);
-
- Root_Density b2BB_lambda_B(Npts, lambdamax);
-
- // We now attempt to find a solution...
-
- int niter = 0;
- do {
- Iterate_XXZ_b2BB_lambda_B (zeta, B, b2BB_lambda_B);
- niter++;
- } while (b2BB_lambda_B.diff > req_prec);
-
- return(b2BB_lambda_B);
- }
-
- void Iterate_XXZ_b2BB_lambda_lambdap (DP zeta, DP B, DP lambdap, Root_Density& b2BB)
- {
- // Calculates the vector corresponding to b2BB (lambda,lambdap)
-
- // First, copy the actual values into the previous ones:
- for (int i = 0; i < b2BB.Npts; ++i) b2BB.prev_value[i] = b2BB.value[i];
-
- // Calculate the new values:
- DP conv = 0.0;
- DP sin2zeta = sin(2.0*zeta);
- DP cos2zeta = cos(2.0*zeta);
- for (int i = 0; i < b2BB.Npts; ++i) {
- if (fabs(b2BB.lambda[i]) > B) b2BB.value[i] = 0.0;
- else {
- // First, calculate the convolution
- conv = 0.0;
- for (int j = 0; j < b2BB.Npts; ++j)
- conv += fabs(b2BB.lambda[j]) > B ? 0.0 :
- XXZ_a2_kernel (sin2zeta, cos2zeta, b2BB.lambda[i] - b2BB.lambda[j])
- * b2BB.prev_value[j] * b2BB.dlambda[j];
- b2BB.value[i] = -XXZ_a2_kernel(sin2zeta, cos2zeta, b2BB.lambda[i] - lambdap)
- - conv;
- }
- }
- // Calculate the sum of differences:
- b2BB.diff = 0.0;
- for (int i = 0; i < b2BB.Npts; ++i)
- b2BB.diff += fabs(b2BB.value[i] - b2BB.prev_value[i]);
-
- return;
- }
-
- Root_Density XXZ_b2BB_lambda_lambdap (DP Delta, DP B, DP lambdap, DP lambdamax, int Npts, DP req_prec)
- {
-
- // This function returns a Root_Density object corresponding to the inverse
- // kernel b2BB (lambda, lambdap) used in Kbar function.
-
- if (Delta >= 1.0 || Delta <= 0.0) ABACUSerror("Delta out of bounds in XXZ_Kbackflow_GS.");
-
- DP zeta = acos(Delta);
-
- Root_Density b2BB_lambda_lambdap(Npts, lambdamax);
-
- // We now attempt to find a solution...
-
- int niter = 0;
- do {
- Iterate_XXZ_b2BB_lambda_lambdap (zeta, B, lambdap, b2BB_lambda_lambdap);
- niter++;
- } while (b2BB_lambda_lambdap.diff > req_prec);
-
- return(b2BB_lambda_lambdap);
- }
-
- void Iterate_XXZ_Kbackflow_GS (DP zeta, DP B, DP lambda_p, DP lambda_h, Root_Density& Kbackflow_GS)
- {
- // Performs an iteration of the TBA equation for Kbackflow_GS:
-
- // First, copy the actual values into the previous ones:
- for (int i = 0; i < Kbackflow_GS.Npts; ++i) Kbackflow_GS.prev_value[i] = Kbackflow_GS.value[i];
-
- // Calculate the new values:
- DP conv = 0.0;
- DP sin2zeta = sin(2.0*zeta);
- DP cos2zeta = cos(2.0*zeta);
- for (int i = 0; i < Kbackflow_GS.Npts; ++i) {
- if (false && fabs(Kbackflow_GS.lambda[i]) > B) Kbackflow_GS.value[i] = 0.0;
- else {
- // First, calculate the convolution
- conv = 0.0;
- for (int j = 0; j < Kbackflow_GS.Npts; ++j)
- conv += fabs(Kbackflow_GS.lambda[j]) > B ? 0.0 :
- XXZ_a2_kernel (sin2zeta, cos2zeta, Kbackflow_GS.lambda[i] - Kbackflow_GS.lambda[j])
- * Kbackflow_GS.prev_value[j] * Kbackflow_GS.dlambda[j];
- Kbackflow_GS.value[i] = -XXZ_a2_kernel(sin2zeta, cos2zeta, Kbackflow_GS.lambda[i] - lambda_p)
- + XXZ_a2_kernel(sin2zeta, cos2zeta, Kbackflow_GS.lambda[i] - lambda_h) - conv;
- }
- }
- // Calculate the sum of differences:
- Kbackflow_GS.diff = 0.0;
- for (int i = 0; i < Kbackflow_GS.Npts; ++i)
- Kbackflow_GS.diff += fabs(Kbackflow_GS.value[i] - Kbackflow_GS.prev_value[i]);
-
- return;
- }
-
- Root_Density XXZ_Kbackflow_GS (DP Delta, DP B, DP lambdamax, DP lambda_p, DP lambda_h, int Npts, DP req_prec)
- {
-
- // This function returns a Root_Density object corresponding to the ground state
- // backflow function of the XXZ model.
-
- if (Delta >= 1.0 || Delta <= 0.0) ABACUSerror("Delta out of bounds in XXZ_Kbackflow_GS.");
-
- DP zeta = acos(Delta);
-
- Root_Density Kbackflow_GS(Npts, lambdamax);
-
- // We now attempt to find a solution...
-
- int niter = 0;
- do {
- Iterate_XXZ_Kbackflow_GS (zeta, B, lambda_p, lambda_h, Kbackflow_GS);
- niter++;
- } while (Kbackflow_GS.diff > req_prec);
-
- return(Kbackflow_GS);
- }
-
- void Iterate_XXZ_Fbackflow_GS (DP zeta, DP B, DP lambda_p, DP lambda_h, Root_Density& Fbackflow_GS)
- {
- // Performs an iteration of the TBA equation for Fbackflow_GS:
-
- // First, copy the actual values into the previous ones:
- for (int i = 0; i < Fbackflow_GS.Npts; ++i) Fbackflow_GS.prev_value[i] = Fbackflow_GS.value[i];
-
- // Calculate the new values:
- DP conv = 0.0;
- DP sin2zeta = sin(2.0*zeta);
- DP cos2zeta = cos(2.0*zeta);
- for (int i = 0; i < Fbackflow_GS.Npts; ++i) {
- if (fabs(Fbackflow_GS.lambda[i]) > B) Fbackflow_GS.value[i] = 0.0;
- else {
- // First, calculate the convolution
- conv = 0.0;
- for (int j = 0; j < Fbackflow_GS.Npts; ++j)
- conv += fabs(Fbackflow_GS.lambda[j]) > B ? 0.0 :
- XXZ_a2_kernel (sin2zeta, cos2zeta, Fbackflow_GS.lambda[i] - Fbackflow_GS.lambda[j])
- * Fbackflow_GS.prev_value[j] * Fbackflow_GS.dlambda[j];
- Fbackflow_GS.value[i] = (-XXZ_phi2_kernel(zeta, Fbackflow_GS.lambda[i] - lambda_p)
- + XXZ_phi2_kernel(zeta, Fbackflow_GS.lambda[i] - lambda_h))/twoPI - conv;
- }
- }
- // Calculate the sum of differences:
- Fbackflow_GS.diff = 0.0;
- for (int i = 0; i < Fbackflow_GS.Npts; ++i)
- Fbackflow_GS.diff += fabs(Fbackflow_GS.value[i] - Fbackflow_GS.prev_value[i]);
-
- return;
- }
-
- Root_Density XXZ_Fbackflow_GS (DP Delta, DP B, DP lambdamax, DP lambda_p, DP lambda_h, int Npts, DP req_prec)
- {
-
- // This function returns a Root_Density object corresponding to the ground state
- // F backflow function of the XXZ model.
-
- if (Delta >= 1.0 || Delta <= 0.0) ABACUSerror("Delta out of bounds in XXZ_Fbackflow_GS.");
-
- DP zeta = acos(Delta);
-
- Root_Density Fbackflow_GS(Npts, lambdamax);
-
- // We now attempt to find a solution...
-
- int niter = 0;
- do {
- Iterate_XXZ_Fbackflow_GS (zeta, B, lambda_p, lambda_h, Fbackflow_GS);
- niter++;
- } while (Fbackflow_GS.diff > req_prec);
-
- return(Fbackflow_GS);
- }
-
- void Iterate_XXZ_Z_GS (DP zeta, DP B, Root_Density& Z_GS)
- {
- // Performs an iteration of the TBA equation for the dressed charge:
-
- // First, copy the actual values into the previous ones:
- for (int i = 0; i < Z_GS.Npts; ++i) Z_GS.prev_value[i] = Z_GS.value[i];
-
- // Calculate the new values:
- DP conv = 0.0;
- DP sin2zeta = sin(2.0*zeta);
- DP cos2zeta = cos(2.0*zeta);
- for (int i = 0; i < Z_GS.Npts; ++i) {
- // First, calculate the convolution
- conv = 0.0;
- for (int j = 0; j < Z_GS.Npts; ++j)
- conv += fabs(Z_GS.lambda[j]) > B ? 0.0 :
- XXZ_a2_kernel (sin2zeta, cos2zeta, Z_GS.lambda[i] - Z_GS.lambda[j])
- * Z_GS.prev_value[j] * Z_GS.dlambda[j];
- Z_GS.value[i] = 1.0 - conv;
- }
-
- // Calculate the sum of differences:
- Z_GS.diff = 0.0;
- for (int i = 0; i < Z_GS.Npts; ++i)
- Z_GS.diff += fabs(Z_GS.value[i] - Z_GS.prev_value[i]);
-
- return;
- }
-
- Root_Density XXZ_Z_GS (DP Delta, DP B, DP lambdamax, int Npts, DP req_prec)
- {
-
- // This function returns a Root_Density object corresponding to the ground state
- // dressed charge function of the XXZ model.
-
- if (Delta >= 1.0 || Delta <= 0.0) ABACUSerror("Delta out of bounds in XXZ_Z_GS.");
-
- DP zeta = acos(Delta);
-
- Root_Density Z_GS(Npts, lambdamax);
-
- // We now attempt to find a solution...
-
- do {
- Iterate_XXZ_Z_GS (zeta, B, Z_GS);
- } while (Z_GS.diff > req_prec);
-
- return(Z_GS);
- }
-
-
- } // namespace ABACUS
|