72 const std::vector<std::shared_ptr<Matter>> &path,
73 long numImages,
int atoms,
double maxEnergy,
double E_ref) {
79 double avgPotForce = 0.0;
80 double avgPathCurvature = 0.0;
82 for (
long j = 1; j <= numImages; j++) {
83 avgPotForce += path[j]->getForces().norm();
87 AtomMatrix curvVec = path[j]->pbc(next + prev - 2.0 * curr);
88 avgPathCurvature += curvVec.norm();
91 if (count > 0 && avgPathCurvature > 1e-6) {
93 base_k = scale * (avgPotForce / avgPathCurvature);
100 std::vector<AtomMatrix> L_vecs(numImages + 2);
101 for (
long j = 0; j <= numImages + 1; j++) {
102 L_vecs[j].resize(atoms, 3);
103 if (j == 0 || j == numImages + 1) {
106 const AtomMatrix &forces = path[j]->getForces();
108 for (
int k = 0; k < atoms; k++) {
109 L_vecs[j].row(k) = alpha_k * forces.row(k);
119 std::vector<double> springConstants(numImages + 2, k_l);
121 double energyRange = maxEnergy - E_ref;
122 if (energyRange < 1e-10) {
123 std::fill(springConstants.begin(), springConstants.end(), k_l);
125 for (
int idx = 1; idx <= numImages + 1; idx++) {
126 double Ei = std::max(path[idx]->getPotentialEnergy(),
127 path[idx - 1]->getPotentialEnergy());
129 double alpha_i = (maxEnergy - Ei) / energyRange;
130 alpha_i = std::max(0.0, std::min(1.0, alpha_i));
131 springConstants[idx - 1] = (1.0 - alpha_i) * k_u + alpha_i * k_l;
133 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