17#include "rgpot/ForceStructs.hpp"
18#include "rgpot/pot_caps.hpp"
41 void force(
long N,
const double *R,
const int *atomicNrs,
double *F,
42 double *U,
double *variance,
const double *box)
override {
43 rgpot::ForceInput in{
static_cast<size_t>(N), R, atomicNrs, box};
44 rgpot::ForceOut out{F, 0.0, 0.0};
45 pot_.forceImpl(in, &out);
47 if (variance !=
nullptr) {
48 *variance = out.variance;
57 return pot_.caps().batched;
68 void forceBatch(
long nSystems,
long nAtoms,
const double *
const *positions,
69 const int *
const *atomicNrs,
double *
const *forces,
70 double *energies,
double *variances,
71 const double *
const *boxes)
override {
72 const auto n =
static_cast<size_t>(nSystems);
73 std::vector<rgpot::ForceInput> in;
74 std::vector<rgpot::ForceOut> out;
77 for (
size_t i = 0; i < n; ++i) {
78 in.push_back(rgpot::ForceInput{
static_cast<size_t>(nAtoms), positions[i],
79 atomicNrs[i], boxes[i]});
80 out.push_back(rgpot::ForceOut{forces[i], 0.0, 0.0});
84 rgpot::ForceBatch{.nSystems = n, .in = in.data(), .out = out.data()});
86 for (
size_t i = 0; i < n; ++i) {
87 energies[i] = out[i].energy;
88 if (variances !=
nullptr) {
89 variances[i] = out[i].variance;
97 return pot_.caps().reentrancy == rgpot::Reentrancy::SharedInstance;
101 const auto caps =
pot_.caps();
102 return caps.perImageInstances ||
103 caps.reentrancy == rgpot::Reentrancy::PerInstance;
106 [[nodiscard]]
const RPot &
kernel() const noexcept {
return pot_; }
117 return std::make_shared<RgpotAdapter<RPot>>(ptype, params);
121template <
class RPot,
class Cfg>
124 return std::make_shared<RgpotAdapter<RPot>>(ptype, params, cfg);
std::shared_ptr< Potential > makeRgpot(PotType ptype, const Parameters ¶ms, const Cfg &cfg)
Factory arm helper: construct the kernel from its config and wrap it.
std::shared_ptr< Potential > makeRgpotDefault(PotType ptype, const Parameters ¶ms)
Factory arm helper for kernels whose parameters are fixed tabulated data with no eOn-side configurati...
bool isThreadSafe() const noexcept override
Whether this potential's force() can be called from multiple threads on the SAME instance.
bool supportsBatchEvaluation() const noexcept override
Reports whether the kernel serves a batch natively.
void force(long N, const double *R, const int *atomicNrs, double *F, double *U, double *variance, const double *box) override
RgpotAdapter(PotType ptype, const Parameters ¶ms, const Cfg &cfg)
Kernels construct in place from their config: several hold mutexes or other immovable state,...
RgpotAdapter(PotType ptype, const Parameters ¶ms)
Kernels with no configuration surface default-construct in place.
const RPot & kernel() const noexcept
bool needsPerImageInstance() const noexcept override
Whether NEB should create separate Potential instances per image for true parallel force evaluation.
void forceBatch(long nSystems, long nAtoms, const double *const *positions, const int *const *atomicNrs, double *const *forces, double *energies, double *variances, const double *const *boxes) override
Hands eOn's batch straight to the kernel.
static PotRegistry & get() noexcept
Process-lifetime singleton.
void on_force_call(PotType t) noexcept
std::atomic< size_t > forceCallCounter
Potential(PotType a_ptype)