ABACUS/src/HEIS/Heis_Sumrules.cc

255 lines
8.5 KiB
C++

/**********************************************************
This software is part of J.-S. Caux's ABACUS library.
Copyright (c) J.-S. Caux.
-----------------------------------------------------------
File: src/HEIS/Heis_Sumrules.cc
Purpose: defines sumrule factors for Heisenberg
***********************************************************/
#include "ABACUS.h"
using namespace std;
namespace ABACUS {
DP X_avg (char xyorz, DP Delta, int N, int M)
{
// Calculates \sum_j < S_j^a S_{j+1}^a >, a = x, y or z.
DP eps_Delta = 0.00000001;
if (Delta < 1.0 && 1.0 - Delta < 1.0e-6) eps_Delta *= -1.0;
// Define the chain: J, Delta, h, Nsites
Heis_Chain chain(1.0, Delta, 0.0, N);
// Define the base: chain, Mdown
Heis_Base gbase(chain, M);
// Define the chain: J, Delta, h, Nsites
Heis_Chain chain2(1.0, Delta + eps_Delta, 0.0, N);
// Define the base: chain, Mdown
Heis_Base gbase2(chain2, M);
DP E0_Delta = 0.0;
DP E0_Delta_eps = 0.0;
if (Delta > 0.0 && Delta < 1.0) {
// Define the ground state
XXZ_Bethe_State gstate(chain, gbase);
// Compute everything about the ground state
gstate.Compute_All(true);
E0_Delta = gstate.E;
// Define the ground state
XXZ_Bethe_State gstate2(chain2, gbase2);
// Compute everything about the ground state
gstate2.Compute_All(true);
E0_Delta_eps = gstate2.E;
}
else if (Delta == 1.0) {
// Define the ground state
XXX_Bethe_State gstate(chain, gbase);
// Compute everything about the ground state
gstate.Compute_All(true);
E0_Delta = gstate.E;
// Define the ground state
XXZ_gpd_Bethe_State gstate2(chain2, gbase2); // need XXZ_gpd here
// Compute everything about the ground state
gstate2.Compute_All(true);
E0_Delta_eps = gstate2.E;
}
else if (Delta > 1.0) {
// Define the ground state
XXZ_gpd_Bethe_State gstate(chain, gbase);
// Compute everything about the ground state
gstate.Compute_All(true);
E0_Delta = gstate.E;
// Define the ground state
XXZ_gpd_Bethe_State gstate2(chain2, gbase2);
// Compute everything about the ground state
gstate2.Compute_All(true);
E0_Delta_eps = gstate2.E;
}
else ABACUSerror("Wrong anisotropy in S1_sumrule_factor.");
DP answer = 0.0;
//if (xyorz == 'x' || xyorz == 'y') answer = 0.5 * (E0_Delta - Delta * (E0_Delta_eps - E0_Delta)/eps_Delta);
if (xyorz == 'x' || xyorz == 'y') answer = 0.5 * (E0_Delta - Delta * (E0_Delta_eps - E0_Delta)/eps_Delta);
// Careful for z ! Hamiltonian defined as S^z S^z - 1/4, so add back N/4:
else if (xyorz == 'z') answer = (E0_Delta_eps - E0_Delta)/eps_Delta + 0.25 * N;
else ABACUSerror("option not implemented in X_avg.");
return(answer);
}
DP S1_sumrule_factor (char mporz, DP Delta, int N, int M, DP Chem_Pot, int iK)
{
DP X_x = X_avg ('x', Delta, N, M);
DP X_z = X_avg ('z', Delta, N, M);
DP sumrule = 0.0;
if (mporz == 'm' || mporz == 'p') sumrule = - 4.0 * ((1.0 - Delta * cos((twoPI * iK)/N)) * X_x + (Delta - cos((twoPI * iK)/N)) * X_z + 0.5 * Chem_Pot * 0.5 *(N - 2*M))/N;
//if (mporz == 'm' || mporz == 'p') sumrule = - 1.0 * ((1.0 - Delta * cos((twoPI * iK)/N)) * 2.0 * X_x + (Delta - cos((twoPI * iK)/N)) * (X_x + X_z))/N;
else if (mporz == 'z') sumrule = iK == 0 ? 1.0 : -2.0 * X_x * (1.0 - cos((twoPI * iK)/N))/N;
else if (mporz == 'Z') sumrule = 1.0; // partition function
else if (mporz == 'a') sumrule = 1.0;
else if (mporz == 'b') sumrule = 1.0;
else if (mporz == 'c') sumrule = 1.0;
else ABACUSerror("option not implemented in S1_sumrule_factor.");
//return(1.0/sumrule);
return(1.0/(sumrule + 1.0e-16)); // sumrule is 0 for iK == 0 or N
}
DP S1_sumrule_factor (char mporz, DP Delta, int N, int M, DP Chem_Pot, DP X_x, DP X_z, int iK)
{
//DP X_x = X_avg ('x', Delta, N, M);
//DP X_z = X_avg ('z', Delta, N, M);
DP sumrule = 0.0;
if (mporz == 'm' || mporz == 'p') sumrule = - 4.0 * ((1.0 - Delta * cos((twoPI * iK)/N)) * X_x + (Delta - cos((twoPI * iK)/N)) * X_z + 0.5 * Chem_Pot * 0.5 *(N - 2*M))/N;
//if (mporz == 'm' || mporz == 'p') sumrule = - 1.0 * ((1.0 - Delta * cos((twoPI * iK)/N)) * 2.0 * X_x + (Delta - cos((twoPI * iK)/N)) * (X_x + X_z))/N;
else if (mporz == 'z') sumrule = -2.0 * X_x * (1.0 - cos((twoPI * iK)/N))/N;
else if (mporz == 'Z') sumrule = 1.0; // partition function
else if (mporz == 'a') sumrule = 1.0;
else if (mporz == 'b') sumrule = 1.0;
else if (mporz == 'c') sumrule = 1.0;
else ABACUSerror("option not implemented in S1_sumrule_factor.");
return(1.0/(sumrule + 1.0e-16)); // sumrule is 0 for iK == 0 or N
}
//DP Sumrule_Factor (char whichDSF, Heis_Bethe_State& AveragingState, DP Chem_Pot, bool fixed_iK, int iKneeded)
DP Sumrule_Factor (char whichDSF, Heis_Bethe_State& AveragingState, DP Chem_Pot, int iKmin, int iKmax)
{
DP sumrule_factor = 1.0;
//if (!fixed_iK) {
if (iKmin != iKmax) {
if (whichDSF == 'Z') sumrule_factor = 1.0;
else if (whichDSF == 'm')
sumrule_factor = 1.0/AveragingState.base.Mdown;
else if (whichDSF == 'z') sumrule_factor = 1.0/(0.25 * AveragingState.chain.Nsites);
else if (whichDSF == 'p') sumrule_factor = 1.0/(AveragingState.chain.Nsites - AveragingState.base.Mdown);
else if (whichDSF == 'a') sumrule_factor = 1.0;
else if (whichDSF == 'b') sumrule_factor = 1.0;
else if (whichDSF == 'c') sumrule_factor = 1.0;
else if (whichDSF == 'q') sumrule_factor = 1.0;
else ABACUSerror("whichDSF option not consistent in Sumrule_Factor");
}
//else if (fixed_iK) {
else if (iKmin == iKmax) {
if (whichDSF == 'Z') sumrule_factor = 1.0;
else if (whichDSF == 'm' || whichDSF == 'z' || whichDSF == 'p')
//sumrule_factor = S1_sumrule_factor (whichDSF, AveragingState.chain.Delta, AveragingState.chain.Nsites, AveragingState.base.Mdown, iKneeded);
sumrule_factor = S1_sumrule_factor (whichDSF, AveragingState.chain.Delta, AveragingState.chain.Nsites, AveragingState.base.Mdown, Chem_Pot, iKmax);
else if (whichDSF == 'a') sumrule_factor = 1.0;
else if (whichDSF == 'b') sumrule_factor = 1.0;
else if (whichDSF == 'c') sumrule_factor = 1.0;
else if (whichDSF == 'q') sumrule_factor = 1.0;
else ABACUSerror("whichDSF option not consistent in Sumrule_Factor");
}
return(sumrule_factor);
}
void Evaluate_F_Sumrule (string prefix, char whichDSF, const Heis_Bethe_State& AveragingState, DP Chem_Pot, int iKmin_ref, int iKmax_ref)
{
stringstream RAW_stringstream; string RAW_string;
RAW_stringstream << prefix << ".raw";
RAW_string = RAW_stringstream.str(); const char* RAW_Cstr = RAW_string.c_str();
stringstream FSR_stringstream; string FSR_string;
FSR_stringstream << prefix << ".fsr";
FSR_string = FSR_stringstream.str(); const char* FSR_Cstr = FSR_string.c_str();
ifstream infile;
infile.open(RAW_Cstr);
if(infile.fail()) ABACUSerror("Could not open raw input file in Evaluate_F_Sumrule(Heis...).");
int iKmin = 0;
int iKmax = AveragingState.chain.Nsites;
int iKmod = AveragingState.chain.Nsites;
// We run through the data file to chech the f sumrule at each positive momenta:
//Vect<DP> Sum_omega_MEsq(0.0, iKmax - iKmin + 1);
Vect<DP> Sum_omega_MEsq(0.0, iKmax - iKmin + 1);
DP omega, ME;
int iK, iKexc;
//int conv;
DP dev;
string label;
while (infile.peek() != EOF) {
infile >> omega >> iK >> ME >> dev >> label;
//if (iK >= iKmin && iK <= iKmax) Sum_omega_MEsq[iK - iKmin] += omega * ME * ME;
iKexc = iK;
while (iKexc > iKmax && iKexc - iKmod >= iKmin) iKexc -= iKmod;
while (iKexc < iKmin && iKexc + iKmod <= iKmax) iKexc += iKmod;
if (iKexc >= iKmin && iKexc <= iKmax) Sum_omega_MEsq[iKexc - iKmin] += omega * ME * ME;
}
infile.close();
ofstream outfile;
outfile.open(FSR_Cstr);
outfile.precision(16);
DP X_x = X_avg ('x', AveragingState.chain.Delta, AveragingState.chain.Nsites, AveragingState.base.Mdown);
DP X_z = X_avg ('z', AveragingState.chain.Delta, AveragingState.chain.Nsites, AveragingState.base.Mdown);
for (int i = iKmin; i <= iKmax; ++i) {
if (i > iKmin) outfile << endl;
outfile << i << "\t" << Sum_omega_MEsq[i] * S1_sumrule_factor (whichDSF, AveragingState.chain.Delta, AveragingState.chain.Nsites, AveragingState.base.Mdown, Chem_Pot, X_x, X_z, i);
}
outfile.close();
}
} // namespace ABACUS