eOn client
Long-timescale dynamics: aKMC, NEB, parallel replica
☾
Toggle main menu visibility
Loading...
Searching...
No Matches
LammpsLoader.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
#include "
eon/potentials/LAMMPS/LammpsLoader.h
"
13
14
#include <cstdlib>
15
#include <filesystem>
16
#include <iostream>
17
#include <string>
18
#include <system_error>
19
20
namespace
eonc
{
21
22
namespace
{
23
24
const
char
*
const
*lammps_lib_names() noexcept {
25
#ifdef _WIN32
26
static
const
char
*names[] = {
"lammps.dll"
,
"liblammps.dll"
,
nullptr
};
27
#elif defined(__APPLE__)
28
static
const
char
*names[] = {
"liblammps.dylib"
,
"liblammps.0.dylib"
,
29
nullptr
};
30
#else
31
static
const
char
*names[] = {
"liblammps.so"
,
"liblammps.so.0"
,
nullptr
};
32
#endif
33
return
names;
34
}
35
36
bool
path_exists(
const
std::filesystem::path &p) {
37
std::error_code ec;
38
return
std::filesystem::exists(p, ec);
39
}
40
41
bool
lib_file_visible(
const
char
*
const
*names) {
42
for
(
const
char
*
const
*n = names; *n; ++n) {
43
if
(path_exists(*n))
44
return
true
;
45
}
46
#ifdef _WIN32
47
const
char
*path = std::getenv(
"PATH"
);
48
const
char
sep =
';'
;
49
#else
50
const
char
*path = std::getenv(
"LD_LIBRARY_PATH"
);
51
#ifdef __APPLE__
52
if
(!path || !*path)
53
path = std::getenv(
"DYLD_LIBRARY_PATH"
);
54
#endif
55
const
char
sep =
':'
;
56
#endif
57
if
(!path || !*path)
58
return
false
;
59
const
std::string paths(path);
60
std::string::size_type start = 0;
61
while
(start < paths.size()) {
62
auto
pos = paths.find(sep, start);
63
if
(pos == std::string::npos)
64
pos = paths.size();
65
if
(pos > start) {
66
const
std::filesystem::path dir(paths.substr(start, pos - start));
67
for
(
const
char
*
const
*n = names; *n; ++n) {
68
if
(path_exists(dir / *n))
69
return
true
;
70
}
71
}
72
start = pos + 1;
73
}
74
return
false
;
75
}
76
77
}
// namespace
78
79
LammpsLoader
&
LammpsLoader::instance
() {
80
static
LammpsLoader
loader;
81
return
loader;
82
}
83
84
void
LammpsLoader::ensure_loaded
() {
85
if
(
m_tried
)
86
return
;
87
m_tried
=
true
;
88
89
m_handle
=
dynlib::openFirst
(lammps_lib_names());
90
if
(!
m_handle
) {
91
return
;
92
}
93
94
open_no_mpi
=
dynlib::loadSym<open_no_mpi_fn>
(
m_handle
,
"lammps_open_no_mpi"
);
95
close
=
dynlib::loadSym<close_fn>
(
m_handle
,
"lammps_close"
);
96
command
=
dynlib::loadSym<command_fn>
(
m_handle
,
"lammps_command"
);
97
file
=
dynlib::loadSym<file_fn>
(
m_handle
,
"lammps_file"
);
98
scatter_atoms
=
99
dynlib::loadSym<scatter_atoms_fn>
(
m_handle
,
"lammps_scatter_atoms"
);
100
extract_variable
=
101
dynlib::loadSym<extract_var_fn>
(
m_handle
,
"lammps_extract_variable"
);
102
103
#ifdef EONMPI
104
open_mpi =
dynlib::loadSym<open_mpi_fn>
(
m_handle
,
"lammps_open"
);
105
#endif
106
107
if
(!
open_no_mpi
|| !
close
|| !
command
|| !
file
|| !
scatter_atoms
||
108
!
extract_variable
) {
109
std::cerr <<
"[LAMMPS] Library loaded but missing required symbols\n"
;
110
dynlib::close
(
m_handle
);
111
m_handle
= {};
112
return
;
113
}
114
115
m_loaded
=
true
;
116
}
117
118
LammpsLoader::~LammpsLoader
() {
dynlib::close
(
m_handle
); }
119
120
bool
LammpsLoader::available
()
const
{
121
return
lib_file_visible(lammps_lib_names());
122
}
123
124
void
LammpsLoader::require_loaded
() {
125
ensure_loaded
();
126
if
(!
m_loaded
) {
127
throw
std::runtime_error(
128
"LAMMPS potential requested but liblammps not found.\n"
129
"Install via: conda install -c conda-forge lammps\n"
130
"Or ensure liblammps is in your library search path "
131
"(LD_LIBRARY_PATH / DYLD_LIBRARY_PATH / PATH)."
);
132
}
133
}
134
135
}
// namespace eonc
LammpsLoader.h
eonc::LammpsLoader::scatter_atoms
scatter_atoms_fn scatter_atoms
Definition
LammpsLoader.h:55
eonc::LammpsLoader::available
bool available() const
Filesystem probe: a candidate liblammps file is visible without dlopen, so LAMMPS static initializers...
Definition
LammpsLoader.cpp:120
eonc::LammpsLoader::~LammpsLoader
~LammpsLoader()
Definition
LammpsLoader.cpp:118
eonc::LammpsLoader::require_loaded
void require_loaded()
Load on first use, then throw if liblammps is not available.
Definition
LammpsLoader.cpp:124
eonc::LammpsLoader::open_no_mpi
open_no_mpi_fn open_no_mpi
Definition
LammpsLoader.h:51
eonc::LammpsLoader::LammpsLoader
LammpsLoader(const LammpsLoader &)=delete
eonc::LammpsLoader::file
file_fn file
Definition
LammpsLoader.h:54
eonc::LammpsLoader::command
command_fn command
Definition
LammpsLoader.h:53
eonc::LammpsLoader::m_loaded
bool m_loaded
Definition
LammpsLoader.h:80
eonc::LammpsLoader::close
close_fn close
Definition
LammpsLoader.h:52
eonc::LammpsLoader::ensure_loaded
void ensure_loaded()
Definition
LammpsLoader.cpp:84
eonc::LammpsLoader::instance
static LammpsLoader & instance()
Thread-safe singleton accessor (Meyer's pattern). Does not dlopen.
Definition
LammpsLoader.cpp:79
eonc::LammpsLoader::m_handle
dynlib::Handle m_handle
Definition
LammpsLoader.h:82
eonc::LammpsLoader::extract_variable
extract_var_fn extract_variable
Definition
LammpsLoader.h:56
eonc::LammpsLoader::m_tried
bool m_tried
Definition
LammpsLoader.h:81
eonc::dynlib::close
void close(Handle h) noexcept
Definition
DynLib.h:77
eonc::dynlib::loadSym
Fn loadSym(Handle h, const char *name) noexcept
Load a symbol and cast to a function pointer type.
Definition
DynLib.h:99
eonc::dynlib::openFirst
Handle openFirst(const char *const names[]) noexcept
Try a list of library names in order, return first successful handle.
Definition
DynLib.h:89
eonc
RAII resource manager for the ARTn C library with global synchronization.
Definition
ARTnSaddleSearch.cpp:19
client
potentials
LAMMPS
LammpsLoader.cpp
Generated by
1.17.0
Generated by
Doxygen 1.17.0
Analytics by
Antics
provided by
TurtleTech ehf