neighbours.cpp
Go to the documentation of this file.
Code
1//-----------------------------------------------------------------------------------
2// d-SEAMS - Deferred Structural Elucidation Analysis for Molecular Simulations
3//
4// Copyright (c) 2018--present d-SEAMS core team
5//
6// This program is free software: you can redistribute it and/or modify
7// it under the terms of the MIT License as published by
8// the Open Source Initiative.
9//
10// A copy of the MIT License is included in the LICENSE file of this repository.
11// You should have received a copy of the MIT License along with this program.
12// If not, see <https://opensource.org/licenses/MIT>.
13//-----------------------------------------------------------------------------------
14
15#include <iostream>
16#include <math.h>
17#include <neighbours.hpp>
18
29std::vector<std::vector<int>>
30nneigh::neighList(double rcutoff,
32 int typeI, int typeJ) {
33 std::vector<std::vector<int>> nList; // Vector of vector of ints
34 int jatomIndex; // Atom ID corresponding to jatom
35 int iatomIndex; // Atom ID corresponding to iatom
36 double r_ij; // cutoff
37
38 // Initialize with nop (irrespective of type)
39 // Initialize and fill the first element with the current atom ID whose
40 // neighbour list will be filled
41 for (int iatom = 0; iatom < yCloud->nop; iatom++) {
42 // Find the atom ID (key) given the index or iatom (value)
43 auto itr = std::find_if(
44 yCloud->idIndexMap.begin(), yCloud->idIndexMap.end(),
45 [&iatom](const std::pair<int, int> &p) { return p.second == iatom; });
46 // If found:
47 if (itr == yCloud->idIndexMap.end()) {
48 std::cerr << "Something is wrong with your idIndexMap!\n";
49 continue;
50 } else {
51 iatomIndex = itr->first;
52 } // End of finding the atom ID to fill as the first element in the
53 // neighbour list
54 nList.push_back(std::vector<int>()); // Empty vector for the index iatom
55 // Fill the first element with the atom ID of iatom itself
56 nList[iatom].push_back(iatomIndex);
57 } // end of init
58
59 // pairs of atoms of type I and J
60 // Loop through every iatom and find nearest neighbours within rcutoff
61 for (int iatom = 0; iatom < yCloud->nop; iatom++) {
62 if (yCloud->pts[iatom].type != typeI) {
63 continue;
64 }
65 // Loop through the other atoms
66 for (int jatom = 0; jatom < yCloud->nop; jatom++) {
67 if (yCloud->pts[jatom].type != typeJ) {
68 continue;
69 }
70 // If the distance is greater than rcutoff, continue
71 r_ij = gen::periodicDist(yCloud, iatom, jatom);
72 if (r_ij > rcutoff) {
73 continue;
74 }
75
76 // Get the atom IDs for iatom and jatom
77 auto gotI = std::find_if(
78 yCloud->idIndexMap.begin(), yCloud->idIndexMap.end(),
79 [&iatom](const std::pair<int, int> &p) { return p.second == iatom; });
80 if (gotI == yCloud->idIndexMap.end()) {
81 std::cerr << "Something is wrong with your idIndexMap!\n";
82 return nList;
83 } else {
84 iatomIndex = gotI->first;
85 } // End of finding the atom ID for iatom
86 // Find the atom ID of jatom
87 auto gotJ = std::find_if(
88 yCloud->idIndexMap.begin(), yCloud->idIndexMap.end(),
89 [&jatom](const std::pair<int, int> &p) { return p.second == jatom; });
90 if (gotJ == yCloud->idIndexMap.end()) {
91 std::cerr << "Something is wrong with your idIndexMap!\n";
92 return nList;
93 } else {
94 jatomIndex = gotJ->first;
95 } // End of finding the atom ID for jatom
96 // Update the neighbour indices with atom IDs for iatom and jatom both
97 // (full list)
98 nList[iatom].push_back(jatomIndex);
99 nList[jatom].push_back(iatomIndex);
100
101 } // End of loop through jatom
102 } // End of loop for iatom
103
104 return nList;
105}
106
117std::vector<std::vector<int>>
118nneigh::neighListO(double rcutoff,
120 int typeI) {
121 std::vector<std::vector<int>>
122 nList; // Vector of vectors of the neighbour list
123 double r_ij; // Distance between iatom and jatom
124 int iatomIndex; // Atomic ID of the atom with index iatom
125 int jatomIndex; // Atomic ID of the atom with index jatom
126 int indexYay;
127 std::vector<int> tempListIatom;
128
129 // Initialize and fill the first element with the current atom ID whose
130 // neighbour list will be filled
131 for (int iatom = 0; iatom < yCloud->nop; iatom++) {
132 // Find the atom ID (key) given the index or iatom (value)
133 auto itr = std::find_if(
134 yCloud->idIndexMap.begin(), yCloud->idIndexMap.end(),
135 [&iatom](const std::pair<int, int> &p) { return p.second == iatom; });
136 // If found:
137 if (itr == yCloud->idIndexMap.end()) {
138 std::cerr << "Something is wrong with your idIndexMap!\n";
139 continue;
140 } else {
141 iatomIndex = itr->first;
142 } // End of finding the atom ID to fill as the first element in the
143 // neighbour list
144 nList.push_back(std::vector<int>()); // Empty vector for the index iatom
145 // Fill the first element with the atom ID of iatom itself
146 nList[iatom].push_back(iatomIndex);
147 } // end of init
148
149 // Loop through every iatom and find nearest neighbours within rcutoff
150 for (int iatom = 0; iatom < yCloud->nop - 1; iatom++) {
151 if (yCloud->pts[iatom].type != typeI) {
152 continue;
153 }
154 // Loop through the other atoms
155 for (int jatom = iatom + 1; jatom < yCloud->nop; jatom++) {
156 if (yCloud->pts[jatom].type != typeI) {
157 continue;
158 }
159 // If the distance is greater than rcutoff, continue
160 r_ij = gen::periodicDist(yCloud, iatom, jatom);
161 if (r_ij > rcutoff) {
162 continue;
163 }
164
165 // Get the atom IDs for iatom and jatom
166 auto gotI = std::find_if(
167 yCloud->idIndexMap.begin(), yCloud->idIndexMap.end(),
168 [&iatom](const std::pair<int, int> &p) { return p.second == iatom; });
169 if (gotI == yCloud->idIndexMap.end()) {
170 std::cerr << "Something is wrong with your idIndexMap!\n";
171 return nList;
172 } else {
173 iatomIndex = gotI->first;
174 } // End of finding the atom ID for iatom
175 // Find the atom ID of jatom
176 auto gotJ = std::find_if(
177 yCloud->idIndexMap.begin(), yCloud->idIndexMap.end(),
178 [&jatom](const std::pair<int, int> &p) { return p.second == jatom; });
179 if (gotJ == yCloud->idIndexMap.end()) {
180 std::cerr << "Something is wrong with your idIndexMap!\n";
181 return nList;
182 } else {
183 jatomIndex = gotJ->first;
184 } // End of finding the atom ID for jatom
185 // Update the neighbour indices with atom IDs for iatom and jatom both
186 // (full list)
187 nList[iatom].push_back(jatomIndex);
188 nList[jatom].push_back(iatomIndex);
189
190 } // End of loop through jatom
191 } // End of loop for iatom
192
193 return nList;
194}
195
206std::vector<std::vector<int>>
209 int typeI) {
210 std::vector<std::vector<int>>
211 nList; // Vector of vectors of the neighbour list
212 double r_ij; // Distance between iatom and jatom
213 int iatomIndex; // Atomic ID of the atom with index iatom
214 int jatomIndex; // Atomic ID of the atom with index jatom
215 int indexYay;
216 std::vector<int> tempListIatom;
217
218 // Initialize and fill the first element with the current atom ID whose
219 // neighbour list will be filled
220 for (int iatom = 0; iatom < yCloud->nop; iatom++) {
221 // Find the atom ID (key) given the index or iatom (value)
222 auto itr = std::find_if(
223 yCloud->idIndexMap.begin(), yCloud->idIndexMap.end(),
224 [&iatom](const std::pair<int, int> &p) { return p.second == iatom; });
225 // If found:
226 if (itr == yCloud->idIndexMap.end()) {
227 std::cerr << "Something is wrong with your idIndexMap!\n";
228 continue;
229 } else {
230 iatomIndex = itr->first;
231 } // End of finding the atom ID to fill as the first element in the
232 // neighbour list
233 nList.push_back(std::vector<int>()); // Empty vector for the index iatom
234 // Fill the first element with the atom ID of iatom itself
235 nList[iatom].push_back(iatomIndex);
236 } // end of init
237
238 // Loop through every iatom and find nearest neighbours within rcutoff
239 for (int iatom = 0; iatom < yCloud->nop - 1; iatom++) {
240 if (yCloud->pts[iatom].type != typeI) {
241 continue;
242 }
243 // Loop through the other atoms
244 for (int jatom = iatom + 1; jatom < yCloud->nop; jatom++) {
245 if (yCloud->pts[jatom].type != typeI) {
246 continue;
247 }
248 // If the distance is greater than rcutoff, continue
249 r_ij = gen::periodicDist(yCloud, iatom, jatom);
250 if (r_ij > rcutoff) {
251 continue;
252 }
253
254 // Get the atom IDs for iatom and jatom
255 auto gotI = std::find_if(
256 yCloud->idIndexMap.begin(), yCloud->idIndexMap.end(),
257 [&iatom](const std::pair<int, int> &p) { return p.second == iatom; });
258 if (gotI == yCloud->idIndexMap.end()) {
259 std::cerr << "Something is wrong with your idIndexMap!\n";
260 return nList;
261 } else {
262 iatomIndex = gotI->first;
263 } // End of finding the atom ID for iatom
264 // Find the atom ID of jatom
265 auto gotJ = std::find_if(
266 yCloud->idIndexMap.begin(), yCloud->idIndexMap.end(),
267 [&jatom](const std::pair<int, int> &p) { return p.second == jatom; });
268 if (gotJ == yCloud->idIndexMap.end()) {
269 std::cerr << "Something is wrong with your idIndexMap!\n";
270 return nList;
271 } else {
272 jatomIndex = gotJ->first;
273 } // End of finding the atom ID for jatom
274 // Update the neighbour indices with atom IDs for iatom and jatom both
275 // (full list)
276 nList[iatom].push_back(jatomIndex);
277
278 } // End of loop through jatom
279 } // End of loop for iatom
280
281 return nList;
282}
283
294std::vector<std::vector<int>> nneigh::getNewNeighbourListByIndex(
295 molSys::PointCloud<molSys::Point<double>, double> *yCloud, double cutoff) {
296 //
297 std::vector<std::vector<int>> nList;
298 double r_ij; // Distance between iatom and jatom
299 std::vector<int> tempListIatom;
300
301 // Initialize and fill the first element with the current atom ID whose
302 // neighbour list will be filled
303 for (int iatom = 0; iatom < yCloud->nop; iatom++) {
304 //
305 nList.push_back(std::vector<int>()); // Empty vector for the index iatom
306 // Fill the first element with the atom ID of iatom itself
307 nList[iatom].push_back(iatom);
308 } // end of init
309 // -------------------------------------------------------
310 // Loop through every iatom and find nearest neighbours within rcutoff
311 for (int iatom = 0; iatom < yCloud->nop - 1; iatom++) {
312 // Loop through the other atoms
313 for (int jatom = iatom + 1; jatom < yCloud->nop; jatom++) {
314 // If the distance is greater than rcutoff, continue
315 r_ij = gen::periodicDist(yCloud, iatom, jatom);
316 if (r_ij > cutoff) {
317 continue;
318 }
319
320 // Update the neighbour indices with atom IDs for iatom and jatom both
321 // (full list)
322 nList[iatom].push_back(jatom);
323 nList[jatom].push_back(iatom);
324
325 } // End of loop through jatom
326 } // End of loop for iatom
327
328 return nList;
329} // end of function
330
341std::vector<std::vector<int>> nneigh::neighbourListByIndex(
343 std::vector<std::vector<int>> nList) {
344 //
345 std::vector<std::vector<int>> indexNlist; // Desired neighbour list of indices
346 int iatomID, jatomID; // Atom IDs
347 int iatomIndex, jatomIndex; // Indices of iatom and jatom
348 int nnumNeighbours; // Number of nearest neighbours
349
350 // Loop through every atom whose neighbours are contained in the neighbour
351 // list
352 for (int iatom = 0; iatom < nList.size(); iatom++) {
353 iatomID = nList[iatom][0]; // Atom ID
354 // Get the index of iatom
355 auto gotI = yCloud->idIndexMap.find(iatomID);
356 if (gotI != yCloud->idIndexMap.end()) {
357 iatomIndex = gotI->second;
358 } // found iatomIndex
359 //
360 nnumNeighbours = nList[iatomIndex].size() - 1;
361 // Update the new neighbour list
362 indexNlist.push_back(
363 std::vector<int>()); // Empty vector for the index iatom
364 // Fill the first element with the atom ID of iatom itself
365 indexNlist[iatom].push_back(iatomIndex);
366 //
367 // Loop through the neighbours of iatom
368 for (int jatom = 1; jatom <= nnumNeighbours; jatom++) {
369 jatomID = nList[iatomIndex][jatom]; // Atom ID of neighbour
370 //
371 // Get the index of the j^th atom
372 auto gotJ = yCloud->idIndexMap.find(jatomID);
373 if (gotJ != yCloud->idIndexMap.end()) {
374 jatomIndex = gotJ->second;
375 } // found jatomIndex
376 // Add to the neighbour list
377 indexNlist[iatom].push_back(jatomIndex);
378 } // end of loop through neighbours
379 } // end of loop through every atom
380
381 // Return the new neighbour list
382 return indexNlist;
383}
384
391int nneigh::clearNeighbourList(std::vector<std::vector<int>> &nList) {
392 //
393 std::vector<std::vector<int>> tempEmpty;
394
395 nList.swap(tempEmpty);
396
397 return 0;
398}
double periodicDist(molSys::PointCloud< molSys::Point< double >, double > *yCloud, int iatom, int jatom)
Inline generic function for obtaining the unwrapped periodic distance between two particles,...
Definition generic.hpp:108
std::vector< std::vector< int > > neighList(double rcutoff, molSys::PointCloud< molSys::Point< double >, double > *yCloud, int typeI, int typeJ)
All these functions use atom IDs and not indices.
std::vector< std::vector< int > > neighbourListByIndex(molSys::PointCloud< molSys::Point< double >, double > *yCloud, std::vector< std::vector< int > > nList)
int clearNeighbourList(std::vector< std::vector< int > > &nList)
Erases memory for a vector of vectors for the neighbour list.
std::vector< std::vector< int > > halfNeighList(double rcutoff, molSys::PointCloud< molSys::Point< double >, double > *yCloud, int typeI=1)
std::vector< std::vector< int > > neighListO(double rcutoff, molSys::PointCloud< molSys::Point< double >, double > *yCloud, int typeI)
std::vector< std::vector< int > > getNewNeighbourListByIndex(molSys::PointCloud< molSys::Point< double >, double > *yCloud, double cutoff)
Header file for neighbour list generation.
This contains a collection of points; contains information for a particular frame.
Definition mol_sys.hpp:170
This contains per-particle information.
Definition mol_sys.hpp:149