Loading...
Searching...
No Matches
eonc::neb::zoom Namespace Reference

Classes

struct  Window
 Inclusive image indices on the current band. More...

Functions

Window selectWindow (const std::vector< double > &energy, std::size_t climbingImage, const neb_options_t::zoom_options_t &cfg)
 Auto: contiguous images around the climbing image whose energy is above E_ref + alpha * barrier.
bool redistributePath (std::vector< std::shared_ptr< Matter > > &path, Window window, neb_options_t::zoom_options_t::Interpolation how)
 Place every band image on the window by equal arc length.

Function Documentation

◆ redistributePath()

bool eonc::neb::zoom::redistributePath ( std::vector< std::shared_ptr< Matter > > & path,
Window window,
neb_options_t::zoom_options_t::Interpolation how )

Place every band image on the window by equal arc length.

Window endpoints become the new fixed band endpoints. Cubic uses resamplePath; linear uses segment interpolation. Returns false when the window cannot be resampled.

Definition at line 118 of file NEBZoom.cpp.

119 {
120 if (!window.valid || path.size() < 3 || window.hi <= window.lo ||
121 window.hi >= path.size()) {
122 return false;
123 }
124 for (const auto &image : path) {
125 if (!image) {
126 return false;
127 }
128 }
129
130 std::vector<Matter> sub;
131 sub.reserve(window.hi - window.lo + 1);
132 for (std::size_t i = window.lo; i <= window.hi; ++i) {
133 sub.push_back(*path[i]);
134 }
135
136 std::vector<Matter> placed;
138 placed = linearResample(sub, path.size());
139 } else if (sub.size() == path.size()) {
140 std::vector<std::shared_ptr<Matter>> tmp;
141 tmp.reserve(sub.size());
142 for (const auto &image : sub) {
143 tmp.push_back(std::make_shared<Matter>(image));
144 }
146 std::span<std::shared_ptr<Matter>>{tmp.data(), tmp.size()});
147 placed.reserve(tmp.size());
148 for (const auto &image : tmp) {
149 placed.push_back(*image);
150 }
151 } else {
152 placed = eonc::helpers::neb_paths::resamplePath(sub, path.size() - 2);
153 }
154 if (placed.size() != path.size()) {
155 return false;
156 }
157 for (std::size_t i = 0; i < path.size(); ++i) {
158 path[i]->setPositions(placed[i].getPositions());
159 }
160 return true;
161}
std::vector< Matter > resamplePath(const std::vector< Matter > &densePath, size_t targetCount)
void resamplePathInPlace(std::span< std::shared_ptr< Matter > > path)
In-place path reparameterization for NEB shared_ptr paths.

◆ selectWindow()

Window eonc::neb::zoom::selectWindow ( const std::vector< double > & energy,
std::size_t climbingImage,
const neb_options_t::zoom_options_t & cfg )

Auto: contiguous images around the climbing image whose energy is above E_ref + alpha * barrier.

Manual: climbing image +/- offset. A one-image auto window falls back to the manual offset.

Definition at line 74 of file NEBZoom.cpp.

76 {
77 Window window;
78 const std::size_t n = energy.size();
79 if (n < 3 || climbingImage == 0 || climbingImage + 1 >= n) {
80 return window;
81 }
82
83 std::size_t lo = 0;
84 std::size_t hi = 0;
86 std::tie(lo, hi) = manualWindow(n, climbingImage, cfg.offset);
87 } else {
88 const double eRef = std::min(energy.front(), energy.back());
89 const double eMax = *std::max_element(energy.begin(), energy.end());
90 const double barrier = eMax - eRef;
91 const bool usable = barrier > 0.0 && cfg.alpha > 0.0 && cfg.alpha < 1.0;
92 if (!usable) {
93 std::tie(lo, hi) = manualWindow(n, climbingImage, cfg.offset);
94 } else {
95 const double threshold = eRef + cfg.alpha * barrier;
96 lo = climbingImage;
97 hi = climbingImage;
98 while (lo > 0 && energy[lo - 1] > threshold) {
99 --lo;
100 }
101 while (hi + 1 < n && energy[hi + 1] > threshold) {
102 ++hi;
103 }
104 if (hi <= lo) {
105 std::tie(lo, hi) = manualWindow(n, climbingImage, cfg.offset);
106 }
107 }
108 }
109 if (hi <= lo || hi >= n) {
110 return window;
111 }
112 window.lo = lo;
113 window.hi = hi;
114 window.valid = true;
115 return window;
116}
Inclusive image indices on the current band.
Definition NEBZoom.h:25