/********************************************************** 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, bool fixed_iK, int iKneeded) DP Sumrule_Factor (char whichDSF, LiebLin_Bethe_State& RefState, 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 == '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)); /* // Measure using the g2(0) + delta function: // DOES NOT WORK VERY WELL DP dE0_dc = LiebLin_dE0_dc (RefState.c_int, RefState.L, RefState.N); //sumrule_factor = 1.0/((dE0_dc + (2.0 * RefState.Tableau[0].Ncols + 1.0)*RefState.N/RefState.L)/RefState.L); // Assume that iKmin == 0 here: //sumrule_factor = 1.0/((dE0_dc + (2*iKmax + 1)*RefState.N/RefState.L)/RefState.L); // For iKmin != 0: sumrule_factor = 1.0/((dE0_dc + (iKmax - iKmin + 1)*RefState.N/RefState.L)/RefState.L); */ } // For the Green's function, it's the delta function \delta(x = 0) plus the density: //else if (whichDSF == 'g') sumrule_factor = 1.0/((2.0 * RefState.Tableau[0].Ncols + 1.0)/RefState.L + RefState.N/RefState.L); // Assume that iKmin == 0 here: //else if (whichDSF == 'g') sumrule_factor = 1.0/(2.0* iKmax + 1.0)/RefState.L + RefState.N/RefState.L); else if (whichDSF == 'g') sumrule_factor = 1.0/((abs(iKmax - iKmin) + 1.0)/RefState.L + RefState.N/RefState.L); //sumrule_factor = 1.0/((pow(twoPI * iKmax/RefState.L, 2.0) - Chem_Pot + 4.0 * RefState.c_int * RefState.N/RefState.L)/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 (fixed_iK) { else if (iKmin == iKmax) { if (whichDSF == 'Z') sumrule_factor = 1.0; else if (whichDSF == 'd' || whichDSF == '1') //// We sum up omega * MEsq/(iK^2): this should give (1/L) x (N/L) x k^2 = N x (2\pi)^2/L^4 //sumrule_factor = pow(RefState.L, 4.0)/(4.0 * PI * PI * RefState.N); // We sum up omega * MEsq //sumrule_factor = pow(RefState.L, 4.0)/(4.0 * PI * PI * iKneeded * iKneeded * RefState.N); 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 * iKneeded/RefState.L, 2.0) - Chem_Pot + 4.0 * RefState.c_int * RefState.N/RefState.L)/RefState.L); 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 == '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"); } 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: //int iK_UL = RefState.Tableau[0].Ncols; // this is iK_UL //Vect Sum_omega_MEsq(0.0, iK_UL + 1); 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; //int conv; 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 > 0 && iK <= iK_UL) Sum_omega_MEsq[iK] += omega * MEsq; 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(); //cout << "Read " << nraw << " entries in raw file." << endl; ofstream outfile; outfile.open(FSR_Cstr); outfile.precision(16); if (whichDSF == 'd' || whichDSF == '1') { /* outfile << 0 << "\t" << 1; // full saturation at k = 0 ! for (int i = 1; i <= iK_UL; ++i) outfile << endl << i << "\t" << Sum_omega_MEsq[i] * RefState.L * RefState.L * RefState.L * RefState.L/(4.0 * PI * PI * i * i * RefState.N); */ 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); 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 = 0; i <= iK_UL; ++i) outfile << endl << i << "\t" << Sum_omega_MEsq[i] * RefState.L /((4.0 * PI * PI * i * i)/(RefState.L * RefState.L) - Chem_Pot + 4.0 * RefState.c_int * RefState.N/RefState.L); //cout << "Sum_MEsq = " << Sum_MEsq << "\tN/L = " << RefState.N/RefState.L << endl; */ 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); 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; //int conv; 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 << "_ns_" << nstates_req << ".ens"; 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, kBT, ensemble.state[ns], ensemble.state[ns], ensemble.state[ns].label); 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 > 0 && iK <= iK_UL) Sum_omega_MEsq[iK] += omega * MEsq; 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') { /* outfile << 0 << "\t" << 1; // full saturation at k = 0 ! for (int i = 1; i <= iK_UL; ++i) outfile << endl << i << "\t" << Sum_omega_MEsq[i] * RefState.L * RefState.L * RefState.L * RefState.L/(4.0 * PI * PI * i * i * RefState.N); */ 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); 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 = 0; i <= iK_UL; ++i) outfile << endl << i << "\t" << Sum_omega_MEsq[i] * RefState.L /((4.0 * PI * PI * i * i)/(RefState.L * RefState.L) - Chem_Pot + 4.0 * RefState.c_int * RefState.N/RefState.L); //cout << "Sum_MEsq = " << Sum_MEsq << "\tN/L = " << RefState.N/RefState.L << endl; */ 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); 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