193 lines
6.0 KiB
C++
193 lines
6.0 KiB
C++
/**********************************************************
|
|
|
|
This software is part of J.-S. Caux's ABACUS library.
|
|
|
|
Copyright (c) J.-S. Caux.
|
|
|
|
-----------------------------------------------------------
|
|
|
|
File: src/ODSLF/ODSLF_Sumrules.cc
|
|
|
|
Purpose: defines sumrule factors for spinless fermions related to Heisenberg
|
|
|
|
***********************************************************/
|
|
|
|
#include "ABACUS.h"
|
|
|
|
using namespace ABACUS;
|
|
using namespace std;
|
|
|
|
namespace ABACUS {
|
|
|
|
|
|
DP ODSLF_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;
|
|
|
|
// Define the chain: J, Delta, h, Nsites
|
|
Heis_Chain chain(1.0, Delta, 0.0, N);
|
|
|
|
// Define the base: chain, Mdown
|
|
ODSLF_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
|
|
ODSLF_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
|
|
ODSLF_XXZ_Bethe_State gstate(chain, gbase);
|
|
|
|
// Compute everything about the ground state
|
|
gstate.Compute_All(true);
|
|
|
|
E0_Delta = gstate.E;
|
|
|
|
// Define the ground state
|
|
ODSLF_XXZ_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 ODSLF_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);
|
|
|
|
// 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 ODSLF_X_avg.");
|
|
|
|
return(answer);
|
|
}
|
|
|
|
DP ODSLF_S1_sumrule_factor (char mporz, DP Delta, int N, int M, int iK)
|
|
{
|
|
|
|
DP X_x = ODSLF_X_avg ('x', Delta, N, M);
|
|
DP X_z = ODSLF_X_avg ('z', Delta, N, M);
|
|
|
|
DP sumrule = 0.0;
|
|
|
|
if (mporz == 'm' || mporz == 'p')
|
|
sumrule = - 2.0 * ((1.0 - Delta * cos((twoPI * iK)/N)) * X_x + (Delta - cos((twoPI * iK)/N)) * 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 == 'a') sumrule = 1.0;
|
|
else if (mporz == 'b') sumrule = 1.0;
|
|
|
|
else ABACUSerror("option not implemented in ODSLF_S1_sumrule_factor.");
|
|
|
|
return(1.0/(sumrule + 1.0e-32)); // sumrule is 0 for iK == 0 or N
|
|
}
|
|
|
|
DP ODSLF_S1_sumrule_factor (char mporz, DP Delta, int N, DP X_x, DP X_z, int iK)
|
|
{
|
|
DP sumrule = 0.0;
|
|
|
|
if (mporz == 'm' || mporz == 'p')
|
|
sumrule = - 2.0 * ((1.0 - Delta * cos((twoPI * iK)/N)) * X_x + (Delta - cos((twoPI * iK)/N)) * X_z)/N;
|
|
|
|
else if (mporz == 'z') sumrule = -2.0 * X_x * (1.0 - cos((twoPI * iK)/N))/N;
|
|
|
|
else if (mporz == 'a') sumrule = 1.0;
|
|
else if (mporz == 'b') sumrule = 1.0;
|
|
|
|
else ABACUSerror("option not implemented in ODSLF_S1_sumrule_factor.");
|
|
|
|
return(1.0/(sumrule + 1.0e-32)); // sumrule is 0 for iK == 0 or N
|
|
}
|
|
|
|
DP Sumrule_Factor (char whichDSF, ODSLF_Bethe_State& RefState, DP Chem_Pot, int iKmin, int iKmax)
|
|
{
|
|
DP sumrule_factor = 1.0;
|
|
if (iKmin != iKmax) {
|
|
if (whichDSF == 'Z') sumrule_factor = 1.0;
|
|
else if (whichDSF == 'm')
|
|
sumrule_factor = 1.0/RefState.base.Mdown;
|
|
else if (whichDSF == 'z') sumrule_factor = 1.0/(0.25 * RefState.chain.Nsites);
|
|
else if (whichDSF == 'p') sumrule_factor = 1.0/(RefState.chain.Nsites - RefState.base.Mdown);
|
|
else if (whichDSF == 'a') sumrule_factor = 1.0;
|
|
else if (whichDSF == 'b') sumrule_factor = 1.0;
|
|
else if (whichDSF == 'q') sumrule_factor = 1.0;
|
|
|
|
else ABACUSerror("whichDSF option not consistent in Sumrule_Factor");
|
|
}
|
|
else if (iKmin == iKmax) {
|
|
if (whichDSF == 'Z') sumrule_factor = 1.0;
|
|
else if (whichDSF == 'm' || whichDSF == 'z' || whichDSF == 'p')
|
|
sumrule_factor = ODSLF_S1_sumrule_factor (whichDSF, RefState.chain.Delta, RefState.chain.Nsites,
|
|
RefState.base.Mdown, iKmax);
|
|
else if (whichDSF == 'a') sumrule_factor = 1.0;
|
|
else if (whichDSF == 'b') 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 ODSLF_Bethe_State& RefState,
|
|
DP Chem_Pot, int iKmin, int iKmax)
|
|
{
|
|
|
|
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 input file in Evaluate_F_Sumrule(ODSLF...).");
|
|
|
|
// We run through the data file to chech the f sumrule at each positive momenta:
|
|
Vect<DP> Sum_omega_FFsq(0.0, iKmax - iKmin + 1); //
|
|
|
|
DP omega, FF;
|
|
int iK, conv;
|
|
long long int base_id, type_id, id;
|
|
|
|
while (infile.peek() != EOF) {
|
|
infile >> omega >> iK >> FF >> conv >> base_id >> type_id >> id;
|
|
if (iK >= iKmin && iK <= iKmax) Sum_omega_FFsq[iK - iKmin] += omega * FF * FF;
|
|
}
|
|
|
|
infile.close();
|
|
|
|
ofstream outfile;
|
|
outfile.open(FSR_Cstr);
|
|
outfile.precision(16);
|
|
|
|
DP X_x = X_avg ('x', RefState.chain.Delta, RefState.chain.Nsites, RefState.base.Mdown);
|
|
DP X_z = X_avg ('z', RefState.chain.Delta, RefState.chain.Nsites, RefState.base.Mdown);
|
|
|
|
for (int i = iKmin; i <= iKmax; ++i) {
|
|
if (i > iKmin) outfile << endl;
|
|
outfile << i << "\t" << Sum_omega_FFsq[i] * ODSLF_S1_sumrule_factor (whichDSF, RefState.chain.Delta,
|
|
RefState.chain.Nsites, X_x, X_z, i);
|
|
}
|
|
|
|
outfile.close();
|
|
}
|
|
|
|
} // namespace ABACUS
|