Loading...
Searching...
No Matches
RGPotEngine Class Reference

Opaque rgpot-backed engine (nwchemc / cpmdc / metatomic / xtb). More...

#include <RGPotEngine.h>

Classes

struct  Impl

Public Member Functions

 RGPotEngine (const RGPotEngineOptions &opt)
 ~RGPotEngine ()
 RGPotEngine (const RGPotEngine &)=delete
RGPotEngineoperator= (const RGPotEngine &)=delete
const std::string & backend () const noexcept
bool available () const
void force (long N, const double *R, const int *atomicNrs, double *F, double *U, const double *box) const

Private Attributes

std::unique_ptr< Implimpl_
std::string backend_

Detailed Description

Opaque rgpot-backed engine (nwchemc / cpmdc / metatomic / xtb).

Definition at line 40 of file RGPotEngine.h.

Constructor & Destructor Documentation

◆ RGPotEngine() [1/2]

RGPotEngine::RGPotEngine ( const RGPotEngineOptions & opt)
explicit

Definition at line 80 of file RGPotEngine.cpp.

81 : impl_(std::make_unique<Impl>()) {
82 backend_ = to_lower(opt.backend);
83 if (backend_ == "nwchem" || backend_ == "nwchemc" ||
84 backend_ == "nwchempot") {
85 backend_ = "nwchemc";
87 ::capnp::MallocMessageBuilder msg;
88 auto params = msg.initRoot<::NWChemParams>();
89 params.setBasis(opt.basis);
90 params.setTheory(opt.theory);
91 params.setScfType(opt.scf_type);
92 params.setCharge(opt.charge);
93 params.setMultiplicity(opt.multiplicity);
94 if (!opt.engine_path.empty())
95 params.setEnginePath(opt.engine_path);
96 else if (!opt.engine_library.empty())
97 params.setEnginePath(opt.engine_library);
98 if (!opt.engine_root.empty())
99 params.setNwchemRoot(opt.engine_root);
100 if (!opt.title.empty())
101 params.setTitle(opt.title);
102 if (opt.memory_mb > 0)
103 params.setMemoryMb(static_cast<uint32_t>(opt.memory_mb));
104 if (!opt.scratch_dir.empty())
105 params.setScratchDir(opt.scratch_dir);
106 // DFT XC as inputBlocks when theory=dft and scfType is an XC label
107 std::string block = opt.input_block;
108 if (block.empty()) {
109 if (const char *env = std::getenv("RGPOT_NWCHEM_INPUT_BLOCK"))
110 block = env;
111 }
112 if (block.empty() && (opt.theory == "dft" || opt.theory == "DFT") &&
113 looks_like_dft_xc(opt.scf_type)) {
114 block = "dft\n xc " + opt.scf_type + "\n mult " +
115 std::to_string(opt.multiplicity) + "\nend";
116 } else if (block.empty() && looks_like_dft_xc(opt.theory)) {
117 block = "dft\n xc " + opt.theory + "\n mult " +
118 std::to_string(opt.multiplicity) + "\nend";
119 }
120 if (!block.empty()) {
121 auto blocks = params.initInputBlocks(1);
122 blocks.set(0, block);
123 }
124 impl_->nwchem = std::make_unique<rgpot::NWChemPot>(params.asReader());
125 if (!impl_->nwchem->available())
126 throw std::runtime_error(
127 "RGPOT(nwchemc): engine not available (set NWCHEMC_LIBRARY / "
128 "RGPOT_NWCHEMC_ENGINE or [RgpotPot] engine_path)");
129 } else if (backend_ == "cpmd" || backend_ == "cpmdc" ||
130 backend_ == "cpmdpot") {
131 backend_ = "cpmdc";
132 impl_->backend = Impl::Backend::Cpmdc;
133 ::capnp::MallocMessageBuilder msg;
134 auto params = msg.initRoot<::CPMDParams>();
135 params.setFunctional(opt.functional);
136 params.setCutOffRy(opt.cutoff_ry);
137 params.setCharge(opt.charge);
138 params.setMultiplicity(opt.multiplicity);
139 if (!opt.engine_path.empty())
140 params.setEnginePath(opt.engine_path);
141 else if (!opt.engine_library.empty())
142 params.setEnginePath(opt.engine_library);
143 if (!opt.engine_root.empty())
144 params.setCpmdRoot(opt.engine_root);
145 if (!opt.title.empty())
146 params.setTitle(opt.title);
147 if (opt.memory_mb > 0)
148 params.setMemoryMb(static_cast<uint32_t>(opt.memory_mb));
149 if (!opt.scratch_dir.empty())
150 params.setScratchDir(opt.scratch_dir);
151 impl_->cpmd = std::make_unique<rgpot::CPMDPot>(params.asReader());
152 if (!impl_->cpmd->available())
153 throw std::runtime_error(
154 "RGPOT(cpmdc): engine not available (set CPMDC_LIBRARY / "
155 "RGPOT_CPMDC_ENGINE or [RgpotPot] engine_path)");
156 } else if (backend_ == "metatomic" || backend_ == "mta" ||
157 backend_ == "metatomicpot") {
158 backend_ = "metatomic";
160 MetatomicEngineOptions mopt;
161 mopt.model_path = opt.model_path;
162 mopt.device = opt.device;
163 mopt.length_unit = opt.length_unit;
167 mopt.engine_path =
168 !opt.engine_path.empty() ? opt.engine_path : opt.engine_library;
170 impl_->metatomic = std::make_unique<MetatomicEngineLoader>(mopt);
171 if (!impl_->metatomic->available())
172 throw std::runtime_error(
173 "RGPOT(metatomic): engine not available (set RGPOT_METATOMIC_ENGINE "
174 "or [RgpotPot] engine_path to libmetatomic_engine.so)");
175 } else if (backend_ == "xtb" || backend_ == "xtbpot" || backend_ == "gfn" ||
176 backend_ == "gfnxtb") {
177 backend_ = "xtb";
178 impl_->backend = Impl::Backend::Xtb;
179 XTBEngineOptions xopt;
180 xopt.method = xtb_method_from_paramset(opt.xtb_paramset);
181 xopt.accuracy = opt.xtb_accuracy;
184 xopt.charge = opt.xtb_charge;
185 xopt.uhf = opt.xtb_uhf;
186 xopt.engine_path =
187 !opt.engine_path.empty() ? opt.engine_path : opt.engine_library;
188 impl_->xtb = std::make_unique<XTBEngineLoader>(xopt);
189 if (!impl_->xtb->available())
190 throw std::runtime_error(
191 "RGPOT(xtb): engine not available (set RGPOT_XTB_ENGINE or "
192 "[RgpotPot] engine_path to libxtb_engine.so)");
193 } else {
194 throw std::runtime_error("RGPOT: unknown backend '" + opt.backend +
195 "' (expected nwchemc, cpmdc, metatomic, or xtb)");
196 }
197}
std::unique_ptr< Impl > impl_
Definition RGPotEngine.h:54
std::string backend_
Definition RGPotEngine.h:55
std::string scf_type
Definition RGPotEngine.h:10
std::string title
Definition RGPotEngine.h:18
std::string xtb_paramset
Definition RGPotEngine.h:31
std::string basis
Definition RGPotEngine.h:8
std::string scratch_dir
Definition RGPotEngine.h:20
std::string engine_path
Definition RGPotEngine.h:15
std::string backend
Definition RGPotEngine.h:7
std::string extensions_directory
Definition RGPotEngine.h:26
std::string engine_library
Definition RGPotEngine.h:16
double xtb_electronic_temperature
Definition RGPotEngine.h:33
std::string functional
Definition RGPotEngine.h:11
std::string length_unit
Definition RGPotEngine.h:25
bool torch_determinism_strict
Definition RGPotEngine.h:29
std::string device
Definition RGPotEngine.h:24
std::string model_path
Definition RGPotEngine.h:23
std::string engine_root
Definition RGPotEngine.h:17
double uncertainty_threshold
Definition RGPotEngine.h:28
std::string theory
Definition RGPotEngine.h:9
std::string input_block
Definition RGPotEngine.h:21
std::string engine_path
double electronic_temperature

