Loading...
Searching...
No Matches
neighbours.hpp
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#ifndef SEAMS_NEIGHBOURS_H_
16#define SEAMS_NEIGHBOURS_H_
17
18#include <algorithm>
19#include <array>
20#include <string>
21#include <tuple>
22#include <utility>
23#include <vector>
24
25#include <generic.hpp>
26#include <mol_sys.hpp>
27
28#ifdef SEAMS_HAS_LINKCELL
29#include <linkcell.hpp>
30#endif
31#ifdef SEAMS_HAS_MINIMAGE
32#include <minimage.h>
33#endif
34
38
43
66
67namespace nneigh {
68
74inline void dumpBoundsToH(const std::vector<double> &box,
75 const std::vector<double> &boxLow, double H[3][3],
76 double origin[3]) {
77 const double xspan = box.size() > 0 ? box[0] : 0.0;
78 const double yspan = box.size() > 1 ? box[1] : 0.0;
79 const double zspan = box.size() > 2 ? box[2] : 0.0;
80 const double xlo_b = boxLow.size() > 0 ? boxLow[0] : 0.0;
81 const double ylo_b = boxLow.size() > 1 ? boxLow[1] : 0.0;
82 const double zlo_b = boxLow.size() > 2 ? boxLow[2] : 0.0;
83 const double xy = box.size() >= 6 ? box[3] : 0.0;
84 const double xz = box.size() >= 6 ? box[4] : 0.0;
85 const double yz = box.size() >= 6 ? box[5] : 0.0;
86 const double xmin = std::min(std::min(0.0, xy), std::min(xz, xy + xz));
87 const double xmax = std::max(std::max(0.0, xy), std::max(xz, xy + xz));
88 const double ymin = std::min(0.0, yz);
89 const double ymax = std::max(0.0, yz);
90 H[0][0] = xspan - xmax + xmin;
91 H[0][1] = 0.0;
92 H[0][2] = 0.0;
93 H[1][0] = xy;
94 H[1][1] = yspan - ymax + ymin;
95 H[1][2] = 0.0;
96 H[2][0] = xz;
97 H[2][1] = yz;
98 H[2][2] = zspan;
99 origin[0] = xlo_b - xmin;
100 origin[1] = ylo_b - ymin;
101 origin[2] = zlo_b;
102}
103
105inline void dumpCellLengths(const std::vector<double> &box,
106 const std::vector<double> &boxLow,
107 double lengths[3]) {
108 double H[3][3];
109 double origin[3];
110 dumpBoundsToH(box, boxLow, H, origin);
111 lengths[0] = H[0][0];
112 lengths[1] = H[1][1];
113 lengths[2] = H[2][2];
114}
115
117inline int dumpAxialDim(const std::vector<double> &box,
118 const std::vector<double> &boxLow) {
119 double lengths[3];
120 dumpCellLengths(box, boxLow, lengths);
121 int axial = 0;
122 if (lengths[1] > lengths[axial]) {
123 axial = 1;
124 }
125 if (lengths[2] > lengths[axial]) {
126 axial = 2;
127 }
128 return axial;
129}
130
131inline int dumpAxialDim(
132 const molSys::PointCloud<molSys::Point<double>, double> &yCloud) {
133 return dumpAxialDim(yCloud.box, yCloud.boxLow);
134}
135
137inline void dumpToFrac(const double H[3][3], const double origin[3], double x,
138 double y, double z, double s[3]) {
139 const double lx = H[0][0];
140 const double ly = H[1][1];
141 const double lz = H[2][2];
142 const double xy = H[1][0];
143 const double xz = H[2][0];
144 const double yz = H[2][1];
145 s[2] = (z - origin[2]) / lz;
146 s[1] = (y - origin[1] - yz * s[2]) / ly;
147 s[0] = (x - origin[0] - xy * s[1] - xz * s[2]) / lx;
148}
149
151inline void dumpFromFrac(const double H[3][3], const double origin[3],
152 const double s[3], double r[3]) {
153 r[0] = origin[0] + H[0][0] * s[0] + H[1][0] * s[1] + H[2][0] * s[2];
154 r[1] = origin[1] + H[1][1] * s[1] + H[2][1] * s[2];
155 r[2] = origin[2] + H[2][2] * s[2];
156}
157
160inline double dumpVolume(const std::vector<double> &box,
161 const std::vector<double> &boxLow) {
162 double H[3][3];
163 double origin[3];
164 dumpBoundsToH(box, boxLow, H, origin);
165 const double vol = H[0][0] * H[1][1] * H[2][2];
166 return vol < 0.0 ? -vol : vol;
167}
168
169inline double dumpVolume(
170 const molSys::PointCloud<molSys::Point<double>, double> &yCloud) {
171 return dumpVolume(yCloud.box, yCloud.boxLow);
172}
173
174#ifdef SEAMS_HAS_LINKCELL
176inline lc_cell lammpsBoxToLcCell(const std::vector<double> &box,
177 const std::vector<double> &boxLow) {
178#ifdef SEAMS_HAS_MINIMAGE
179 const double xspan = box.size() > 0 ? box[0] : 0.0;
180 const double yspan = box.size() > 1 ? box[1] : 0.0;
181 const double zspan = box.size() > 2 ? box[2] : 0.0;
182 const double xy = box.size() >= 6 ? box[3] : 0.0;
183 const double xz = box.size() >= 6 ? box[4] : 0.0;
184 const double yz = box.size() >= 6 ? box[5] : 0.0;
185 const double xlo_b = boxLow.size() > 0 ? boxLow[0] : 0.0;
186 const double ylo_b = boxLow.size() > 1 ? boxLow[1] : 0.0;
187 const double zlo_b = boxLow.size() > 2 ? boxLow[2] : 0.0;
188 mi_cell raw;
189 mi_cell_from_lammps_bounds(xspan, yspan, zspan, xy, xz, yz, xlo_b, ylo_b,
190 zlo_b, &raw);
191 lc_cell c = lc_cell_ortho(raw.ax, raw.by, raw.cz);
192 c.ax = raw.ax;
193 c.ay = raw.ay;
194 c.az = raw.az;
195 c.bx = raw.bx;
196 c.by = raw.by;
197 c.bz = raw.bz;
198 c.cx = raw.cx;
199 c.cy = raw.cy;
200 c.cz = raw.cz;
201 c.ox = raw.ox;
202 c.oy = raw.oy;
203 c.oz = raw.oz;
204 return c;
205#else
206 double H[3][3], o[3];
207 dumpBoundsToH(box, boxLow, H, o);
208 lc_cell c = lc_cell_ortho(H[0][0], H[1][1], H[2][2]);
209 c.ax = H[0][0];
210 c.ay = H[0][1];
211 c.az = H[0][2];
212 c.bx = H[1][0];
213 c.by = H[1][1];
214 c.bz = H[1][2];
215 c.cx = H[2][0];
216 c.cy = H[2][1];
217 c.cz = H[2][2];
218 c.ox = o[0];
219 c.oy = o[1];
220 c.oz = o[2];
221 return c;
222#endif
223}
224
225inline linkcell::Cell lammpsBoxToLinkcell(const std::vector<double> &box,
226 const std::vector<double> &boxLow) {
227 return linkcell::Cell(lammpsBoxToLcCell(box, boxLow));
228}
229
234inline void residentFrameCell(const double *box, const double *boxLow,
235 int nBox, linkcell::Cell &cell,
236 const double *&frameLens) {
237 cell = linkcell::Cell::ortho(box[0], box[1], box[2]);
238 frameLens = box;
239 if (boxLow != nullptr || nBox >= 6) {
240 std::vector<double> dump(static_cast<std::size_t>(std::max(nBox, 3)));
241 for (int i = 0; i < nBox && i < static_cast<int>(dump.size()); ++i) {
242 dump[static_cast<std::size_t>(i)] = box[i];
243 }
244 std::vector<double> lo;
245 if (boxLow != nullptr) {
246 lo = {boxLow[0], boxLow[1], boxLow[2]};
247 }
248 cell = lammpsBoxToLinkcell(dump, lo);
249 frameLens = nullptr;
250 }
251}
252#endif
253
255
259std::vector<std::vector<int>> neighList(
260 double rcutoff, const molSys::PointCloud<molSys::Point<double>, double> &yCloud,
261 int typeI, int typeJ);
262
265std::vector<std::vector<int>> neighListPair(
266 double rcutoff, const molSys::PointCloud<molSys::Point<double>, double> &yCloud,
267 int typeI, int typeJ);
268
278 const molSys::PointCloud<molSys::Point<double>, double> &yCloud,
279 const std::vector<int> &subset, double rcutoff,
280 std::vector<std::vector<int>> &rows);
281
285std::vector<std::vector<int>> neighListO(
286 double rcutoff, const molSys::PointCloud<molSys::Point<double>, double> &yCloud,
287 int typeI);
288
291std::vector<std::vector<int>> halfNeighList(
292 double rcutoff, const molSys::PointCloud<molSys::Point<double>, double> &yCloud,
293 int typeI = 1);
294
297
300std::vector<std::vector<int>> neighbourListByIndex(
301 const molSys::PointCloud<molSys::Point<double>, double> &yCloud,
302 const std::vector<std::vector<int>> &nList);
303
306std::vector<std::vector<int>> getNewNeighbourListByIndex(
307 const molSys::PointCloud<molSys::Point<double>, double> &yCloud, double cutoff);
308
324std::vector<std::vector<int>> kNearestNeighbourList(
325 const molSys::PointCloud<molSys::Point<double>, double> &yCloud, int k,
326 double candidateCutoff, int typeI, bool mutual = true);
327
330std::vector<std::vector<int>> kNearestNeighbourList(
331 const molSys::PointCloud<molSys::Point<double>, double> &yCloud, int k,
332 double candidateCutoff, const std::vector<int> &types, bool mutual = true);
333
337std::pair<std::vector<std::vector<int>>, std::vector<std::vector<int>>>
339 const molSys::PointCloud<molSys::Point<double>, double> &yCloud, int k,
340 double candidateCutoff, int typeI);
341
342std::pair<std::vector<std::vector<int>>, std::vector<std::vector<int>>>
344 const molSys::PointCloud<molSys::Point<double>, double> &yCloud, int k,
345 double candidateCutoff, const std::vector<int> &types);
346
353std::pair<double, double> shellSeparation(
354 const molSys::PointCloud<molSys::Point<double>, double> &yCloud, int k,
355 int typeI);
356
363std::vector<std::tuple<int, int, double>> nearestUnlike(
364 const molSys::PointCloud<molSys::Point<double>, double> &yCloud, int typeI,
365 int typeJ);
366
370std::vector<std::pair<int, int>> mutualNearestUnlike(
371 const molSys::PointCloud<molSys::Point<double>, double> &yCloud, int typeI,
372 int typeJ);
373
375[[nodiscard]] int clearNeighbourList(std::vector<std::vector<int>> &nList);
376
384
385BondGraph bondGraphFromName(const std::string &name);
386const char *bondGraphName(BondGraph graph);
387
397public:
400 SkinNeighborList(double cutoff, double skin, int typeI,
402
403 [[nodiscard]] BondGraph graph() const { return graph_; }
404
407 const std::vector<std::vector<int>> &
409
410 [[nodiscard]] bool lastRebuilt() const { return rebuilt_; }
412 [[nodiscard]] int lastChangedAtoms() const { return changedAtoms_; }
413 [[nodiscard]] const std::vector<std::vector<int>> &bonds() const {
414 return nList_;
415 }
416
417private:
418 double cutoff_;
419 double skin_;
420 double cutoffSq_;
421 double triggerSq_;
422 int typeI_;
423 int k_;
425 bool mutual_{true};
426 bool rebuilt_{true};
427 int changedAtoms_{0};
428 std::vector<double> x0_;
429 std::vector<double> y0_;
430 std::vector<double> z0_;
431 std::vector<double> box0_;
432 std::vector<std::pair<int, int>> candidates_;
433 std::vector<std::pair<int, int>> bonded_;
434 std::vector<std::vector<int>> nList_;
435
436 bool mustRebuild(
437 const molSys::PointCloud<molSys::Point<double>, double> &yCloud) const;
438 void rebuildCandidates(
439 const molSys::PointCloud<molSys::Point<double>, double> &yCloud);
440 void refreshBonds(
441 const molSys::PointCloud<molSys::Point<double>, double> &yCloud);
442};
443
444} // namespace nneigh
445
446#endif // SEAMS_NEIGHBOURS_H_
File for containing generic or common functions.
std::pair< double, double > shellSeparation(const molSys::PointCloud< molSys::Point< double >, double > &yCloud, int k, int typeI)
The shell-separation certificate for the exact reduction of the k-nearest graph to the cutoff graph: ...
std::vector< std::vector< int > > kNearestNeighbourList(const molSys::PointCloud< molSys::Point< double >, double > &yCloud, int k, double candidateCutoff, int typeI, bool mutual=true)
Bonded graph from the k nearest neighbours of each particle rather than a distance cutoff.
const char * bondGraphName(BondGraph graph)
void dumpBoundsToH(const std::vector< double > &box, const std::vector< double > &boxLow, double H[3][3], double origin[3])
LAMMPS dump bound spans to restricted triclinic H (rows a, b, c).
void dumpCellLengths(const std::vector< double > &box, const std::vector< double > &boxLow, double lengths[3])
Recovered restricted-triclinic lengths lx, ly, lz (H diagonal).
std::pair< std::vector< std::vector< int > >, std::vector< std::vector< int > > > kNearestNeighbourPair(const molSys::PointCloud< molSys::Point< double >, double > &yCloud, int k, double candidateCutoff, int typeI)
Mutual and union k-nearest graphs from one candidate search.
std::vector< std::tuple< int, int, double > > nearestUnlike(const molSys::PointCloud< molSys::Point< double >, double > &yCloud, int typeI, int typeJ)
Nearest unlike image of each typeI particle among typeJ particles.
void dumpFromFrac(const double H[3][3], const double origin[3], const double s[3], double r[3])
Fractional to cartesian coordinates via dump H.
std::vector< std::vector< int > > halfNeighList(double rcutoff, const molSys::PointCloud< molSys::Point< double >, double > &yCloud, int typeI=1)
std::vector< std::pair< int, int > > mutualNearestUnlike(const molSys::PointCloud< molSys::Point< double >, double > &yCloud, int typeI, int typeJ)
Subset of nearestUnlike where j's nearest typeI is i (mutual).
int clearNeighbourList(std::vector< std::vector< int > > &nList)
Erases memory for a vector of vectors for the neighbour list.
void dumpToFrac(const double H[3][3], const double origin[3], double x, double y, double z, double s[3])
Cartesian to fractional coordinates via dump H.
SkinNeighborList(double cutoff, double skin, int typeI, BondGraph graph=BondGraph::KnnMutual, int k=4)
const std::vector< std::vector< int > > & update(const molSys::PointCloud< molSys::Point< double >, double > &yCloud)
int dumpAxialDim(const std::vector< double > &box, const std::vector< double > &boxLow)
Longest recovered length: 0 = x, 1 = y, 2 = z.
bool cellListRowsThreaded(const molSys::PointCloud< molSys::Point< double >, double > &yCloud, const std::vector< int > &subset, double rcutoff, std::vector< std::vector< int > > &rows)
std::vector< std::vector< int > > neighList(double rcutoff, const 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 > > getNewNeighbourListByIndex(const molSys::PointCloud< molSys::Point< double >, double > &yCloud, double cutoff)
BondGraph graph() const
int lastChangedAtoms() const
Atoms whose cutoff bond set changed on the last update.
const std::vector< std::vector< int > > & bonds() const
std::vector< std::vector< int > > neighbourListByIndex(const molSys::PointCloud< molSys::Point< double >, double > &yCloud, const std::vector< std::vector< int > > &nList)
double dumpVolume(const std::vector< double > &box, const std::vector< double > &boxLow)
Triclinic dump-cell volume |det(H)| from dumpBoundsToH.
BondGraph bondGraphFromName(const std::string &name)
std::vector< std::vector< int > > neighListPair(double rcutoff, const molSys::PointCloud< molSys::Point< double >, double > &yCloud, int typeI, int typeJ)
BondGraph
Bond graph for TUM.
std::vector< std::vector< int > > neighListO(double rcutoff, const molSys::PointCloud< molSys::Point< double >, double > &yCloud, int typeI)
The main molecular system handler.
Functions for building neighbour lists.
void dump(const Runtime &cfg, std::ostream &os)
This contains a collection of points; contains information for a particular frame.
Definition mol_sys.hpp:173
This contains per-particle information.
Definition mol_sys.hpp:152