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

#include <IDPPObjectiveFunction.hpp>

Inheritance diagram for eonc::CollectiveIDPPObjectiveFunction:

Public Member Functions

 CollectiveIDPPObjectiveFunction (std::vector< Matter > &pathRef, const Parameters &paramsPassed)
double getEnergy () override
VectorXd getGradient (bool fdstep=false) override
void setPositions (const VectorXd &x) override
VectorXd getPositions () override
int degreesOfFreedom () override
bool isConverged () override
double getConvergence () override
VectorXd difference (const VectorXd &a, const VectorXd &b) override
Public Member Functions inherited from eonc::ObjectiveFunction
 ObjectiveFunction (const Parameters &paramsPassed)
virtual ~ObjectiveFunction ()
virtual bool supportsFiniteDifferenceCurvature () const
virtual std::optional< double > knownCurvature () const
virtual void minimumImage (Eigen::Ref< Eigen::Vector3d >) const
virtual VectorXd getMasses () const
virtual bool getPeriodic () const

Private Member Functions

MatrixXd getDistanceMatrix (const Matter &m)
MatrixXd getIDPPForces (const Matter &m, const MatrixXd &dTarget)

Private Attributes

std::vector< Matter > & path
MatrixXd dInit
MatrixXd dFinal
double lastMaxForce = 100.0

Additional Inherited Members

Protected Attributes inherited from eonc::ObjectiveFunction
const Parameters & params

Detailed Description

Definition at line 73 of file IDPPObjectiveFunction.hpp.

Constructor & Destructor Documentation

◆ CollectiveIDPPObjectiveFunction()

eonc::CollectiveIDPPObjectiveFunction::CollectiveIDPPObjectiveFunction ( std::vector< Matter > & pathRef,
const Parameters & paramsPassed )
inline

Definition at line 75 of file IDPPObjectiveFunction.hpp.

77 : ObjectiveFunction(paramsPassed), path(pathRef) {
78
79 // Initialize distances for endpoints
80 dInit = getDistanceMatrix(path.front());
82 }
ObjectiveFunction(const Parameters &paramsPassed)

Member Function Documentation

◆ degreesOfFreedom()

int eonc::CollectiveIDPPObjectiveFunction::degreesOfFreedom ( )
inlineoverridevirtual

Implements eonc::ObjectiveFunction.

Definition at line 110 of file IDPPObjectiveFunction.hpp.

110 {
111 return 3 * static_cast<int>(path[0].numberOfFreeAtoms()) *
112 (static_cast<int>(path.size()) - 2);
113 }

◆ difference()

VectorXd eonc::CollectiveIDPPObjectiveFunction::difference ( const VectorXd & a,
const VectorXd & b )
inlineoverridevirtual

Implements eonc::ObjectiveFunction.

Definition at line 123 of file IDPPObjectiveFunction.hpp.

123 {
124 // Simple difference for this purpose, assuming pre-aligned or handling PBC
125 // inside
126 return a - b;
127 }

◆ getConvergence()

double eonc::CollectiveIDPPObjectiveFunction::getConvergence ( )
inlineoverridevirtual

◆ getDistanceMatrix()

MatrixXd eonc::CollectiveIDPPObjectiveFunction::getDistanceMatrix ( const Matter & m)
private

Definition at line 98 of file IDPPObjectiveFunction.cpp.

98 {
99 int natoms = m.numberOfAtoms();
100 MatrixXd d(natoms, natoms);
101 auto pos = m.getPositions();
102 for (int i = 0; i < natoms; ++i) {
103 for (int j = 0; j < natoms; ++j) {
104 d(i, j) = m.pbc(pos.row(i) - pos.row(j)).norm();
105 }
106 }
107 return d;
108}
Eigen::Matrix< double, Eigen::Dynamic, Eigen::Dynamic, eOnStorageOrder > MatrixXd
Definition Eigen.h:33

◆ getEnergy()

double eonc::CollectiveIDPPObjectiveFunction::getEnergy ( )
inlineoverridevirtual

Implements eonc::ObjectiveFunction.

Definition at line 86 of file IDPPObjectiveFunction.hpp.

86{ return 0.0; }

◆ getGradient()

VectorXd eonc::CollectiveIDPPObjectiveFunction::getGradient ( bool fdstep = false)
overridevirtual

Implements eonc::ObjectiveFunction.

Definition at line 138 of file IDPPObjectiveFunction.cpp.

