eOn client
Long-timescale dynamics: aKMC, NEB, parallel replica
☾
Toggle main menu visibility
Loading...
Searching...
No Matches
EpiCenters.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/EpiCenters.h
"
13
#include "
eon/HelperFunctions.h
"
14
15
#include <cassert>
16
#include <climits>
17
#include <memory>
18
#include <vector>
19
20
using namespace
eonc::helpers
;
21
22
long
eonc::EpiCenters::cnaEpiCenter
(
const
Matter
*matter,
23
double
neighborCutoff) {
24
long
nAtoms = matter->
numberOfAtoms
();
25
std::vector<long> cnaList(nAtoms);
26
long
indexEpiCenter = -2;
27
28
cna
(cnaList.data(), matter, neighborCutoff);
29
30
// Count atoms that are not FCC or HCP and are free to move
31
long
count = 0;
32
for
(
long
i = 0; i < nAtoms; i++) {
33
if
(cnaList[i] == 2 && !matter->
getFixed
(i))
34
count++;
35
}
36
// Pick a random atom being both free and not FCC or HCP coordinated
37
long
pick =
static_cast<
long
>
(
randomDouble
(count)) + 1;
38
for
(
long
i = 0; i < nAtoms; i++) {
39
if
(cnaList[i] == 2 && !matter->
getFixed
(i)) {
40
pick--;
41
if
(!pick) {
42
indexEpiCenter = i;
43
break
;
44
}
45
}
46
}
47
48
assert(indexEpiCenter > -1 && indexEpiCenter < nAtoms);
49
return
indexEpiCenter;
50
}
51
52
long
eonc::EpiCenters::minCoordinatedEpiCenter
(
const
Matter
*matter,
53
double
neighborCutoff) {
54
long
nAtoms = matter->
numberOfAtoms
();
55
// Can't use vector<bool> (.data() is deleted), use unique_ptr<bool[]>
56
auto
minCoordinatedList = std::make_unique<bool[]>(nAtoms);
57
long
indexEpiCenter = -2;
58
59
long
minCoordinationVal =
minCoordination
(matter, neighborCutoff);
60
coordinationLessOrEqual
(minCoordinatedList.get(), minCoordinationVal, matter,
61
neighborCutoff);
62
63
// Count all atoms that are minimally coordinated and free to move
64
long
count = 0;
65
for
(
long
i = 0; i < nAtoms; i++) {
66
if
(minCoordinatedList[i] && !matter->
getFixed
(i))
67
count++;
68
}
69
// Pick a random atom that is free and minimally coordinated
70
long
pick =
static_cast<
long
>
(
randomDouble
(count));
71
for
(
long
i = 0; i < nAtoms; i++) {
72
if
(minCoordinatedList[i] && !matter->
getFixed
(i)) {
73
if
(!pick) {
74
indexEpiCenter = i;
75
break
;
76
}
else
{
77
pick--;
78
}
79
}
80
}
81
82
assert(indexEpiCenter > -1 && indexEpiCenter < nAtoms);
83
return
indexEpiCenter;
84
}
85
86
long
eonc::EpiCenters::lastAtom
(
const
Matter
*matter) {
87
long
nAtoms = matter->
numberOfAtoms
();
88
long
indexEpiCenter = nAtoms - 1;
89
assert(indexEpiCenter > -1 && indexEpiCenter < nAtoms);
90
return
indexEpiCenter;
91
}
92
93
long
eonc::EpiCenters::randomFreeAtomEpiCenter
(
const
Matter
*matter) {
94
long
nAtoms = matter->
numberOfAtoms
();
95
long
indexEpiCenter = -2;
96
97
long
freeCount = matter->
numberOfFreeAtoms
() - 1;
98
long
pick =
static_cast<
long
>
(
randomDouble
(freeCount));
99
100
for
(
long
i = 0; i < nAtoms; i++) {
101
if
(!matter->
getFixed
(i)) {
102
if
(!pick) {
103
indexEpiCenter = i;
104
break
;
105
}
else
{
106
pick--;
107
}
108
}
109
}
110
assert(indexEpiCenter > -1 && indexEpiCenter < nAtoms);
111
return
indexEpiCenter;
112
}
113
114
void
eonc::EpiCenters::cna
(
long
*
cna
,
const
Matter
*matter,
115
double
neighborCutoff) {
116
long
nAtoms = matter->
numberOfAtoms
();
117
std::vector<int> nFCC(nAtoms, 0);
118
std::vector<int> nHCP(nAtoms, 0);
119
std::vector<std::vector<int>> neighborLists(nAtoms);
120
121
for
(
long
i = 0; i < nAtoms - 1; i++) {
122
for
(
long
j = i + 1; j < nAtoms; j++) {
123
double
diffR = matter->
distance
(i, j);
124
if
(diffR < neighborCutoff) {
125
neighborLists[i].push_back(
static_cast<
int
>
(j));
126
neighborLists[j].push_back(
static_cast<
int
>
(i));
127
}
128
}
129
}
130
131
for
(
long
a2 = 0; a2 < nAtoms; a2++) {
132
const
auto
&nbs2 = neighborLists[a2];
133
for
(
size_t
n2 = 0; n2 < nbs2.size(); n2++) {
134
int
a1 = nbs2[n2];
135
if
(a1 < a2) {
136
std::vector<int> common;
137
const
auto
&nbs1 = neighborLists[a1];
138
for
(
size_t
n1 = 0; n1 < nbs1.size(); n1++) {
139
int
a3 = nbs1[n1];
140
for
(
size_t
m2 = 0; m2 < nbs2.size(); m2++) {
141
if
(a3 == nbs2[m2])
142
common.push_back(a3);
143
}
144
}
145
if
(common.size() == 4) {
146
int
nBonds = 0;
147
int
bondsSum = 0;
148
for
(
int
j2 = 1; j2 < 4; j2++) {
149
const
auto
&nbs = neighborLists[common[j2]];
150
for
(
int
j1 = 0; j1 < j2; j1++) {
151
for
(
size_t
n = 0; n < nbs.size(); n++) {
152
if
(common[j1] == nbs[n]) {
153
nBonds++;
154
bondsSum += j1 + j2;
155
break
;
156
}
157
}
158
}
159
}
160
if
(nBonds == 2) {
161
if
(bondsSum == 6) {
162
nFCC[a1]++;
163
nFCC[a2]++;
164
}
else
{
165
nHCP[a1]++;
166
nHCP[a2]++;
167
}
168
}
169
}
170
}
171
}
172
}
173
// 0: fcc (421), 1: hcp (422), 2: other
174
for
(
long
i = 0; i < nAtoms; i++) {
175
if
(neighborLists[i].size() == 12) {
176
if
(nFCC[i] == 12)
177
cna
[i] = 0;
178
else
if
(nFCC[i] == 6 && nHCP[i] == 6)
179
cna
[i] = 1;
180
else
181
cna
[i] = 2;
182
}
else
{
183
cna
[i] = 2;
184
}
185
}
186
}
187
188
void
eonc::EpiCenters::coordination
(
long
*coordinationVal,
const
Matter
*matter,
189
double
neighborCutoff) {
190
long
nAtoms = matter->
numberOfAtoms
();
191
for
(
long
i = 0; i < nAtoms; i++)
192
coordinationVal[i] = 0;
193
194
for
(
long
i = 0; i < nAtoms - 1; i++) {
195
for
(
long
j = i + 1; j < nAtoms; j++) {
196
double
diffR = matter->
distance
(i, j);
197
if
(diffR < neighborCutoff) {
198
coordinationVal[i]++;
199
coordinationVal[j]++;
200
}
201
}
202
}
203
}
204
205
void
eonc::EpiCenters::coordinationLessOrEqual
(
bool
*result,
206
long
coordinationMaxVal,
207
const
Matter
*matter,
208
double
neighborCutoff) {
209
long
nAtoms = matter->
numberOfAtoms
();
210
std::vector<long> coordinationVal(nAtoms);
211
212
coordination
(coordinationVal.data(), matter, neighborCutoff);
213
214
for
(
long
i = 0; i < nAtoms; i++) {
215
result[i] =
216
(coordinationVal[i] <= coordinationMaxVal) && !matter->
getFixed
(i);
217
}
218
}
219
220
long
eonc::EpiCenters::listedAtomEpiCenter
(
const
Matter
*matter,
221
const
std::vector<long> &atomList) {
222
long
nAtoms = matter->
numberOfAtoms
();
223
// Filter to only free atoms from the provided list
224
std::vector<long> freeAtoms;
225
for
(
long
idx : atomList) {
226
if
(idx >= 0 && idx < nAtoms && !matter->getFixed(idx)) {
227
freeAtoms.push_back(idx);
228
}
229
}
230
assert(!freeAtoms.empty());
231
long
pick =
232
static_cast<
long
>
(
randomDouble
(
static_cast<
long
>
(freeAtoms.size() - 1)));
233
return
freeAtoms[pick];
234
}
235
236
long
eonc::EpiCenters::minCoordination
(
const
Matter
*matter,
237
double
neighborCutoff) {
238
long
nAtoms = matter->
numberOfAtoms
();
239
std::vector<long> coordinationVal(nAtoms);
240
241
coordination
(coordinationVal.data(), matter, neighborCutoff);
242
243
long
minVal = LONG_MAX;
244
for
(
long
i = 0; i < nAtoms; i++) {
245
if
(coordinationVal[i] < minVal && !matter->
getFixed
(i)) {
246
minVal = coordinationVal[i];
247
}
248
}
249
return
minVal;
250
}
EpiCenters.h
HelperFunctions.h
eonc::Matter
Definition
Matter.h:92
eonc::Matter::distance
double distance(long index1, long index2) const
Definition
Matter.cpp:360
eonc::Matter::numberOfAtoms
long int numberOfAtoms() const
Definition
Matter.cpp:209
eonc::Matter::numberOfFreeAtoms
long int numberOfFreeAtoms() const
Definition
Matter.cpp:475
eonc::Matter::getFixed
int getFixed(long int atom) const
1 if every Cartesian axis of the atom is fixed, else 0.
Definition
Matter.cpp:402
eonc::EpiCenters::lastAtom
long lastAtom(const Matter *matter)
Definition
EpiCenters.cpp:86
eonc::EpiCenters::minCoordination
long minCoordination(const Matter *matter, double neighborCutoff)
Definition
EpiCenters.cpp:236
eonc::EpiCenters::cna
void cna(long *cna, const Matter *matter, double neighborCutoff)
Definition
EpiCenters.cpp:114
eonc::EpiCenters::cnaEpiCenter
long cnaEpiCenter(const Matter *matter, double neighborCutoff)
Definition
EpiCenters.cpp:22
eonc::EpiCenters::randomFreeAtomEpiCenter
long randomFreeAtomEpiCenter(const Matter *matter)
Definition
EpiCenters.cpp:93
eonc::EpiCenters::coordinationLessOrEqual
void coordinationLessOrEqual(bool *result, long coordinationMaxVal, const Matter *matter, double neighborCutoff)
Definition
EpiCenters.cpp:205
eonc::EpiCenters::listedAtomEpiCenter
long listedAtomEpiCenter(const Matter *matter, const std::vector< long > &atomList)
Definition
EpiCenters.cpp:220
eonc::EpiCenters::minCoordinatedEpiCenter
long minCoordinatedEpiCenter(const Matter *matter, double neighborCutoff)
Definition
EpiCenters.cpp:52
eonc::EpiCenters::coordination
void coordination(long *coordinationVal, const Matter *matter, double neighborCutoff)
Definition
EpiCenters.cpp:188
eonc::helpers
Definition
EnvHelpers.cc:5
eonc::helpers::randomDouble
double randomDouble()
Definition
RandomNumbers.cpp:62
client
EpiCenters.cpp
Generated by
1.17.0
Generated by
Doxygen 1.17.0
Analytics by
Antics
provided by
TurtleTech ehf