Loading...
Searching...
No Matches
ASEOrcaPot Class Reference

#include <ASE_ORCA.h>

Inheritance diagram for ASEOrcaPot:

Public Member Functions

 ASEOrcaPot (const eonc::Parameters &a_params)
virtual ~ASEOrcaPot ()
void force (long nAtoms, const double *R, const int *atomicNrs, double *F, double *U, double *variance, const double *box) override
bool isThreadSafe () const noexcept override
 Whether this potential's force() can be called from multiple threads on the SAME instance.
bool requiresIsolatedMoleculeLayout () const noexcept override
 ORCA does not support PBC; non-centered PBC wraps tear molecules (#188).
bool needsPerImageInstance () const noexcept override
 ORCA runs as external subprocess; separate instances are independent.
Public Member Functions inherited from eonc::Potential
 Potential (PotType a_ptype)
 Production default: construction-scope registry, else PotRegistry::get().
 Potential (PotType a_ptype, IPotRegistry &registry)
 Test seam: injected registry, no process-default get() counters.
 Potential (PotType a_ptype, const Parameters &p)
 Potential (const Parameters &a_params)
virtual ~Potential ()
void force (std::span< const double > positions, std::span< const int > atomicNrs, std::span< double > forces, double *energy, double *variance, std::span< const double > box)
 C++ call site: size-checked view over the raw FFI force().
virtual void setFixedMask (long nAtoms, const double *isFixed)
 Optional frozen-atom mask (nAtoms*3, 1.0 = fixed).
std::tuple< double, AtomMatrix > get_ef (const AtomMatrix &pos, const VectorXi &atmnrs, const Matrix3d &box)
PotType getType () const
virtual double finiteCutoff () const noexcept
 Finite interaction range in position length units.
virtual bool isSurrogate () const noexcept
 Whether this is a surrogate (GP) potential.
virtual unsigned layoutFlags () const noexcept
virtual bool isSharedInstanceThreadSafe () const noexcept
 Conservative gate for sharing one Potential instance across threads.
virtual std::shared_ptr< Potential > clonePotential () const
 Independent instance that does not reload from disk.
virtual bool supportsBatchEvaluation () const noexcept
 Whether this potential supports batched evaluation of N systems in a single call.
virtual bool computesStress () const noexcept
 True when force() leaves a Cauchy stress that cauchyStress() can read until the next force() on this instance.
virtual Matrix3d cauchyStress () const
 Cauchy stress in eV/Angstrom^3.
virtual void forceBatchOwned (long nSystems, long nAtoms, const double *const *positions, const int *const *atomicNrs, double *const *forces, double *energies, double *variances, const double *const *boxes, const long *owners)
 Evaluate forces for N systems in a single call.
virtual 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)

Private Attributes

py::object calc
py::object ase
std::filesystem::path workDir
size_t counter {0}

Additional Inherited Members

Public Types inherited from eonc::Potential
enum class  PotLayout : unsigned { InProcess = 1u << 0 , NeedsWorkingDirectory = 1u << 1 , Subprocess = 1u << 2 }
 How the pot is executed. Combine with bitwise or. More...
Public Attributes inherited from eonc::Potential
std::atomic< size_t > forceCallCounter
Protected Attributes inherited from eonc::Potential
PotType ptype

Detailed Description

Definition at line 25 of file ASE_ORCA.h.

Constructor & Destructor Documentation

◆ ASEOrcaPot()

ASEOrcaPot::ASEOrcaPot ( const eonc::Parameters & a_params)

Definition at line 59 of file ASE_ORCA.cpp.

60 : eonc::Potential(eonc::PotType::ASE_ORCA, a_params) {
61 using namespace pybind11::literals;
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");
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};
py::object ase
Definition ASE_ORCA.h:29
size_t counter
Definition ASE_ORCA.h:31
py::object calc
Definition ASE_ORCA.h:28
std::filesystem::path workDir
Definition ASE_ORCA.h:30
const ase_orca_options_t & ase_orca_options() const
std::string get_value_from_env_or_param(const char *env_variable, const std::string &param_value, const std::string &default_value, const std::string &warning_message, const bool is_mandatory)
Definition EnvHelpers.cc:7
void ensure_interpreter()
Definition NbGuard.h:21

◆ ~ASEOrcaPot()

ASEOrcaPot::~ASEOrcaPot ( )
virtual

Definition at line 110 of file ASE_ORCA.cpp.

110 {
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}
quill::Logger * get() noexcept
Get or create the default "combi" logger.
Definition EonLogger.h:44

Member Function Documentation

◆ force()

void ASEOrcaPot::force ( long nAtoms,
const double * R,
const int * atomicNrs,
double * F,
double * U,
double * variance,
const double * box )
overridevirtual

Implements eonc::Potential.

Definition at line 119 of file ASE_ORCA.cpp.

121 {
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}

◆ isThreadSafe()

bool ASEOrcaPot::isThreadSafe ( ) const
inlinenodiscardoverridevirtualnoexcept

Whether this potential's force() can be called from multiple threads on the SAME instance.

Python-based potentials return false. Potentials with internal mutex (MetatomicPotential) return true but serialize internally – use needsPerImageInstance() to check if separate instances would enable true parallelism.

Reimplemented from eonc::Potential.

Definition at line 40 of file ASE_ORCA.h.

40{ return false; }

◆ needsPerImageInstance()

bool ASEOrcaPot::needsPerImageInstance ( ) const
inlinenodiscardoverridevirtualnoexcept

ORCA runs as external subprocess; separate instances are independent.

Reimplemented from eonc::Potential.

Definition at line 46 of file ASE_ORCA.h.

46 {
47 return true;
48 }

◆ requiresIsolatedMoleculeLayout()

bool ASEOrcaPot::requiresIsolatedMoleculeLayout ( ) const
inlinenodiscardoverridevirtualnoexcept

ORCA does not support PBC; non-centered PBC wraps tear molecules (#188).

Reimplemented from eonc::Potential.

Definition at line 42 of file ASE_ORCA.h.

42 {
43 return true;
44 }

Member Data Documentation

◆ ase

py::object ASEOrcaPot::ase
private

Definition at line 29 of file ASE_ORCA.h.

◆ calc

py::object ASEOrcaPot::calc
private

Definition at line 28 of file ASE_ORCA.h.

◆ counter

size_t ASEOrcaPot::counter {0}
private

Definition at line 31 of file ASE_ORCA.h.

31{0};

◆ workDir

std::filesystem::path ASEOrcaPot::workDir
private

Definition at line 30 of file ASE_ORCA.h.


The documentation for this class was generated from the following files:
  • /home/runner/work/eOn/eOn/include/eon/potentials/ASE_ORCA/ASE_ORCA.h
  • /home/runner/work/eOn/eOn/client/potentials/ASE_ORCA/ASE_ORCA.cpp