123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249 |
- /**********************************************************
-
- 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
|