Loading...
Searching...
No Matches
RgpotAdapter.h
Go to the documentation of this file.
1/*
2** This file is part of eOn.
3**
4** SPDX-License-Identifier: BSD-3-Clause
5**
6** Adapter over rgpot potential kernels. Migrated pair potentials live in
7** librgpot (github.com/OmniPotentRPC/rgpot); eOn's config surface,
8** PotRegistry, force counters, and caching stay on this side.
9*/
10#pragma once
11
12#include <memory>
13#include <vector>
14
15#include "eon/Potential.h"
16
17#include "rgpot/ForceStructs.hpp"
18#include "rgpot/pot_caps.hpp"
19
27template <class RPot> class RgpotAdapter final : public Potential {
28public:
31 template <class Cfg>
32 RgpotAdapter(PotType ptype, const Parameters &params, const Cfg &cfg)
33 : Potential(ptype, params),
34 pot_(cfg) {}
35
38 : Potential(ptype, params),
39 pot_() {}
40
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);
46 *U = out.energy;
47 if (variance != nullptr) {
48 *variance = out.variance;
49 }
50 }
51
56 [[nodiscard]] bool supportsBatchEvaluation() const noexcept override {
57 return pot_.caps().batched;
58 }
59
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;
75 in.reserve(n);
76 out.reserve(n);
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});
81 }
82
83 pot_.forceBatchImpl(
84 rgpot::ForceBatch{.nSystems = n, .in = in.data(), .out = out.data()});
85
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;
90 }
93 }
94 }
95
96 [[nodiscard]] bool isThreadSafe() const noexcept override {
97 return pot_.caps().reentrancy == rgpot::Reentrancy::SharedInstance;
98 }
99
100 [[nodiscard]] bool needsPerImageInstance() const noexcept override {
101 const auto caps = pot_.caps();
102 return caps.perImageInstances ||
103 caps.reentrancy == rgpot::Reentrancy::PerInstance;
104 }
105
106 [[nodiscard]] const RPot &kernel() const noexcept { return pot_; }
107
108private:
109 RPot pot_;
110};
111
114template <class RPot>
115std::shared_ptr<Potential> makeRgpotDefault(PotType ptype,
116 const Parameters &params) {
117 return std::make_shared<RgpotAdapter<RPot>>(ptype, params);
118}
119
121template <class RPot, class Cfg>
122std::shared_ptr<Potential> makeRgpot(PotType ptype, const Parameters &params,
123 const Cfg &cfg) {
124 return std::make_shared<RgpotAdapter<RPot>>(ptype, params, cfg);
125}
std::shared_ptr< Potential > makeRgpot(PotType ptype, const Parameters &params, const Cfg &cfg)
Factory arm helper: construct the kernel from its config and wrap it.
std::shared_ptr< Potential > makeRgpotDefault(PotType ptype, const Parameters &params)
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 &params, const Cfg &cfg)
Kernels construct in place from their config: several hold mutexes or other immovable state,...
RgpotAdapter(PotType ptype, const Parameters &params)
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
Definition Potential.h:32
PotType ptype
Definition Potential.h:25
Potential(PotType a_ptype)
Definition Potential.h:35