/********************************************************** This software is part of J.-S. Caux's ABACUS library. Copyright (c). ----------------------------------------------------------- File: LiebLin_Fourier_to_Qsqx.cc Purpose: Compute the Q(x)^2 expectation value for LiebLin, where Q(x) = \int_0^x dx \rho(x). ***********************************************************/ #include "JSC.h" using namespace std; using namespace JSC; int main(int argc, char* argv[]) { if (argc != 9) { // provide some info cout << endl << "Welcome to ABACUS++\t(copyright J.-S. Caux)." << endl; cout << endl << "Usage of LiebLin_Fourier_to_Qsqx executable: " << endl; cout << endl << "Provide the following arguments:" << endl << endl; cout << "char whichDSF \t\t Which structure factor ? Options are: d for rho rho, g for psi psi{dagger}, o for psi{dagger} psi" << endl; cout << "DP c_int \t\t Value of the interaction parameter" << endl; cout << "DP L \t\t\t Length of the system" << endl; cout << "int N \t\t\t Number of particles" << endl; cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers scanned over" << endl; cout << "DP kBT \t\t Temperature" << endl; cout << "int Npts_x Number of points in space for the Fourier transform" << endl; } else { // (argc == 9), correct nr of arguments char whichDSF = *argv[1]; DP c_int = atof(argv[2]); DP L = atof(argv[3]); int N = atoi(argv[4]); int iKmin = atoi(argv[5]); int iKmax = atoi(argv[6]); DP kBT = atof(argv[7]); int Npts_x = atoi(argv[8]); // Force Npts_x //Npts_x = L; if (whichDSF != 'd') JSCerror("Must use whichDSF == d in LiebLin_Fourier_ssf_to_Qsqx"); stringstream filenameprefix; Data_File_Name (filenameprefix, whichDSF, c_int, L, N, iKmin, iKmax, kBT, 0.0, ""); 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 RAW_infile; RAW_infile.open(RAW_Cstr); if (RAW_infile.fail()) { cout << RAW_Cstr << endl; JSCerror("Could not open RAW_infile... "); } // We also read the f-sumrule file, to correct for missing intensity. stringstream FSR_stringstream; string FSR_string; FSR_stringstream << prefix << ".fsr"; FSR_string = FSR_stringstream.str(); const char* FSR_Cstr = FSR_string.c_str(); ifstream FSR_infile; FSR_infile.open(FSR_Cstr); if (FSR_infile.fail()) { cout << FSR_Cstr << endl; JSCerror("Could not open FSR_infile... "); } stringstream SFT_stringstream; string SFT_string; SFT_stringstream << prefix << ".Qsqx"; SFT_string = SFT_stringstream.str(); const char* SFT_Cstr = SFT_string.c_str(); ofstream SFT_outfile; SFT_outfile.open(SFT_Cstr); if (SFT_outfile.fail()) JSCerror("Could not open SFT_outfile... "); // First compute the static structure factor from the RAW data: Vect_DP SSF(0.0, iKmax - iKmin + 1); DP omega; int iK; DP FF; //int conv; DP dev; string label; while (RAW_infile.peek() != EOF) { RAW_infile >> omega >> iK >> FF >> dev >> label; if (iK >= iKmin && iK <= iKmax) { SSF[iK - iKmin] += FF * FF; } } RAW_infile.close(); // Reset proper normalization: DP normalization = twoPI * L; for (int iK = 0; iK < iKmax - iKmin + 1; ++iK) SSF[iK] *= normalization/twoPI; // twoPI from integral over omega // Now define real-space coordinates: between 0 and L/2 Vect_DP xlattice(Npts_x); for (int i = 0; i < Npts_x; ++i) xlattice[i] = (i + 0.5) * 0.5* L/Npts_x; // Now the correlation at x: Vect_DP FT(0.0, Npts_x); DP pioverL = PI/L; // Fourier transform: for (int ix = 0; ix < Npts_x; ++ix) { for (int iK = 1; iK <= iKmax; ++iK) { FT[ix] += SSF[iK - iKmin] * pow(sin(pioverL * iK * xlattice[ix])/iK, 2.0); } // Reset proper normalization: 1/L from space FT, FT[ix] *= 2.0*L/(PI * PI); // Outside of window iKmin, iKmax, we take the DSF to be a constant with delta function // at free energy k^2, so DSF = 2\pi N/L \delta(\omega - k^2) (to fit f-sumrule) // so SSF becomes N/L. // We thus need to correct above by adding // \frac{1}{L} \sum_{-\infty}^{iKmin - 1} SSF e^{ikx} + \frac{1}{L} \sum_{iKmax + 1}^\infty SSF e^{ikx} // Resumming carefully: //FTre[ix] += (sin(twopioverL * (iKmin - 0.5) * xlattice[ix]) - sin(twopioverL * (iKmax + 0.5) * xlattice[ix])) //* N/(2.0 * L*L * sin(PI * xlattice[ix]/L)); //FTim[ix] += (-cos(twopioverL * (iKmin - 0.5) * xlattice[ix]) + cos(twopioverL * (iKmax + 0.5) * xlattice[ix])) //* N/(2.0 * L*L * sin(PI * xlattice[ix]/L)); } // Output to file: for (int ix = 0; ix < Npts_x; ++ix) { if (ix > 0) SFT_outfile << endl; //SFT_outfile << xlattice[ix] << "\t" << FTre[ix] << "\t" << FTim[ix] << "\t" << FTreavg[ix] << "\t" << FTimavg[ix]; SFT_outfile << xlattice[ix]/L << "\t" << FT[ix]; } SFT_outfile.close(); } return(0); }