216 {
217 if (N <= 0)
218 throw std::runtime_error("RGPotEngine::force called with N <= 0");
219
221 for (long i = 0; i < N; ++i) {
222 const int ii = static_cast<int>(i);
223 positions(ii, 0) = R[3 * i + 0];
224 positions(ii, 1) = R[3 * i + 1];
225 positions(ii, 2) = R[3 * i + 2];
226 }
227 std::vector<int> atmtypes(atomicNrs, atomicNrs + N);
228 const auto cell = box_from_row_major(box);
229
231 impl_->metatomic->force(N, R, atomicNrs, F, U,
nullptr, box);
232 return;
233 }
235 impl_->xtb->force(N, R, atomicNrs, F, U,
nullptr, box);
236 return;
237 }
238
239
240 std::tuple<double, AtomMatrix, double> result;
242 result = (*
impl_->nwchem)(positions, atmtypes, cell);
243 else
244 result = (*
impl_->cpmd)(positions, atmtypes, cell);
245
246 *U = std::get<0>(result);
247 const auto &forces = std::get<1>(result);
248 for (long i = 0; i < N; ++i) {
249 const int ii = static_cast<int>(i);
250 F[3 * i + 0] = forces(ii, 0);
251 F[3 * i + 1] = forces(ii, 1);
252 F[3 * i + 2] = forces(ii, 2);
253 }
254}
Eigen::Matrix< double, Eigen::Dynamic, 3, eOnStorageOrder > AtomMatrix