eOn client
Long-timescale dynamics: aKMC, NEB, parallel replica
☾
Toggle main menu visibility
Loading...
Searching...
No Matches
NEBForceProjection.cpp
Go to the documentation of this file.
1
/*
2
** This file is part of eOn.
3
**
4
** SPDX-License-Identifier: BSD-3-Clause
5
**
6
** Copyright (c) 2010--present, eOn Development Team
7
** All rights reserved.
8
**
9
** Repo:
10
** https://github.com/TheochemUI/eOn
11
*/
12
#include "
eon/NEBForceProjection.h
"
13
#include "
eon/HelperFunctions.h
"
14
15
#include <algorithm>
16
#include <cmath>
17
18
namespace
eonc::neb
{
19
20
// matDot is now in Eigen.h (shared across all files)
21
22
AtomMatrix
computeTangent
(
const
AtomMatrix
&posDiffNext,
23
const
AtomMatrix
&posDiffPrev,
double
energy,
24
double
energyPrev,
double
energyNext,
25
bool
use_old_tangent) {
26
AtomMatrix
tang;
27
28
if
(use_old_tangent) {
29
tang = posDiffNext;
30
}
else
{
31
// Improved tangent scheme
32
if
(energyNext > energy && energy > energyPrev) {
33
tang = posDiffNext;
34
}
else
if
(energy > energyNext && energyPrev > energy) {
35
tang = posDiffPrev;
36
}
else
{
37
// Extremum: energy-weighted combination
38
double
energyDiffPrev = energyPrev - energy;
39
double
energyDiffNext = energyNext - energy;
40
double
minDiffEnergy =
41
std::min(std::abs(energyDiffPrev), std::abs(energyDiffNext));
42
double
maxDiffEnergy =
43
std::max(std::abs(energyDiffPrev), std::abs(energyDiffNext));
44
45
if
(energyDiffPrev > energyDiffNext) {
46
tang = posDiffNext * minDiffEnergy + posDiffPrev * maxDiffEnergy;
47
}
else
{
48
tang = posDiffNext * maxDiffEnergy + posDiffPrev * minDiffEnergy;
49
}
50
}
51
}
52
53
// Normalize with safety check
54
double
norm = tang.norm();
55
if
(norm > 1e-10) {
56
tang /= norm;
57
}
else
{
58
// Fallback: use direction to next image
59
tang = posDiffNext;
60
norm = tang.norm();
61
if
(norm > 1e-10) {
62
tang /= norm;
63
}
64
}
65
66
return
tang;
67
}
68
69
AtomMatrix
forcePerp
(
const
AtomMatrix
&force,
const
AtomMatrix
&tangent) {
70
return
force -
matDot
(force, tangent) * tangent;
71
}
72
73
AtomMatrix
climbingImageForce
(
const
AtomMatrix
&force,
74
const
AtomMatrix
&tangent,
75
const
AtomMatrix
&forceDNEB) {
76
return
force - 2.0 *
matDot
(force, tangent) * tangent + forceDNEB;
77
}
78
79
AtomMatrix
computeDNEB
(
const
AtomMatrix
&forceSpring,
const
AtomMatrix
&tangent,
80
const
AtomMatrix
&fPerp) {
81
AtomMatrix
forceSpringPerp =
82
forceSpring -
matDot
(forceSpring, tangent) * tangent;
83
84
const
double
forceSpringPerpNorm = forceSpringPerp.norm();
85
const
double
forcePerpNorm = fPerp.norm();
86
87
if
(forceSpringPerpNorm > 1e-10 && forcePerpNorm > 1e-10) {
88
AtomMatrix
forcePerpNormalized = fPerp / forcePerpNorm;
89
AtomMatrix
dneb =
90
forceSpringPerp -
91
matDot
(forceSpringPerp, forcePerpNormalized) * forcePerpNormalized;
92
93
double
switching = 2.0 /
eonc::helpers::pi
*
94
std::atan(forcePerpNorm * forcePerpNorm /
95
(forceSpringPerpNorm * forceSpringPerpNorm));
96
dneb *= switching;
97
return
dneb;
98
}
99
100
return
AtomMatrix::Zero(tangent.rows(), tangent.cols());
101
}
102
103
void
zeroTranslation
(
AtomMatrix
&projectedForce,
int
nFreeAtoms,
int
nAtoms) {
104
if
(nFreeAtoms == nAtoms) {
105
for
(
int
j = 0; j <= 2; j++) {
106
double
translationMag = projectedForce.col(j).sum();
107
int
natoms = projectedForce.col(j).size();
108
projectedForce.col(j).array() -=
109
translationMag /
static_cast<
double
>
(natoms);
110
}
111
}
112
}
113
114
}
// namespace eonc::neb
matDot
double matDot(const AtomMatrix &a, const AtomMatrix &b)
SIMD-optimized dot product for contiguous Eigen matrices.
Definition
Eigen.h:50
AtomMatrix
Eigen::Matrix< double, Eigen::Dynamic, 3, eOnStorageOrder > AtomMatrix
Definition
Eigen.h:37
HelperFunctions.h
NEBForceProjection.h
eonc::helpers::pi
constexpr double pi
Definition
HelperFunctions.h:28
eonc::neb
Definition
NEBForceProjection.cpp:18
eonc::neb::zeroTranslation
void zeroTranslation(AtomMatrix &projectedForce, int nFreeAtoms, int nAtoms)
Zero net translational force for fully free systems.
Definition
NEBForceProjection.cpp:103
eonc::neb::climbingImageForce
AtomMatrix climbingImageForce(const AtomMatrix &force, const AtomMatrix &tangent, const AtomMatrix &forceDNEB)
Compute the climbing image projected force.
Definition
NEBForceProjection.cpp:73
eonc::neb::computeTangent
AtomMatrix computeTangent(const AtomMatrix &posDiffNext, const AtomMatrix &posDiffPrev, double energy, double energyPrev, double energyNext, bool use_old_tangent)
Compute the tangent vector at image i using the improved tangent scheme.
Definition
NEBForceProjection.cpp:22
eonc::neb::forcePerp
AtomMatrix forcePerp(const AtomMatrix &force, const AtomMatrix &tangent)
Compute the perpendicular component of force relative to the tangent.
Definition
NEBForceProjection.cpp:69
eonc::neb::computeDNEB
AtomMatrix computeDNEB(const AtomMatrix &forceSpring, const AtomMatrix &tangent, const AtomMatrix &fPerp)
Compute the doubly-nudged elastic band perpendicular spring force.
Definition
NEBForceProjection.cpp:79
client
NEBForceProjection.cpp
Generated by
1.17.0
Generated by
Doxygen 1.17.0
Analytics by
Antics
provided by
TurtleTech ehf