66 {
68
69 eonc::safemath::safe_normalize_inplace(initialDirection);
71
72
73
76 static_cast<quill::Logger *
>(
log))) {
81 eonc::safemath::safe_normalize_inplace(
direction);
82 for (
long i = 0; i <
nAtoms; ++i) {
85 }
86 }
88 return;
89 }
90
91 long rotations = 0;
93 long forceCallsDimer =
matterDimer->getForceCalls();
94 double curvature = 0.0;
95 double rotationAngle = 0.0;
96 double torque = 0.0;
97
101 rotationalForce.setZero();
102 rotationalForceOld.setZero();
103 rotationalPlaneOld.setZero();
104
106 double lengthRotationalForceOld = 0.0;
107
108
109 bool doneRotating = false;
110 while (!doneRotating) {
112
114 rotationalPlaneOld, lengthRotationalForceOld);
115
116 torque = rotationalForce.norm();
117
118 assert(std::isfinite(torque));
119
120
121 if ((torque >
params.dimer_options().torque_max &&
122 rotations >=
params.dimer_options().rotations_max) ||
123 (torque <
params.dimer_options().torque_max &&
124 torque >=
params.dimer_options().torque_min &&
125 rotations >=
params.dimer_options().rotations_min) ||
126 (torque <
params.dimer_options().torque_min)) {
127 doneRotating = true;
128 }
129
130
131
132 if (!doneRotating) {
135
138
139 double rotForceChange =
140 (rotForce1 - rotForce2) /
params.dimer_options().rotation_angle;
141 double forceDimer = (rotForce1 + rotForce2) / 2.0;
142
144 rotForceChange, 0.0) /
145 2.0 -
146 params.dimer_options().rotation_angle / 2.0;
147
148 if (rotForceChange < 0) {
150 }
151
154 rotations++;
155 }
157 "[DimerRot] ----- --------- ---------------- "
158 "--------- {:9.3e} {:9.3e} {:9.3e} ---------\n",
159 curvature, torque,
161 }
162
165 eonc::safemath::safe_normalize_inplace(
direction);
166 for (
long i = 0; i <
nAtoms; ++i) {
169 }
170 }
175
176 forceCallsCenter =
matterCenter->getForceCalls() - forceCallsCenter;
177 forceCallsDimer =
matterDimer->getForceCalls() - forceCallsDimer;
179}
void determineRotationalPlane(const AtomMatrix &rotationalForce, AtomMatrix &rotationalForceOld, const AtomMatrix &rotationalPlaneOld, double &lengthRotationalForceOld)
Determine rotational plane via conjugate gradient.
double calcRotationalForceReturnCurvature(AtomMatrix &rotationalForce)
Compute rotational force and return curvature along the dimer.
void rotate(double rotationAngle)
Rotate the dimer by the given angle (radians).
eonc::log::FileScoped log
double safe_acos(double x)
double safe_atan_ratio(double num, double denom, double fallback=0.0)
std::optional< DimerRotationResult > runAlternativeRotation(DimerRotationBackend backend, const std::shared_ptr< Matter > &matter, const Parameters ¶ms, const std::shared_ptr< Potential > &pot, const AtomMatrix &initialDirection, quill::Logger *log=nullptr)
Run Lanczos, Davidson, or LOR.