96 throw std::runtime_error(
"xtsci min-mode requires a geometry");
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");
103 const auto nAtoms = matter->numberOfAtoms();
104 if (initialDirection.rows() != nAtoms || initialDirection.cols() != 3) {
105 throw std::runtime_error(
"xtsci min-mode direction shape");
110 if (!(initialDirection.norm() > 1.0e-14)) {
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;
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;
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);
142#if RGSADDLE_ABI_MINOR >= 5
146 ? RGSADDLE_DIFFERENCE_FORWARD
147 : RGSADDLE_DIFFERENCE_CENTRAL;
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
165 initialDirection.data());
167 throw std::runtime_error(
"rgsaddle_minmode_create failed");
171 checkStatus(rgsaddle_minmode_set_mode(
m_session, initialDirection.data()),
172 "rgsaddle_minmode_set_mode");
174 const AtomMatrix gradient = -matter->getForces();
176 rgsaddle_minmode_set_position(
m_session, saved.data(), gradient.data()),
177 "rgsaddle_minmode_set_position");
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");
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");
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");
201 static_cast<long>(matter->getPotentialCalls() - callsBefore);