15#ifndef SEAMS_NEIGHBOURS_H_
16#define SEAMS_NEIGHBOURS_H_
28#ifdef SEAMS_HAS_LINKCELL
29#include <linkcell.hpp>
31#ifdef SEAMS_HAS_MINIMAGE
75 const std::vector<double> &boxLow,
double H[3][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;
94 H[1][1] = yspan - ymax + ymin;
99 origin[0] = xlo_b - xmin;
100 origin[1] = ylo_b - ymin;
106 const std::vector<double> &boxLow,
111 lengths[0] = H[0][0];
112 lengths[1] = H[1][1];
113 lengths[2] = H[2][2];
118 const std::vector<double> &boxLow) {
122 if (lengths[1] > lengths[axial]) {
125 if (lengths[2] > lengths[axial]) {
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;
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];
161 const std::vector<double> &boxLow) {
165 const double vol = H[0][0] * H[1][1] * H[2][2];
166 return vol < 0.0 ? -vol : vol;
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;
189 mi_cell_from_lammps_bounds(xspan, yspan, zspan, xy, xz, yz, xlo_b, ylo_b,
191 lc_cell c = lc_cell_ortho(raw.ax, raw.by, raw.cz);
206 double H[3][3], o[3];
208 lc_cell c = lc_cell_ortho(H[0][0], H[1][1], H[2][2]);
225inline linkcell::Cell lammpsBoxToLinkcell(
const std::vector<double> &box,
226 const std::vector<double> &boxLow) {
227 return linkcell::Cell(lammpsBoxToLcCell(box, boxLow));
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]);
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];
244 std::vector<double> lo;
245 if (boxLow !=
nullptr) {
246 lo = {boxLow[0], boxLow[1], boxLow[2]};
248 cell = lammpsBoxToLinkcell(dump, lo);
261 int typeI,
int typeJ);
267 int typeI,
int typeJ);
279 const std::vector<int> &subset,
double rcutoff,
280 std::vector<std::vector<int>> &rows);
302 const std::vector<std::vector<int>> &nList);
326 double candidateCutoff,
int typeI,
bool mutual =
true);
332 double candidateCutoff,
const std::vector<int> &types,
bool mutual =
true);
337std::pair<std::vector<std::vector<int>>, std::vector<std::vector<int>>>
340 double candidateCutoff,
int typeI);
342std::pair<std::vector<std::vector<int>>, std::vector<std::vector<int>>>
345 double candidateCutoff,
const std::vector<int> &types);
407 const std::vector<std::vector<int>> &
413 [[nodiscard]]
const std::vector<std::vector<int>> &
bonds()
const {
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_;
437 const molSys::PointCloud<molSys::Point<double>,
double> &yCloud)
const;
438 void rebuildCandidates(
439 const molSys::PointCloud<molSys::Point<double>,
double> &yCloud);
441 const molSys::PointCloud<molSys::Point<double>,
double> &yCloud);
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)
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.
This contains per-particle information.