66 const std::vector<std::shared_ptr<Matter>> &path,
67 long numImages,
int atoms,
double maxEnergy,
double E_ref) {
73 double avgPotForce = 0.0;
74 double avgPathCurvature = 0.0;
76 for (
long j = 1; j <= numImages; j++) {
77 avgPotForce += path[j]->getForces().norm();
81 AtomMatrix curvVec = path[j]->pbc(next + prev - 2.0 * curr);
82 avgPathCurvature += curvVec.norm();
85 if (count > 0 && avgPathCurvature > 1e-6) {
87 base_k = scale * (avgPotForce / avgPathCurvature);
94 std::vector<AtomMatrix> L_vecs(numImages + 2);
95 for (
long j = 0; j <= numImages + 1; j++) {
96 L_vecs[j].resize(atoms, 3);
97 if (j == 0 || j == numImages + 1) {
100 const AtomMatrix &forces = path[j]->getForces();
102 for (
int k = 0; k < atoms; k++) {
103 L_vecs[j].row(k) = alpha_k * forces.row(k);
113 std::vector<double> springConstants(numImages + 2, k_l);
115 double energyRange = maxEnergy - E_ref;
116 if (energyRange < 1e-10) {
117 std::fill(springConstants.begin(), springConstants.end(), k_l);
119 for (
int idx = 1; idx <= numImages + 1; idx++) {
120 double Ei = std::max(path[idx]->getPotentialEnergy(),
121 path[idx - 1]->getPotentialEnergy());
123 double alpha_i = (maxEnergy - Ei) / energyRange;
124 alpha_i = std::max(0.0, std::min(1.0, alpha_i));
125 springConstants[idx - 1] = (1.0 - alpha_i) * k_u + alpha_i * k_l;
127 springConstants[idx - 1] = k_l;
SpringStrategy buildSpringStrategy(const Parameters ¶ms, const std::vector< std::shared_ptr< Matter > > &path, long numImages, int atoms, double maxEnergy, double E_ref)
Build the appropriate spring strategy from parameters and current path state.
SpringResult compute(long i, const AtomMatrix &tangent, const AtomMatrix &posNext, const AtomMatrix &posPrev, const AtomMatrix &pos, const std::shared_ptr< Matter > &image) const