Loading...
Searching...
No Matches
PrefactorJob.cpp
Go to the documentation of this file.
1/*
2** This file is part of eOn.
3**
4** SPDX-License-Identifier: BSD-3-Clause
5**
6** Copyright (c) 2010--present, eOn Development Team
7** All rights reserved.
8**
9** Repo:
10** https://github.com/TheochemUI/eOn
11*/
12#include "eon/PrefactorJob.h"
13#include "eon/EonLogger.h"
14#include "eon/HelperFunctions.h"
15#include "eon/Hessian.h"
16#include "eon/Matter.h"
17#include "eon/PotRegistry.h"
18#include "eon/Potential.h"
19#include "eon/Prefactor.h"
20
21#include <cmath>
22#include <filesystem>
23#include <format>
24#include <fstream>
25#include <stdexcept>
26#include <string>
27
28const char PrefactorJob::PREFACTOR_REACTANT[] = "reactant";
29const char PrefactorJob::PREFACTOR_SADDLE[] = "saddle";
30const char PrefactorJob::PREFACTOR_PRODUCT[] = "product";
31
32std::vector<std::string> PrefactorJob::run() {
33 std::vector<std::string> returnFiles;
34 VectorXd freqs;
35
36 std::string reactantFilename("reactant.con");
37 std::string saddleFilename("saddle.con");
38 std::string productFilename("product.con");
39
40 auto reactant = std::make_unique<Matter>(pot, params);
41 auto saddle = std::make_unique<Matter>(pot, params);
42 auto product = std::make_unique<Matter>(pot, params);
43
44 if (!eonc::io::io_ok(reactant->con2matter("reactant.con")) ||
45 !eonc::io::io_ok(saddle->con2matter("saddle.con")) ||
46 !eonc::io::io_ok(product->con2matter("product.con"))) {
47 EONC_LOG_CRITICAL("Failed to load reactant/saddle/product for prefactor");
48 throw std::runtime_error("failed to load prefactor geometries");
49 }
50 double pref1, pref2;
51 eonc::Prefactor::getPrefactors(params, reactant.get(), saddle.get(),
52 product.get(), pref1, pref2);
53
54 VectorXi atoms;
55 if (params.prefactor_options.all_free_atoms) {
56 std::string matterFilename;
57 if (params.prefactor_options.configuration ==
59 matterFilename = reactantFilename;
60 } else if (params.prefactor_options.configuration ==
62 matterFilename = saddleFilename;
63 } else if (params.prefactor_options.configuration ==
65 matterFilename = productFilename;
66 }
67 if (!eonc::io::io_ok(reactant->con2matter(matterFilename)) ||
68 !eonc::io::io_ok(saddle->con2matter(matterFilename)) ||
69 !eonc::io::io_ok(product->con2matter(matterFilename))) {
70 EONC_LOG_CRITICAL("Failed to reload {} for all-free-atoms prefactor",
71 matterFilename);
72 throw std::runtime_error("failed to load prefactor configuration");
73 }
74
75 atoms = eonc::Prefactor::allFreeAtoms(reactant.get());
76 } else {
77 if (!eonc::io::io_ok(reactant->con2matter(reactantFilename)) ||
78 !eonc::io::io_ok(saddle->con2matter(saddleFilename)) ||
79 !eonc::io::io_ok(product->con2matter(productFilename))) {
81 "Failed to reload reactant/saddle/product for prefactor");
82 throw std::runtime_error("failed to load prefactor geometries");
83 }
84
85 atoms = eonc::Prefactor::movedAtoms(params, reactant.get(), saddle.get(),
86 product.get());
87 }
88 assert(3 * atoms.rows() > 0);
89
90 if (params.prefactor_options.configuration ==
92 Hessian hessian(params, reactant.get());
93 freqs = hessian.getFreqs(reactant.get(), atoms);
94 } else if (params.prefactor_options.configuration ==
96 Hessian hessian(params, saddle.get());
97 freqs = hessian.getFreqs(saddle.get(), atoms);
98 } else if (params.prefactor_options.configuration ==
100 Hessian hessian(params, product.get());
101 freqs = hessian.getFreqs(product.get(), atoms);
102 }
103
104 bool failed = freqs.size() != 3 * atoms.rows();
105
106 std::string results_file("results.dat");
107 std::string freq_file("freq.dat");
108 returnFiles.push_back(results_file);
109 returnFiles.push_back(freq_file);
110
111 std::ofstream outResults(results_file, std::ios::binary);
112 std::ofstream outFreq(freq_file, std::ios::binary);
113
114 if (outResults) {
115 outResults << std::format("{} termination_reason\n", failed ? 1 : 0);
116 outResults << std::format("{} termination_reason_text\n",
117 failed ? "fail" : "good");
118 outResults << "prefactor job_type\n";
119 outResults << std::format("{} good\n", failed ? "false" : "true");
120 outResults << std::format("{} force_calls\n",
121 PotRegistry::get().total_force_calls());
122 outResults << std::format("{} total_force_calls\n",
123 PotRegistry::get().total_force_calls());
124 }
125
126 if (outFreq && !failed) {
127 for (int i = 0; i < freqs.size(); i++) {
128 if (0. < freqs[i]) {
129 outFreq << std::format("{:f}\n",
130 std::sqrt(freqs[i]) /
131 (2 * eonc::helpers::pi * 10.18e-15));
132 } else {
133 outFreq << std::format("{:f}\n",
134 -std::sqrt(-freqs[i]) /
135 (2 * eonc::helpers::pi * 10.18e-15));
136 }
137 }
138 }
139
140 if (std::filesystem::exists("freqs.dat")) {
141 returnFiles.push_back("freqs.dat");
142 }
143 if (std::filesystem::exists("hessian.dat")) {
144 returnFiles.push_back("hessian.dat");
145 }
146
147 return returnFiles;
148}
#define EONC_LOG_CRITICAL(...)
Definition EonLogger.h:268
std::vector< std::string > run()
Virtual run; used solely for dynamic dispatch.
static const char PREFACTOR_REACTANT[]
static const char PREFACTOR_PRODUCT[]
static const char PREFACTOR_SADDLE[]
VectorXd getFreqs(Matter *matterIn, const VectorXi &atomsIn)
Definition Hessian.cpp:99
std::shared_ptr< Potential > pot
Definition Job.h:55
Parameters params
Definition Job.h:54
static PotRegistry & get() noexcept
Process-lifetime singleton.
static const char PREFACTOR_REACTANT[]
static const char PREFACTOR_PRODUCT[]
static const char PREFACTOR_SADDLE[]
VectorXi allFreeAtoms(Matter *matter)
VectorXi movedAtoms(const Parameters &parameters, Matter *min1, Matter *saddle, Matter *min2)
int getPrefactors(const Parameters &parameters, Matter *min1, Matter *saddle, Matter *min2, double &pref1, double &pref2)
Definition Prefactor.cpp:22
constexpr double pi
constexpr bool io_ok(IoStatus s) noexcept
Definition ConFileIO.h:38