Loading...
Searching...
No Matches
eonc::ImprovedDimer Class Reference

#include <ImprovedDimer.h>

Inheritance diagram for eonc::ImprovedDimer:

Public Member Functions

 ImprovedDimer (std::shared_ptr< Matter > matter, const Parameters &params, std::shared_ptr< Potential > pot)
 ~ImprovedDimer ()=default
void compute (std::shared_ptr< Matter > matter, AtomMatrix initialDirection) override
double getEigenvalue () override
AtomMatrix getEigenvector () override
void setReferenceMode (const VectorXd &ref)
void clearReferenceMode ()
Public Member Functions inherited from eonc::LowestEigenmode
 LowestEigenmode (std::shared_ptr< Potential > potPassed, const Parameters &parameters)
virtual ~LowestEigenmode ()=default

Public Attributes

std::shared_ptr< Matter > x0
std::shared_ptr< Matter > x1
VectorXd tau
VectorXd theta
VectorXd F_R
double C_tau {0.0}
bool rotationDidConverge {false}
bool foundNegativeCurvature {false}
VectorXd F_R_Old
VectorXd thetaOld
double a {0.0}
double b {0.0}
double gamma {0.0}
bool init_cg {false}
std::vector< VectorXd > s
std::vector< VectorXd > y
std::vector< double > rho
bool init_lbfgs {false}
VectorXd rPrev
std::vector< VectorXd > gradients
std::vector< VectorXd > positions
Public Attributes inherited from eonc::LowestEigenmode
long totalForceCalls {0}
double statsTorque {0.0}
double statsCurvature {0.0}
double statsAngle {0.0}
long statsRotations {0}
long totalIterations {0}

Private Attributes

eonc::log::Scoped log
VectorXd fixedReferenceMode
bool hasFixedReference = false

Additional Inherited Members

Static Public Attributes inherited from eonc::LowestEigenmode
static const char MINMODE_DIMER [] = "dimer"
static const char MINMODE_GPRDIMER [] = "gprdimer"
static const char MINMODE_LANCZOS [] = "lanczos"
static const char MINMODE_DAVIDSON [] = "davidson"
Protected Attributes inherited from eonc::LowestEigenmode
std::shared_ptr< Potential > pot
const Parameters & params

Detailed Description

Definition at line 23 of file ImprovedDimer.h.

Constructor & Destructor Documentation

◆ ImprovedDimer()

eonc::ImprovedDimer::ImprovedDimer ( std::shared_ptr< Matter > matter,
const Parameters & params,
std::shared_ptr< Potential > pot )

Definition at line 31 of file ImprovedDimer.cpp.

35 // Each dimer image gets its own potential for lock-free parallel evaluation
36 // A clone keeps the caller's potential; makePotential rebuilds from the
37 // configuration and is the fallback for backends that cannot clone.
38 std::shared_ptr<Potential> x1Pot = pot;
39 if (pot->needsPerImageInstance() && params.main_options().parallel) {
40 auto cloned = pot->clonePotential();
41 x1Pot = cloned ? cloned : eonc::helpers::makePotential(params);
42 }
43 x0 = std::make_shared<Matter>(pot, params);
44 x1 = std::make_shared<Matter>(x1Pot, params);
45 // Matter's copy assignment copies the potential too; keep x1's own
46 // instance so the two images can be evaluated at the same time.
47 *x0 = *matter;
48 *x1 = *matter;
49 x1->setPotential(x1Pot);
50 tau.resize(3 * matter->numberOfAtoms());
51 tau.setZero();
53
54 if (params.dimer_options().opt_method == OptType::CG) {
55 init_cg = true;
56 }
57}
std::shared_ptr< Matter > x1
std::shared_ptr< Matter > x0
const Parameters & params
std::shared_ptr< Potential > pot
LowestEigenmode(std::shared_ptr< Potential > potPassed, const Parameters &parameters)
std::shared_ptr< Potential > makePotential(const Parameters &params)

◆ ~ImprovedDimer()

eonc::ImprovedDimer::~ImprovedDimer ( )
default

Member Function Documentation

◆ clearReferenceMode()

void eonc::ImprovedDimer::clearReferenceMode ( )

Definition at line 67 of file ImprovedDimer.cpp.

67{ hasFixedReference = false; }

◆ compute()

void eonc::ImprovedDimer::compute ( std::shared_ptr< Matter > matter,
AtomMatrix initialDirection )
overridevirtual

Implements eonc::LowestEigenmode.

Definition at line 69 of file ImprovedDimer.cpp.

70 {
71
72 VectorXd initialDirection = VectorXd::Map(initialDirectionAtomMatrix.data(),
73 3 * matter->numberOfAtoms());
74 tau = initialDirection.array() * matter->getFreeV().array();
77 if (tau.norm() > 1e-10) {
78 eonc::safemath::safe_normalize_inplace(tau);
79 } else {
80 // Fallback if the tangent was zero on free atoms (unlikely but safe)
81 tau.setRandom();
82 tau = tau.array() * matter->getFreeV().array();
83 eonc::safemath::safe_normalize_inplace(tau);
84 }
85
86 // Track the best (most negative) curvature and corresponding mode
87 double bestNegativeCurvature = std::numeric_limits<double>::max();
88 VectorXd bestTau = tau;
89 VectorXd bestX0Positions;
90 VectorXd bestG0, bestG1;
91
92 // Reference mode tracking for OCINEB mode-switching prevention
93 VectorXd referenceMode = hasFixedReference ? fixedReferenceMode : tau;
94
95 {
96 // Keep x1's per-image potential across the copy (see the constructor).
97 auto x1Pot = x1->getPotential();
98 *x0 = *matter;
99 *x1 = *matter;
100 x1->setPotential(x1Pot);
101 }
102 VectorXd x0_r = x0->getPositionsV();
103 bestX0Positions = x0_r;
104
105 double delta = params.main_options().finiteDifference;
106 x1->setPositionsV(x0_r + delta * tau);
107
108 // x0 and x1 in one call when both need one, so two calculator groups
109 // take one each; a cached x0 costs nothing.
110 {
111 Matter *const ends[] = {x0.get(), x1.get()};
113 }
114
115 // If we stepped into a high-energy wall, flip the tangent immediately
116 if (x1->getPotentialEnergy() - x0->getPotentialEnergy() > 10.0 * delta) {
117 tau = -tau;
118 x1->setPositionsV(x0_r + delta * tau);
119 QUILL_LOG_DEBUG(
120 log, "[IDimer] Initial tangent flipped due to high energy wall.");
121 }
122
123 // Optional: LOR / Lanczos / Davidson rotation backends (enum dispatch).
124 if (auto alt = runAlternativeRotation(
125 params.dimer_options().rotation_backend, matter, params, pot,
126 AtomMatrix::Map(tau.data(), matter->numberOfAtoms(), 3),
127 static_cast<quill::Logger *>(log))) {
128 C_tau = alt->eigenvalue;
129 tau = VectorXd::Map(alt->eigenvector.data(), 3 * matter->numberOfAtoms());
130 totalForceCalls += alt->forceCalls;
131 statsRotations = alt->rotations;
132 tau = tau.array() * matter->getFreeV().array();
133 eonc::safemath::safe_normalize_inplace(tau);
134 x0_r = matter->getPositionsV();
135 x0->setPositionsV(x0_r);
136 x1->setPositionsV(x0_r + delta * tau);
137 *matter = *x0;
138 rotationDidConverge = alt->converged;
140 return;
141 }
142
143 if (params.dimer_options().opt_method == OptType::LBFGS) {
144 s.clear();
145 y.clear();
146 rho.clear();
147 init_lbfgs = true;
148 }
149 if (params.dimer_options().opt_method == OptType::CG) {
150 init_cg = true;
151 }
152
153 VectorXd x1_rp, x1_r, tau_prime, tau_Old, g1_prime;
154 double phi_tol =
155 eonc::helpers::pi * (params.dimer_options().converged_angle / 180.0);
156 double phi_prime = 0.0;
157 double phi_min = 0.0;
158
159 statsRotations = 0;
160
161 // Use x1's potential for the trial rotation image (consistent with per-image)
162 auto x1p = std::make_shared<Matter>(x1->getPotential(), params);
163
164 // Melander, Laasonen, Jonsson, JCTC 11(3), 1055-1062, 2015
165 if (params.dimer_options().remove_rotation) {
167 AtomMatrix::Map(x0_r.data(), x0->numberOfAtoms(), 3), x1);
168 x1_r = x1->getPositionsV();
169 tau = x1->pbcV(x1_r - x0_r);
170 eonc::safemath::safe_normalize_inplace(tau);
171 x1_r = x0_r + tau * delta;
172 x1->setPositionsV(x1_r);
173 }
174
175 // Calculate gradients on x0 and x1.
176 // Prefer batched evaluation when the potential supports it (single
177 // model.forward() call for both replicas, e.g. MetatomicPotential on GPU).
178 // Else fall back to thread-parallel when the potential is thread-safe or
179 // wants per-image instances. Otherwise sequential.
180 VectorXd g0, g1;
181 // Two threads may share an instance only when it is thread safe; a
182 // per-image potential needs x0 and x1 to hold distinct instances.
183 bool canParallel = eonc::potAllowsSharedInstance(*pot) ||
184 (pot->needsPerImageInstance() &&
185 x0->getPotential().get() != x1->getPotential().get());
186 if (pot->supportsBatchEvaluation()) {
187 long n = x0->numberOfAtoms();
188 bool x0dirty = x0->needsForceUpdate();
189 bool x1dirty = x1->needsForceUpdate();
190
191 if (x0dirty && x1dirty) {
192 auto nrs0 = x0->getAtomicNrs();
193 auto nrs1 = x1->getAtomicNrs();
194 auto box0 = x0->getCell();
195 auto box1 = x1->getCell();
196 const double *posVec[] = {x0->getPositions().data(),
197 x1->getPositions().data()};
198 const int *nrsVec[] = {nrs0.data(), nrs1.data()};
199 double *frcVec[] = {x0->forcesData(), x1->forcesData()};
200 double energies[2], vars[2];
201 const double *boxVec[] = {box0.data(), box1.data()};
202 pot->forceBatch(2, n, posVec, nrsVec, frcVec, energies, vars, boxVec);
203 x0->setComputedPotential(energies[0], vars[0]);
204 x1->setComputedPotential(energies[1], vars[1]);
205 } else if (x1dirty) {
206 auto nrs = x1->getAtomicNrs();
207 auto box = x1->getCell();
208 const double *posVec[] = {x1->getPositions().data()};
209 const int *nrsVec[] = {nrs.data()};
210 double *frcVec[] = {x1->forcesData()};
211 double energies[1], vars[1];
212 const double *boxVec[] = {box.data()};
213 pot->forceBatch(1, n, posVec, nrsVec, frcVec, energies, vars, boxVec);
214 x1->setComputedPotential(energies[0], vars[0]);
215 } else if (x0dirty) {
216 x0->getForcesRaw(); // through computePotential
217 }
218 g0 = -x0->getForcesV();
219 g1 = -x1->getForcesV();
220 } else if (params.main_options().parallel && canParallel) {
221 // std::thread instead of std::jthread (Apple Clang libc++). Guard so an
222 // exception from the foreground call still joins t0 before rethrow.
223 // An exception may not leave a thread function (std::terminate), so t0
224 // hands its error back and the caller rethrows after the join.
225 std::exception_ptr t0Error;
226 std::thread t0([&] {
227 try {
228 g0 = -x0->getForcesV();
229 } catch (...) {
230 t0Error = std::current_exception();
231 }
232 });
233 try {
234 g1 = -x1->getForcesV();
235 } catch (...) {
236 t0.join();
237 throw;
238 }
239 t0.join();
240 if (t0Error)
241 std::rethrow_exception(t0Error);
242 } else {
243 g0 = -x0->getForcesV();
244 g1 = -x1->getForcesV();
245 }
246
247 bestG0 = g0;
248 bestG1 = g1;
249
250 positions.clear();
251 gradients.clear();
252 positions.push_back(x0->getPositionsV());
253 positions.push_back(x1->getPositionsV());
254 gradients.push_back(g0);
255 gradients.push_back(g1);
256
257 do { // Rotation loop: converge phi or hit max rotations
258
259 // Rotational force, F_R
260 F_R = -2.0 * (g1 - g0) + 2.0 * ((g1 - g0).dot(tau)) * tau;
261 statsTorque = eonc::safemath::safe_div(F_R.norm(), delta * 2.0, 0.0);
262
263 // Determine step direction theta via selected optimizer
264 if (params.dimer_options().opt_method == OptType::SD) {
265 theta = eonc::safemath::safe_normalized(F_R);
266
267 } else if (params.dimer_options().opt_method == OptType::CG) {
268 if (init_cg) {
269 init_cg = false;
270 gamma = 0.0;
271 } else {
272 a = std::abs(F_R.dot(F_R_Old));
273 b = F_R_Old.squaredNorm();
274 gamma = (a < 0.5 * b)
276 : 0.0;
277 }
278
279 theta = (gamma == 0.0) ? F_R : F_R + thetaOld * gamma;
280 theta -= theta.dot(tau) * tau;
281 thetaOld = theta;
282 if (theta.norm() < eonc::safemath::eps) {
283 theta = F_R - F_R.dot(tau) * tau;
284 }
285 eonc::safemath::safe_normalize_inplace(theta);
286 F_R_Old = F_R;
287
288 } else if (params.dimer_options().opt_method == OptType::LBFGS) {
289 if (!init_lbfgs) {
290 VectorXd s0 = tau - tau_Old;
291 s.push_back(s0);
292 VectorXd y0 =
293 eonc::safemath::safe_div(1.0, delta, 0.0) * (F_R_Old - F_R);
294 y.push_back(y0);
295 rho.push_back(eonc::safemath::safe_recip(s0.dot(y0), 0.0));
296 } else {
297 init_lbfgs = false;
298 }
299
300 double H0 = 1.0 / 60.0;
301 size_t loopmax = s.size();
302 std::vector<double> alpha(loopmax);
303
304 VectorXd q = -F_R;
305 for (long i = static_cast<long>(loopmax) - 1; i >= 0; i--) {
306 alpha[i] = rho[i] * s[i].dot(q);
307 q -= alpha[i] * y[i];
308 }
309 VectorXd z = H0 * q;
310 for (size_t i = 0; i < loopmax; i++) {
311 double bv = rho[i] * y[i].dot(z);
312 z += s[i] * (alpha[i] - bv);
313 }
314
315 double vd = std::clamp(-eonc::safemath::safe_normalized(z).dot(
316 eonc::safemath::safe_normalized(F_R)),
317 -1.0, 1.0);
318 double angle =
320
321 if (angle > 87.0) {
322 s.clear();
323 y.clear();
324 rho.clear();
325 z = -F_R;
326 }
327
328 theta = -eonc::safemath::safe_normalized(z);
329 theta -= theta.dot(tau) * tau;
330 eonc::safemath::safe_normalize_inplace(theta);
331
332 thetaOld = theta;
333 F_R_Old = F_R;
334 tau_Old = tau;
335 }
336
337 // Curvature along tau
338 C_tau = eonc::safemath::safe_div((g1 - g0).dot(tau), delta, 0.0);
339
340 // Track best negative curvature for mode restoration
341 if (C_tau < bestNegativeCurvature) {
342 bestNegativeCurvature = C_tau;
343 bestTau = tau;
344 bestX0Positions = x0->getPositionsV();
345 bestG0 = g0;
346 bestG1 = g1;
348 }
349
350 // Estimate optimum rotation angle
351 double d_C_tau_d_phi =
352 2.0 * eonc::safemath::safe_div((g1 - g0).dot(theta), delta, 0.0);
353 phi_prime = -0.5 * eonc::safemath::safe_atan_ratio(
354 d_C_tau_d_phi, 2.0 * std::abs(C_tau), 0.0);
355 statsAngle = phi_prime * (180.0 / eonc::helpers::pi);
356
357 double alignment = std::abs(tau.dot(referenceMode));
358
359 if (std::abs(phi_prime) > phi_tol) {
360 double b1 = 0.5 * d_C_tau_d_phi;
361
362 // Trial rotation to phi_prime
363 x0_r = x0->getPositionsV();
364 tau_prime = tau * std::cos(phi_prime) + theta * std::sin(phi_prime);
365 tau_prime = eonc::safemath::safe_normalized(tau_prime);
366 x1_rp = x0_r + tau_prime * delta;
367
368 *x1p = *x1;
369 x1p->setPositionsV(x1_rp);
370 g1_prime = -x1p->getForcesV();
371
372 positions.push_back(x1_rp);
373 gradients.push_back(g1_prime);
374
375 double C_tau_prime =
376 eonc::safemath::safe_div((g1_prime - g0).dot(tau_prime), delta, 0.0);
377
378 // Optimal rotation angle via Fourier interpolation
379 double a1 = eonc::safemath::safe_div(
380 C_tau - C_tau_prime + b1 * std::sin(2.0 * phi_prime),
381 1.0 - std::cos(2.0 * phi_prime), 0.0);
382 double a0 = 2.0 * (C_tau - a1);
383 phi_min = 0.5 * eonc::safemath::safe_atan_ratio(b1, a1, 0.0);
384
385 double C_tau_min = 0.5 * a0 + a1 * std::cos(2.0 * phi_min) +
386 b1 * std::sin(2.0 * phi_min);
387
388 // If curvature is being maximized, push over pi/2
389 if (C_tau_min > C_tau) {
390 phi_min += eonc::helpers::pi * 0.5;
391 C_tau_min = 0.5 * a0 + a1 * std::cos(2.0 * phi_min) +
392 b1 * std::sin(2.0 * phi_min);
393 }
394
395 // Keep phi_min in [-pi/2, pi/2] for accurate LBFGS
396 if (phi_min > eonc::helpers::pi * 0.5) {
397 phi_min -= eonc::helpers::pi;
398 }
399 statsAngle = phi_min * (180.0 / eonc::helpers::pi);
400
401 // Apply optimal rotation
402 tau = tau * std::cos(phi_min) + theta * std::sin(phi_min);
403 tau = eonc::safemath::safe_normalized(tau);
404 x1_r = x0_r + tau * delta;
405
406 // Melander, Laasonen, Jonsson, JCTC 11(3), 1055-1062, 2015
407 if (params.dimer_options().remove_rotation) {
408 x1->setPositionsV(x1_r);
410 AtomMatrix::Map(x0_r.data(), x0->numberOfAtoms(), 3), x1);
411 x1_r = x1->getPositionsV();
412 tau = x1_r - x0_r;
413 eonc::safemath::safe_normalize_inplace(tau);
414 x1_r = x0_r + tau * delta;
415 }
416
417 x1->setPositionsV(x1_r);
418 C_tau = C_tau_min;
419
420 // Interpolate g1 at phi_min from g1 and g1_prime (saves one force call)
421 double sin_pp = std::sin(phi_prime);
422 g1 = g1 * eonc::safemath::safe_div(std::sin(phi_prime - phi_min), sin_pp,
423 0.0) +
424 g1_prime * eonc::safemath::safe_div(std::sin(phi_min), sin_pp, 0.0) +
425 g0 * (1.0 - std::cos(phi_min) -
426 std::sin(phi_min) * std::tan(phi_prime * 0.5));
427
428 statsTorque = eonc::safemath::safe_div(F_R.norm(), 2.0 * delta, 0.0);
429 statsRotations += 1;
430 QUILL_LOG_INFO(
431 log,
432 "[IDimerRot] ----- --------- ---------- ------------------ "
433 "{:9.4f} {:7.3f} {:6.3f} {:4} {:5.3f}",
435 } else {
436 QUILL_LOG_INFO(
437 log,
438 "[IDimerRot] ----- --------- ---------- ------------------ "
439 "{:9.4f} {:7.3f} ------ ---- {:5.3f}",
440 C_tau, F_R.norm() / delta, alignment);
441 }
442
443 // Check for mode loss (OCINEB dimer refinement)
444 if (alignment < params.neb_options().climbing_image.ocineb.angle_tol &&
445 params.neb_options().climbing_image.ocineb.use_mmf) {
446 QUILL_LOG_WARNING(
447 log, "Terminating dimer due to lost mode (align {:.3f}).", alignment);
448 rotationDidConverge = false;
449
450 if (bestNegativeCurvature < 0.0) {
451 // Restore the best negative curvature state
452 C_tau = bestNegativeCurvature;
453 tau = bestTau;
454 x0->setPositionsV(bestX0Positions);
455 x1->setPositionsV(bestX0Positions + delta * bestTau);
456 *matter = *x0;
457 QUILL_LOG_DEBUG(
458 log, "Restored best negative curvature state: C_tau={:.4f}", C_tau);
459 throw eonc::DimerModeRestoredException();
460 } else {
461 QUILL_LOG_WARNING(
462 log, "Never found negative curvature. Final C_tau: {:.4f}", C_tau);
463 throw eonc::DimerModeLostException();
464 }
465 }
466
467 } while (std::abs(phi_prime) > std::abs(phi_tol) &&
468 std::abs(phi_min) > std::abs(phi_tol) &&
469 statsRotations < params.dimer_options().rotations_max);
470}
std::vector< VectorXd > s
VectorXd fixedReferenceMode
std::vector< VectorXd > positions
std::vector< VectorXd > gradients
std::vector< VectorXd > y
eonc::log::Scoped log
std::vector< double > rho
void rotationRemove(const AtomMatrix r1, std::shared_ptr< Matter > m2)
constexpr double pi
constexpr double safe_div(double num, double denom, double fallback=0.0)
Definition SafeMath.h:21
double safe_acos(double x)
Definition SafeMath.h:34
constexpr double eps
Definition SafeMath.h:19
constexpr double safe_recip(double x, double fallback=0.0)
Definition SafeMath.h:29
double safe_atan_ratio(double num, double denom, double fallback=0.0)
Definition SafeMath.h:42
void evaluateTogether(Potential &pot, std::span< Matter *const > systems)
Evaluates every system that needs a force update.
Definition Matter.cpp:847
bool potAllowsSharedInstance(const P &p) noexcept
std::optional< DimerRotationResult > runAlternativeRotation(DimerRotationBackend backend, const std::shared_ptr< Matter > &matter, const Parameters &params, const std::shared_ptr< Potential > &pot, const AtomMatrix &initialDirection, quill::Logger *log=nullptr)
Run Lanczos, Davidson, or LOR.

◆ getEigenvalue()

double eonc::ImprovedDimer::getEigenvalue ( )
overridevirtual

Implements eonc::LowestEigenmode.

Definition at line 472 of file ImprovedDimer.cpp.

472{ return C_tau; }

◆ getEigenvector()

AtomMatrix eonc::ImprovedDimer::getEigenvector ( )
overridevirtual

Implements eonc::LowestEigenmode.

Definition at line 474 of file ImprovedDimer.cpp.

474 {
475 return AtomMatrix::Map(tau.data(), x0->numberOfAtoms(), 3);
476}

◆ setReferenceMode()

void eonc::ImprovedDimer::setReferenceMode ( const VectorXd & ref)

Definition at line 59 of file ImprovedDimer.cpp.

59 {
61 if (fixedReferenceMode.norm() > 1e-10) {
62 eonc::safemath::safe_normalize_inplace(fixedReferenceMode);
63 }
64 hasFixedReference = true;
65}

Member Data Documentation

◆ a

double eonc::ImprovedDimer::a {0.0}

Definition at line 55 of file ImprovedDimer.h.

55{0.0}, b{0.0}, gamma{0.0};

◆ b

double eonc::ImprovedDimer::b {0.0}

Definition at line 55 of file ImprovedDimer.h.

55{0.0}, b{0.0}, gamma{0.0};

◆ C_tau

double eonc::ImprovedDimer::C_tau {0.0}

Definition at line 46 of file ImprovedDimer.h.

46{0.0}; // Curvature along tau

◆ F_R

VectorXd eonc::ImprovedDimer::F_R

Definition at line 45 of file ImprovedDimer.h.

◆ F_R_Old

VectorXd eonc::ImprovedDimer::F_R_Old

Definition at line 53 of file ImprovedDimer.h.

◆ fixedReferenceMode

VectorXd eonc::ImprovedDimer::fixedReferenceMode
private

Definition at line 28 of file ImprovedDimer.h.

◆ foundNegativeCurvature

bool eonc::ImprovedDimer::foundNegativeCurvature {false}

Definition at line 51 of file ImprovedDimer.h.

51{false};

◆ gamma

double eonc::ImprovedDimer::gamma {0.0}

Definition at line 55 of file ImprovedDimer.h.

55{0.0}, b{0.0}, gamma{0.0};

◆ gradients

std::vector<VectorXd> eonc::ImprovedDimer::gradients

Definition at line 64 of file ImprovedDimer.h.

◆ hasFixedReference

bool eonc::ImprovedDimer::hasFixedReference = false
private

Definition at line 29 of file ImprovedDimer.h.

◆ init_cg

bool eonc::ImprovedDimer::init_cg {false}

Definition at line 56 of file ImprovedDimer.h.

56{false};

◆ init_lbfgs

bool eonc::ImprovedDimer::init_lbfgs {false}

Definition at line 61 of file ImprovedDimer.h.

61{false};

◆ log

eonc::log::Scoped eonc::ImprovedDimer::log
private

Definition at line 26 of file ImprovedDimer.h.

◆ positions

std::vector<VectorXd> eonc::ImprovedDimer::positions

Definition at line 65 of file ImprovedDimer.h.

◆ rho

std::vector<double> eonc::ImprovedDimer::rho

Definition at line 60 of file ImprovedDimer.h.

◆ rotationDidConverge

bool eonc::ImprovedDimer::rotationDidConverge {false}

Definition at line 50 of file ImprovedDimer.h.

50{false};

◆ rPrev

VectorXd eonc::ImprovedDimer::rPrev

Definition at line 62 of file ImprovedDimer.h.

◆ s

std::vector<VectorXd> eonc::ImprovedDimer::s

Definition at line 59 of file ImprovedDimer.h.

◆ tau

VectorXd eonc::ImprovedDimer::tau

Definition at line 43 of file ImprovedDimer.h.

◆ theta

VectorXd eonc::ImprovedDimer::theta

Definition at line 44 of file ImprovedDimer.h.

◆ thetaOld

VectorXd eonc::ImprovedDimer::thetaOld

Definition at line 54 of file ImprovedDimer.h.

◆ x0

std::shared_ptr<Matter> eonc::ImprovedDimer::x0

Definition at line 41 of file ImprovedDimer.h.

◆ x1

std::shared_ptr<Matter> eonc::ImprovedDimer::x1

Definition at line 42 of file ImprovedDimer.h.

◆ y

std::vector<VectorXd> eonc::ImprovedDimer::y

Definition at line 59 of file ImprovedDimer.h.


The documentation for this class was generated from the following files: