44 {
46
47 eonc::safemath::safe_normalize_inplace(initialDirection);
49
50
51
54 static_cast<quill::Logger *
>(
log))) {
59 eonc::safemath::safe_normalize_inplace(
direction);
61 return;
62 }
63
64 long rotations = 0;
66 long forceCallsDimer =
matterDimer->getForceCalls();
67 double curvature = 0.0;
68 double rotationAngle = 0.0;
69 double torque = 0.0;
70
74 rotationalForce.setZero();
75 rotationalForceOld.setZero();
76 rotationalPlaneOld.setZero();
77
79 double lengthRotationalForceOld = 0.0;
80
81
82 bool doneRotating = false;
83 while (!doneRotating) {
85
87 rotationalPlaneOld, lengthRotationalForceOld);
88
89 torque = rotationalForce.norm();
90 assert(std::isnormal(torque));
91
92
93 if ((torque >
params.dimer_options.torque_max &&
94 rotations >=
params.dimer_options.rotations_max) ||
95 (torque <
params.dimer_options.torque_max &&
96 torque >=
params.dimer_options.torque_min &&
97 rotations >=
params.dimer_options.rotations_min) ||
98 (torque <
params.dimer_options.torque_min)) {
99 doneRotating = true;
100 }
101
104
105 if (!doneRotating) {
108
109 double rotForceChange =
110 (rotForce1 - rotForce2) /
params.dimer_options.rotation_angle;
111 double forceDimer = (rotForce1 + rotForce2) / 2.0;
112
114 rotForceChange, 0.0) /
115 2.0 -
116 params.dimer_options.rotation_angle / 2.0;
117
118 if (rotForceChange < 0) {
120 }
121
124 rotations++;
125 }
127 "[DimerRot] ----- --------- ---------------- "
128 "--------- {:9.3e} {:9.3e} {:9.3e} ---------\n",
129 curvature, torque,
131 }
132
135 eonc::safemath::safe_normalize_inplace(
direction);
140
141 forceCallsCenter =
matterCenter->getForceCalls() - forceCallsCenter;
142 forceCallsDimer =
matterDimer->getForceCalls() - forceCallsDimer;
144}
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
void determineRotationalPlane(const AtomMatrix &rotationalForce, AtomMatrix &rotationalForceOld, const AtomMatrix &rotationalPlaneOld, double &lengthRotationalForceOld)
Determine rotational plane via conjugate gradient.
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.