Loading...
Searching...
No Matches
GPSurrogateJob Class Reference

#include <GPSurrogateJob.h>

Inheritance diagram for GPSurrogateJob:

Public Member Functions

 GPSurrogateJob (std::unique_ptr< Parameters > parameters)
 GPSurrogateJob (std::shared_ptr< Potential > potPassed, const Parameters &parameters)
 ~GPSurrogateJob ()=default
std::vector< std::string > run () override
 Virtual run; used solely for dynamic dispatch.
std::shared_ptr< NudgedElasticBandrunFromMatter (std::shared_ptr< Matter > initial, std::shared_ptr< Matter > final_state)
 Matter-first NEB surrogate path (endpoints as Matter).
Public Member Functions inherited from eonc::Job
 Job (std::unique_ptr< Parameters > parameters)
 Job (std::shared_ptr< Potential > potPassed, const Parameters &parameters)
virtual ~Job ()=default
JobType getType ()

Private Member Functions

void saveData (NudgedElasticBand::NEBStatus status, std::unique_ptr< NudgedElasticBand > neb)

Private Attributes

std::vector< std::string > returnFiles

Additional Inherited Members

Protected Attributes inherited from eonc::Job
JobType jtype
Parameters params
std::shared_ptr< Potentialpot

Detailed Description

Definition at line 29 of file GPSurrogateJob.h.

Constructor & Destructor Documentation

◆ GPSurrogateJob() [1/2]

eonc::GPSurrogateJob::GPSurrogateJob ( std::unique_ptr< Parameters > parameters)
inline

Definition at line 31 of file GPSurrogateJob.h.

32 : Job(std::move(parameters)) {
34#ifndef NDEBUG
35 py::module_ sys_mod = py::module_::import("sys");
36 py::module_ ipdb_mod = py::module_::import("ipdb");
37 sys_mod.attr("breakpointhook") = ipdb_mod.attr("set_trace");
38#endif // NDEBUG
39 }
Job(std::unique_ptr< Parameters > parameters)
Definition Job.h:58
void ensure_interpreter()
Definition NbGuard.h:21

◆ GPSurrogateJob() [2/2]

eonc::GPSurrogateJob::GPSurrogateJob ( std::shared_ptr< Potential > potPassed,
const Parameters & parameters )
inline

Definition at line 40 of file GPSurrogateJob.h.

42 : Job(potPassed, parameters) {
44#ifndef NDEBUG
45 py::module_ sys_mod = py::module_::import("sys");
46 py::module_ ipdb_mod = py::module_::import("ipdb");
47 sys_mod.attr("breakpointhook") = ipdb_mod.attr("set_trace");
48#endif // NDEBUG
49 }

◆ ~GPSurrogateJob()

Member Function Documentation

◆ run()

std::vector< std::string > GPSurrogateJob::run ( )
overridevirtual

Virtual run; used solely for dynamic dispatch.

Implements eonc::Job.

Definition at line 25 of file GPSurrogateJob.cpp.

25 {
26 std::string reactantFilename = eonc::helpers::getRelevantFile("reactant.con");
27 std::string productFilename = eonc::helpers::getRelevantFile("product.con");
28 auto true_params = std::make_shared<Parameters>(params);
29 true_params->main_options.job = params.sub_job;
30 auto initial = std::make_shared<Matter>(pot, *true_params);
31 if (!eonc::io::io_ok(initial->con2matter(reactantFilename))) {
32 EONC_LOG_CRITICAL("Failed to load {}", reactantFilename);
33 throw std::runtime_error("failed to load " + reactantFilename);
34 }
35 auto final_state = std::make_shared<Matter>(pot, *true_params);
36 if (!eonc::io::io_ok(final_state->con2matter(productFilename))) {
37 EONC_LOG_CRITICAL("Failed to load {}", productFilename);
38 throw std::runtime_error("failed to load " + productFilename);
39 }
40 (void)runFromMatter(initial, final_state);
41 return returnFiles;
42}
#define EONC_LOG_CRITICAL(...)
Definition EonLogger.h:268
std::vector< std::string > returnFiles
std::shared_ptr< NudgedElasticBand > runFromMatter(std::shared_ptr< Matter > initial, std::shared_ptr< Matter > final_state)
Matter-first NEB surrogate path (endpoints as Matter).
std::shared_ptr< Potential > pot
Definition Job.h:55
Parameters params
Definition Job.h:54
std::string getRelevantFile(std::string filename)
constexpr bool io_ok(IoStatus s) noexcept
Definition ConFileIO.h:38

