eOn 3.2.0
Long-timescale dynamics: aKMC, NEB, parallel replica
☾
Toggle main menu visibility
Loading...
Searching...
No Matches
ASE_ORCA.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_ORCA/ASE_ORCA.h
"
14
#include "
eon/EnvHelpers.hpp
"
15
#include "
eon/EonLogger.h
"
16
#include "
eon/Parameters.h
"
17
#include "
eon/PyGuard.h
"
18
#include "
eon/fpe_handler.h
"
19
20
#include <atomic>
21
#include <format>
22
#include <stdexcept>
23
#include <string>
24
#include <system_error>
25
26
#ifdef _WIN32
27
#include <process.h>
28
#else
29
#include <unistd.h>
30
#endif
31
32
namespace
{
33
34
std::filesystem::path makeAseWorkDir(
const
char
*prefix) {
35
static
std::atomic<long> instanceCount{0};
36
#ifdef _WIN32
37
const
long
pid =
static_cast<
long
>
(_getpid());
38
#else
39
const
long
pid =
static_cast<
long
>
(getpid());
40
#endif
41
std::error_code ec;
42
auto
dir = std::filesystem::temp_directory_path(ec);
43
if
(ec) {
44
throw
std::runtime_error(std::format(
45
"ASE-ORCA: cannot resolve temp directory: {}"
, ec.message()));
46
}
47
dir /= std::format(
"{}_{}_{}"
, prefix, pid, instanceCount.fetch_add(1));
48
std::filesystem::create_directories(dir, ec);
49
if
(ec) {
50
throw
std::runtime_error(
51
std::format(
"ASE-ORCA: cannot create work directory {}: {}"
,
52
dir.string(), ec.message()));
53
}
54
return
dir;
55
}
56
57
}
// namespace
58
59
ASEOrcaPot::ASEOrcaPot
(
const
eonc::Parameters
&a_params)
60
:
eonc
::
Potential
(
eonc
::PotType::ASE_ORCA, a_params) {
61
using namespace
pybind11::literals;
62
eonc::ensure_interpreter
();
63
counter
= 0;
64
py::module_ sys = py::module_::import(
"sys"
);
65
// Fix for gh-184, see
66
// https://github.com/numpy/numpy/issues/20504#issuecomment-985542508
67
eonc::FPEHandler
fpeh;
68
fpeh.
eat_fpe
();
69
ase
= py::module_::import(
"ase"
);
70
fpeh.
restore_fpe
();
71
py::module_ ase_orca = py::module_::import(
"ase.calculators.orca"
);
72
py::module_ psutil = py::module_::import(
"psutil"
);
73
std::string orcpth =
eonc::helpers::get_value_from_env_or_param
(
74
"ORCA_COMMAND"
, a_params.
ase_orca_options
().
path
,
""
,
""
,
true
);
75
std::string orca_simpleinput =
eonc::helpers::get_value_from_env_or_param
(
76
"ORCA_SIMPLEINPUT"
, a_params.
ase_orca_options
().
simpleinput
,
77
"ENGRAD HF-3c"
,
78
"Using ENGRAD HF-3c as a default input, set simpleinput or the "
79
"environment variable ORCA_SIMPLEINPUT.\n"
);
80
81
// Set up ORCA profile and calculator
82
py::object OrcaProfile = ase_orca.attr(
"OrcaProfile"
);
83
py::object ORCA = ase_orca.attr(
"ORCA"
);
84
size_t
nproc{0};
85
86
if
(a_params.
ase_orca_options
().
nproc
==
"auto"
) {
87
nproc = py::cast<int>(psutil.attr(
"cpu_count"
)(
false
));
88
}
else
{
89
nproc = std::stoi(a_params.
ase_orca_options
().
nproc
);
90
}
91
92
// One directory per calculator instance so two LocalInProcess jobs in
93
// the same cwd do not share ORCA scratch and output files.
94
workDir
= makeAseWorkDir(
"eon_ase_orca"
);
95
96
try
{
97
this->
calc
=
98
ORCA(
"profile"
_a = OrcaProfile(py::str(orcpth)),
99
"orcasimpleinput"
_a = orca_simpleinput,
100
"orcablocks"
_a = py::str(std::format(
"%pal nprocs {} end"
, nproc)),
101
"directory"
_a =
workDir
.string());
102
}
catch
(...) {
103
std::error_code ec;
104
std::filesystem::remove_all(
workDir
, ec);
105
workDir
.clear();
106
throw
;
107
}
108
};
109
110
ASEOrcaPot::~ASEOrcaPot
() {
111
QUILL_LOG_INFO(
eonc::log::get
(),
"[ASEOrca] called potential {} times"
,
112
counter
);
113
if
(!
workDir
.empty()) {
114
std::error_code ec;
115
std::filesystem::remove_all(
workDir
, ec);
116
}
117
}
118
119
void
ASEOrcaPot::force
(
long
nAtoms,
const
double
*R,
const
int
*atomicNrs,
120
double
*F,
double
*U,
double
*variance,
121
const
double
*box) {
122
using namespace
pybind11::literals;
123
if
(variance !=
nullptr
) {
124
*variance = 0.0;
125
}
126
try
{
127
const
Eigen::Map<const AtomMatrix> positions(R, nAtoms, 3);
128
const
Eigen::Map<const RotationMatrix> boxx(box);
129
const
Eigen::Map<const Eigen::VectorXi> atmnmrs(atomicNrs, nAtoms);
130
py::object atoms = this->
ase
.attr(
"Atoms"
)(
131
"symbols"
_a = atmnmrs,
"positions"
_a = positions,
"cell"
_a = boxx,
132
"charge"
_a = params.ase_orca_options().charge);
133
atoms.attr(
"set_calculator"
)(this->
calc
);
134
atoms.attr(
"set_pbc"
)(std::tuple<bool, bool, bool>(
true
,
true
,
true
));
135
double
py_e = py::cast<double>(atoms.attr(
"get_potential_energy"
)());
136
Eigen::MatrixXd py_force =
137
py::cast<Eigen::MatrixXd>(atoms.attr(
"get_forces"
)());
138
139
// Populate the output parameters
140
*U = py_e;
141
for
(
long
i = 0; i < nAtoms; ++i) {
142
F[3 * i] = py_force(i, 0);
143
F[3 * i + 1] = py_force(i, 1);
144
F[3 * i + 2] = py_force(i, 2);
145
}
146
}
catch
(py::error_already_set &e) {
147
throw
std::runtime_error(std::string(
"ASE-ORCA Python error: "
) + e.what());
148
}
catch
(
const
std::exception &e) {
149
throw
std::runtime_error(std::string(
"ASE-ORCA C++ exception: "
) +
150
e.what());
151
}
152
153
counter
++;
154
return
;
155
}
ASE_ORCA.h
EnvHelpers.hpp
EonLogger.h
Parameters.h
PyGuard.h
ASEOrcaPot::force
void force(long nAtoms, const double *R, const int *atomicNrs, double *F, double *U, double *variance, const double *box) override
Definition
ASE_ORCA.cpp:119
ASEOrcaPot::~ASEOrcaPot
virtual ~ASEOrcaPot()
Definition
ASE_ORCA.cpp:110
ASEOrcaPot::ASEOrcaPot
ASEOrcaPot(const eonc::Parameters &a_params)
Definition
ASE_ORCA.cpp:59
ASEOrcaPot::ase
py::object ase
Definition
ASE_ORCA.h:29
ASEOrcaPot::counter
size_t counter
Definition
ASE_ORCA.h:31
ASEOrcaPot::calc
py::object calc
Definition
ASE_ORCA.h:28
ASEOrcaPot::workDir
std::filesystem::path workDir
Definition
ASE_ORCA.h:30
eonc::FPEHandler
Definition
fpe_handler.h:34
eonc::FPEHandler::restore_fpe
void restore_fpe()
Definition
fpe_handler.cpp:561
eonc::FPEHandler::eat_fpe
void eat_fpe()
Definition
fpe_handler.cpp:556
eonc::Parameters
Definition
Parameters.h:35
eonc::Parameters::ase_orca_options
const ase_orca_options_t & ase_orca_options() const
Definition
ParametersAccess.cpp:152
eonc::Potential::Potential
Potential(PotType a_ptype)
Production default: construction-scope registry, else PotRegistry::get().
Definition
PotentialParams.cpp:29
fpe_handler.h
eonc::helpers::get_value_from_env_or_param
std::string get_value_from_env_or_param(const char *env_variable, const std::string ¶m_value, const std::string &default_value, const std::string &warning_message, const bool is_mandatory)
Definition
EnvHelpers.cc:7
eonc::log::get
quill::Logger * get() noexcept
Get or create the default "combi" logger.
Definition
EonLogger.h:44
eonc
RAII resource manager for the ARTn C library with global synchronization.
Definition
ARTnSaddleSearch.cpp:23
eonc::ensure_interpreter
void ensure_interpreter()
Definition
NbGuard.h:21
eonc::ase_orca_options_t::path
std::string path
Definition
ParametersOptions.h:398
eonc::ase_orca_options_t::nproc
std::string nproc
Definition
ParametersOptions.h:399
eonc::ase_orca_options_t::simpleinput
std::string simpleinput
Definition
ParametersOptions.h:400
client
potentials
ASE_ORCA
ASE_ORCA.cpp
Generated by
1.17.0
Generated by
Doxygen 1.17.0
Analytics by
Antics
provided by
TurtleTech ehf