diff --git a/examples/Carbyne/carbyne.rom.cfg b/examples/Carbyne/carbyne.rom.cfg index 38b9a678..cb0cd295 100644 --- a/examples/Carbyne/carbyne.rom.cfg +++ b/examples/Carbyne/carbyne.rom.cfg @@ -18,14 +18,17 @@ pseudopotential=pseudo.C_ONCV_PBE_SG15 [Run] type=QUENCH [Quench] -max_steps=10 +max_steps=5 atol=1.e-8 [Orbitals] initial_type=Fourier [Restart] output_level=4 -# input_level=4 -# input_filename=snapshot0_24_109_22_36 +input_level=4 +input_filename=snapshot0_000 [ROM.offline] -restartFilename=snapshot0_24_109_22_39 +restart_filefmt=snapshot0_%03d +restart_min_idx=0 +restart_max_idx=1 +basis_file=carom diff --git a/src/Control.cc b/src/Control.cc index ae39c3ab..c0497546 100644 --- a/src/Control.cc +++ b/src/Control.cc @@ -2063,7 +2063,11 @@ void Control::setROMOptions(const boost::program_options::variables_map& vm) if (onpe0) { - rom_pri_option.restart_filename = vm["ROM.offline.restartFilename"].as(); + rom_pri_option.restart_file_fmt = vm["ROM.offline.restart_filefmt"].as(); + rom_pri_option.restart_file_minidx = vm["ROM.offline.restart_min_idx"].as(); + rom_pri_option.restart_file_maxidx = vm["ROM.offline.restart_max_idx"].as(); + + rom_pri_option.basis_file = vm["ROM.offline.basis_file"].as(); } // onpe0 // synchronize all processors @@ -2077,7 +2081,8 @@ void Control::syncROMOptions() MGmol_MPI& mmpi = *(MGmol_MPI::instance()); - mmpi.bcast(rom_pri_option.restart_filename, comm_global_); + mmpi.bcast(rom_pri_option.restart_file_fmt, comm_global_); + mmpi.bcast(rom_pri_option.basis_file, comm_global_); auto bcast_check = [](int mpirc) { if (mpirc != MPI_SUCCESS) @@ -2092,5 +2097,11 @@ void Control::syncROMOptions() mpirc = MPI_Bcast(&rom_stage, 1, MPI_SHORT, 0, comm_global_); bcast_check(mpirc); + mpirc = MPI_Bcast(&rom_pri_option.restart_file_minidx, 1, MPI_INT, 0, comm_global_); + bcast_check(mpirc); + + mpirc = MPI_Bcast(&rom_pri_option.restart_file_maxidx, 1, MPI_INT, 0, comm_global_); + bcast_check(mpirc); + rom_pri_option.rom_stage = static_cast(rom_stage); } \ No newline at end of file diff --git a/src/rom_Control.h b/src/rom_Control.h index 67525e45..255326a2 100644 --- a/src/rom_Control.h +++ b/src/rom_Control.h @@ -27,7 +27,10 @@ enum class ROMStage /* Stored as a private member variable of Control class */ struct ROMPrivateOptions { - std::string restart_filename = ""; + std::string restart_file_fmt = ""; + int restart_file_minidx = -1; + int restart_file_maxidx = -1; + std::string basis_file = ""; ROMStage rom_stage = ROMStage::UNSUPPORTED; }; diff --git a/src/rom_workflows.cc b/src/rom_workflows.cc index 26db2f82..4594dd3a 100644 --- a/src/rom_workflows.cc +++ b/src/rom_workflows.cc @@ -8,20 +8,63 @@ // Please also read this link https://github.com/llnl/mgmol/LICENSE #include "rom_workflows.h" +#include +#include +#include + +template +std::string string_format( const std::string& format, Args ... args ) +{ + int size_s = std::snprintf( nullptr, 0, format.c_str(), args ... ) + 1; // Extra space for '\0' + if( size_s <= 0 ){ throw std::runtime_error( "Error during formatting." ); } + auto size = static_cast( size_s ); + std::unique_ptr buf( new char[ size ] ); + std::snprintf( buf.get(), size, format.c_str(), args ... ); + return std::string( buf.get(), buf.get() + size - 1 ); // We don't want the '\0' inside +} template void readRestartFiles(MGmolInterface *mgmol_) { Control& ct = *(Control::instance()); ROMPrivateOptions rom_options = ct.getROMOptions(); + assert(rom_options.restart_file_minidx >= 0); + assert(rom_options.restart_file_maxidx >= 0); + const int minidx = rom_options.restart_file_minidx; + const int maxidx = rom_options.restart_file_maxidx; + const int num_restart = maxidx - minidx + 1; MGmol *mgmol = static_cast *>(mgmol_); + OrbitalsType *orbitals = nullptr; + std::string filename; - OrbitalsType *orbitals = mgmol->loadOrbitalFromRestartFile(rom_options.restart_filename); + /* Read the first snapshot to determin dimension and number of snapshots */ + filename = string_format(rom_options.restart_file_fmt, minidx); + orbitals = mgmol->loadOrbitalFromRestartFile(filename); + const int dim = orbitals->getLocNumpt(); + const int chrom_num = orbitals->chromatic_number(); + const int totalSamples = orbitals->chromatic_number() * num_restart; + delete orbitals; - mgmol->save_orbital_snapshot("test", *orbitals); + /* Initialize libROM classes */ + CAROM::Options svd_options(dim, totalSamples, 1); + CAROM::BasisGenerator basis_generator(svd_options, false, rom_options.basis_file); + + /* Collect the restart files */ + for (int k = minidx; k <= maxidx; k++) + { + filename = string_format(rom_options.restart_file_fmt, k); + orbitals = mgmol->loadOrbitalFromRestartFile(filename); + assert(dim == orbitals->getLocNumpt()); + assert(chrom_num == orbitals->chromatic_number()); - delete orbitals; + for (int i = 0; i < chrom_num; ++i) + basis_generator.takeSample(orbitals->getPsi(i)); + + delete orbitals; + } + basis_generator.writeSnapshot(); + basis_generator.endSamples(); } template void readRestartFiles(MGmolInterface *mgmol_); diff --git a/src/tools/OptionDescription.cc b/src/tools/OptionDescription.cc index 93e6ed4a..9a4c8fa5 100644 --- a/src/tools/OptionDescription.cc +++ b/src/tools/OptionDescription.cc @@ -320,6 +320,12 @@ void setupHiddenOption(po::options_description &hidden) void setupROMConfigOption(po::options_description &rom_cfg) { rom_cfg.add_options() - ("ROM.offline.restartFilename", po::value()->required(), - "File name to read for snapshots."); + ("ROM.offline.restart_filefmt", po::value()->required(), + "File name format to read for snapshots.") + ("ROM.offline.restart_min_idx", po::value()->required(), + "Minimum index for snapshot file format.") + ("ROM.offline.restart_max_idx", po::value()->required(), + "Maximum index for snapshot file format.") + ("ROM.offline.basis_file", po::value()->required(), + "File name for libROM snapshot/POD matrices."); }