250 lines
9.2 KiB
C++
250 lines
9.2 KiB
C++
/**********************************************************
|
|
|
|
This software is part of J.-S. Caux's ABACUS library.
|
|
|
|
Copyright (c) J.-S. Caux.
|
|
|
|
-----------------------------------------------------------
|
|
|
|
File: src/LIEBLIN/LiebLin_Sumrules.cc
|
|
|
|
Purpose: provides functions evaluating various sumrule factors
|
|
for Lieb-Liniger.
|
|
|
|
***********************************************************/
|
|
|
|
#include "ABACUS.h"
|
|
|
|
using namespace std;
|
|
using namespace ABACUS;
|
|
|
|
namespace ABACUS {
|
|
|
|
DP Sumrule_Factor (char whichDSF, LiebLin_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 == 'd' || whichDSF == '1') {
|
|
|
|
// Here, we use a measure decreasing in K with K^2.
|
|
// We sum up omega * MEsq/(iK^2) for all values of iKmin <= iK <= iKmax, discounting iK == 0 (where DSF vanishes)
|
|
// We therefore have (N/L) x L^{-1} x (2\pi/L)^2 x (iKmax - iKmin + 1) = 4 \pi^2 x N x (iKmax - iKmin + 1)/L^4
|
|
// Discounting iK == 0 (where DSF vanishes),
|
|
// if iKmin <= 0 && iKmax >= 0 (in which case 0 is containted in [iKmin, iKmax])
|
|
sumrule_factor = (iKmin <= 0 && iKmax >= 0) ?
|
|
(RefState.L * RefState.L * RefState.L * RefState.L)/(4.0 * PI * PI * RefState.N * (iKmax - iKmin))
|
|
: (RefState.L * RefState.L * RefState.L * RefState.L)/(4.0 * PI * PI * RefState.N * (iKmax - iKmin + 1));
|
|
}
|
|
// For the Green's function, it's the delta function \delta(x = 0) plus the density:
|
|
else if (whichDSF == 'g')
|
|
sumrule_factor = 1.0/((abs(iKmax - iKmin) + 1.0)/RefState.L + RefState.N/RefState.L);
|
|
// For the one-body function, it's just the density:
|
|
else if (whichDSF == 'o') sumrule_factor = RefState.L/RefState.N;
|
|
else if (whichDSF == 'q') sumrule_factor = 1.0;
|
|
else if (whichDSF == 'B') sumrule_factor = 1.0;
|
|
else if (whichDSF == 'C') 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 == 'd' || whichDSF == '1')
|
|
// We sum up omega * MEsq
|
|
sumrule_factor = pow(RefState.L, 4.0)/(4.0 * PI * PI * iKmax * iKmax * RefState.N);
|
|
else if (whichDSF == 'g' || whichDSF == 'o') {
|
|
// We sum up omega * MEsq
|
|
sumrule_factor = 1.0/((pow(twoPI * iKmax/RefState.L, 2.0) - Chem_Pot
|
|
+ 4.0 * RefState.c_int * RefState.N/RefState.L)/RefState.L);
|
|
}
|
|
else if (whichDSF == 'q') sumrule_factor = 1.0;
|
|
else if (whichDSF == 'B') sumrule_factor = 1.0;
|
|
else if (whichDSF == 'C') sumrule_factor = 1.0;
|
|
else ABACUSerror("whichDSF option not consistent in Sumrule_Factor");
|
|
}
|
|
|
|
return(sumrule_factor);
|
|
}
|
|
|
|
void Evaluate_F_Sumrule (char whichDSF, const LiebLin_Bethe_State& RefState, DP Chem_Pot,
|
|
int iKmin, int iKmax, const char* RAW_Cstr, const char* FSR_Cstr)
|
|
{
|
|
|
|
ifstream infile;
|
|
infile.open(RAW_Cstr);
|
|
if(infile.fail()) {
|
|
cout << "Filename RAW_Cstr = " << RAW_Cstr << endl;
|
|
ABACUSerror("Could not open input file in Evaluate_F_Sumrule(LiebLin...).");
|
|
}
|
|
|
|
// We run through the data file to check the f sumrule at each positive momenta:
|
|
Vect_DP Sum_omega_MEsq (0.0, iKmax - iKmin + 1);
|
|
Vect_DP Sum_abs_omega_MEsq (0.0, iKmax - iKmin + 1);
|
|
|
|
DP Sum_MEsq = 0.0;
|
|
|
|
DP omega, ME;
|
|
int iK;
|
|
DP dev;
|
|
string label;
|
|
int nr, nl;
|
|
|
|
int nraw = 0;
|
|
|
|
while (infile.peek() != EOF) {
|
|
nraw++;
|
|
infile >> omega >> iK >> ME >> dev >> label;
|
|
if (whichDSF == '1') infile >> nr >> nl;
|
|
if (iK >= iKmin && iK <= iKmax) Sum_omega_MEsq[iK - iKmin] += omega * ME * ME;
|
|
if (iK >= iKmin && iK <= iKmax) Sum_abs_omega_MEsq[iK - iKmin] += fabs(omega * ME * ME);
|
|
Sum_MEsq += ME * ME;
|
|
}
|
|
|
|
infile.close();
|
|
|
|
ofstream outfile;
|
|
outfile.open(FSR_Cstr);
|
|
outfile.precision(16);
|
|
|
|
if (whichDSF == 'd' || whichDSF == '1') {
|
|
|
|
for (int i = iKmin; i <= iKmax; ++i) {
|
|
|
|
if (i > iKmin) outfile << endl;
|
|
|
|
outfile << i << "\t" << Sum_omega_MEsq[i - iKmin] * pow(RefState.L, 4.0)
|
|
/(pow(2.0 * PI * ABACUS::max(abs(i), 1), 2.0) * RefState.N)
|
|
// Include average of result at +iK and -iK in a third column: iK is at index index(iK) = iK - iKmin
|
|
// so -iK is at index index(-iK) = -iK - iKmin
|
|
// We can only use this index if it is >= 0 and < iKmax - iKmin + 1, otherwise third column is copy of second:
|
|
<< "\t" << ((i + iKmin <= 0 && -i < iKmax + 1) ?
|
|
0.5 * (Sum_omega_MEsq[i - iKmin] + Sum_omega_MEsq[-i - iKmin])
|
|
: Sum_omega_MEsq[i - iKmin])
|
|
* pow(RefState.L, 4.0)/(pow(2.0 * PI * ABACUS::max(abs(i), 1), 2.0) * RefState.N);
|
|
}
|
|
}
|
|
else if (whichDSF == 'g' || whichDSF == 'o') {
|
|
for (int i = iKmin; i <= iKmax; ++i) {
|
|
if (i > iKmin) outfile << endl;
|
|
outfile << i << "\t" << Sum_omega_MEsq[i - iKmin] * RefState.L
|
|
/((4.0 * PI * PI * i * i)/(RefState.L * RefState.L) - Chem_Pot + 4.0 * RefState.c_int * RefState.N/RefState.L)
|
|
<< "\t" << ((i + iKmin <= 0 && -i < iKmax + 1) ?
|
|
0.5 * (Sum_omega_MEsq[i - iKmin] + Sum_omega_MEsq[-i - iKmin]) : Sum_omega_MEsq[i - iKmin])
|
|
* RefState.L/((4.0 * PI * PI * i * i)/(RefState.L * RefState.L) - Chem_Pot + 4.0 * RefState.c_int * RefState.N/RefState.L);
|
|
}
|
|
}
|
|
|
|
outfile.close();
|
|
|
|
}
|
|
|
|
void Evaluate_F_Sumrule (string prefix, char whichDSF, const LiebLin_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();
|
|
|
|
Evaluate_F_Sumrule (whichDSF, RefState, Chem_Pot, iKmin, iKmax, RAW_Cstr, FSR_Cstr);
|
|
|
|
}
|
|
|
|
// Using diagonal state ensemble:
|
|
void Evaluate_F_Sumrule (char whichDSF, DP c_int, DP L, int N, DP kBT, int nstates_req,
|
|
DP Chem_Pot, int iKmin, int iKmax, const char* FSR_Cstr)
|
|
{
|
|
|
|
// We run through the data file to check the f sumrule at each positive momenta:
|
|
Vect_DP Sum_omega_MEsq (0.0, iKmax - iKmin + 1);
|
|
|
|
DP Sum_MEsq = 0.0;
|
|
|
|
DP omega, ME;
|
|
int iK;
|
|
DP dev;
|
|
string label;
|
|
int nr, nl;
|
|
|
|
// Read the weights from the ensembles file:
|
|
LiebLin_Diagonal_State_Ensemble ensemble;
|
|
|
|
stringstream ensfilestrstream;
|
|
ensfilestrstream << "LiebLin_c_int_" << c_int << "_L_" << L << "_N_" << N << "_kBT_" << kBT << ".ens";
|
|
string ensfilestr = ensfilestrstream.str();
|
|
const char* ensfile_Cstr = ensfilestr.c_str();
|
|
|
|
ensemble.Load(c_int, L, N, ensfile_Cstr);
|
|
|
|
for (int ns = 0; ns < ensemble.nstates; ++ns) {
|
|
|
|
// Define the raw input file name:
|
|
stringstream filenameprefix;
|
|
Data_File_Name (filenameprefix, whichDSF, iKmin, iKmax, 0.0, ensemble.state[ns],
|
|
ensemble.state[ns], ensemble.state[ns].label);
|
|
string prefix = filenameprefix.str();
|
|
stringstream RAW_stringstream; string RAW_string;
|
|
RAW_stringstream << prefix << ".raw";
|
|
RAW_string = RAW_stringstream.str(); const char* RAW_Cstr = RAW_string.c_str();
|
|
|
|
ifstream infile;
|
|
infile.open(RAW_Cstr);
|
|
if(infile.fail()) {
|
|
cout << "Filename RAW_Cstr = " << RAW_Cstr << endl;
|
|
ABACUSerror("Could not open input file in Evaluate_F_Sumrule(LiebLin...).");
|
|
}
|
|
|
|
while (infile.peek() != EOF) {
|
|
infile >> omega >> iK >> ME >> dev >> label;
|
|
if (whichDSF == '1') infile >> nr >> nl;
|
|
if (iK >= iKmin && iK <= iKmax) Sum_omega_MEsq[iK - iKmin] += ensemble.weight[ns] * omega * ME * ME;
|
|
Sum_MEsq += ensemble.weight[ns] * ME * ME;
|
|
}
|
|
|
|
infile.close();
|
|
}
|
|
|
|
LiebLin_Bethe_State RefState = ensemble.state[0]; // to use the code below, which comes from earlier Evaluate_F_Sumrule
|
|
|
|
ofstream outfile;
|
|
outfile.open(FSR_Cstr);
|
|
outfile.precision(16);
|
|
|
|
if (whichDSF == 'd' || whichDSF == '1') {
|
|
for (int i = iKmin; i <= iKmax; ++i) {
|
|
if (i > iKmin) outfile << endl;
|
|
outfile << i << "\t" << Sum_omega_MEsq[i - iKmin] * pow(RefState.L, 4.0)
|
|
/(pow(2.0 * PI * ABACUS::max(abs(i), 1), 2.0) * RefState.N)
|
|
// Include average of result at +iK and -iK in a third column: iK is at index index(iK) = iK - iKmin
|
|
// so -iK is at index index(-iK) = -iK - iKmin
|
|
// We can only use this index if it is >= 0 and < iKmax - iKmin + 1, otherwise third column is copy of second:
|
|
<< "\t" << ((i + iKmin <= 0 && -i < iKmax + 1) ?
|
|
0.5 * (Sum_omega_MEsq[i - iKmin] + Sum_omega_MEsq[-i - iKmin])
|
|
: Sum_omega_MEsq[i - iKmin])
|
|
* pow(RefState.L, 4.0)/(pow(2.0 * PI * ABACUS::max(abs(i), 1), 2.0) * RefState.N);
|
|
}
|
|
}
|
|
else if (whichDSF == 'g' || whichDSF == 'o') {
|
|
for (int i = iKmin; i <= iKmax; ++i) {
|
|
if (i > iKmin) outfile << endl;
|
|
outfile << i << "\t" << Sum_omega_MEsq[i - iKmin] * RefState.L
|
|
/((4.0 * PI * PI * i * i)/(RefState.L * RefState.L) - Chem_Pot + 4.0 * RefState.c_int * RefState.N/RefState.L)
|
|
<< "\t" << ((i + iKmin <= 0 && -i < iKmax + 1) ?
|
|
0.5 * (Sum_omega_MEsq[i - iKmin] + Sum_omega_MEsq[-i - iKmin])
|
|
: Sum_omega_MEsq[i - iKmin]) * RefState.L
|
|
/((4.0 * PI * PI * i * i)/(RefState.L * RefState.L) - Chem_Pot + 4.0 * RefState.c_int * RefState.N/RefState.L);
|
|
}
|
|
}
|
|
|
|
outfile.close();
|
|
|
|
}
|
|
|
|
|
|
} // namespace ABACUS
|