94 {
95 if (!matter) {
96 throw std::runtime_error("xtsci min-mode requires a geometry");
97 }
98 rgsaddle_version_t stamp{};
99 checkStatus(rgsaddle_abi_stamp(&stamp), "rgsaddle_abi_stamp");
100 if (stamp.major != RGSADDLE_ABI_MAJOR) {
101 throw std::runtime_error("incompatible rgsaddle ABI");
102 }
103 const auto nAtoms = matter->numberOfAtoms();
104 if (initialDirection.rows() != nAtoms || initialDirection.cols() != 3) {
105 throw std::runtime_error("xtsci min-mode direction shape");
106 }
107
108
109
110 if (!(initialDirection.norm() > 1.0e-14)) {
116 return;
117 }
118 const AtomMatrix saved = matter->getPositions();
120 const auto &dim =
params.dimer_options();
121 rgsaddle_minmode_config_t config{};
122 config.version = RGSADDLE_VERSION_INIT;
123 config.flags = 0;
124
125 const bool lanczos =
params.saddle_search_options().minmode_method ==
127 config.kind = lanczos ? RGSADDLE_MINMODE_LANCZOS : RGSADDLE_MINMODE_DIMER;
128 config.method =
params.optimizer_options().xtsci.method ==
"lbfgs"
129 ? RGSADDLE_METHOD_LBFGS
130 : RGSADDLE_METHOD_FIRE;
131
132
133
134 const double fd =
params.main_options().finiteDifference;
135 config.dr = fd > 0.0 ? fd : 1.0e-3;
136 config.rotation_tol = dim.torque_min;
137 config.max_rotations = std::max<long>(1, dim.rotations_max);
138 config.krylov_dim = 12;
139 config.force_tol = 0.0;
140
141 config.max_move = 0.0;
142#if RGSADDLE_ABI_MINOR >= 5
144 config.difference =
146 ? RGSADDLE_DIFFERENCE_FORWARD
147 : RGSADDLE_DIFFERENCE_CENTRAL;
148#endif
149
150 Matter probe(*matter);
151 MinModeUser ctx{matter.get(), &probe, &
m_fixed};
152 const size_t callsBefore = matter->getPotentialCalls();
153 rgsaddle_report_t report{};
154 std::vector<double> mode(static_cast<size_t>(3 * nAtoms), 0.0);
155#if RGSADDLE_ABI_MINOR >= 5
156
157
158
162 }
164 m_session = rgsaddle_minmode_create(&config, nAtoms, saved.data(),
165 initialDirection.data());
167 throw std::runtime_error("rgsaddle_minmode_create failed");
168 }
171 checkStatus(rgsaddle_minmode_set_mode(
m_session, initialDirection.data()),
172 "rgsaddle_minmode_set_mode");
173 }
174 const AtomMatrix gradient = -matter->getForces();
175 checkStatus(
176 rgsaddle_minmode_set_position(
m_session, saved.data(), gradient.data()),
177 "rgsaddle_minmode_set_position");
178 const int rc =
179 xts_minmode_estimate(
m_session, surfaceCallback, &ctx, &report);
180 checkStatus(rc, "rgsaddle_minmode_estimate");
181 checkStatus(rgsaddle_minmode_mode(
m_session, mode.data()),
182 "rgsaddle_minmode_mode");
183#else
184 RgsaddleMinMode *session = rgsaddle_minmode_create(
185 &config, nAtoms, saved.data(), initialDirection.data());
186 if (session == nullptr) {
187 throw std::runtime_error("rgsaddle_minmode_create failed");
188 }
189 const int rc = rgsaddle_minmode_step(session, surfaceCallback, &ctx, &report);
190 const int modeRc = rgsaddle_minmode_mode(session, mode.data());
191 rgsaddle_minmode_free(session);
192 checkStatus(rc, "rgsaddle_minmode_step");
193 checkStatus(modeRc, "rgsaddle_minmode_mode");
194#endif
201 static_cast<long>(matter->getPotentialCalls() - callsBefore);
202}
Eigen::Matrix< double, Eigen::Dynamic, 3, eOnStorageOrder > AtomMatrix
static const char MINMODE_LANCZOS[]
FdScheme parseFdScheme(std::string_view scheme)