Virtual run; used solely for dynamic dispatch.
24 {
26 size_t f1;
27
30
31
32
33 bool tsInterpolate = false;
34 std::shared_ptr<Matter> transitionState = nullptr;
36 std::filesystem::exists("ts.con")) {
37 std::string transitionStateFilename =
39 transitionState = std::make_shared<Matter>(
pot,
params);
40 tsInterpolate = true;
42 transitionState->con2matter(transitionStateFilename))) {
44 throw std::runtime_error("failed to load " + transitionStateFilename);
45 }
46 }
47
48 auto initial = std::make_shared<Matter>(
pot,
params);
49 auto final_state = std::make_shared<Matter>(
pot,
params);
50
51
52
53
54 const bool usePathEndpoints =
56 !
params.neb_options.initialization.input_path.empty();
57
58 if (usePathEndpoints) {
60 params.neb_options.initialization.input_path);
61 if (file_paths.size() < 2) {
62 throw std::runtime_error(
63 "NEB initial_path_in must list at least two frames "
64 "(reactant and product endpoints)");
65 }
66 if (!
eonc::io::io_ok(initial->con2matter(file_paths.front().string()))) {
68 file_paths.front().string());
69 throw std::runtime_error("failed to load NEB path reactant frame");
70 }
71 if (!
eonc::io::io_ok(final_state->con2matter(file_paths.back().string()))) {
73 file_paths.back().string());
74 throw std::runtime_error("failed to load NEB path product frame");
75 }
77 "NEB endpoints from initial path list (skipped {} / {})",
78 reactantFilename, productFilename);
79 } else {
82 throw std::runtime_error("failed to load reactant.con");
83 }
86 throw std::runtime_error("failed to load product.con");
87 }
88 }
89
90
91
92
93
94
95
96
97
98 bool shouldMinimizeEndpoints = false;
99 if (!
params.neb_options.endpoints.minimize) {
100 QUILL_LOG_DEBUG(
m_log,
101 "minimize_endpoints == false: not minimizing endpoints.");
102 shouldMinimizeEndpoints = false;
103 } else {
104 if (
params.neb_options.initialization.input_path.empty()) {
105 QUILL_LOG_DEBUG(
m_log,
"minimize_endpoints == true and nebIpath "
106 "empty: minimizing endpoints.");
107 shouldMinimizeEndpoints = true;
108 } else {
109
110
111 if (
params.neb_options.endpoints.use_path_file) {
112 QUILL_LOG_DEBUG(
114 "minimize_endpoints == true and nebIpath provided, but "
115 "minimize_endpoints_for_ipath == true: minimizing endpoints.");
116 shouldMinimizeEndpoints = true;
117 } else {
118 QUILL_LOG_DEBUG(
120 "minimize_endpoints == true but nebIpath provided and "
121 "minimize_endpoints_for_ipath == false: not minimizing endpoints.");
122 shouldMinimizeEndpoints = false;
123 }
124 }
125 }
126
127 if (shouldMinimizeEndpoints) {
128 QUILL_LOG_DEBUG(
m_log,
"Minimizing reactant");
129
130
131 initial->relax(
false,
params.debug_options.write_movies,
132 params.main_options.checkpoint,
"react_neb",
"react_neb");
133
134
135
136 QUILL_LOG_DEBUG(
m_log,
"Minimized reactant in ");
137 QUILL_LOG_DEBUG(
m_log,
"Minimizing product");
138 final_state->relax(
false,
params.debug_options.write_movies,
139 params.main_options.checkpoint,
"prod_neb",
"prod_neb");
140 }
141
142 auto neb =
143 std::make_unique<NudgedElasticBand>(initial, final_state,
params,
pot);
144
145 if (tsInterpolate) {
146 AtomMatrix reactantToTS = transitionState->pbc(
147 transitionState->getPositions() - initial->getPositions());
148 AtomMatrix TSToProduct = transitionState->pbc(
149 final_state->getPositions() - transitionState->getPositions());
150 for (int image = 1; image <= neb->numImages; image++) {
151 int mid = neb->numImages / 2 + 1;
152 if (image < mid) {
153 double frac = static_cast<double>(image) / static_cast<double>(mid);
154 neb->path[image]->setPositions(initial->getPositions() +
155 frac * reactantToTS);
156 } else if (image > mid) {
157 double frac = static_cast<double>(image - mid) /
158 static_cast<double>(neb->numImages - mid + 1);
159 neb->path[image]->setPositions(transitionState->getPositions() +
160 frac * TSToProduct);
161 } else if (image == mid) {
162 neb->path[image]->setPositions(transitionState->getPositions());
163 }
164 }
165 }
166
168 status = neb->compute();
170
172 neb->printImageData();
173 neb->findExtrema();
174 }
175
178
180}
Eigen::Matrix< double, Eigen::Dynamic, 3, eOnStorageOrder > AtomMatrix
#define EONC_LOG_CRITICAL(...)
std::shared_ptr< Potential > pot
void saveData(NudgedElasticBand::NEBStatus status, NudgedElasticBand *neb)
void printEndState(NudgedElasticBand::NEBStatus status)
std::vector< std::string > returnFiles
static PotRegistry & get() noexcept
Process-lifetime singleton.
size_t total_force_calls() const noexcept
std::vector< fs::path > readFilePaths(const std::string &listFilePath)
Reads a file where each line contains a path to another file.
std::string getRelevantFile(std::string filename)
constexpr bool io_ok(IoStatus s) noexcept