Loading...
Searching...
No Matches
eonc::ProcessSearchJob Class Reference

Declaration of the Process Search job. More...

#include <ProcessSearchJob.h>

Inheritance diagram for eonc::ProcessSearchJob:

Public Member Functions

 ProcessSearchJob (std::unique_ptr< Parameters > parameters, Runtime &rt)
 Process Search job Constructor.
 ProcessSearchJob (std::shared_ptr< Potential > potPassed, const Parameters &parameters)
 ~ProcessSearchJob ()=default
 Process Search job De-constructor.
std::vector< std::string > run (void) override
 Kicks off the Process Search.
std::shared_ptr< Matter > runFromMatter (std::shared_ptr< Matter > seed)
 In-process entry: seed reactant Matter, no pos.con.
std::shared_ptr< Matter > getInitial () const
std::shared_ptr< Matter > getSaddle () const
std::shared_ptr< Matter > getMin1 () const
std::shared_ptr< Matter > getMin2 () const
double prefactorForward () const
double prefactorReverse () const
double barrierForward () const
double barrierReverse () const
Public Member Functions inherited from eonc::Job
void adoptRuntime (std::unique_ptr< Runtime > rt)
 Take ownership of a Runtime previously passed as Runtime&.
 Job (std::unique_ptr< Parameters > parameters, Runtime &rt)
 Borrow: caller keeps Runtime alive (CLI stack / Python Session).
 Job (std::unique_ptr< Parameters > parameters, std::unique_ptr< Runtime > rt)
 Own a Runtime (one-shot makeJob / rvalue).
 Job (std::unique_ptr< Parameters > parameters)
 Own a default-constructed Runtime.
 Job (std::shared_ptr< Potential > potPassed, const Parameters &parameters)
virtual ~Job ()=default
JobType getType ()
PotRegistry & pots () noexcept
void releasePotential ()
 Drop the Potential so on_destroyed is recorded before Runtime dies.

Private Member Functions

std::shared_ptr< Matter > runPrepared ()
int doProcessSearch (void)
 Runs the correct saddle search; also checks if the run was successful.
void printEndState (int status)
 Logs the run status and makes sure the run was successful.
void saveData (int status)
 Writes the results from the run to file.

Private Attributes

eonc::log::Scoped log
std::vector< std::string > returnFiles
 Container for the results of the run.
std::unique_ptr< SaddleSearchMethod > saddleSearch
 Pulled from parameters.
std::shared_ptr< Matter > initial
 Initial configuration.
std::shared_ptr< Matter > saddle
 Configuration used during the saddle point search.
std::shared_ptr< Matter > displacement
 Configuration used during the saddle point search.
std::shared_ptr< Matter > min1
 First minimum from the saddle.
std::shared_ptr< Matter > min2
 Second minimum from the saddle.
double barriersValues [2] {0.0, 0.0}
double prefactorsValues [2] {0.0, 0.0}
size_t fCallsSaddle {0}
 Force calls to find the saddle.
size_t fCallsMin {0}
 Force calls to minimize.
size_t fCallsPrefactors {0}
 Force calls to find the prefactors.

Additional Inherited Members

Protected Attributes inherited from eonc::Job
JobType jtype
Parameters params
std::unique_ptr< Runtime > owned_runtime_
 Non-null when this Job owns the composition root (one-shot makeJob).
Runtime * runtime_
 Always valid: either owned_runtime_.get() or a caller-owned Runtime.
std::shared_ptr< Potential > pot

Detailed Description

Declaration of the Process Search job.

Definition at line 45 of file ProcessSearchJob.h.

Constructor & Destructor Documentation

◆ ProcessSearchJob() [1/2]

eonc::ProcessSearchJob::ProcessSearchJob ( std::unique_ptr< Parameters > parameters,
Runtime & rt )
inline

Process Search job Constructor.

Parameters
*paramsdefined by the config.init file

Definition at line 51 of file ProcessSearchJob.h.

