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
35
40
63
64namespace nneigh {
65
71inline void dumpBoundsToH(const std::vector<double> &box,
72 const std::vector<double> &boxLow, double H[3][3],
73 double origin[3]) {
74 const double xspan = box.size() > 0 ? box[0] : 0.0;
75 const double yspan = box.size() > 1 ? box[1] : 0.0;
76 const double zspan = box.size() > 2 ? box[2] : 0.0;
77 const double xlo_b = boxLow.size() > 0 ? boxLow[0] : 0.0;
78 const double ylo_b = boxLow.size() > 1 ? boxLow[1] : 0.0;
79 const double zlo_b = boxLow.size() > 2 ? boxLow[2] : 0.0;
80 const double xy = box.size() >= 6 ? box[3] : 0.0;
81 const double xz = box.size() >= 6 ? box[4] : 0.0;
82 const double yz = box.size() >= 6 ? box[5] : 0.0;
83 const double xmin = std::min(std::min(0.0, xy), std::min(xz, xy + xz));
84 const double xmax = std::max(std::max(0.0, xy), std::max(xz, xy + xz));
85 const double ymin = std::min(0.0, yz);
86 const double ymax = std::max(0.0, yz);
87 H[0][0] = xspan - xmax + xmin;
88 H[0][1] = 0.0;
89 H[0][2] = 0.0;
90 H[1][0] = xy;
91 H[1][1] = yspan - ymax + ymin;
92 H[1][2] = 0.0;
93 H[2][0] = xz;
94 H[2][1] = yz;
95 H[2][2] = zspan;
96 origin[0] = xlo_b - xmin;
97 origin[1] = ylo_b - ymin;
98 origin[2] = zlo_b;
99}
100
102inline void dumpCellLengths(const std::vector<double> &box,
103 const std::vector<double> &boxLow,
104 double lengths[3]) {
105 double H[3][3];
106 double origin[3];
107 dumpBoundsToH(box, boxLow, H, origin);
108 lengths[0] = H[0][0];
109 lengths[1] = H[1][1];
110 lengths[2] = H[2][2];
111}
112
114inline int dumpAxialDim(const std::vector<double> &box,
115 const std::vector<double> &boxLow) {
116 double lengths[3];
117 dumpCellLengths(box, boxLow, lengths);
118 int axial = 0;
119 if (lengths[1] > lengths[axial]) {
120 axial = 1;
121 }
122 if (lengths[2] > lengths[axial]) {
123 axial = 2;
124 }
125 return axial;
126}
127
128inline int dumpAxialDim(
129 const molSys::PointCloud<molSys::Point<double>, double> &yCloud) {
130 return dumpAxialDim(yCloud.box, yCloud.boxLow);
131}
132
134inline void dumpToFrac(const double H[3][3], const double origin[3], double x,
135 double y, double z, double s[3]) {
136 const double lx = H[0][0];
137 const double ly = H[1][1];
138 const double lz = H[2][2];
139 const double xy = H[1][0];
140 const double xz = H[2][0];
141 const double yz = H[2][1];
142 s[2] = (z - origin[2]) / lz;
143 s[1] = (y - origin[1] - yz * s[2]) / ly;
144 s[0] = (x - origin[0] - xy * s[1] - xz * s[2]) / lx;
145}
146
148inline void dumpFromFrac(const double H[3][3], const double origin[3],
149 const double s[3], double r[3]) {
150 r[0] = origin[0] + H[0][0] * s[0] + H[1][0] * s[1] + H[2][0] * s[2];
151 r[1] = origin[1] + H[1][1] * s[1] + H[2][1] * s[2];
152 r[2] = origin[2] + H[2][2] * s[2];
153}
154
157inline double dumpVolume(const std::vector<double> &box,
158 const std::vector<double> &boxLow) {
159 double H[3][3];
160 double origin[3];
161 dumpBoundsToH(box, boxLow, H, origin);
162 const double vol = H[0][0] * H[1][1] * H[2][2];
163 return vol < 0.0 ? -vol : vol;
164}
165
166inline double dumpVolume(
167 const molSys::PointCloud<molSys::Point<double>, double> &yCloud) {
168 return dumpVolume(yCloud.box, yCloud.boxLow);
169}
170
171#ifdef SEAMS_HAS_LINKCELL
173inline lc_cell lammpsBoxToLcCell(const std::vector<double> &box,
174 const std::vector<double> &boxLow) {
175 double H[3][3], o[3];
176 dumpBoundsToH(box, boxLow, H, o);
177 lc_cell c = lc_cell_ortho(H[0][0], H[1][1], H[2][2]);
178 c.ax = H[0][0];
179 c.ay = H[0][1];
180 c.az = H[0][2];
181 c.bx = H[1][0];
182 c.by = H[1][1];
183 c.bz = H[1][2];
184 c.cx = H[2][0];
185 c.cy = H[2][1];
186 c.cz = H[2][2];
187 c.ox = o[0];
188 c.oy = o[1];
189 c.oz = o[2];
190 return c;
191}
192
193inline linkcell::Cell lammpsBoxToLinkcell(const std::vector<double> &box,
194 const std::vector<double> &boxLow) {
195 return linkcell::Cell(lammpsBoxToLcCell(box, boxLow));
196}
197
202inline void residentFrameCell(const double *box, const double *boxLow,
203 int nBox, linkcell::Cell &cell,
204 const double *&frameLens) {
205 cell = linkcell::Cell::ortho(box[0], box[1], box[2]);
206 frameLens = box;
207 if (boxLow != nullptr || nBox >= 6) {
208 std::vector<double> dump(static_cast<std::size_t>(std::max(nBox, 3)));
209 for (int i = 0; i < nBox && i < static_cast<int>(dump.size()); ++i) {
210 dump[static_cast<std::size_t>(i)] = box[i];
211 }
212 std::vector<double> lo;
213 if (boxLow != nullptr) {
214 lo = {boxLow[0], boxLow[1], boxLow[2]};
215 }
216 cell = lammpsBoxToLinkcell(dump, lo);
217 frameLens = nullptr;
218 }
219}
220#endif
221
223
227std::vector<std::vector<int>> neighList(
228 double rcutoff, const molSys::PointCloud<molSys::Point<double>, double> &yCloud,
229 int typeI, int typeJ);
230
233std::vector<std::vector<int>> neighListPair(
234 double rcutoff, const molSys::PointCloud<molSys::Point<double>, double> &yCloud,
235 int typeI, int typeJ);
236
239std::vector<std::vector<int>> neighListO(
240 double rcutoff, const molSys::PointCloud<molSys::Point<double>, double> &yCloud,
241 int typeI);
242
245std::vector<std::vector<int>> halfNeighList(
246 double rcutoff, const molSys::PointCloud<molSys::Point<double>, double> &yCloud,
247 int typeI = 1);
248
251
254std::vector<std::vector<int>> neighbourListByIndex(
255 const molSys::PointCloud<molSys::Point<double>, double> &yCloud,
256 const std::vector<std::vector<int>> &nList);
257
260std::vector<std::vector<int>> getNewNeighbourListByIndex(
261 const molSys::PointCloud<molSys::Point<double>, double> &yCloud, double cutoff);
262
278std::vector<std::vector<int>> kNearestNeighbourList(
279 const molSys::PointCloud<molSys::Point<double>, double> &yCloud, int k,
280 double candidateCutoff, int typeI, bool mutual = true);
281
285std::pair<std::vector<std::vector<int>>, std::vector<std::vector<int>>>
287 const molSys::PointCloud<molSys::Point<double>, double> &yCloud, int k,
288 double candidateCutoff, int typeI);
289
296std::pair<double, double> shellSeparation(
297 const molSys::PointCloud<molSys::Point<double>, double> &yCloud, int k,
298 int typeI);
299
306std::vector<std::tuple<int, int, double>> nearestUnlike(
307 const molSys::PointCloud<molSys::Point<double>, double> &yCloud, int typeI,
308 int typeJ);
309
313std::vector<std::pair<int, int>> mutualNearestUnlike(
314 const molSys::PointCloud<molSys::Point<double>, double> &yCloud, int typeI,
315 int typeJ);
316
318[[nodiscard]] int clearNeighbourList(std::vector<std::vector<int>> &nList);
319
327
328BondGraph bondGraphFromName(const std::string &name);
329const char *bondGraphName(BondGraph graph);
330
340public:
343 SkinNeighborList(double cutoff, double skin, int typeI,
345
346 [[nodiscard]] BondGraph graph() const { return graph_; }
347
350 const std::vector<std::vector<int>> &
352
353 [[nodiscard]] bool lastRebuilt() const { return rebuilt_; }
355 [[nodiscard]] int lastChangedAtoms() const { return changedAtoms_; }
356 [[nodiscard]] const std::vector<std::vector<int>> &bonds() const {
357 return nList_;
358 }
359
360private:
361 double cutoff_;
362 double skin_;
363 double cutoffSq_;
364 double triggerSq_;
365 int typeI_;
366 int k_;
368 bool mutual_{true};
369 bool rebuilt_{true};
370 int changedAtoms_{0};
371 std::vector<double> x0_;
372 std::vector<double> y0_;
373 std::vector<double> z0_;
374 std::vector<double> box0_;
375 std::vector<std::pair<int, int>> candidates_;
376 std::vector<std::pair<int, int>> bonded_;
377 std::vector<std::vector<int>> nList_;
378
379 bool mustRebuild(
380 const molSys::PointCloud<molSys::Point<double>, double> &yCloud) const;
381 void rebuildCandidates(
382 const molSys::PointCloud<molSys::Point<double>, double> &yCloud);
383 void refreshBonds(
384 const molSys::PointCloud<molSys::Point<double>, double> &yCloud);
385};
386
387} // namespace nneigh
388
389#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.
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