◆ ~RGPotEngine()

RGPotEngine::~RGPotEngine ( )
default

◆ RGPotEngine() [2/2]

RGPotEngine::RGPotEngine ( const RGPotEngine & )
delete

Member Function Documentation

◆ available()

bool RGPotEngine::available ( ) const
nodiscard

Definition at line 201 of file RGPotEngine.cpp.

201 {
202 if (!impl_)
203 return false;
204 if (impl_->backend == Impl::Backend::Nwchemc && impl_->nwchem)
205 return impl_->nwchem->available();
206 if (impl_->backend == Impl::Backend::Cpmdc && impl_->cpmd)
207 return impl_->cpmd->available();
208 if (impl_->backend == Impl::Backend::Metatomic && impl_->metatomic)
209 return impl_->metatomic->available();
210 if (impl_->backend == Impl::Backend::Xtb && impl_->xtb)
211 return impl_->xtb->available();
212 return false;
213}

◆ backend()

const std::string & RGPotEngine::backend ( ) const
inlinenodiscardnoexcept

Definition at line 47 of file RGPotEngine.h.

47{ return backend_; }

◆ force()

void RGPotEngine::force ( long N,
const double * R,
const int * atomicNrs,
double * F,
double * U,
const double * box ) const

Definition at line 215 of file RGPotEngine.cpp.

216 {
217 if (N <= 0)
218 throw std::runtime_error("RGPotEngine::force called with N <= 0");
219
220 AtomMatrix positions(static_cast<int>(N), 3);
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
230 if (impl_->backend == Impl::Backend::Metatomic) {
231 impl_->metatomic->force(N, R, atomicNrs, F, U, nullptr, box);
232 return;
233 }
234 if (impl_->backend == Impl::Backend::Xtb) {
235 impl_->xtb->force(N, R, atomicNrs, F, U, nullptr, box);
236 return;
237 }
238
239 // rgpot >= 2.5.0: operator() returns (energy, forces, variance).
240 std::tuple<double, AtomMatrix, double> result;
241 if (impl_->backend == Impl::Backend::Nwchemc)
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
Definition Eigen.h:37

◆ operator=()

RGPotEngine & RGPotEngine::operator= ( const RGPotEngine & )
delete

Member Data Documentation

◆ backend_

std::string RGPotEngine::backend_
private

Definition at line 55 of file RGPotEngine.h.

◆ impl_

std::unique_ptr<Impl> RGPotEngine::impl_
private

Definition at line 54 of file RGPotEngine.h.


The documentation for this class was generated from the following files: