699 lines
25 KiB
C++
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 << "Code 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
|