neighbours.cpp
Go to the documentation of this file.
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 
30 nneigh::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 
118 nneigh::neighListO(double rcutoff,
119  molSys::PointCloud<molSys::Point<double>, double> *yCloud,
120  int typeI) {
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 
207 nneigh::halfNeighList(double rcutoff,
208  molSys::PointCloud<molSys::Point<double>, double> *yCloud,
209  int typeI) {
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 
295  molSys::PointCloud<molSys::Point<double>, double> *yCloud, double cutoff) {
296  //
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 
342  molSys::PointCloud<molSys::Point<double>, double> *yCloud,
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 
392  //
393  std::vector<std::vector<int>> tempEmpty;
394 
395  nList.swap(tempEmpty);
396 
397  return 0;
398 }
T find_if(T... args)
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.
Definition: neighbours.cpp:30
std::vector< std::vector< int > > halfNeighList(double rcutoff, molSys::PointCloud< molSys::Point< double >, double > *yCloud, int typeI=1)
Definition: neighbours.cpp:207
std::vector< std::vector< int > > neighListO(double rcutoff, molSys::PointCloud< molSys::Point< double >, double > *yCloud, int typeI)
Definition: neighbours.cpp:118
std::vector< std::vector< int > > neighbourListByIndex(molSys::PointCloud< molSys::Point< double >, double > *yCloud, std::vector< std::vector< int >> nList)
Definition: neighbours.cpp:341
int clearNeighbourList(std::vector< std::vector< int >> &nList)
Erases memory for a vector of vectors for the neighbour list.
Definition: neighbours.cpp:391
std::vector< std::vector< int > > getNewNeighbourListByIndex(molSys::PointCloud< molSys::Point< double >, double > *yCloud, double cutoff)
Definition: neighbours.cpp:294
Header file for neighbour list generation.
T push_back(T... args)
T size(T... args)
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
T swap(T... args)