35 std::string reactantFilename(
"pos.con");
36 std::string displacementFilename(
"displacement.con");
37 std::string modeFilename(
"direction.dat");
40 if (
params.saddle_search_options.method ==
"min_mode" ||
41 params.saddle_search_options.method ==
"basin_hopping" ||
42 params.saddle_search_options.method ==
"bgsd") {
44 }
else if (
params.saddle_search_options.method ==
"dynamics") {
49 auto min2Pot = (
pot->needsPerImageInstance() &&
params.main_options.parallel)
53 min2 = std::make_shared<Matter>(min2Pot,
params);
60 if (
params.process_search_options.minimize_first) {
61 QUILL_LOG_DEBUG(
log,
"Minimizing initial structure\n");
62 fctmp =
initial->getPotentialCalls();
65 QUILL_LOG_DEBUG(
log,
"Initial minimization took {} fcalls",
66 initial->getPotentialCalls() - fctmp);
72 if (
params.saddle_search_options.method ==
"min_mode" ||
73 params.saddle_search_options.method ==
"basin_hopping" ||
74 params.saddle_search_options.method ==
"bgsd") {
75 if (
params.saddle_search_options.displace_type ==
81 params.saddle_search_options.displace_magnitude)) {
83 displacementFilename, modeFilename);
96 const bool useARTnAsMinMode =
97 params.saddle_search_options.method ==
"min_mode" &&
98 params.saddle_search_options.minmode_method ==
"artn";
100 if (
params.saddle_search_options.method ==
"min_mode") {
101 if (
params.saddle_search_options.displace_type ==
108 if (useARTnAsMinMode) {
118 }
else if (
params.saddle_search_options.method ==
"artn") {
122 if (
params.saddle_search_options.displace_type ==
130 }
else if (
params.saddle_search_options.method ==
"basin_hopping") {
133 }
else if (
params.saddle_search_options.method ==
"dynamics") {
135 }
else if (
params.saddle_search_options.method ==
"bgsd") {
136 saddleSearch = std::make_unique<BiasedGradientSquaredDescent>(
145 if (
params.saddle_search_options.method ==
"artn") {
146 throw std::runtime_error(
147 "saddle_search.method=artn requires a build with ARTn support "
148 "(reconfigure with -Dwith_artn=true)");
150 if (useARTnAsMinMode) {
151 throw std::runtime_error(
152 "saddle_search.minmode_method=artn requires a build with ARTn "
153 "support (reconfigure with -Dwith_artn=true)");
170 fctmp =
pot->forceCallCounter;
172 if (
params.saddle_search_options.method ==
"min_mode" &&
173 params.saddle_search_options.minmode_method ==
176 }
else if (
params.saddle_search_options.method ==
"artn") {
181 EONC_LOG_DEBUG(
"Got {} calls in the saddle search, with previous {}",
195 params.process_search_options.minimization_offset;
196 min1->setPositions(displacedPos);
201 params.process_search_options.minimization_offset;
202 min2->setPositions(displacedPos);
207 QUILL_LOG_DEBUG(
log,
"Starting Minimization 1 & 2");
208 bool converged1{
false}, converged2{
false};
209 long fc1_before =
min1->getPotentialCalls();
210 long fc2_before =
min2->getPotentialCalls();
213 pot->isSharedInstanceThreadSafe() ||
pot->needsPerImageInstance();
214 if (
params.main_options.parallel && canParallel) {
217 min1->relax(
false,
params.debug_options.write_movies,
false,
"min1");
220 min2->relax(
false,
params.debug_options.write_movies,
false,
"min2");
224 min1->relax(
false,
params.debug_options.write_movies,
false,
"min1");
226 min2->relax(
false,
params.debug_options.write_movies,
false,
"min2");
230 (
min2->getPotentialCalls() - fc2_before);
231 QUILL_LOG_DEBUG(
log,
"Min1: {} fcalls, Min2: {} fcalls",
232 min1->getPotentialCalls() - fc1_before,
233 min2->getPotentialCalls() - fc2_before);
235 if (!converged1 || !converged2) {
250 const double tol =
params.structure_comparison_options.distance_difference;
251 auto countMoved = [&](
const Matter &m) {
253 for (
long i = 0; i <
initial->numberOfAtoms(); ++i) {
255 ->
pbc(
initial->getPositions().row(i) - m.getPositions().row(i))
263 "initial != min1: {} of {} atoms past the {} A tolerance "
264 "for min1 ({} for min2); largest separation {} A",
271 QUILL_LOG_DEBUG(
log,
"both minima are the initial state");
275 if (!
params.process_search_options.minimize_first) {
291 if (!
params.prefactor_options.default_value) {
292 fctmp =
min1->getPotentialCalls();
297 if (prefStatus == -1) {
303 if ((pref1 >
params.prefactor_options.max_value) ||
304 (pref1 <
params.prefactor_options.min_value)) {
308 if ((pref2 >
params.prefactor_options.max_value) ||
309 (pref2 <
params.prefactor_options.min_value)) {
324 std::string resultsFilename(
"results.dat");
327 std::ofstream out(resultsFilename, std::ios::binary);
329 out << std::format(
"{} termination_reason\n", status);
330 out << std::format(
"{} termination_reason_text\n",
332 out << std::format(
"{} random_seed\n",
params.main_options.randomSeed);
334 "{} potential_type\n",
335 magic_enum::enum_name<PotType>(
params.potential_options.potential));
336 out << std::format(
"{} total_force_calls\n",
338 out << std::format(
"{} force_calls_minimization\n",
fCallsMin);
339 out << std::format(
"{} force_calls_saddle\n",
fCallsSaddle);
340 out << std::format(
"{:.12e} potential_energy_saddle\n",
341 saddle->getPotentialEnergy());
342 out << std::format(
"{:.12e} potential_energy_reactant\n",
343 min1->getPotentialEnergy());
344 out << std::format(
"{:.12e} potential_energy_product\n",
345 min2->getPotentialEnergy());
346 out << std::format(
"{:.12e} barrier_reactant_to_product\n",
348 out << std::format(
"{:.12e} barrier_product_to_reactant\n",
350 if (
params.saddle_search_options.method ==
"min_mode") {
351 out << std::format(
"{:.12e} displacement_saddle_distance\n",
354 out << std::format(
"{:.12e} displacement_saddle_distance\n", 0.0);
356 if (
params.saddle_search_options.method ==
"dynamics") {
358 out << std::format(
"{:.12e} simulation_time\n",
359 ds.time *
params.constants.timeUnit);
360 out << std::format(
"{:.12e} md_temperature\n",
361 params.saddle_search_options.dynamics.temperature);
364 out << std::format(
"{:.12e} prefactor_reactant_to_product\n",
366 out << std::format(
"{:.12e} prefactor_product_to_reactant\n",
370 std::string reactantFilename(
"reactant.con");
373 QUILL_LOG_ERROR(
log,
"Failed to write {}", reactantFilename);
376 std::string modeFilename(
"mode.dat");
380 std::string saddleFilename(
"saddle.con");
383 QUILL_LOG_ERROR(
log,
"Failed to write {}", saddleFilename);
386 std::string productFilename(
"product.con");
389 QUILL_LOG_ERROR(
log,
"Failed to write {}", productFilename);
396 QUILL_LOG_DEBUG(
log,
"[Saddle Search] {}", msg);
398 QUILL_LOG_ERROR(
log,
"[Saddle Search] {}", msg);
Eigen::Matrix< double, Eigen::Dynamic, 3, eOnStorageOrder > AtomMatrix
#define EONC_LOG_DEBUG(...)
#define EONC_LOG_ERROR(...)
#define EONC_LOG_CRITICAL(...)
The optimizer class is used to serve as an abstract class for all optimizers, as well as to call an o...
Finds possible escape mecahnisms from a state.
std::vector< std::string > run(void) override
Kicks off the Process Search.
std::shared_ptr< Potential > pot
static const char MINMODE_GPRDIMER[]
@ STATUS_NEGATIVE_BARRIER
@ STATUS_FAILED_PREFACTOR
@ STATUS_BAD_NOT_CONNECTED
@ STATUS_BAD_HIGH_BARRIER
std::shared_ptr< Matter > displacement
Configuration used during the saddle point search.
size_t fCallsPrefactors
Force calls to find the prefactors.
size_t fCallsMin
Force calls to minimize.
std::shared_ptr< Matter > min1
First minimum from the saddle.
std::vector< std::string > returnFiles
Container for the results of the run.
double prefactorsValues[2]
std::shared_ptr< Matter > min2
Second minimum from the saddle.
std::shared_ptr< Matter > saddle
Configuration used during the saddle point search.
int doProcessSearch(void)
Runs the correct saddle search; also checks if the run was successful.
std::shared_ptr< Matter > initial
Initial configuration.
std::unique_ptr< SaddleSearchMethod > saddleSearch
Pulled from parameters.
size_t fCallsSaddle
Force calls to find the saddle.
void saveData(int status)
Writes the results from the run to file.
void printEndState(int status)
Logs the run status and makes sure the run was successful.
int getPrefactors(const Parameters ¶meters, Matter *min1, Matter *saddle, Matter *min2, double &pref1, double &pref2)
bool loadOrSynthesizeDisplacement(Matter &target, const Matter &initial, const std::string &displacementPath, const std::string &modePath, double scale)
AtomMatrix loadMode(FILE *modeFile, int nAtoms)
void saveMode(FILE *modeFile, std::shared_ptr< Matter > matter, AtomMatrix mode)
Write a mode; constrained axes are emitted as 0.
std::shared_ptr< Potential > makePotential(const Parameters ¶ms)
constexpr bool io_ok(IoStatus s) noexcept