52 : Job(std::move(parameters), rt),
53 fCallsSaddle{0},
54 fCallsMin{0},
Job(std::unique_ptr< Parameters > parameters, Runtime &rt)
Borrow: caller keeps Runtime alive (CLI stack / Python Session).
Definition Job.h:76
size_t fCallsPrefactors
Force calls to find the prefactors.
size_t fCallsMin
Force calls to minimize.
size_t fCallsSaddle
Force calls to find the saddle.

◆ ProcessSearchJob() [2/2]

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

Definition at line 56 of file ProcessSearchJob.h.

58 : Job(std::move(potPassed), parameters),
59 fCallsSaddle{0},
60 fCallsMin{0},

◆ ~ProcessSearchJob()

eonc::ProcessSearchJob::~ProcessSearchJob ( )
default

Process Search job De-constructor.

Member Function Documentation

◆ barrierForward()

double eonc::ProcessSearchJob::barrierForward ( ) const
inline

Definition at line 75 of file ProcessSearchJob.h.

75{ return barriersValues[0]; }

◆ barrierReverse()

double eonc::ProcessSearchJob::barrierReverse ( ) const
inline

Definition at line 76 of file ProcessSearchJob.h.

76{ return barriersValues[1]; }

◆ doProcessSearch()

int eonc::ProcessSearchJob::doProcessSearch ( void )
private

Runs the correct saddle search; also checks if the run was successful.

Definition at line 240 of file ProcessSearchJob.cpp.

