ABACUS/src/SCAN/General_Scan_Parallel.cc

699 lines
25 KiB
C++

/**********************************************************
This software is part of J.-S. Caux's ABACUS library.
Copyright (c) J.-S. Caux.
-----------------------------------------------------------
File: src/SCAN/General_Scan_Parallel.cc
Purpose: universal implementation of state scanning:
functions to descend down hierarchy of intermediate states.
Parallel implementation using MPI.
NOTE: since templated functions have to be in the same file,
we put all scanning functions here. The externally-used
functions are defined at the end of this file.
***********************************************************/
//#include "mpi.h"
#include "ABACUS.h"
using namespace std;
using namespace ABACUS;
namespace ABACUS {
//*******************************************************************//
// Functions applicable to all calculations:
void Split_thr_Files (string prefix, char whichDSF, int nr_processors_at_newlevel)
{
// From an existing threads file directory, this produces nr_processors_at_newlevel thread file directories
// containing distributed threads.
stringstream THRDIR_stringstream; string THRDIR_string;
THRDIR_stringstream << prefix << "_thrdir";
THRDIR_string = THRDIR_stringstream.str();
// Load all the info about the threads, in particular the nthreads_total vector:
Scan_Thread_Data thr_data(THRDIR_string, true);
thr_data.Load();
// Create the different directories:
Vect<stringstream> THRDIRS_stringstream(nr_processors_at_newlevel);
for (int rank = 0; rank < nr_processors_at_newlevel; ++rank) {
THRDIRS_stringstream[rank] << prefix << "_" << rank << "_" << nr_processors_at_newlevel << "_thrdir";
mkdir((THRDIRS_stringstream[rank].str()).c_str(), S_IRWXU | S_IRWXG | S_IRWXO);
}
Vect<Scan_Thread_Data> thr_data_par(nr_processors_at_newlevel);
for (int rank = 0; rank < nr_processors_at_newlevel; ++rank)
thr_data_par[rank] = Scan_Thread_Data (THRDIRS_stringstream[rank].str(), false);
// put refine == false here to avoid loading any deprecated data
// Transfer all the existing threads into the new ones:
int rankindex = 0;
int il;
while ((il = thr_data.lowest_il_with_nthreads_neq_0) < thr_data.nlists) {
Vect<Scan_Thread> next_threads = thr_data.Extract_Next_Scan_Threads();
for (int it = 0; it < next_threads.size(); ++it) {
thr_data_par[rankindex++].Include_Thread (il, next_threads[it].label, next_threads[it].type);
rankindex = rankindex % nr_processors_at_newlevel;
}
if (il == thr_data.nlists - 1) break;
// Flush data to disk to preserve memory
for (int rank = 0; rank < nr_processors_at_newlevel; ++rank)
thr_data_par[rank].Flush_to_Disk(il);
}
// thr_data is now empty
thr_data.Save();
// remove the nthreads.dat file from original threads directory:
stringstream datfile_strstream;
datfile_strstream << THRDIR_string << "/nthreads.dat";
string datfilename = datfile_strstream.str();
remove(datfilename.c_str());
// Save the threads in the new directories:
for (int rank = 0; rank < nr_processors_at_newlevel; ++rank) thr_data_par[rank].Save();
return;
}
void Merge_raw_Files (string prefix, char whichDSF, int nr_processors_at_newlevel)
{
// Open the original raw file:
stringstream RAW_stringstream; string RAW_string;
RAW_stringstream << prefix << ".raw";
RAW_string = RAW_stringstream.str(); const char* RAW_Cstr = RAW_string.c_str();
fstream RAW_outfile;
RAW_outfile.open(RAW_Cstr, fstream::out | fstream::app); // NB: we append !!
if (RAW_outfile.fail()) ABACUSerror("Could not open RAW_outfile... ");
RAW_outfile.precision(16);
// Append all other raw files to original one
for (int rank = 0; rank < nr_processors_at_newlevel; ++rank) {
stringstream RAW_in_stringstream; string RAW_in_string;
RAW_in_stringstream << prefix << "_" << rank << "_" << nr_processors_at_newlevel << ".raw";
RAW_in_string = RAW_in_stringstream.str(); const char* RAW_in_Cstr = RAW_in_string.c_str();
ifstream RAW_infile;
RAW_infile.open(RAW_in_Cstr);
if (RAW_infile.fail()) {
continue; // if file isn't there, just continue...
}
DP omega;
int iK;
DP FF;
DP dev;
string label;
int nr, nl;
while (RAW_infile.peek() != EOF) {
RAW_infile >> omega >> iK >> FF >> dev >> label;
if (whichDSF == '1') RAW_infile >> nr >> nl;
RAW_outfile << endl << omega << "\t" << iK << "\t" << FF << "\t" << dev << "\t" << label;
if (whichDSF == '1') RAW_outfile << "\t" << nr << "\t" << nl;
}
RAW_infile.close();
// Delete file
remove(RAW_in_Cstr);
} // for rank
RAW_outfile.close();
return;
}
void Merge_thr_Files (string prefix, char whichDSF, int nr_processors_at_newlevel)
{
stringstream THRDIR_stringstream; string THRDIR_string;
THRDIR_stringstream << prefix << "_thrdir";
THRDIR_string = THRDIR_stringstream.str();
Scan_Thread_Data thr_data(THRDIR_string, true);
Vect<stringstream> THRDIRS_stringstream(nr_processors_at_newlevel);
for (int rank = 0; rank < nr_processors_at_newlevel; ++rank)
THRDIRS_stringstream[rank] << prefix << "_" << rank << "_" << nr_processors_at_newlevel << "_thrdir";
Vect<Scan_Thread_Data> thr_data_par(nr_processors_at_newlevel);
for (int rank = 0; rank < nr_processors_at_newlevel; ++rank) {
thr_data_par[rank] = Scan_Thread_Data (THRDIRS_stringstream[rank].str(), true);
thr_data_par[rank].Load();
}
// Transfer from all the existing threads into the base one:
int il;
for (int rank = 0; rank < nr_processors_at_newlevel; ++rank) {
while ((il = thr_data_par[rank].lowest_il_with_nthreads_neq_0) < thr_data_par[rank].nlists) {
Vect<Scan_Thread> next_threads = thr_data_par[rank].Extract_Next_Scan_Threads();
for (int it = 0; it < next_threads.size(); ++it) {
thr_data.Include_Thread (il, next_threads[it].label, next_threads[it].type);
}
if (il == thr_data_par[rank].nlists - 1) break;
}
}
// all thr_data_par are now empty
// remove the nthreads.dat files from original threads directory:
for (int rank = 0; rank < nr_processors_at_newlevel; ++rank) {
stringstream datfile_strstream;
datfile_strstream << THRDIRS_stringstream[rank].str() << "/nthreads.dat";
string datfilename = datfile_strstream.str();
remove(datfilename.c_str());
rmdir((THRDIRS_stringstream[rank].str()).c_str());
}
thr_data.Save();
return;
}
template<class Tstate>
void Merge_sum_Files (Tstate& SeedScanState, string prefix, char whichDSF, int nr_processors_at_newlevel)
{
Scan_State_List<Tstate> ScanStateList (whichDSF, SeedScanState);
ScanStateList.Populate_List(whichDSF, SeedScanState);
// Open the original file:
stringstream SUM_stringstream; string SUM_string;
SUM_stringstream << prefix << ".sum";
SUM_string = SUM_stringstream.str(); const char* SUM_Cstr = SUM_string.c_str();
// Load the original info:
if (file_exists(SUM_Cstr)) ScanStateList.Load_Info (SUM_Cstr); // Needed again!
// Load all other info:
for (int rank = 0; rank < nr_processors_at_newlevel; ++rank) {
stringstream SUM_in_stringstream; string SUM_in_string;
SUM_in_stringstream << prefix << "_" << rank << "_" << nr_processors_at_newlevel << ".sum";
SUM_in_string = SUM_in_stringstream.str(); const char* SUM_in_Cstr = SUM_in_string.c_str();
if (!file_exists(SUM_in_Cstr)) continue;
ScanStateList.Load_Info (SUM_in_Cstr);
// Delete file
remove(SUM_in_Cstr);
} // for rank
// Save the result in original sum file:
ScanStateList.Order_in_SRC ();
ScanStateList.Save_Info(SUM_Cstr);
return;
}
void Merge_inadm_conv0_src_stat_log_Files (string prefix, char whichDSF, int nr_processors_at_newlevel)
{
// This also deletes any .fsr files at the newlevel.
// Open the original src file:
stringstream SRC_stringstream; string SRC_string;
SRC_stringstream << prefix << ".src";
SRC_string = SRC_stringstream.str(); const char* SRC_Cstr = SRC_string.c_str();
// Load original info:
Scan_Info scan_info;
// If file is there, load it:
if (file_exists(SRC_Cstr)) scan_info.Load(SRC_Cstr);
Scan_Info scan_info_before = scan_info;
// Load all other info:
for (int rank = 0; rank < nr_processors_at_newlevel; ++rank) {
stringstream SRC_in_stringstream; string SRC_in_string;
SRC_in_stringstream << prefix << "_" << rank << "_" << nr_processors_at_newlevel << ".src";
SRC_in_string = SRC_in_stringstream.str(); const char* SRC_in_Cstr = SRC_in_string.c_str();
if (!file_exists(SRC_in_Cstr)) continue;
Scan_Info scan_info_in;
scan_info_in.Load (SRC_in_Cstr);
scan_info += scan_info_in;
// Delete file
remove(SRC_in_Cstr);
} // for rank
// Save the result in original src file:
scan_info.Save(SRC_Cstr);
// Load content of all other inadm files into main inadm:
stringstream INADM_stringstream; string INADM_string;
INADM_stringstream << prefix << ".inadm";
INADM_string = INADM_stringstream.str(); const char* INADM_Cstr = INADM_string.c_str();
ofstream INADM_outfile;
INADM_outfile.open(INADM_Cstr, fstream::out | fstream::app);
if (INADM_outfile.fail()) ABACUSerror("Could not open INADM_outfile... ");
INADM_outfile.precision(16);
for (int rank = 0; rank < nr_processors_at_newlevel; ++rank) {
stringstream INADM_in_stringstream; string INADM_in_string;
INADM_in_stringstream << prefix << "_" << rank << "_" << nr_processors_at_newlevel << ".inadm";
INADM_in_string = INADM_in_stringstream.str(); const char* INADM_in_Cstr = INADM_in_string.c_str();
if (!file_exists(INADM_in_Cstr)) continue;
ifstream INADM_infile;
INADM_infile.open(INADM_in_Cstr);
string line;
string linerej;
while (INADM_infile.good() ) {
getline (INADM_infile, line);
if (line.compare("") != 0) INADM_outfile << line << endl;
}
INADM_infile.close();
// Delete file
remove(INADM_in_Cstr);
} // for rank
INADM_outfile.close();
// Load content of all other conv0 files into main inadm:
stringstream CONV0_stringstream; string CONV0_string;
CONV0_stringstream << prefix << ".conv0";
CONV0_string = CONV0_stringstream.str(); const char* CONV0_Cstr = CONV0_string.c_str();
ofstream CONV0_outfile;
CONV0_outfile.open(CONV0_Cstr, fstream::out | fstream::app);
if (CONV0_outfile.fail()) ABACUSerror("Could not open CONV0_outfile... ");
CONV0_outfile.precision(16);
for (int rank = 0; rank < nr_processors_at_newlevel; ++rank) {
stringstream CONV0_in_stringstream; string CONV0_in_string;
CONV0_in_stringstream << prefix << "_" << rank << "_" << nr_processors_at_newlevel << ".conv0";
CONV0_in_string = CONV0_in_stringstream.str(); const char* CONV0_in_Cstr = CONV0_in_string.c_str();
if (!file_exists(CONV0_in_Cstr)) continue;
ifstream CONV0_infile;
CONV0_infile.open(CONV0_in_Cstr);
string line;
string linerej;
while (CONV0_infile.good() ) {
getline (CONV0_infile, line);
if (line.compare("") != 0) CONV0_outfile << line << endl;
}
CONV0_infile.close();
// Delete file
remove(CONV0_in_Cstr);
} // for rank
CONV0_outfile.close();
// Load content of all other stat files into main:
stringstream STAT_stringstream; string STAT_string;
STAT_stringstream << prefix << ".stat";
STAT_string = STAT_stringstream.str(); const char* STAT_Cstr = STAT_string.c_str();
ofstream STAT_outfile;
STAT_outfile.open(STAT_Cstr, fstream::out | fstream::app);
if (STAT_outfile.fail()) ABACUSerror("Could not open STAT_outfile... ");
STAT_outfile.precision(16);
for (int rank = 0; rank < nr_processors_at_newlevel; ++rank) {
stringstream STAT_in_stringstream; string STAT_in_string;
STAT_in_stringstream << prefix << "_" << rank << "_" << nr_processors_at_newlevel << ".stat";
STAT_in_string = STAT_in_stringstream.str(); const char* STAT_in_Cstr = STAT_in_string.c_str();
if (!file_exists(STAT_in_Cstr)) continue;
ifstream STAT_infile;
STAT_infile.open(STAT_in_Cstr);
string line;
string linerej;
while (STAT_infile.good() ) {
getline (STAT_infile, line);
if (line.compare("") != 0) STAT_outfile << line << endl;
}
STAT_infile.close();
// Delete file
remove(STAT_in_Cstr);
} // for rank
STAT_outfile.close();
// Put some digested info in log file:
Scan_Info scan_info_refinement;
scan_info_refinement = scan_info;
scan_info_refinement -= scan_info_before;
stringstream LOG_stringstream; string LOG_string;
LOG_stringstream << prefix << ".log";
LOG_string = LOG_stringstream.str(); const char* LOG_Cstr = LOG_string.c_str();
ofstream LOG_outfile;
LOG_outfile.open(LOG_Cstr, fstream::out | fstream::app);
if (LOG_outfile.fail()) ABACUSerror("Could not open LOG_outfile... ");
LOG_outfile.precision(16);
// Load content of all other log files into main log:
for (int rank = 0; rank < nr_processors_at_newlevel; ++rank) {
stringstream LOG_in_stringstream; string LOG_in_string;
LOG_in_stringstream << prefix << "_" << rank << "_" << nr_processors_at_newlevel << ".log";
LOG_in_string = LOG_in_stringstream.str(); const char* LOG_in_Cstr = LOG_in_string.c_str();
if (!file_exists(LOG_in_Cstr)) continue;
ifstream LOG_infile;
LOG_infile.open(LOG_in_Cstr);
string line;
while (LOG_infile.good() ) {
getline (LOG_infile, line);
LOG_outfile << line << endl;
}
LOG_infile.close();
// Delete file
remove(LOG_in_Cstr);
} // for rank
// Now remove the .fsr files at the newlevel:
for (int rank = 0; rank < nr_processors_at_newlevel; ++rank) {
stringstream FSR_in_stringstream; string FSR_in_string;
FSR_in_stringstream << prefix << "_" << rank << "_" << nr_processors_at_newlevel << ".fsr";
FSR_in_string = FSR_in_stringstream.str(); const char* FSR_in_Cstr = FSR_in_string.c_str();
// Delete file
remove(FSR_in_Cstr);
}
LOG_outfile << "Refining in parallel mode using " << nr_processors_at_newlevel << " processors."
<< endl << "Refining info: " << scan_info_refinement
<< endl << "Resulting info: " << scan_info << endl;
LOG_outfile << "ABACUS version " << ABACUS_VERSION << ", copyright J.-S. Caux." << endl;
LOG_outfile.close();
return;
}
//****************************************************************************//
// Model-specific functions:
void Prepare_Parallel_Scan_LiebLin (char whichDSF, DP c_int, DP L, int N, int iKmin, int iKmax, DP kBT,
string defaultScanStatename, int paralevel, Vect<int> rank_lower_paralevels,
Vect<int> nr_processors_lower_paralevels, int nr_processors_at_newlevel)
{
// From an existing scan, this function splits the threads into
// nr_processors_at_newlevel separate files, from which the parallel process
// can be launched.
LiebLin_Bethe_State GroundState (c_int, L, N);
// Define file name
stringstream filenameprefix;
Data_File_Name (filenameprefix, whichDSF, iKmin, iKmax, kBT, GroundState, GroundState, defaultScanStatename);
for (int i = 0; i < paralevel - 1; ++i) filenameprefix << "_" << rank_lower_paralevels[i] << "_" << nr_processors_lower_paralevels[i];
string prefix = filenameprefix.str();
Split_thr_Files (prefix, whichDSF, nr_processors_at_newlevel);
return;
}
void Wrapup_Parallel_Scan_LiebLin (char whichDSF, DP c_int, DP L, int N, int iKmin, int iKmax, DP kBT,
string defaultScanStatename, int paralevel, Vect<int> rank_lower_paralevels,
Vect<int> nr_processors_lower_paralevels, int nr_processors_at_newlevel)
{
// Read the saddle-point state from the sps file:
stringstream SPS_stringstream; string SPS_string;
Data_File_Name (SPS_stringstream, whichDSF, c_int, L, N, iKmin, iKmax, kBT, 0.0, "");
SPS_stringstream << ".sps";
SPS_string = SPS_stringstream.str(); const char* SPS_Cstr = SPS_string.c_str();
LiebLin_Bethe_State spstate;
if (file_exists(SPS_Cstr)) {
fstream spsfile;
spsfile.open(SPS_Cstr, fstream::in);
int Nspsread;
spsfile >> Nspsread;
if (Nspsread != N) {
cout << Nspsread << "\t" << N << endl;
ABACUSerror("Wrong number of Ix2 in saddle-point state.");
}
spstate = LiebLin_Bethe_State (c_int, L, N);
for (int i = 0; i < N; ++i) spsfile >> spstate.Ix2[i];
spsfile.close();
spstate.Compute_All(true);
}
else spstate = Canonical_Saddle_Point_State (c_int, L, N, kBT);
int Nscan = N;
if (whichDSF == 'o') Nscan = N - 1;
if (whichDSF == 'g') Nscan = N + 1;
LiebLin_Bethe_State SeedScanState = spstate;
if (whichDSF == 'o' || whichDSF == 'g') SeedScanState = Canonical_Saddle_Point_State (c_int, L, Nscan, kBT);
// Define file name
stringstream filenameprefix;
Data_File_Name (filenameprefix, whichDSF, iKmin, iKmax, kBT, spstate, SeedScanState, defaultScanStatename);
for (int i = 0; i < paralevel - 1; ++i)
filenameprefix << "_" << rank_lower_paralevels[i] << "_" << nr_processors_lower_paralevels[i];
string prefix = filenameprefix.str();
// Merge raw files
Merge_raw_Files (prefix, whichDSF, nr_processors_at_newlevel);
// Merge thr files
Merge_thr_Files (prefix, whichDSF, nr_processors_at_newlevel);
// Merge sum files
Merge_sum_Files (SeedScanState, prefix, whichDSF, nr_processors_at_newlevel);
// Merge src files
Merge_inadm_conv0_src_stat_log_Files (prefix, whichDSF, nr_processors_at_newlevel);
// This also puts some digested info in log file.
DP Chem_Pot = Chemical_Potential (spstate);
if (iKmin != iKmax) if (whichDSF != 'q') Evaluate_F_Sumrule (prefix, whichDSF, spstate, Chem_Pot, iKmin, iKmax);
// ... and we're done.
return;
}
//****************************************************************************//
// Heisenberg:
void Prepare_Parallel_Scan_Heis (char whichDSF, DP Delta, int N, int M, int iKmin, int iKmax,
int paralevel, Vect<int> rank_lower_paralevels, Vect<int> nr_processors_lower_paralevels,
int nr_processors_at_newlevel)
{
// From an existing scan, this function splits the threads into
// nr_processors separate files, from which the parallel process
// can be launched.
Heis_Chain BD1(1.0, Delta, 0.0, N);
Vect_INT Nrapidities_groundstate(0, BD1.Nstrings);
Nrapidities_groundstate[0] = M;
Heis_Base baseconfig_groundstate(BD1, Nrapidities_groundstate);
// Define file name
stringstream filenameprefix;
if ((Delta > 0.0) && (Delta < 1.0)) {
XXZ_Bethe_State GroundState(BD1, baseconfig_groundstate);
Data_File_Name (filenameprefix, whichDSF, iKmin, iKmax, 0.0, GroundState, GroundState, "");
}
else if (Delta == 1.0) {
XXX_Bethe_State GroundState(BD1, baseconfig_groundstate);
Data_File_Name (filenameprefix, whichDSF, iKmin, iKmax, 0.0, GroundState, GroundState, "");
}
else if (Delta > 1.0) {
XXZ_gpd_Bethe_State GroundState(BD1, baseconfig_groundstate);
Data_File_Name (filenameprefix, whichDSF, iKmin, iKmax, 0.0, GroundState, GroundState, "");
}
else ABACUSerror("Delta out of range in Prepare_Parallel_Scan_Heis");
for (int i = 0; i < paralevel - 1; ++i)
filenameprefix << "_" << rank_lower_paralevels[i] << "_" << nr_processors_lower_paralevels[i];
string prefix = filenameprefix.str();
Split_thr_Files (prefix, whichDSF, nr_processors_at_newlevel);
return;
}
void Wrapup_Parallel_Scan_Heis (char whichDSF, DP Delta, int N, int M, int iKmin, int iKmax,
int paralevel, Vect<int> rank_lower_paralevels, Vect<int> nr_processors_lower_paralevels,
int nr_processors_at_newlevel)
{
// From an existing scan, this function splits the threads into
// nr_processors separate files, from which the parallel process
// can be launched.
Heis_Chain BD1(1.0, Delta, 0.0, N);
Vect_INT Nrapidities_groundstate(0, BD1.Nstrings);
Nrapidities_groundstate[0] = M;
Heis_Base baseconfig_groundstate(BD1, Nrapidities_groundstate);
// Define file name
stringstream filenameprefix;
string prefix;
if ((Delta > 0.0) && (Delta < 1.0)) {
XXZ_Bethe_State GroundState(BD1, baseconfig_groundstate);
XXZ_Bethe_State SeedScanState;
if (whichDSF == 'Z' || whichDSF == 'z') SeedScanState = GroundState;
else if (whichDSF == 'm') SeedScanState = XXZ_Bethe_State(GroundState.chain, M - 1);
else if (whichDSF == 'p') SeedScanState = XXZ_Bethe_State(GroundState.chain, M + 1);
else ABACUSerror("Unknown whichDSF in Scan_Heis.");
Data_File_Name (filenameprefix, whichDSF, iKmin, iKmax, 0.0, GroundState, SeedScanState, "");
for (int i = 0; i < paralevel - 1; ++i)
filenameprefix << "_" << rank_lower_paralevels[i] << "_" << nr_processors_lower_paralevels[i];
prefix = filenameprefix.str();
// Merge sum files
Merge_sum_Files (SeedScanState, prefix, whichDSF, nr_processors_at_newlevel);
// Merge raw files
Merge_raw_Files (prefix, whichDSF, nr_processors_at_newlevel);
// Merge thr files
Merge_thr_Files (prefix, whichDSF, nr_processors_at_newlevel);
// Merge src files
Merge_inadm_conv0_src_stat_log_Files (prefix, whichDSF, nr_processors_at_newlevel);
// This also puts some digested info in log file.
// Evaluate f-sumrule:
DP Chem_Pot = Chemical_Potential (GroundState);
if (iKmin != iKmax) if (whichDSF != 'q') Evaluate_F_Sumrule (prefix, whichDSF, GroundState, Chem_Pot, iKmin, iKmax);
}
else if (Delta == 1.0) {
XXX_Bethe_State GroundState(BD1, baseconfig_groundstate);
XXX_Bethe_State SeedScanState;
if (whichDSF == 'Z' || whichDSF == 'z' || whichDSF == 'a' || whichDSF == 'q') SeedScanState = GroundState;
else if (whichDSF == 'm') SeedScanState = XXX_Bethe_State(GroundState.chain, M - 1);
else if (whichDSF == 'p') SeedScanState = XXX_Bethe_State(GroundState.chain, M + 1);
else if (whichDSF == 'c') SeedScanState = XXX_Bethe_State(GroundState.chain, M - 2);
else ABACUSerror("Unknown whichDSF in Scan_Heis.");
Data_File_Name (filenameprefix, whichDSF, iKmin, iKmax, 0.0, GroundState, SeedScanState, "");
for (int i = 0; i < paralevel - 1; ++i)
filenameprefix << "_" << rank_lower_paralevels[i] << "_" << nr_processors_lower_paralevels[i];
prefix = filenameprefix.str();
// Merge sum files
Merge_sum_Files (SeedScanState, prefix, whichDSF, nr_processors_at_newlevel);
// Merge raw files
Merge_raw_Files (prefix, whichDSF, nr_processors_at_newlevel);
// Merge thr files
Merge_thr_Files (prefix, whichDSF, nr_processors_at_newlevel);
// Merge src files
Merge_inadm_conv0_src_stat_log_Files (prefix, whichDSF, nr_processors_at_newlevel);
// This also puts some digested info in log file.
// Evaluate f-sumrule:
DP Chem_Pot = Chemical_Potential (GroundState);
if (iKmin != iKmax) if (whichDSF != 'q') Evaluate_F_Sumrule (prefix, whichDSF, GroundState, Chem_Pot, iKmin, iKmax);
}
else if (Delta > 1.0) {
XXZ_gpd_Bethe_State GroundState(BD1, baseconfig_groundstate);
XXZ_gpd_Bethe_State SeedScanState;
if (whichDSF == 'Z' || whichDSF == 'z') SeedScanState = GroundState;
else if (whichDSF == 'm') SeedScanState = XXZ_gpd_Bethe_State(GroundState.chain, M - 1);
else if (whichDSF == 'p') SeedScanState = XXZ_gpd_Bethe_State(GroundState.chain, M + 1);
else ABACUSerror("Unknown whichDSF in Scan_Heis.");
Data_File_Name (filenameprefix, whichDSF, iKmin, iKmax, 0.0, GroundState, SeedScanState, "");
for (int i = 0; i < paralevel - 1; ++i)
filenameprefix << "_" << rank_lower_paralevels[i] << "_" << nr_processors_lower_paralevels[i];
prefix = filenameprefix.str();
// Merge sum files
Merge_sum_Files (SeedScanState, prefix, whichDSF, nr_processors_at_newlevel);
// Merge raw files
Merge_raw_Files (prefix, whichDSF, nr_processors_at_newlevel);
// Merge thr files
Merge_thr_Files (prefix, whichDSF, nr_processors_at_newlevel);
// Merge src files
Merge_inadm_conv0_src_stat_log_Files (prefix, whichDSF, nr_processors_at_newlevel);
// This also puts some digested info in log file.
// Evaluate f-sumrule:
DP Chem_Pot = Chemical_Potential (GroundState);
if (iKmin != iKmax) if (whichDSF != 'q') Evaluate_F_Sumrule (prefix, whichDSF, GroundState, Chem_Pot, iKmin, iKmax);
}
else ABACUSerror("Delta out of range in Prepare_Parallel_Scan_Heis");
// ... and we're done.
return;
}
} // namespace ABACUS