26 {
27 if (!min1 || !saddle || !min2) {
29 return -1;
30 }
31 VectorXd min1Freqs, saddleFreqs, min2Freqs;
32
33
34 VectorXi atoms;
35
39 } else {
40 atoms =
movedAtoms(parameters, min1, saddle, min2);
41 }
42
43 if (atoms.size() == 0) {
45 return -1;
46 }
47
48
49 Hessian hessian(parameters, min1);
50 min1Freqs = hessian.getFreqs(min1, atoms);
51 if (min1Freqs.size() == 0) {
53 return -1;
54 }
55
57 min1Freqs = hessian.removeZeroFreqs(min1Freqs);
58 }
59
60
61 saddleFreqs = hessian.getFreqs(saddle, atoms);
62 if (saddleFreqs.size() == 0) {
64 return -1;
65 }
66
68 saddleFreqs = hessian.removeZeroFreqs(saddleFreqs);
69 }
70
71
72 min2Freqs = hessian.getFreqs(min2, atoms);
73 if (min2Freqs.size() == 0) {
76 }
77 return -1;
78 }
79
81 min2Freqs = hessian.removeZeroFreqs(min2Freqs);
82 }
83
84
85 if ((min1Freqs.size() != saddleFreqs.size()) ||
86 (min2Freqs.size() != saddleFreqs.size())) {
88 EONC_LOG_ERROR(
"[Prefactor] Bad prefactor: Hessian sizes do not match");
89 }
90 return -1;
91 }
92
96
97
98
99
100
101 int numNegFreq = 0;
102 for (int i = 0; i < min1Freqs.size(); i++) {
103 if (min1Freqs(i) < 0) {
104 EONC_LOG_DEBUG(
"[Prefactor] min1 had negative mode of {}", min1Freqs(i));
105 numNegFreq++;
106 }
107 }
108 if (numNegFreq != 0) {
109 EONC_LOG_DEBUG(
"[Prefactor] Error: {} negative modes at min1", numNegFreq);
110 return -1;
111 }
112
113 numNegFreq = 0;
114 for (int i = 0; i < saddleFreqs.size(); i++) {
115 if (saddleFreqs(i) < 0) {
116 numNegFreq++;
117 }
118 }
119 if (numNegFreq != 1) {
121 return -1;
122 }
123
124 numNegFreq = 0;
125 for (int i = 0; i < min2Freqs.size(); i++) {
126 if (min2Freqs(i) < 0) {
127 numNegFreq++;
128 }
129 }
130 if (numNegFreq != 0) {
132 return -1;
133 }
134
135
136 pref1 = 1.0;
137 pref2 = 1.0;
138
140
141
142 for (int i = 0; i < saddleFreqs.size(); i++) {
143 pref1 *= min1Freqs[i];
144 pref2 *= min2Freqs[i];
145 if (saddleFreqs[i] > 0) {
146 pref1 /= saddleFreqs[i];
147 pref2 /= saddleFreqs[i];
148 }
149 }
155 double h_bar = 6.582119e-16;
156 double h = 4.135667e-15;
157 double temp = (h_bar / (2.0 * kB_T));
158
159 for (int i = 0; i < min1Freqs.size(); i++) {
160 pref1 *= std::sinh(temp * (std::sqrt(min1Freqs[i]) / 10.18e-15));
161 pref2 *= std::sinh(temp * (std::sqrt(min2Freqs[i]) / 10.18e-15));
162
163 if (saddleFreqs[i] > 0) {
164 pref1 /= std::sinh(temp * (std::sqrt(saddleFreqs[i]) / 10.18e-15));
165 pref2 /= std::sinh(temp * (std::sqrt(saddleFreqs[i]) / 10.18e-15));
166 }
167 }
168 pref1 = (2.0 * kB_T / h) * pref1;
169 pref2 = (2.0 * kB_T / h) * pref2;
170 }
171 EONC_LOG_DEBUG(
"[Prefactor] reactant to product prefactor: {:.3e}", pref1);
172 EONC_LOG_DEBUG(
"[Prefactor] product to reactant prefactor: {:.3e}", pref2);
173 return 0;
174}
#define EONC_LOG_DEBUG(...)
#define EONC_LOG_ERROR(...)
const main_options_t & main_options() const
const structure_comparison_options_t & structure_comparison_options() const
const prefactor_options_t & prefactor_options() const
void logFreqs(const VectorXd &freqs, const char *name)
constexpr std::string_view RATE_HTST
VectorXi movedAtomsPct(const Parameters ¶meters, Matter *min1, Matter *saddle, Matter *min2)
VectorXi movedAtoms(const Parameters ¶meters, Matter *min1, Matter *saddle, Matter *min2)
constexpr std::string_view RATE_QQHTST
constexpr std::string_view FILTER_FRACTION
std::string filter_scheme