138 {
139 int nImgs = path.size() - 2; // Exclude fixed endpoints
140 int nfree = static_cast<int>(path[0].numberOfFreeAtoms());
141 VectorXd totalGradient(3 * nfree * nImgs);
142 double maxForce = 0.0;
143
144 // 1. Compute Raw IDPP Forces and Tangents
145 std::vector<AtomMatrix> rawForces(path.size());
146 std::vector<AtomMatrix> tangents(path.size());
147
148 // We compute for 1..N (moving images)
149 for (size_t i = 1; i <= nImgs; ++i) {
150 // Interpolate Target
151 double xi = static_cast<double>(i) / (nImgs + 1);
152 MatrixXd dTarget = (1.0 - xi) * dInit + xi * dFinal;
153
154 rawForces[i] = getIDPPForces(path[i], dTarget);
155
156 // Simple Tangent: Next - Prev
157 AtomMatrix nextPos = path[i + 1].getPositions();
158 AtomMatrix prevPos = path[i - 1].getPositions();
159 tangents[i] = path[i].pbc(nextPos - prevPos);
160 const double tnorm = tangents[i].norm();
161 if (tnorm > 1e-10) {
162 tangents[i] /= tnorm;
163 }
164 }
165
166 // 2. Project Forces and Add Springs (The "NEB" part of IDPP-NEB)
167 double k = params.neb_options().spring.constant;
168
169 for (size_t i = 1; i <= nImgs; ++i) {
170 AtomMatrix f = rawForces[i];
171 AtomMatrix t = tangents[i];
172
173 // Perpendicular Force (IDPP optimization)
174 double f_dot_t = matDot(f, t);
175 AtomMatrix f_perp = f - f_dot_t * t;
176
177 // Spring Force (Spacing optimization)
178 double distNext = path[i].distanceTo(path[i + 1]);
179 double distPrev = path[i].distanceTo(path[i - 1]);
180 AtomMatrix f_spring = k * (distNext - distPrev) * t;
181
182 AtomMatrix f_neb = f_perp + f_spring;
183
184 VectorXd freeForce = packFree(path[i], f_neb);
185 totalGradient.segment(3 * nfree * static_cast<int>(i - 1), 3 * nfree) =
186 freeForce * -1.0;
187
188 // Free-atom residuals only. Frozen pair rows stay in f_neb for
189 // Newton's third law and must not pin lastMaxForce.
190 maxForce = std::max(maxForce, freeForce.lpNorm<Eigen::Infinity>());
191 }
192
193 lastMaxForce = maxForce;
194 return totalGradient;
195}
double matDot(const AtomMatrix &a, const AtomMatrix &b)
SIMD-optimized dot product for contiguous Eigen matrices.
Definition Eigen.h:50
Eigen::Matrix< double, Eigen::Dynamic, 3, eOnStorageOrder > AtomMatrix
Definition Eigen.h:37
MatrixXd getIDPPForces(const Matter &m, const MatrixXd &dTarget)
const Parameters & params

◆ getIDPPForces()

MatrixXd eonc::CollectiveIDPPObjectiveFunction::getIDPPForces ( const Matter & m,
const MatrixXd & dTarget )
private

Definition at line 111 of file IDPPObjectiveFunction.cpp.

112 {
113 int natoms = m.numberOfAtoms();
114 AtomMatrix forces = AtomMatrix::Zero(natoms, 3);
115 auto pos = m.getPositions();
116
117 for (int i = 0; i < natoms; ++i) {
118 for (int j = i + 1; j < natoms; ++j) {
119 Eigen::RowVector3d dr_vec = m.pbc(pos.row(i) - pos.row(j));
120 double r = dr_vec.norm();
121 if (r < 1e-4)
122 r = 1e-4;
123
124 double diff = r - dTarget(i, j);
125 // SOTA Weighting: w = 1/r^4. Gradient logic matches Smidstrup/ASE
126 double r2 = r * r;
127 double r5 = r2 * r2 * r;
128 double dEdr = (diff / r5) * (2.0 * dTarget(i, j) - r);
129
130 Eigen::RowVector3d f = -dEdr * (dr_vec / r); // -dE/dr * r_hat
131 forces.row(i) += f;
132 forces.row(j) -= f;
133 }
134 }
135 return forces;
136}

◆ getPositions()

VectorXd eonc::CollectiveIDPPObjectiveFunction::getPositions ( )
inlineoverridevirtual

Implements eonc::ObjectiveFunction.

Definition at line 98 of file IDPPObjectiveFunction.hpp.

98 {
99 const int nfree = static_cast<int>(path[0].numberOfFreeAtoms());
100 const int seg = 3 * nfree;
101 const int n_free_images = static_cast<int>(path.size()) - 2;
102 VectorXd pos(seg * n_free_images);
103 for (size_t i = 1; i < path.size() - 1; ++i) {
104 pos.segment(seg * static_cast<int>(i - 1), seg) =
105 path[i].getPositionsFreeV();
106 }
107 return pos;
108 }

◆ isConverged()

bool eonc::CollectiveIDPPObjectiveFunction::isConverged ( )
inlineoverridevirtual

Implements eonc::ObjectiveFunction.

Definition at line 116 of file IDPPObjectiveFunction.hpp.

116 {
117 return getConvergence() <
118 params.neb_options().initialization.force_tolerance;
119 }

◆ setPositions()

void eonc::CollectiveIDPPObjectiveFunction::setPositions ( const VectorXd & x)
inlineoverridevirtual

Implements eonc::ObjectiveFunction.

Definition at line 90 of file IDPPObjectiveFunction.hpp.

90 {
91 const int nfree = static_cast<int>(path[0].numberOfFreeAtoms());
92 const int seg = 3 * nfree;
93 for (size_t i = 1; i < path.size() - 1; ++i) {
94 path[i].setPositionsFreeV(x.segment(seg * static_cast<int>(i - 1), seg));
95 }
96 }

Member Data Documentation

◆ dFinal

MatrixXd eonc::CollectiveIDPPObjectiveFunction::dFinal
private

Definition at line 131 of file IDPPObjectiveFunction.hpp.

◆ dInit

MatrixXd eonc::CollectiveIDPPObjectiveFunction::dInit
private

Definition at line 131 of file IDPPObjectiveFunction.hpp.

◆ lastMaxForce

double eonc::CollectiveIDPPObjectiveFunction::lastMaxForce = 100.0
private

Definition at line 132 of file IDPPObjectiveFunction.hpp.

◆ path

std::vector<Matter>& eonc::CollectiveIDPPObjectiveFunction::path
private

Definition at line 130 of file IDPPObjectiveFunction.hpp.


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