240 {
241 Matter matterTemp(pot, params);
242 long status;
243 size_t fctmp{0};
244
245 fctmp = pot->forceCallCounter;
246 status = saddleSearch->run();
247 if (params.saddle_search_options().method == "min_mode" &&
248 params.saddle_search_options().minmode_method ==
250 fCallsSaddle += saddleSearch->getForceCalls();
251 } else if (params.saddle_search_options().method == "artn") {
252 fCallsSaddle += saddleSearch->getForceCalls();
253 } else {
254 fCallsSaddle += pot->forceCallCounter - fctmp;
255 }
256 EONC_LOG_DEBUG("Got {} calls in the saddle search, with previous {}",
257 fCallsSaddle, fctmp);
258
259 if (status != MinModeSaddleSearch::STATUS_GOOD) {
260 return status;
261 }
262
263 AtomMatrix posSaddle = saddle->getPositions();
264 AtomMatrix displacedPos;
265
266 // Matter's copy assignment copies the potential; keep each endpoint's
267 // own instance so the two minimizations can run at the same time.
268 const auto min1Pot = min1->getPotential();
269 const auto min2Pot = min2->getPotential();
270 *min1 = *saddle;
271 min1->setPotential(min1Pot);
272
273 displacedPos =
274 posSaddle - saddleSearch->getEigenvector() *
275 params.process_search_options().minimization_offset;
276 min1->setPositions(displacedPos);
277
278 *min2 = *saddle;
279 min2->setPotential(min2Pot);
280 displacedPos =
281 posSaddle + saddleSearch->getEigenvector() *
282 params.process_search_options().minimization_offset;
283 min2->setPositions(displacedPos);
284
285 // Minimize both endpoints concurrently when the shared potential instance is
286 // safe to call from multiple threads, or when each endpoint owns a separate
287 // potential instance.
288 QUILL_LOG_DEBUG(log, "Starting Minimization 1 & 2");
289 bool converged1{false}, converged2{false};
290 long fc1_before = min1->getPotentialCalls();
291 long fc2_before = min2->getPotentialCalls();
292
293 // Two threads may share an instance only when it is thread safe; a
294 // per-image potential needs the endpoints to hold distinct instances.
295 bool canParallel = eonc::potAllowsSharedInstance(*pot) ||
296 (pot->needsPerImageInstance() &&
297 min1->getPotential().get() != min2->getPotential().get());
298 if (params.main_options().parallel && canParallel) {
299 // An exception may not leave a thread function (std::terminate), and a
300 // joinable std::thread may not be destroyed: t1 hands its error back and
301 // the caller joins before rethrowing either side's.
302 std::exception_ptr t1Error;
303 std::thread t1([&] {
304 try {
305 converged1 = min1->relax(false, params.debug_options().write_movies,
306 false, "min1");
307 } catch (...) {
308 t1Error = std::current_exception();
309 }
310 });
311 try {
312 converged2 = min2->relax(false, params.debug_options().write_movies,
313 false, "min2");
314 } catch (...) {
315 t1.join();
316 throw;
317 }
318 t1.join();
319 if (t1Error)
320 std::rethrow_exception(t1Error);
321 } else {
322 converged1 =
323 min1->relax(false, params.debug_options().write_movies, false, "min1");
324 converged2 =
325 min2->relax(false, params.debug_options().write_movies, false, "min2");
326 }
327
328 if (min1->getPotential().get() == min2->getPotential().get()) {
329 fCallsMin += min1->getPotentialCalls() - fc1_before;
330 } else {
331 fCallsMin += (min1->getPotentialCalls() - fc1_before) +
332 (min2->getPotentialCalls() - fc2_before);
333 }
334 QUILL_LOG_DEBUG(log, "Min1: {} fcalls, Min2: {} fcalls",
335 min1->getPotentialCalls() - fc1_before,
336 min2->getPotentialCalls() - fc2_before);
337
338 if (!converged1 || !converged2) {
340 }
341
342 auto sameAs = [](const Matter &a, const Matter &b) {
343 Matter probe(a);
344 return probe.compare(b);
345 };
346
347 if (!sameAs(*initial, *min1) && sameAs(*initial, *min2)) {
348 matterTemp = *min1;
349 *min1 = *min2;
350 *min2 = matterTemp;
351 }
352
353 if (!sameAs(*initial, *min1)) {
354 // Report how far off the endpoint landed. Whether the minimisation
355 // stopped just outside the state-identity tolerance or relaxed into a
356 // different state entirely calls for opposite fixes, and the status
357 // alone does not distinguish them.
358 const double tol =
359 params.structure_comparison_options().distance_difference;
360 auto countMoved = [&](const Matter &m) {
361 long moved = 0;
362 for (long i = 0; i < initial->numberOfAtoms(); ++i) {
363 if (initial
364 ->pbc(initial->getPositions().row(i) - m.getPositions().row(i))
365 .norm() > tol) {
366 ++moved;
367 }
368 }
369 return moved;
370 };
371 QUILL_LOG_INFO(log,
372 "initial != min1: {} of {} atoms past the {} A tolerance "
373 "for min1 ({} for min2); largest separation {} A",
374 countMoved(*min1), initial->numberOfAtoms(), tol,
375 countMoved(*min2), initial->perAtomNorm(*min1));
377 }
378
379 if (sameAs(*initial, *min2)) {
380 QUILL_LOG_DEBUG(log, "both minima are the initial state");
382 }
383
384 if (!params.process_search_options().minimize_first) {
385 min1 = initial;
386 }
387
388 barriersValues[0] = saddle->getPotentialEnergy() - min1->getPotentialEnergy();
389 barriersValues[1] = saddle->getPotentialEnergy() - min2->getPotentialEnergy();
390
391 if ((params.saddle_search_options().max_energy < barriersValues[0]) ||
392 (params.saddle_search_options().max_energy < barriersValues[1])) {
394 }
395
396 if (barriersValues[0] < 0.0 || barriersValues[1] < 0.0) {
398 }
399
400 if (!params.prefactor_options().default_value) {
401 fctmp = min1->getPotentialCalls();
402 int prefStatus;
403 double pref1, pref2;
405 params, min1.get(), saddle.get(), min2.get(), pref1, pref2);
406 if (prefStatus == -1) {
407 EONC_LOG_ERROR("Prefactor: bad calculation");
409 }
410 fCallsPrefactors += min1->getPotentialCalls() - fctmp;
411
412 if ((pref1 > params.prefactor_options().max_value) ||
413 (pref1 < params.prefactor_options().min_value)) {
414 EONC_LOG_ERROR("Bad reactant-to-saddle prefactor: {}", pref1);
416 }
417 if ((pref2 > params.prefactor_options().max_value) ||
418 (pref2 < params.prefactor_options().min_value)) {
419 EONC_LOG_ERROR("Bad product-to-saddle prefactor: {}", pref2);
421 }
422 prefactorsValues[0] = pref1;
423 prefactorsValues[1] = pref2;
424
425 } else {
426 prefactorsValues[0] = params.prefactor_options().default_value;
427 prefactorsValues[1] = params.prefactor_options().default_value;
428 }
430}
Eigen::Matrix< double, Eigen::Dynamic, 3, eOnStorageOrder > AtomMatrix
Definition Eigen.h:37
#define EONC_LOG_DEBUG(...)
Definition EonLogger.h:243
#define EONC_LOG_ERROR(...)
Definition EonLogger.h:261
std::shared_ptr< Potential > pot
Definition Job.h:63
Parameters params
Definition Job.h:58
static const char MINMODE_GPRDIMER[]
eonc::log::Scoped log
std::shared_ptr< Matter > min1
First minimum from the saddle.
std::shared_ptr< Matter > min2
Second minimum from the saddle.
std::shared_ptr< Matter > saddle
Configuration used during the saddle point search.
std::shared_ptr< Matter > initial
Initial configuration.
std::unique_ptr< SaddleSearchMethod > saddleSearch
Pulled from parameters.
int getPrefactors(const Parameters &parameters, Matter *min1, Matter *saddle, Matter *min2, double &pref1, double &pref2)
Definition Prefactor.cpp:24
bool potAllowsSharedInstance(const P &p) noexcept

