30 [[nodiscard]]
const char *
what() const noexcept
override {
31 return "host surface recoverable";
46 [[nodiscard]]
unsigned long long surfaceEpoch() const noexcept
override {
51 void bindPath(
const std::vector<std::shared_ptr<Matter>> &path) {
54 void bindBand(
const std::vector<std::shared_ptr<Matter>> &path)
override {
61 void force(
long nAtoms,
const double *positions,
const int *atomicNrs,
62 double *forces,
double *energy,
double *variance,
63 const double *box)
override {
64 const double *posv[] = {positions};
65 const int *nrv[] = {atomicNrs};
66 double *frcv[] = {forces};
67 const double *boxv[] = {box};
71 forceBatch(1, nAtoms, posv, nrv, frcv, &e, &var, boxv);
81 void forceBatch(
long nSystems,
long nAtoms,
const double *
const *positions,
82 const int *
const *atomicNrs,
double *
const *forces,
83 double *energies,
double *variances,
84 const double *
const *boxes)
override {
86 throw std::runtime_error(
"HostSurfacePotential: NULL surface");
88 const long npos = 3 * nAtoms * nSystems;
89 const long nbox = 9 * nSystems;
90 std::vector<double> pos(
static_cast<size_t>(npos), 0.0);
91 std::vector<double> frc(
static_cast<size_t>(npos), 0.0);
92 std::vector<double> box(
static_cast<size_t>(nbox), 0.0);
93 std::vector<int32_t> z(
static_cast<size_t>(nAtoms), 0);
94 std::vector<int64_t> ids(
static_cast<size_t>(nSystems), 0);
95 if (atomicNrs && atomicNrs[0]) {
96 for (
long a = 0; a < nAtoms; ++a) {
97 z[
static_cast<size_t>(a)] = atomicNrs[0][a];
100 for (
long s = 0; s < nSystems; ++s) {
102 if (positions && positions[s]) {
103 for (
size_t i = 0; i <
path_.size(); ++i) {
104 if (
path_[i] &&
path_[i]->getPositions().data() == positions[s]) {
105 id =
static_cast<int64_t
>(i);
110 ids[
static_cast<size_t>(s)] =
id;
111 if (positions && positions[s]) {
112 for (
long k = 0; k < 3 * nAtoms; ++k) {
113 pos[
static_cast<size_t>(s * 3 * nAtoms + k)] = positions[s][k];
116 if (boxes && boxes[s]) {
117 for (
long k = 0; k < 9; ++k) {
118 box[
static_cast<size_t>(s * 9 + k)] = boxes[s][k];
122 std::vector<double> ebuf(
static_cast<size_t>(nSystems), 0.0);
123 std::vector<double> vbuf(
static_cast<size_t>(nSystems), 0.0);
124 std::uint64_t new_epoch =
epoch_;
128 req.
n_images =
static_cast<int64_t
>(nSystems);
129 req.
n_atoms =
static_cast<int64_t
>(nAtoms);
132 req.
boxes = box.data();
140 throw std::runtime_error(
"HostSurfacePotential: surface failed");
145 if (new_epoch !=
epoch_) {
149 for (
long s = 0; s < nSystems; ++s) {
153 for (
long s = 0; s < nSystems; ++s) {
155 energies[s] = ebuf[
static_cast<size_t>(s)];
158 variances[s] = vbuf[
static_cast<size_t>(s)];
160 if (forces && forces[s]) {
161 for (
long k = 0; k < 3 * nAtoms; ++k) {
162 forces[s][k] = frc[
static_cast<size_t>(s * 3 * nAtoms + k)];
174 std::vector<std::shared_ptr<Matter>>
path_;
int lastStatus() const noexcept
bool forwardsStoredCell() const noexcept override
A host that owns the cell reads the stored matrix.
void bindPath(const std::vector< std::shared_ptr< Matter > > &path)
void setEpoch(std::uint64_t epoch)
bool supportsBatchEvaluation() const noexcept override
Whether this potential supports batched evaluation of N systems in a single call.
HostSurfacePotential(eon_relax_surface_fn fn, void *user, std::uint64_t epoch)
unsigned long long surfaceEpoch() const noexcept override
Host-visible surface generation.
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
std::vector< std::shared_ptr< Matter > > path_
void force(long nAtoms, const double *positions, const int *atomicNrs, double *forces, double *energy, double *variance, const double *box) override
void bindBand(const std::vector< std::shared_ptr< Matter > > &path) override
NEB calls this with the finished band before the first force evaluation, so a host surface can name e...
void recordForceCall() noexcept
Charge one evaluated geometry to this potential and its owning registry.
Potential(PotType a_ptype)
Production default: construction-scope registry, else PotRegistry::get().
Tier-2 C ABI: eOn as a dlopen relaxation engine.
#define EON_RELAX_ABI_MAJOR
#define EON_RELAX_ABI_MINOR
#define EON_RELAX_IMAGE_NONE
int(* eon_relax_surface_fn)(void *user, eon_relax_surface_request_t *req)
Return 0 on success, positive recoverable, negative fatal.
RAII resource manager for the ARTn C library with global synchronization.
Host-surface request: one struct, engine-stamped version, so the callback contract grows behind the v...
const int32_t * atomic_nrs
const int64_t * image_ids
eon_relax_version_t version
SurfaceRecoverable(int code)
const char * what() const noexcept override