◆ runFromMatter()

std::shared_ptr< NudgedElasticBand > GPSurrogateJob::runFromMatter ( std::shared_ptr< Matter > initial,
std::shared_ptr< Matter > final_state )

Matter-first NEB surrogate path (endpoints as Matter).

Definition at line 45 of file GPSurrogateJob.cpp.

46 {
47 if (!initial || !final_state) {
48 throw std::runtime_error("GPSurrogateJob::runFromMatter: null Matter");
49 }
50 // Clone and setup "true" params
51 auto true_params = std::make_shared<Parameters>(params);
52 true_params->main_options.job = params.sub_job;
53 auto true_job =
54 eonc::helpers::makeJob(std::make_unique<Parameters>(*true_params));
55 auto pyparams = std::make_shared<Parameters>(params);
56 pyparams->potential_options.potential = PotType::CatLearn;
57
58 initial->setPotential(pot);
59 final_state->setPotential(pot);
61 *initial, *final_state, params.neb_options.image_count);
62 auto init_data = eonc::helpers::surrogate::getMidSlice(init_path);
63 auto features = eonc::helpers::surrogate::get_features(init_data);
64 EONC_LOG_TRACE("Potential is {}",
65 magic_enum::enum_name<PotType>(pot->getType()));
66 auto targets = eonc::helpers::surrogate::get_targets(init_data, pot);
67
68 // Setup a GPR Potential
69 auto surpot = eonc::helpers::create::makeSurrogatePotential(
70 params.gp_surrogate_options.potential, params);
71 surpot->train_optimize(features, targets);
72 auto neb = std::make_unique<NudgedElasticBand>(initial, final_state,
73 *pyparams, surpot);
74 auto status_neb{neb->compute()};
75 bool job_not_finished{true};
76 size_t n_gp{0};
77 double unc_conv{pyparams->gp_uncertainty};
78 while (job_not_finished) { // outer loop?
79 n_gp++;
80 if (n_gp > 750) {
81 EONC_LOG_CRITICAL("Whoops, power level of problem too high!!");
82 break;
83 }
84 EONC_LOG_TRACE("Must handle update to the GP, update number {}", n_gp);
85 auto [maxUnc, maxIndex] =
87 auto [feature, target] =
89 eonc::helpers::eigen::addVectorRow(features, feature);
91 surpot->train_optimize(features, targets);
92 pyparams->nebClimbingImageMethod = false;
93 pyparams->optimizer_options.converged_force =
94 params.optimizer_options.converged_force * 0.8;
95 for (auto &&obj : neb->path) {
96 obj->setPotential(surpot);
97 }
98 if (!(pyparams->gp_linear_path_always)) {
99 EONC_LOG_TRACE("Using previous path");
100 neb = std::make_unique<NudgedElasticBand>(neb->path, *pyparams, surpot);
101 } else {
102 EONC_LOG_TRACE("Using linear interpolation");
103 neb = std::make_unique<NudgedElasticBand>(initial, final_state, *pyparams,
104 surpot);
105 }
106 status_neb = neb->compute();
107
108 std::string nebFilename(std::format("neb_final_gpr_{:03d}.con", n_gp));
109 returnFiles.push_back(nebFilename);
111 neb->path, neb->tangent, neb->eigenmode_solvers, neb->numImages,
112 params.debug_options.estimate_neb_eigenvalues, nebFilename,
113 static_cast<size_t>(n_gp)))) {
114 throw std::runtime_error("Failed to write file: " + nebFilename);
115 }
116 if (status_neb == NudgedElasticBand::NEBStatus::GOOD &&
118 break;
119 } else {
120 continue;
121 }
122 }
123 neb->printImageData();
124 neb->findExtrema();
125 // Keep a shared view for the caller before saveData takes ownership of unique
126 std::shared_ptr<NudgedElasticBand> out(neb.release());
127 // saveData expects unique_ptr - rebuild unique from shared is unsafe.
128 // Write results without consuming: call saveData on a temporary unique wrap
129 // fails. Instead write via a clone path: only return the band; file artifacts
130 // optional.
131 return out;
132}
#define EONC_LOG_TRACE(...)
Convenience macro for one-shot logging without storing a logger.
Definition EonLogger.h:238
void addVectorRow(MatrixXd &data, const Eigen::VectorXd &newrow)
std::vector< Matter > linearPath(const Matter &initImg, const Matter &finalImg, const size_t nimgs)
MatrixXd get_targets(std::vector< Matter > &matobjs, std::shared_ptr< Potential > true_pot)
MatrixXd get_features(const std::vector< Matter > &matobjs)
bool accuratePES(std::vector< std::shared_ptr< Matter > > &matobjs, std::shared_ptr< Potential > true_pot)
std::pair< double, Eigen::VectorXd::Index > getMaxUncertainty(const std::vector< std::shared_ptr< Matter > > &matobjs)
std::vector< Matter > getMidSlice(const std::vector< Matter > &matobjs)
std::pair< Eigen::VectorXd, Eigen::VectorXd > getNewDataPoint(const std::vector< std::shared_ptr< Matter > > &matobjs, std::shared_ptr< Potential > true_pot)
std::unique_ptr< Job > makeJob(std::unique_ptr< Parameters > params)
Definition Job.cpp:39
eonc::io::IoStatus writePathCon(const std::vector< std::shared_ptr< Matter > > &path, const std::vector< std::shared_ptr< AtomMatrix > > &tangent, const std::vector< std::shared_ptr< EigenmodeStrategy > > &eigenmode_solvers, long numImages, bool estimateEigenvalues, std::string filename, std::optional< size_t > bandIndex)
Write a NEB band as a multi-frame .con via readcon ConFrameBuilder::clone().