◆ getInitial()

std::shared_ptr< Matter > eonc::ProcessSearchJob::getInitial ( ) const
inline

Definition at line 69 of file ProcessSearchJob.h.

69{ return initial; }

◆ getMin1()

std::shared_ptr< Matter > eonc::ProcessSearchJob::getMin1 ( ) const
inline

Definition at line 71 of file ProcessSearchJob.h.

71{ return min1; }

◆ getMin2()

std::shared_ptr< Matter > eonc::ProcessSearchJob::getMin2 ( ) const
inline

Definition at line 72 of file ProcessSearchJob.h.

72{ return min2; }

◆ getSaddle()

std::shared_ptr< Matter > eonc::ProcessSearchJob::getSaddle ( ) const
inline

Definition at line 70 of file ProcessSearchJob.h.

70{ return saddle; }

◆ prefactorForward()

double eonc::ProcessSearchJob::prefactorForward ( ) const
inline

Definition at line 73 of file ProcessSearchJob.h.

73{ return prefactorsValues[0]; }

◆ prefactorReverse()

double eonc::ProcessSearchJob::prefactorReverse ( ) const
inline

Definition at line 74 of file ProcessSearchJob.h.

74{ return prefactorsValues[1]; }

◆ printEndState()

void eonc::ProcessSearchJob::printEndState ( int status)
private

Logs the run status and makes sure the run was successful.

Definition at line 502 of file ProcessSearchJob.cpp.

502 {
503 auto msg = saddleSearch->describeStatus(status);
504 if (status == MinModeSaddleSearch::STATUS_GOOD) {
505 QUILL_LOG_DEBUG(log, "[Saddle Search] {}", msg);
506 } else {
507 QUILL_LOG_ERROR(log, "[Saddle Search] {}", msg);
508 }
509}

◆ run()

std::vector< std::string > eonc::ProcessSearchJob::run ( void )
overridevirtual

Kicks off the Process Search.

Implements eonc::Job.

Definition at line 39 of file ProcessSearchJob.cpp.

39 {
40 std::string reactantFilename = eonc::helpers::getRelevantFile("pos.con");
41 std::string displacementFilename("displacement.con");
42 std::string modeFilename("direction.dat");
43 size_t fctmp{0};
44 initial = std::make_shared<Matter>(pot, params);
45 if (params.saddle_search_options().method == "min_mode" ||
46 params.saddle_search_options().method == "basin_hopping" ||
47 params.saddle_search_options().method == "bgsd") {
48 displacement = std::make_shared<Matter>(pot, params);
49 } else if (params.saddle_search_options().method == "dynamics") {
50 displacement = nullptr;
51 }
52 saddle = std::make_shared<Matter>(pot, params);
53 // Give min2 its own potential for parallel endpoint minimization
54 // A clone keeps this job's potential; makePotential rebuilds from the
55 // configuration and is the fallback for backends that cannot clone.
56 std::shared_ptr<Potential> min2Pot = pot;
57 if (pot->needsPerImageInstance() && params.main_options().parallel) {
58 auto cloned = pot->clonePotential();
59 min2Pot = cloned ? cloned : eonc::helpers::makePotential(params);
60 }
61 min1 = std::make_shared<Matter>(pot, params);
62 min2 = std::make_shared<Matter>(min2Pot, params);
63
64 if (!eonc::io::io_ok(initial->con2matter(reactantFilename))) {
65 EONC_LOG_CRITICAL("Failed to load {}", reactantFilename);
66 throw std::runtime_error("failed to load " + reactantFilename);
67 }
68
69 if (params.process_search_options().minimize_first) {
70 QUILL_LOG_DEBUG(log, "Minimizing initial structure\n");
71 fctmp = initial->getPotentialCalls();
72 initial->relax();
73 fCallsMin += initial->getPotentialCalls() - fctmp;
74 QUILL_LOG_DEBUG(log, "Initial minimization took {} fcalls",
75 initial->getPotentialCalls() - fctmp);
76 }
77
80
81 AtomMatrix mode = AtomMatrix::Zero(initial->numberOfAtoms(), 3);
82 if (params.saddle_search_options().method == "min_mode" ||
83 params.saddle_search_options().method == "basin_hopping" ||
84 params.saddle_search_options().method == "bgsd") {
85 if (params.saddle_search_options().displace_type ==
87 // Load displacement.con, or synthesize from pos.con + direction.dat
88 // (#79).
90 *saddle, *initial, displacementFilename, modeFilename,
91 params.saddle_search_options().displace_magnitude)) {
92 EONC_LOG_CRITICAL("Failed to load {} (and no usable {})",
93 displacementFilename, modeFilename);
94 throw std::runtime_error("failed to load " + displacementFilename);
95 }
96 *min1 = *min2 = *initial;
98 &mode)) {
99 *min1 = *min2 = *initial;
100 } else {
101 *saddle = *min1 = *min2 = *initial;
102 }
103 if (displacement) {
105 }
106 } else {
107 // ARTn and dynamics start from the initial minimum
108 *saddle = *min1 = *min2 = *initial;
109 }
110 min2->setPotential(min2Pot);
111
112 const bool useARTnAsMinMode =
113 params.saddle_search_options().method == "min_mode" &&
114 params.saddle_search_options().minmode_method == "artn";
115
116 if (params.saddle_search_options().method == "min_mode") {
117 if (params.saddle_search_options().displace_type ==
119 std::filesystem::exists(modeFilename)) {
120 mode = eonc::helpers::loadMode(modeFilename, initial->numberOfAtoms());
121 }
122#ifdef WITH_ARTN
123 // ARTn as a min-mode drop-in: eOn displaces, seeds the mode, ARTn
124 // takes over from the displaced structure.
125 if (useARTnAsMinMode) {
127 std::make_unique<ARTnSaddleSearch>(saddle, pot, mode, params);
128 } else
129#endif
130 {
131 saddleSearch = std::make_unique<MinModeSaddleSearch>(
132 saddle, mode, initial->getPotentialEnergy(), params, pot);
133 }
134#ifdef WITH_ARTN
135 } else if (params.saddle_search_options().method == "artn") {
136 // ARTn handles its own push from the minimum, eigenmode estimation,
137 // and perpendicular relaxation internally.
138 AtomMatrix artnMode = AtomMatrix::Zero(initial->numberOfAtoms(), 3);
139 if (params.saddle_search_options().displace_type ==
141 std::filesystem::exists(modeFilename)) {
142 artnMode =
143 eonc::helpers::loadMode(modeFilename, initial->numberOfAtoms());
144 }
146 std::make_unique<ARTnSaddleSearch>(saddle, pot, artnMode, params);
147#endif
148 } else if (params.saddle_search_options().method == "basin_hopping") {
150 std::make_unique<BasinHoppingSaddleSearch>(min1, saddle, pot, params);
151 } else if (params.saddle_search_options().method == "dynamics") {
152 saddleSearch = std::make_unique<DynamicsSaddleSearch>(saddle, params);
153 } else if (params.saddle_search_options().method == "bgsd") {
154 saddleSearch = std::make_unique<BiasedGradientSquaredDescent>(
155 saddle, initial->getPotentialEnergy(), params);
156 }
157
158#ifndef WITH_ARTN
159 // Post-dispatch guard for both ARTn entry points so users without a
160 // WITH_ARTN build get a clean per-case error instead of a silent
161 // fall-through. Two distinct messages so downstream tooling and the
162 // integration tests can match on the specific entry point.
163 if (params.saddle_search_options().method == "artn") {
164 throw std::runtime_error(
165 "saddle_search.method=artn requires a build with ARTn support "
166 "(reconfigure with -Dwith_artn=true)");
167 }
168 if (useARTnAsMinMode) {
169 throw std::runtime_error(
170 "saddle_search.minmode_method=artn requires a build with ARTn "
171 "support (reconfigure with -Dwith_artn=true)");
172 }
173#endif
174
175 if (!saddleSearch) {
176 throw std::runtime_error("unknown saddle_search.method");
177 }
178
179 (void)runPrepared();
180 return returnFiles;
181}
#define EONC_LOG_CRITICAL(...)
Definition EonLogger.h:267
std::shared_ptr< Matter > displacement
Configuration used during the saddle point search.
std::vector< std::string > returnFiles
Container for the results of the run.
std::shared_ptr< Matter > runPrepared()
const char DISP_LOAD[]
Definition EpiCenters.h:20
bool applyClientDisplacement(Matter &target, const Matter &initial, const Parameters &params, AtomMatrix *modeOut)
std::string getRelevantFile(std::string filename)
bool loadOrSynthesizeDisplacement(Matter &target, const Matter &initial, const std::string &displacementPath, const std::string &modePath, double scale)
AtomMatrix loadMode(FILE *modeFile, int nAtoms)
std::shared_ptr< Potential > makePotential(const Parameters &params)
constexpr bool io_ok(IoStatus s) noexcept
Definition ConFileIO.h:38

