eOn client
Long-timescale dynamics: aKMC, NEB, parallel replica
☾
Toggle main menu visibility
Loading...
Searching...
No Matches
RGPotEngine.cpp
Go to the documentation of this file.
1
// Isolated TU: rgpot only (no eOn Potential.h) — avoids Cap'n Proto Potential
2
// clash.
3
#include "
eon/potentials/Rgpot/RGPotEngine.h
"
4
5
#include <array>
6
#include <cctype>
7
#include <cstdint>
8
#include <cstdlib>
9
#include <stdexcept>
10
#include <tuple>
11
#include <vector>
12
13
#include <capnp/message.h>
14
15
#include "
eon/potentials/Rgpot/MetatomicEngineLoader.h
"
16
#include "
eon/potentials/Rgpot/XTBEngineLoader.h
"
17
#include "rgpot/CPMDPot/CPMDPot.hpp"
18
#include "rgpot/NWChemPot/NWChemPot.hpp"
19
#include "rgpot/rpc/Potentials.capnp.h"
20
21
using
rgpot::types::AtomMatrix;
22
23
namespace
{
24
25
std::string to_lower(std::string s) {
26
for
(
char
&c : s)
27
c =
static_cast<
char
>
(std::tolower(
static_cast<
unsigned
char
>
(c)));
28
return
s;
29
}
30
31
std::array<std::array<double, 3>, 3> box_from_row_major(
const
double
*box) {
32
std::array<std::array<double, 3>, 3> out{};
33
for
(
int
i = 0; i < 3; ++i)
34
for
(
int
j = 0; j < 3; ++j)
35
out[
static_cast<
size_t
>
(i)][
static_cast<
size_t
>
(j)] = box[i * 3 + j];
36
return
out;
37
}
38
39
bool
looks_like_dft_xc(
const
std::string &s) {
40
if
(s.empty())
41
return
false
;
42
static
const
char
*k[] = {
"b3lyp"
,
"blyp"
,
"pbe"
,
"pw91"
,
"bp86"
,
43
"hcth"
,
"ft97"
,
"hfexch"
,
"xperpbe"
,
nullptr
};
44
for
(
int
i = 0; k[i]; ++i) {
45
if
(s.size() >= std::char_traits<char>::length(k[i]) &&
46
s.compare(0, std::char_traits<char>::length(k[i]), k[i]) == 0)
47
return
true
;
48
}
49
return
false
;
50
}
51
53
int
xtb_method_from_paramset(
const
std::string ¶mset) {
54
const
std::string p = to_lower(paramset);
55
if
(p ==
"gfnff"
|| p ==
"gfn-ff"
)
56
return
RGPOT_XTB_METHOD_GFNFF
;
57
if
(p ==
"gfn0xtb"
|| p ==
"gfn0"
|| p ==
"gfn0-xtb"
)
58
return
RGPOT_XTB_METHOD_GFN0
;
59
if
(p ==
"gfn1xtb"
|| p ==
"gfn1"
|| p ==
"gfn1-xtb"
)
60
return
RGPOT_XTB_METHOD_GFN1
;
61
if
(p ==
"gfn2xtb"
|| p ==
"gfn2"
|| p ==
"gfn2-xtb"
|| p.empty())
62
return
RGPOT_XTB_METHOD_GFN2
;
63
throw
std::runtime_error(
64
"RGPOT(xtb): paramset must be GFNFF, GFN0xTB, GFN1xTB, or GFN2xTB "
65
"(got '"
+
66
paramset +
"')"
);
67
}
68
69
}
// namespace
70
71
struct
RGPotEngine::Impl
{
72
enum class
Backend
{
Nwchemc
,
Cpmdc
,
Metatomic
,
Xtb
};
73
Backend
backend
{
Backend::Nwchemc
};
74
std::unique_ptr<rgpot::NWChemPot>
nwchem
;
75
std::unique_ptr<rgpot::CPMDPot>
cpmd
;
76
std::unique_ptr<MetatomicEngineLoader>
metatomic
;
77
std::unique_ptr<XTBEngineLoader>
xtb
;
78
};
79
80
RGPotEngine::RGPotEngine
(
const
RGPotEngineOptions
&opt)
81
:
impl_
(std::make_unique<
Impl
>()) {
82
backend_
= to_lower(opt.
backend
);
83
if
(
backend_
==
"nwchem"
||
backend_
==
"nwchemc"
||
84
backend_
==
"nwchempot"
) {
85
backend_
=
"nwchemc"
;
86
impl_
->backend =
Impl::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"
;
159
impl_
->backend =
Impl::Backend::Metatomic
;
160
MetatomicEngineOptions
mopt;
161
mopt.
model_path
= opt.
model_path
;
162
mopt.
device
= opt.
device
;
163
mopt.
length_unit
= opt.
length_unit
;
164
mopt.
extensions_directory
= opt.
extensions_directory
;
165
mopt.
check_consistency
= opt.
check_consistency
;
166
mopt.
uncertainty_threshold
= opt.
uncertainty_threshold
;
167
mopt.
engine_path
=
168
!opt.
engine_path
.empty() ? opt.
engine_path
: opt.
engine_library
;
169
mopt.
torch_determinism_strict
= opt.
torch_determinism_strict
;
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
;
182
xopt.
electronic_temperature
= opt.
xtb_electronic_temperature
;
183
xopt.
max_iterations
= opt.
xtb_max_iterations
;
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
}
198
199
RGPotEngine::~RGPotEngine
() =
default
;
200
201
bool
RGPotEngine::available
()
const
{
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
}
214
215
void
RGPotEngine::force
(
long
N,
const
double
*R,
const
int
*atomicNrs,
216
double
*F,
double
*U,
const
double
*box)
const
{
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
}
AtomMatrix
Eigen::Matrix< double, Eigen::Dynamic, 3, eOnStorageOrder > AtomMatrix
Definition
Eigen.h:37
MetatomicEngineLoader.h
RGPotEngine.h
XTBEngineLoader.h
RGPotEngine::available
bool available() const
Definition
RGPotEngine.cpp:201
RGPotEngine::RGPotEngine
RGPotEngine(const RGPotEngineOptions &opt)
Definition
RGPotEngine.cpp:80
RGPotEngine::~RGPotEngine
~RGPotEngine()
RGPotEngine::impl_
std::unique_ptr< Impl > impl_
Definition
RGPotEngine.h:54
RGPotEngine::backend_
std::string backend_
Definition
RGPotEngine.h:55
RGPotEngine::force
void force(long N, const double *R, const int *atomicNrs, double *F, double *U, const double *box) const
Definition
RGPotEngine.cpp:215
MetatomicEngineOptions
Definition
MetatomicEngineLoader.h:9
MetatomicEngineOptions::uncertainty_threshold
double uncertainty_threshold
Definition
MetatomicEngineLoader.h:15
MetatomicEngineOptions::check_consistency
bool check_consistency
Definition
MetatomicEngineLoader.h:14
MetatomicEngineOptions::length_unit
std::string length_unit
Definition
MetatomicEngineLoader.h:12
MetatomicEngineOptions::extensions_directory
std::string extensions_directory
Definition
MetatomicEngineLoader.h:13
MetatomicEngineOptions::device
std::string device
Definition
MetatomicEngineLoader.h:11
MetatomicEngineOptions::torch_determinism_strict
bool torch_determinism_strict
Definition
MetatomicEngineLoader.h:17
MetatomicEngineOptions::engine_path
std::string engine_path
Definition
MetatomicEngineLoader.h:16
MetatomicEngineOptions::model_path
std::string model_path
Definition
MetatomicEngineLoader.h:10
RGPotEngineOptions
Definition
RGPotEngine.h:6
RGPotEngineOptions::xtb_uhf
int xtb_uhf
Definition
RGPotEngine.h:36
RGPotEngineOptions::scf_type
std::string scf_type
Definition
RGPotEngine.h:10
RGPotEngineOptions::check_consistency
bool check_consistency
Definition
RGPotEngine.h:27
RGPotEngineOptions::title
std::string title
Definition
RGPotEngine.h:18
RGPotEngineOptions::multiplicity
int multiplicity
Definition
RGPotEngine.h:14
RGPotEngineOptions::xtb_paramset
std::string xtb_paramset
Definition
RGPotEngine.h:31
RGPotEngineOptions::basis
std::string basis
Definition
RGPotEngine.h:8
RGPotEngineOptions::scratch_dir
std::string scratch_dir
Definition
RGPotEngine.h:20
RGPotEngineOptions::engine_path
std::string engine_path
Definition
RGPotEngine.h:15
RGPotEngineOptions::cutoff_ry
double cutoff_ry
Definition
RGPotEngine.h:12
RGPotEngineOptions::xtb_max_iterations
int xtb_max_iterations
Definition
RGPotEngine.h:34
RGPotEngineOptions::memory_mb
int memory_mb
Definition
RGPotEngine.h:19
RGPotEngineOptions::backend
std::string backend
Definition
RGPotEngine.h:7
RGPotEngineOptions::extensions_directory
std::string extensions_directory
Definition
RGPotEngine.h:26
RGPotEngineOptions::engine_library
std::string engine_library
Definition
RGPotEngine.h:16
RGPotEngineOptions::xtb_electronic_temperature
double xtb_electronic_temperature
Definition
RGPotEngine.h:33
RGPotEngineOptions::charge
int charge
Definition
RGPotEngine.h:13
RGPotEngineOptions::functional
std::string functional
Definition
RGPotEngine.h:11
RGPotEngineOptions::length_unit
std::string length_unit
Definition
RGPotEngine.h:25
RGPotEngineOptions::torch_determinism_strict
bool torch_determinism_strict
Definition
RGPotEngine.h:29
RGPotEngineOptions::device
std::string device
Definition
RGPotEngine.h:24
RGPotEngineOptions::model_path
std::string model_path
Definition
RGPotEngine.h:23
RGPotEngineOptions::xtb_accuracy
double xtb_accuracy
Definition
RGPotEngine.h:32
RGPotEngineOptions::engine_root
std::string engine_root
Definition
RGPotEngine.h:17
RGPotEngineOptions::uncertainty_threshold
double uncertainty_threshold
Definition
RGPotEngine.h:28
RGPotEngineOptions::theory
std::string theory
Definition
RGPotEngine.h:9
RGPotEngineOptions::input_block
std::string input_block
Definition
RGPotEngine.h:21
RGPotEngineOptions::xtb_charge
double xtb_charge
Definition
RGPotEngine.h:35
RGPotEngine::Impl
Definition
RGPotEngine.cpp:71
RGPotEngine::Impl::backend
Backend backend
Definition
RGPotEngine.cpp:73
RGPotEngine::Impl::nwchem
std::unique_ptr< rgpot::NWChemPot > nwchem
Definition
RGPotEngine.cpp:74
RGPotEngine::Impl::Backend
Backend
Definition
RGPotEngine.cpp:72
RGPotEngine::Impl::Backend::Cpmdc
@ Cpmdc
Definition
RGPotEngine.cpp:72
RGPotEngine::Impl::Backend::Nwchemc
@ Nwchemc
Definition
RGPotEngine.cpp:72
RGPotEngine::Impl::Backend::Xtb
@ Xtb
Definition
RGPotEngine.cpp:72
RGPotEngine::Impl::Backend::Metatomic
@ Metatomic
Definition
RGPotEngine.cpp:72
RGPotEngine::Impl::cpmd
std::unique_ptr< rgpot::CPMDPot > cpmd
Definition
RGPotEngine.cpp:75
RGPotEngine::Impl::metatomic
std::unique_ptr< MetatomicEngineLoader > metatomic
Definition
RGPotEngine.cpp:76
RGPotEngine::Impl::xtb
std::unique_ptr< XTBEngineLoader > xtb
Definition
RGPotEngine.cpp:77
XTBEngineOptions
Definition
XTBEngineLoader.h:10
XTBEngineOptions::uhf
int uhf
Definition
XTBEngineLoader.h:16
XTBEngineOptions::engine_path
std::string engine_path
Definition
XTBEngineLoader.h:17
XTBEngineOptions::max_iterations
int max_iterations
Definition
XTBEngineLoader.h:14
XTBEngineOptions::charge
double charge
Definition
XTBEngineLoader.h:15
XTBEngineOptions::electronic_temperature
double electronic_temperature
Definition
XTBEngineLoader.h:13
XTBEngineOptions::method
int method
Definition
XTBEngineLoader.h:11
XTBEngineOptions::accuracy
double accuracy
Definition
XTBEngineLoader.h:12
RGPOT_XTB_METHOD_GFNFF
@ RGPOT_XTB_METHOD_GFNFF
Definition
xtb_c_abi.h:32
RGPOT_XTB_METHOD_GFN1
@ RGPOT_XTB_METHOD_GFN1
Definition
xtb_c_abi.h:34
RGPOT_XTB_METHOD_GFN2
@ RGPOT_XTB_METHOD_GFN2
Definition
xtb_c_abi.h:35
RGPOT_XTB_METHOD_GFN0
@ RGPOT_XTB_METHOD_GFN0
Definition
xtb_c_abi.h:33
client
potentials
Rgpot
RGPotEngine.cpp
Generated by
1.17.0
Generated by
Doxygen 1.17.0
Analytics by
Antics
provided by
TurtleTech ehf