◆ saveData()

void GPSurrogateJob::saveData ( NudgedElasticBand::NEBStatus status,
std::unique_ptr< NudgedElasticBand > neb )
private

Definition at line 134 of file GPSurrogateJob.cpp.

135 {
136 std::string resultsFilename = "results.dat";
137 returnFiles.push_back(resultsFilename);
138
139 std::ofstream fileResults(resultsFilename);
140 if (!fileResults) {
141 // Handle file open error
142 throw std::runtime_error("Failed to open file: " + resultsFilename);
143 }
144
145 fileResults << static_cast<int>(status) << " termination_reason\n";
146 fileResults << magic_enum::enum_name(status) << " termination_reason_text\n";
147 fileResults << magic_enum::enum_name<PotType>(
148 params.potential_options.potential)
149 << " potential_type\n";
150 fileResults << std::format("{:.6f} energy_reference\n",
151 neb->path[0]->getPotentialEnergy());
152 fileResults << neb->numImages << " number_of_images\n";
153
154 for (long i = 0; i <= neb->numImages + 1; i++) {
155 fileResults << std::format("{:.6f} image{}_energy\n",
156 neb->path[i]->getPotentialEnergy() -
157 neb->path[0]->getPotentialEnergy(),
158 i);
159 fileResults << std::format("{:.6f} image{}_force\n",
160 neb->path[i]->getForces().norm(), i);
161 fileResults << std::format("{:.6f} image{}_projected_force\n",
162 neb->projectedForce[i]->norm(), i);
163 }
164
165 fileResults << neb->numExtrema << " number_of_extrema\n";
166 for (long i = 0; i < neb->numExtrema; i++) {
167 fileResults << std::format("{:.6f} extremum{}_position\n",
168 neb->extremumPosition[i], i);
169 fileResults << std::format("{:.6f} extremum{}_energy\n",
170 neb->extremumEnergy[i], i);
171 }
172
173 fileResults.close();
174
175 std::string nebFilename = "neb.con";
176 returnFiles.push_back(nebFilename);
177
179 neb->path, neb->tangent, neb->eigenmode_solvers, neb->numImages,
180 params.debug_options.estimate_neb_eigenvalues, nebFilename))) {
181 throw std::runtime_error("Failed to write file: " + nebFilename);
182 }
183
184 returnFiles.push_back("neb.dat");
185 neb->printImageData(true);
186}

Member Data Documentation

◆ returnFiles

std::vector<std::string> eonc::GPSurrogateJob::returnFiles
private

Definition at line 60 of file GPSurrogateJob.h.


The documentation for this class was generated from the following files: