Loading...
Searching...
No Matches
eonc::detail Namespace Reference

Functions

template<typename Solver>
DimerRotationResult runRotationSolver (const std::shared_ptr< Matter > &matter, const Parameters &params, const std::shared_ptr< Potential > &pot, const AtomMatrix &initialDirection)
double maxFreeAtomForceNormScalar (const double *forces, const double *fixed, long begin, long nAtoms)
 Scalar max of per-atom Euclidean norms on [begin, nAtoms).

Function Documentation

◆ maxFreeAtomForceNormScalar()

double eonc::detail::maxFreeAtomForceNormScalar ( const double * forces,
const double * fixed,
long begin,
long nAtoms )
inline

Scalar max of per-atom Euclidean norms on [begin, nAtoms).

Fully fixed atoms (fixed entries all > 0.5) contribute nothing. A NaN norm on a free atom is returned as is: std::max would drop it and let a convergence test pass on bad forces.

Definition at line 25 of file ForceNorm.h.

27 {
28 double best = 0.0;
29 if (forces == nullptr || nAtoms <= 0 || begin >= nAtoms) {
30 return best;
31 }
32 if (begin < 0) {
33 begin = 0;
34 }
35 for (long i = begin; i < nAtoms; ++i) {
36 if (fixed != nullptr) {
37 const double *mask = fixed + 3 * i;
38 if (mask[0] > 0.5 && mask[1] > 0.5 && mask[2] > 0.5) {
39 continue;
40 }
41 }
42 const double *row = forces + 3 * i;
43 const double xx = row[0] * row[0];
44 const double yy = row[1] * row[1];
45 const double zz = row[2] * row[2];
46 const double norm = std::sqrt((xx + yy) + zz);
47 if (std::isnan(norm)) {
48 return norm;
49 }
50 best = std::max(best, norm);
51 }
52 return best;
53}

◆ runRotationSolver()

template<typename Solver>
DimerRotationResult eonc::detail::runRotationSolver ( const std::shared_ptr< Matter > & matter,
const Parameters & params,
const std::shared_ptr< Potential > & pot,
const AtomMatrix & initialDirection )
nodiscard

Definition at line 48 of file DimerRotationDispatch.h.

50 {
51 Solver solver(matter, params, pot);
52 solver.compute(matter, initialDirection);
54 out.eigenvector = solver.getEigenvector();
55 out.eigenvalue = solver.getEigenvalue();
56 out.forceCalls = solver.totalForceCalls;
57 out.rotations = solver.statsRotations;
58 if constexpr (std::is_same_v<Solver, LORRotation>) {
59 out.converged = solver.convergedOnResidual;
60 } else {
61 out.converged = true;
62 }
63 return out;
64}
Result of a non-classical dimer rotation backend (mode estimate only).
bool converged
LOR: true only when residual stop fired; Lanczos/Davidson: true (internal convergence criteria,...