ABACUS/src/XXX_VOA/XXX_h0_v2.cc

233 lines
6.6 KiB
C++
Executable File

/****************************************************************
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;
Heis_Write_K_File (Npts_p);
Heis_Write_w_File (Npts_o, 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