◆ runFromMatter()

std::shared_ptr< Matter > eonc::ProcessSearchJob::runFromMatter ( std::shared_ptr< Matter > seed)

In-process entry: seed reactant Matter, no pos.con.

Definition at line 184 of file ProcessSearchJob.cpp.

184 {
185 if (!seed) {
186 throw std::runtime_error("ProcessSearchJob::runFromMatter: null Matter");
187 }
188 initial = seed;
189 initial->setPotential(pot);
190 // A clone keeps this job's potential; makePotential rebuilds from the
191 // configuration and is the fallback for backends that cannot clone.
192 std::shared_ptr<Potential> min2Pot = pot;
193 if (pot->needsPerImageInstance() && params.main_options().parallel) {
194 auto cloned = pot->clonePotential();
195 min2Pot = cloned ? cloned : eonc::helpers::makePotential(params);
196 }
197 displacement = std::make_shared<Matter>(pot, params);
198 saddle = std::make_shared<Matter>(pot, params);
199 min1 = std::make_shared<Matter>(pot, params);
200 min2 = std::make_shared<Matter>(min2Pot, params);
201 AtomMatrix mode = AtomMatrix::Zero(initial->numberOfAtoms(), 3);
203 &mode)) {
204 *saddle = *initial;
205 }
207 *min1 = *min2 = *initial;
208 min2->setPotential(min2Pot);
209 if (params.saddle_search_options().method == "min_mode") {
210 saddleSearch = std::make_unique<MinModeSaddleSearch>(
211 saddle, mode, initial->getPotentialEnergy(), params, pot);
212 } else if (params.saddle_search_options().method == "basin_hopping") {
214 std::make_unique<BasinHoppingSaddleSearch>(min1, saddle, pot, params);
215 } else if (params.saddle_search_options().method == "dynamics") {
216 saddleSearch = std::make_unique<DynamicsSaddleSearch>(saddle, params);
217 } else if (params.saddle_search_options().method == "bgsd") {
218 saddleSearch = std::make_unique<BiasedGradientSquaredDescent>(
219 saddle, initial->getPotentialEnergy(), params);
220 } else {
221 throw std::runtime_error(
222 "ProcessSearchJob::runFromMatter: unsupported saddle_search.method");
223 }
224 return runPrepared();
225}

