eOn client
Long-timescale dynamics: aKMC, NEB, parallel replica
☾
Toggle main menu visibility
Loading...
Searching...
No Matches
ASE.cpp
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
** Copyright (c) 2010--present, eOn Development Team
7
** All rights reserved.
8
**
9
** Repo:
10
** https://github.com/TheochemUI/eOn
11
*/
12
13
#include "
eon/potentials/ASE/ASE.h
"
14
#include "
eon/PyGuard.h
"
15
#include "
eon/fpe_handler.h
"
16
#include <pybind11/embed.h>
17
#include <pybind11/numpy.h>
// for py::array_t
18
#include <pybind11/pybind11.h>
19
#include <stdexcept>
20
#include <string>
21
#include <tuple>
22
#include <vector>
23
24
namespace
py = pybind11;
25
26
ASE::ASE
(
const
Parameters
&a_params)
27
:
Potential
(
PotType
::ASE_POT, a_params) {
28
eonc::ensure_interpreter
();
29
counter
= 1;
30
std::string py_file = a_params.
potential_options
.
extPotPath
;
31
32
// import
33
try
{
34
// must briefly disable FPE because Python packages like Numpy causes it
35
// during import
36
eonc::FPEHandler
fpeh;
37
fpeh.
eat_fpe
();
38
39
// Create a Python script to use importlib.util to load the module
40
py::exec(R
"(
41
import sys
42
import importlib.util
43
44
def load_module_from_path(module_name, file_path):
45
spec = importlib.util.spec_from_file_location(module_name, file_path)
46
module = importlib.util.module_from_spec(spec)
47
sys.modules[module_name] = module
48
spec.loader.exec_module(module)
49
return module
50
)");
51
52
// Prepare the module name and file path
53
std::string module_name =
"ase_eon"
;
54
py::object load_module = py::globals()[
"load_module_from_path"
];
55
py_module
= load_module(module_name, py_file);
56
57
fpeh.
restore_fpe
();
58
59
calculator
=
py_module
.attr(
"ase_calc"
)();
60
_calculate
=
py_module
.attr(
"_calculate"
);
61
62
}
catch
(
const
std::exception &e) {
63
fprintf(stderr,
64
"ASE Calculator: Exception during Python module import: %s\n"
,
65
e.what());
66
fprintf(stderr,
"%s should exist and have no errors on the Python side.\n"
,
67
py_file.c_str());
68
throw
std::runtime_error(std::string(
"ASE calculator import failed: "
) +
69
e.what());
70
}
71
return
;
72
}
73
74
void
ASE::force
(
long
nAtoms,
const
double
*R,
const
int
*atomicNrs,
double
*F,
75
double
*U,
double
*variance,
const
double
*box) {
76
variance =
nullptr
;
77
try
{
78
// TODO(rg): This is easier on the type system if Eigen::Map is used like in
79
// ASE_ORCA convert arrays to Numpy arrays
80
std::vector<size_t> R_shape = {
static_cast<
size_t
>
(nAtoms), 3};
81
py::array_t<double> R_np(R_shape, R);
82
py::array_t<int> atomicNrs_np(nAtoms, atomicNrs);
83
py::array_t<double> box_np({3, 3}, box);
84
85
// get energy and forces (in this order) from Python
86
std::tuple<double, py::array_t<double>> py_result =
87
_calculate
(R_np, atomicNrs_np, box_np,
calculator
)
88
.cast<std::tuple<double, py::array_t<double>>>();
89
90
// copy the results to the output arrays
91
*U = std::get<0>(py_result);
92
py::array_t<double> forces = std::get<1>(py_result);
93
auto
buffer = forces.request();
94
double
*ptr =
static_cast<
double
*
>
(buffer.ptr);
95
std::copy(ptr, ptr + buffer.size, F);
96
97
}
catch
(py::error_already_set &e) {
98
fprintf(stderr,
"ASE calculator: Python error: %s\n"
, e.what());
99
throw
std::runtime_error(std::string(
"ASE calculator Python error: "
) +
100
e.what());
101
}
catch
(
const
std::exception &e) {
102
fprintf(stderr,
"ASE calculator: C++ exception: %s\n"
, e.what());
103
throw
std::runtime_error(std::string(
"ASE calculator C++ exception: "
) +
104
e.what());
105
}
106
107
counter
++;
108
return
;
109
}
ASE.h
PyGuard.h
ASE::calculator
py::object calculator
Definition
ASE.h:24
ASE::force
void force(long nAtoms, const double *R, const int *atomicNrs, double *F, double *U, double *variance, const double *box) override
Definition
ASE.cpp:64
ASE::py_module
py::module_ py_module
Definition
ASE.h:23
ASE::ASE
ASE(const Parameters &a_params)
Definition
ASE.cpp:26
ASE::counter
size_t counter
Definition
ASE.h:22
ASE::_calculate
py::object _calculate
Definition
ASE.h:25
eonc::FPEHandler
Definition
fpe_handler.h:25
eonc::FPEHandler::restore_fpe
void restore_fpe()
Definition
fpe_handler.cpp:251
eonc::FPEHandler::eat_fpe
void eat_fpe()
Definition
fpe_handler.cpp:246
eonc::Parameters
Definition
Parameters.h:28
eonc::Parameters::potential_options
struct eonc::Parameters::potential_options_t potential_options
eonc::Potential::Potential
Potential(PotType a_ptype)
Definition
Potential.h:35
fpe_handler.h
eonc::PotType
PotType
Definition
BaseStructures.h:36
eonc::ensure_interpreter
void ensure_interpreter()
Definition
NbGuard.h:21
eonc::Parameters::potential_options_t::extPotPath
std::string extPotPath
Definition
Parameters.h:73
client
potentials
ASE
ASE.cpp
Generated by
1.17.0
Generated by
Doxygen 1.17.0
Analytics by
Antics
provided by
TurtleTech ehf