/**************************************************************** This software is part of J.-S. Caux's C++ library. Copyright (c) J.-S. Caux. ----------------------------------------------------------- File: XXX_h0_v2.cc Purpose: Defines all class procedures used for the XXX chain in zero field. Aims at calculating the full k, omega dependence in one go. ******************************************************************/ #include "ABACUS.h" using namespace std; namespace ABACUS { DP Direct_J_integral (int Npts_p, DP req_prec, I_table Itable) { stringstream outfile_stringstream; string outfile_string; outfile_stringstream << "SF_4p_Np_" << Npts_p << "_prec_" << req_prec << ".raw"; outfile_string = outfile_stringstream.str(); const char* outfile_Cstr = outfile_string.c_str(); ofstream outfile; outfile.open(outfile_Cstr); outfile.precision(16); stringstream src_stringstream; string src_string; src_stringstream << "SF_4p_Np_" << Npts_p << "_prec_" << req_prec << ".src"; src_string = src_stringstream.str(); const char* src_Cstr = src_string.c_str(); ofstream srcfile; srcfile.open(src_Cstr); srcfile.precision(16); Vect_DP p(4); DP J_fn_cont = 0.0; DP sum_J_fn = 0.0; for (int ip0 = 0; ip0 < Npts_p; ++ip0) { p[0] = - (ip0 + 0.5) * PI/Npts_p; for (int ip1 = ip0 + 1; ip1 < Npts_p; ++ip1) { p[1] = - (ip1 + 0.5) * PI/Npts_p; for (int ip2 = ip1 + 1; ip2 < Npts_p; ++ip2) { p[2] = - (ip2 + 0.5) * PI/Npts_p; for (int ip3 = ip2 + 1; ip3 < Npts_p; ++ip3) { p[3] = - (ip3 + 0.5) * PI/Npts_p; J_fn_cont = J_fn (p, req_prec, Itable); sum_J_fn += J_fn_cont; if (p[0] > 0 || p[1] > 1 || p[2] > 2 || p[3] > 3) outfile << endl; outfile << p << "\t" << J_fn_cont; } } } } DP integral_J = Compute_C4 (req_prec) * 24.0 * sum_J_fn * pow(PI/Npts_p, 4.0); // 24: from using ordered p's srcfile << integral_J << "\t" << integral_J/(4.0 * PI * PI) << "\t" << integral_J/(PI * PI) << endl; outfile.close(); srcfile.close(); return(integral_J); } void Smoothen_raw_SF_4p (int Npts_p, int Npts_o, DP req_prec, DP width) { stringstream rawfile_stringstream; string rawfile_string; rawfile_stringstream << "SF_4p_Np_" << Npts_p << "_No_" << Npts_o << "_prec_" << req_prec << ".raw"; rawfile_string = rawfile_stringstream.str(); const char* rawfile_Cstr = rawfile_string.c_str(); ifstream rawfile; rawfile.open(rawfile_Cstr); stringstream smfile_stringstream; string smfile_string; smfile_stringstream << "SF_4p_Np_" << Npts_p << "_No_" << Npts_o << "_prec_" << req_prec << "_w_" << width << ".dat"; smfile_string = smfile_stringstream.str(); const char* smfile_Cstr = smfile_string.c_str(); ofstream smfile; smfile.open(smfile_Cstr); smfile.precision(16); DP* SF_4p_raw = new DP[(Npts_p + 1) * Npts_o]; DP* SF_4p_sm = new DP[(Npts_p + 1) * Npts_o]; for (int iw = 0; iw < Npts_o; ++iw) for (int ik = 0; ik <= Npts_p; ++ik) rawfile >> SF_4p_raw[Npts_o * ik + iw]; rawfile.close(); // We now broaden to a Gaussian: int iw_half_window = int(width/(2.0 * PI/Npts_o)); if (iw_half_window == 0) ABACUSerror("width too small in Smoothen_raw_SF_4p"); int iwstart, iwstop; DP domega_sq_over_width_sq = pow(2.0 * PI/(Npts_o * width), 2.0); DP exp_factor; for (int iw = 0; iw < Npts_o; ++iw) { iwstart = ABACUS::max(0, iw - 10 * iw_half_window); iwstop = ABACUS::min(Npts_o, iw + 10 * iw_half_window); for (int iwraw = iwstart; iwraw <= iwstop; ++iwraw) { exp_factor = exp(-(iwraw - iw) * (iwraw - iw) * domega_sq_over_width_sq); for (int ik = 0; ik <= Npts_p; ++ik) { SF_4p_sm[Npts_o * ik + iw] += SF_4p_raw[Npts_o * ik + iwraw] * exp_factor; } } } // Reset normalization from delta function and output data DP prefactor = 1.0/(sqrt(PI) * width); for (int iw = 0; iw < Npts_o; ++iw) { for (int ik = 0; ik <= Npts_p; ++ik) smfile << SF_4p_sm[Npts_o * ik + iw] * prefactor << "\t"; smfile << endl; } smfile.close(); } DP Direct_J_integral_bin (int Npts_p, int Npts_o, DP req_prec, I_table Itable) { // Produces binned file for J stringstream rawfile_stringstream; string rawfile_string; rawfile_stringstream << "SF_4p_Np_" << Npts_p << "_No_" << Npts_o << "_prec_" << req_prec << ".raw"; rawfile_string = rawfile_stringstream.str(); const char* rawfile_Cstr = rawfile_string.c_str(); ofstream rawfile; rawfile.open(rawfile_Cstr); rawfile.precision(16); stringstream src_stringstream; string src_string; src_stringstream << "SF_4p_Np_" << Npts_p << "_No_" << Npts_o << "_prec_" << req_prec << ".src"; src_string = src_stringstream.str(); const char* src_Cstr = src_string.c_str(); ofstream srcfile; srcfile.open(src_Cstr); srcfile.precision(16); Vect_DP p(4); DP J_fn_cont = 0.0; DP sum_J_fn = 0.0; DP* SF_4p_raw = new DP[(Npts_p + 1) * Npts_o]; // labelling: index is Npts_o * ik + iomega DP omegamax = 2.0 * PI; Write_K_File (Npts_p, 0, Npts_p); Write_Omega_File (Npts_o, 0.0, omegamax); int ik; DP omega; int iomega; DP sinp0, sinp1, sinp2; for (int ip0 = 0; ip0 < Npts_p; ++ip0) { p[0] = - (ip0 + 0.5) * PI/Npts_p; sinp0 = sin(p[0]); for (int ip1 = ip0 + 1; ip1 < Npts_p; ++ip1) { p[1] = - (ip1 + 0.5) * PI/Npts_p; sinp1 = sin(p[1]); for (int ip2 = ip1 + 1; ip2 < Npts_p; ++ip2) { p[2] = - (ip2 + 0.5) * PI/Npts_p; sinp2 = sin(p[2]); for (int ip3 = ip2 + 1; ip3 < Npts_p; ++ip3) { p[3] = - (ip3 + 0.5) * PI/Npts_p; ik = ip0 + ip1 + ip2 + ip3; if (ik > 2 * Npts_p) ik -= 2*Npts_p; // guarantees 0 <= ik < 2Npts if (ik <= Npts_p) { omega = -0.5 * PI * (sinp0 + sinp1 + sinp2 + sin(p[3])); iomega = int(omega * Npts_o/omegamax); J_fn_cont = J_fn (p, req_prec, Itable); sum_J_fn += (ik == Npts_p ? 1.0 : 2.0) * J_fn_cont; SF_4p_raw[Npts_o * ik + iomega] += J_fn_cont; } } } } } DP prefactor = Compute_C4 (req_prec) * 24.0 * pow(PI/Npts_p, 4.0); // 24: from using ordered p's DP integral_J = prefactor * sum_J_fn; // Output raw file for (int iw = 0; iw < Npts_o; ++iw) { for (int iK = 0; iK <= Npts_p; ++iK) rawfile << prefactor * SF_4p_raw[Npts_o * iK + iw] << "\t"; rawfile << endl; } srcfile << integral_J << "\t" << integral_J/(4.0 * PI * PI) << "\t" << integral_J/(PI * PI) << endl; rawfile.close(); srcfile.close(); delete[] SF_4p_raw; return(integral_J); } } // namespace ABACUS