◆ runPrepared()

std::shared_ptr< Matter > eonc::ProcessSearchJob::runPrepared ( )
private

Definition at line 227 of file ProcessSearchJob.cpp.

227 {
228 if (!saddleSearch) {
229 throw std::runtime_error("unknown saddle_search.method");
230 }
231
232 int status = doProcessSearch();
233
234 printEndState(status);
235 saveData(status);
236
237 return min2 ? min2 : saddle;
238}
void printEndState(int status)
Logs the run status and makes sure the run was successful.
void saveData(int status)
Writes the results from the run to file.
int doProcessSearch(void)
Runs the correct saddle search; also checks if the run was successful.

◆ saveData()

void eonc::ProcessSearchJob::saveData ( int status)
private

Writes the results from the run to file.

Definition at line 432 of file ProcessSearchJob.cpp.

432 {
433 std::string resultsFilename("results.dat");
434 returnFiles.push_back(resultsFilename);
435
436 std::ofstream out(resultsFilename, std::ios::binary);
437 if (out) {
438 out << std::format("{} termination_reason\n", status);
439 out << std::format("{} termination_reason_text\n",
440 saddleSearch->describeStatus(status));
441 out << std::format("{} random_seed\n", params.main_options().randomSeed);
442 out << std::format(
443 "{} potential_type\n",
444 magic_enum::enum_name<PotType>(params.potential_options().potential));
445 out << std::format("{} total_force_calls\n",
447 out << std::format("{} force_calls_minimization\n", fCallsMin);
448 out << std::format("{} force_calls_saddle\n", fCallsSaddle);
449 out << std::format("{:.12e} potential_energy_saddle\n",
450 saddle->getPotentialEnergy());
451 out << std::format("{:.12e} potential_energy_reactant\n",
452 min1->getPotentialEnergy());
453 out << std::format("{:.12e} potential_energy_product\n",
454 min2->getPotentialEnergy());
455 out << std::format("{:.12e} barrier_reactant_to_product\n",
456 barriersValues[0]);
457 out << std::format("{:.12e} barrier_product_to_reactant\n",
458 barriersValues[1]);
459 if (params.saddle_search_options().method == "min_mode") {
460 out << std::format("{:.12e} displacement_saddle_distance\n",
461 displacement->perAtomNorm(*saddle));
462 } else {
463 out << std::format("{:.12e} displacement_saddle_distance\n", 0.0);
464 }
465 if (params.saddle_search_options().method == "dynamics") {
466 auto ds = dynamic_cast<DynamicsSaddleSearch &>(*saddleSearch);
467 out << std::format("{:.12e} simulation_time\n",
468 ds.time * params.constants().timeUnit);
469 out << std::format("{:.12e} md_temperature\n",
470 params.saddle_search_options().dynamics.temperature);
471 }
472 out << std::format("{} force_calls_prefactors\n", fCallsPrefactors);
473 out << std::format("{:.12e} prefactor_reactant_to_product\n",
475 out << std::format("{:.12e} prefactor_product_to_reactant\n",
477 }
478
479 std::string reactantFilename("reactant.con");
480 returnFiles.push_back(reactantFilename);
481 if (!eonc::io::io_ok(min1->matter2con(reactantFilename))) {
482 QUILL_LOG_ERROR(log, "Failed to write {}", reactantFilename);
483 }
484
485 std::string modeFilename("mode.dat");
486 returnFiles.push_back(modeFilename);
487 eonc::helpers::saveMode(modeFilename, saddle, saddleSearch->getEigenvector());
488
489 std::string saddleFilename("saddle.con");
490 returnFiles.push_back(saddleFilename);
491 if (!eonc::io::io_ok(saddle->matter2con(saddleFilename))) {
492 QUILL_LOG_ERROR(log, "Failed to write {}", saddleFilename);
493 }
494
495 std::string productFilename("product.con");
496 returnFiles.push_back(productFilename);
497 if (!eonc::io::io_ok(min2->matter2con(productFilename))) {
498 QUILL_LOG_ERROR(log, "Failed to write {}", productFilename);
499 }
500}
void saveMode(FILE *modeFile, std::shared_ptr< Matter > matter, AtomMatrix mode)
Write a mode; constrained axes are emitted as 0.

Member Data Documentation

◆ barriersValues

double eonc::ProcessSearchJob::barriersValues[2] {0.0, 0.0}
private

Array containg the value of the potential barriers from reactant to product and vice versa

Definition at line 110 of file ProcessSearchJob.h.

110{0.0, 0.0};

◆ displacement

std::shared_ptr<Matter> eonc::ProcessSearchJob::displacement
private

Configuration used during the saddle point search.

Definition at line 102 of file ProcessSearchJob.h.

◆ fCallsMin

size_t eonc::ProcessSearchJob::fCallsMin {0}
private

Force calls to minimize.

Definition at line 118 of file ProcessSearchJob.h.

118{0};

◆ fCallsPrefactors

size_t eonc::ProcessSearchJob::fCallsPrefactors {0}
private

Force calls to find the prefactors.

Definition at line 120 of file ProcessSearchJob.h.

120{0};

◆ fCallsSaddle

size_t eonc::ProcessSearchJob::fCallsSaddle {0}
private

Force calls to find the saddle.

Definition at line 116 of file ProcessSearchJob.h.

116{0};

◆ initial

std::shared_ptr<Matter> eonc::ProcessSearchJob::initial
private

Initial configuration.

Definition at line 98 of file ProcessSearchJob.h.

◆ log

eonc::log::Scoped eonc::ProcessSearchJob::log
private

Definition at line 79 of file ProcessSearchJob.h.

◆ min1

std::shared_ptr<Matter> eonc::ProcessSearchJob::min1
private

First minimum from the saddle.

Definition at line 104 of file ProcessSearchJob.h.

◆ min2

std::shared_ptr<Matter> eonc::ProcessSearchJob::min2
private

Second minimum from the saddle.

Definition at line 106 of file ProcessSearchJob.h.

◆ prefactorsValues

double eonc::ProcessSearchJob::prefactorsValues[2] {0.0, 0.0}
private

Array containg the value of the prefactors of the matter from reactant to product and vice versa

Definition at line 113 of file ProcessSearchJob.h.

113{0.0, 0.0};

◆ returnFiles

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

Container for the results of the run.

Definition at line 89 of file ProcessSearchJob.h.

◆ saddle

std::shared_ptr<Matter> eonc::ProcessSearchJob::saddle
private

Configuration used during the saddle point search.

Definition at line 100 of file ProcessSearchJob.h.

◆ saddleSearch

std::unique_ptr<SaddleSearchMethod> eonc::ProcessSearchJob::saddleSearch
private

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