eOn 3.2.0
Long-timescale dynamics: aKMC, NEB, parallel replica
☾
Toggle main menu visibility
Loading...
Searching...
No Matches
MobileAtoms.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/MobileAtoms.h
"
13
14
#include <cctype>
15
#include <stdexcept>
16
#include <string>
17
#include <unordered_set>
18
#include <vector>
19
20
namespace
eonc
{
21
22
bool
atomListMeansAll
(
const
std::string &atomList) {
23
if
(atomList.empty()) {
24
return
true
;
25
}
26
// Trim and case-fold "all"
27
size_t
b = 0;
28
while
(b < atomList.size() &&
29
std::isspace(
static_cast<
unsigned
char
>
(atomList[b]))) {
30
++b;
31
}
32
size_t
e = atomList.size();
33
while
(e > b && std::isspace(
static_cast<
unsigned
char
>
(atomList[e - 1]))) {
34
--e;
35
}
36
if
(e <= b) {
37
return
true
;
38
}
39
if
(e - b != 3) {
40
return
false
;
41
}
42
auto
lower = [](
char
c) {
43
return
static_cast<
char
>
(std::tolower(
static_cast<
unsigned
char
>
(c)));
44
};
45
return
lower(atomList[b]) ==
'a'
&& lower(atomList[b + 1]) ==
'l'
&&
46
lower(atomList[b + 2]) ==
'l'
;
47
}
48
49
VectorXi
freeAtomIndices
(
const
Matter
*matter) {
50
if
(!matter) {
51
throw
std::invalid_argument(
"freeAtomIndices: null Matter"
);
52
}
53
const
long
n = matter->
numberOfAtoms
();
54
std::vector<int> free;
55
free.reserve(
static_cast<
size_t
>
(matter->
numberOfFreeAtoms
()));
56
for
(
long
i = 0; i < n; ++i) {
57
if
(!matter->
getFixed
(i)) {
58
free.push_back(
static_cast<
int
>
(i));
59
}
60
}
61
VectorXi out(
static_cast<
Eigen::Index
>
(free.size()));
62
for
(Eigen::Index k = 0; k < out.size(); ++k) {
63
out(k) = free[
static_cast<
size_t
>
(k)];
64
}
65
return
out;
66
}
67
68
VectorXi
resolveMobileAtoms
(
const
Matter
*matter,
const
std::string &atomList) {
69
if
(!matter) {
70
throw
std::invalid_argument(
"resolveMobileAtoms: null Matter"
);
71
}
72
if
(
atomListMeansAll
(atomList)) {
73
return
freeAtomIndices
(matter);
74
}
75
const
long
n = matter->
numberOfAtoms
();
76
std::vector<int> mobile;
77
std::unordered_set<int> seen;
78
std::string token;
79
for
(
size_t
p = 0; p <= atomList.size(); ++p) {
80
const
char
c = (p < atomList.size()) ? atomList[p] :
','
;
81
if
(c ==
','
|| c ==
' '
|| c ==
'\t'
|| p == atomList.size()) {
82
if
(!token.empty()) {
83
try
{
84
const
long
idx = std::stol(token);
85
if
(idx >= 0 && idx < n && !matter->getFixed(idx) &&
86
seen.insert(
static_cast<
int
>
(idx)).second) {
87
mobile.push_back(
static_cast<
int
>
(idx));
88
}
89
}
catch
(
const
std::exception &) {
90
// skip non-integer tokens
91
}
92
token.clear();
93
}
94
}
else
{
95
token.push_back(c);
96
}
97
}
98
VectorXi out(
static_cast<
Eigen::Index
>
(mobile.size()));
99
for
(Eigen::Index k = 0; k < out.size(); ++k) {
100
out(k) = mobile[
static_cast<
size_t
>
(k)];
101
}
102
return
out;
103
}
104
105
VectorXi
resolveMobileAtoms
(
const
Matter
*matter,
const
VectorXi &candidates) {
106
if
(!matter) {
107
throw
std::invalid_argument(
"resolveMobileAtoms: null Matter"
);
108
}
109
const
long
n = matter->
numberOfAtoms
();
110
std::vector<int> mobile;
111
std::unordered_set<int> seen;
112
mobile.reserve(
static_cast<
size_t
>
(candidates.size()));
113
for
(Eigen::Index k = 0; k < candidates.size(); ++k) {
114
const
long
idx = candidates(k);
115
if
(idx >= 0 && idx < n && !matter->getFixed(idx) &&
116
seen.insert(
static_cast<
int
>
(idx)).second) {
117
mobile.push_back(
static_cast<
int
>
(idx));
118
}
119
}
120
VectorXi out(
static_cast<
Eigen::Index
>
(mobile.size()));
121
for
(Eigen::Index k = 0; k < out.size(); ++k) {
122
out(k) = mobile[
static_cast<
size_t
>
(k)];
123
}
124
return
out;
125
}
126
127
VectorXd
packMobileRows
(
const
AtomMatrix
&full,
const
VectorXi &mobile) {
128
VectorXd packed(3 * mobile.size());
129
for
(Eigen::Index a = 0; a < mobile.size(); ++a) {
130
packed.segment<3>(3 * a) = full.row(mobile(a));
131
}
132
return
packed;
133
}
134
135
void
unpackMobileRows
(
const
VectorXd &packed,
const
VectorXi &mobile,
136
AtomMatrix
&full) {
137
for
(Eigen::Index a = 0; a < mobile.size(); ++a) {
138
full.row(mobile(a)) = packed.segment<3>(3 * a);
139
}
140
}
141
142
VectorXd
mobileForces
(
Matter
*matter,
const
VectorXi &mobile) {
143
const
AtomMatrix
forces = matter->
getForces
();
144
return
packMobileRows
(forces, mobile);
145
}
146
147
}
// namespace eonc
AtomMatrix
Eigen::Matrix< double, Eigen::Dynamic, 3, eOnStorageOrder > AtomMatrix
Definition
Eigen.h:37
MobileAtoms.h
eonc::Matter
Definition
Matter.h:90
eonc::Matter::numberOfAtoms
long int numberOfAtoms() const
Definition
Matter.cpp:273
eonc::Matter::numberOfFreeAtoms
long int numberOfFreeAtoms() const
Definition
Matter.cpp:583
eonc::Matter::getForces
const AtomMatrix & getForces() const
Definition
Matter.cpp:412
eonc::Matter::getFixed
int getFixed(long int atom) const
1 if every Cartesian axis of the atom is fixed, else 0.
Definition
Matter.cpp:505
eonc
RAII resource manager for the ARTn C library with global synchronization.
Definition
ARTnSaddleSearch.cpp:23
eonc::atomListMeansAll
bool atomListMeansAll(const std::string &atomList)
Whether atomList means "every free atom" (empty, "all", case-insensitive).
Definition
MobileAtoms.cpp:22
eonc::resolveMobileAtoms
VectorXi resolveMobileAtoms(const Matter *matter, const std::string &atomList)
PHVA-class mobile set for FD Hessian and matrix-free Krylov (Lanczos / Davidson).
Definition
MobileAtoms.cpp:68
eonc::unpackMobileRows
void unpackMobileRows(const VectorXd &packed, const VectorXi &mobile, AtomMatrix &full)
Write a 3*n_mobile vector into full AtomMatrix rows (other rows unchanged).
Definition
MobileAtoms.cpp:135
eonc::freeAtomIndices
VectorXi freeAtomIndices(const Matter *matter)
Free (unfixed) atom indices in ascending order.
Definition
MobileAtoms.cpp:49
eonc::packMobileRows
VectorXd packMobileRows(const AtomMatrix &full, const VectorXi &mobile)
Pack full (n_atoms,3) rows of mobile atoms into a 3*n_mobile vector.
Definition
MobileAtoms.cpp:127
eonc::mobileForces
VectorXd mobileForces(Matter *matter, const VectorXi &mobile)
Force components on mobile atoms after Matter has a valid force cache (calls getForces under the hood...
Definition
MobileAtoms.cpp:142
client
MobileAtoms.cpp
Generated by
1.17.0
Generated by
Doxygen 1.17.0
Analytics by
Antics
provided by
TurtleTech ehf