Loading...
Searching...
No Matches
generic.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_GENERIC_H_
16#define SEAMS_GENERIC_H_
17
18#include <algorithm>
19#include <array>
20#include <cmath>
21#include <cstddef>
22#include <filesystem>
23#include <iostream>
24#include <sstream>
25#include <string>
26#include <vector>
27#include <mol_sys.hpp>
28
29#ifdef SEAMS_HAS_MINIMAGE
30#include <minimage.h>
31#endif
32
33// C++20
34#include <numbers>
35// Eigen
36#include <Eigen/Core>
37#include <Eigen/Dense>
38
42
47
58
59namespace gen {
60
64constexpr double pi = std::numbers::pi;
65
71inline double radDeg(double angle) { return (angle * 180) / gen::pi; }
72
74double eigenVecAngle(std::vector<double> OO, std::vector<double> OH);
75
77double getAverageWithoutOutliers(std::vector<double> inpVec);
78
87inline double calcMedian(std::vector<double> *input) {
88 int n = (*input).size(); // Number of elements
89 double median; // Output median value
90
91 // Sort a copy (avoid mutating input)
92 std::vector<double> sorted = *input;
93 std::sort(sorted.begin(), sorted.end());
94
95 // Calculate the median
96 // For even values, the median is the average of the two middle values
97 if (n % 2 == 0) {
98 median = 0.5 * (sorted[n / 2] + sorted[n / 2 - 1]);
99 } else {
100 median = sorted[(n + 1) / 2 - 1];
101 }
102
103 return median;
104}
105
106#ifdef SEAMS_HAS_MINIMAGE
107// Dump bound spans plus optional tilt onto an mi_cell.
108inline bool pointCloudCell(
109 const molSys::PointCloud<molSys::Point<double>, double> &yCloud,
110 mi_cell *out) {
111 const auto &box = yCloud.box;
112 const auto &boxLow = yCloud.boxLow;
113 const double xlo_b = boxLow.size() > 0 ? boxLow[0] : 0.0;
114 const double ylo_b = boxLow.size() > 1 ? boxLow[1] : 0.0;
115 const double zlo_b = boxLow.size() > 2 ? boxLow[2] : 0.0;
116 if (box.size() >= 6) {
117 return mi_cell_from_lammps_bounds(box[0], box[1], box[2], box[3], box[4],
118 box[5], xlo_b, ylo_b, zlo_b, out) == 0;
119 }
120 if (box.size() >= 3 && box[0] > 0.0 && box[1] > 0.0 && box[2] > 0.0) {
121 *out = mi_cell_ortho(box[0], box[1], box[2]);
122 out->ox = xlo_b;
123 out->oy = ylo_b;
124 out->oz = zlo_b;
125 return true;
126 }
127 return false;
128}
129#endif
130
131// One dump box, recovered once per frame. Orthorhombic lengths are the
132// bound spans. A tilt dump stores those spans in box[0..2] and xy, xz, yz
133// in box[3..5]; lx, ly, lz are the recovered edge lengths, and wx, wy, wz
134// the separations of opposite faces, which tilt makes shorter.
135struct FracBox {
136 double lx = 0.0;
137 double ly = 0.0;
138 double lz = 0.0;
139 double xy = 0.0;
140 double xz = 0.0;
141 double yz = 0.0;
142 double ox = 0.0;
143 double oy = 0.0;
144 double oz = 0.0;
145 double wx = 0.0;
146 double wy = 0.0;
147 double wz = 0.0;
148 double halfMin = 0.0;
149 bool triclinic = false;
150 bool ok = false;
151};
152
153inline FracBox
155 FracBox b;
156 const auto &box = yCloud.box;
157 const auto &boxLow = yCloud.boxLow;
158 b.ox = boxLow.size() > 0 ? boxLow[0] : 0.0;
159 b.oy = boxLow.size() > 1 ? boxLow[1] : 0.0;
160 b.oz = boxLow.size() > 2 ? boxLow[2] : 0.0;
161 if (box.size() >= 6) {
162 const double xy = box[3];
163 const double xz = box[4];
164 const double yz = box[5];
165 const double xmin = std::min(std::min(0.0, xy), std::min(xz, xy + xz));
166 const double xmax = std::max(std::max(0.0, xy), std::max(xz, xy + xz));
167 const double ymin = std::min(0.0, yz);
168 const double ymax = std::max(0.0, yz);
169 b.lx = box[0] - xmax + xmin;
170 b.ly = box[1] - ymax + ymin;
171 b.lz = box[2];
172 b.xy = xy;
173 b.xz = xz;
174 b.yz = yz;
175 b.ox -= xmin;
176 b.oy -= ymin;
177 b.triclinic = true;
178 } else if (box.size() >= 3) {
179 b.lx = box[0];
180 b.ly = box[1];
181 b.lz = box[2];
182 } else {
183 return b;
184 }
185 if (!(b.lx > 0.0 && b.ly > 0.0 && b.lz > 0.0)) {
186 return b;
187 }
188 const double bcz = b.xy * b.yz - b.ly * b.xz;
189 b.wx = b.lx * b.ly * b.lz /
190 std::sqrt(b.ly * b.lz * b.ly * b.lz + b.xy * b.lz * b.xy * b.lz +
191 bcz * bcz);
192 b.wy = b.ly * b.lz / std::sqrt(b.lz * b.lz + b.yz * b.yz);
193 b.wz = b.lz;
194 b.halfMin = 0.5 * std::min(b.wx, std::min(b.wy, b.wz));
195 b.ok = true;
196 return b;
197}
198
199// Displacement from (xj, yj, zj) to (xi, yi, zi). Orthorhombic axes wrap
200// independently. A tilt box wraps the fractional difference and maps it
201// back through H. That vector is the Euclidean minimum image while its
202// length stays below half the shortest edge.
203inline std::array<double, 3> fracDelta(const FracBox &b, double xi, double yi,
204 double zi, double xj, double yj,
205 double zj) {
206 if (!b.triclinic) {
207 std::array<double, 3> dr = {xi - xj, yi - yj, zi - zj};
208 const double len[3] = {b.lx, b.ly, b.lz};
209 for (int k = 0; k < 3; k++) {
210 dr[static_cast<std::size_t>(k)] -=
211 len[k] * std::floor(dr[static_cast<std::size_t>(k)] / len[k] + 0.5);
212 }
213 return dr;
214 }
215 const double sz_i = (zi - b.oz) / b.lz;
216 const double sy_i = (yi - b.oy - b.yz * sz_i) / b.ly;
217 const double sx_i = (xi - b.ox - b.xy * sy_i - b.xz * sz_i) / b.lx;
218 const double sz_j = (zj - b.oz) / b.lz;
219 const double sy_j = (yj - b.oy - b.yz * sz_j) / b.ly;
220 const double sx_j = (xj - b.ox - b.xy * sy_j - b.xz * sz_j) / b.lx;
221 double dsx = sx_i - sx_j;
222 double dsy = sy_i - sy_j;
223 double dsz = sz_i - sz_j;
224 dsx -= std::round(dsx);
225 dsy -= std::round(dsy);
226 dsz -= std::round(dsz);
227 return {b.lx * dsx + b.xy * dsy + b.xz * dsz, b.ly * dsy + b.yz * dsz,
228 b.lz * dsz};
229}
230
231inline double fracDistSq(const FracBox &b, double xi, double yi, double zi,
232 double xj, double yj, double zj) {
233 const auto dr = fracDelta(b, xi, yi, zi, xj, yj, zj);
234 return dr[0] * dr[0] + dr[1] * dr[1] + dr[2] * dr[2];
235}
236
237// Smith, CCP5 1989: below half the narrowest face separation the fractional
238// wrap is the only lattice image in the ball, and every image inside that
239// ball is a fractional wrap. An orthorhombic wrap is that image on every
240// axis, including past half an edge.
241inline bool smithInside(const FracBox &b, double r2) {
242 return b.ok && (!b.triclinic || std::sqrt(r2) + 1e-12 < b.halfMin);
243}
244
245#ifdef SEAMS_HAS_MINIMAGE
246inline bool euclideanDelta(
247 const molSys::PointCloud<molSys::Point<double>, double> &yCloud, double xi,
248 double yi, double zi, double xj, double yj, double zj, double dr[3]) {
249 mi_cell cell;
250 if (!pointCloudCell(yCloud, &cell)) {
251 return false;
252 }
253 const double p[3] = {xj, yj, zj};
254 const double q[3] = {xi, yi, zi};
255 return mi_displacement_euclidean(&cell, p, q, dr) == 0;
256}
257
258// One frame on minimage's cell, built once, with the positions packed for
259// its batch kernels.
260struct CellFrame {
261 mi_cell cell{};
262 std::vector<double> xyz;
263 bool ok = false;
264};
265
266inline CellFrame
267makeCellFrame(const molSys::PointCloud<molSys::Point<double>, double> &yCloud) {
268 CellFrame f;
269 if (!pointCloudCell(yCloud, &f.cell)) {
270 return f;
271 }
272 const std::size_t n = yCloud.pts.size();
273 f.xyz.resize(3 * n);
274 for (std::size_t i = 0; i < n; i++) {
275 f.xyz[3 * i] = yCloud.pts[i].x;
276 f.xyz[3 * i + 1] = yCloud.pts[i].y;
277 f.xyz[3 * i + 2] = yCloud.pts[i].z;
278 }
279 f.ok = true;
280 return f;
281}
282
283// Squared Euclidean minimum image from j to i on the frame's cell, or -1.
284inline double euclideanDistSq(const CellFrame &f, int i, int j) {
285 double dr[3];
286 if (mi_displacement_euclidean(&f.cell, &f.xyz[3 * static_cast<std::size_t>(j)],
287 &f.xyz[3 * static_cast<std::size_t>(i)],
288 dr) != 0) {
289 return -1.0;
290 }
291 return dr[0] * dr[0] + dr[1] * dr[1] + dr[2] * dr[2];
292}
293#endif
294
295// Recover H (columns a, b, c) and origin from a LAMMPS dump box with the
296// same mapping as nneigh::lammpsBoxToLcCell: box[0..3] are bound spans,
297// box[3..6] are tilt factors xy, xz, yz, boxLow is the bound lo.
298inline std::array<double, 3> triclinicMinImage(
299 const molSys::PointCloud<molSys::Point<double>, double> &yCloud, double xi,
300 double yi, double zi, double xj, double yj, double zj) {
301 const FracBox b = makeFracBox(yCloud);
302 if (b.ok && b.triclinic) {
303 const auto dr = fracDelta(b, xi, yi, zi, xj, yj, zj);
304 const double r2 = dr[0] * dr[0] + dr[1] * dr[1] + dr[2] * dr[2];
305 if (smithInside(b, r2)) {
306 return dr;
307 }
308#ifdef SEAMS_HAS_MINIMAGE
309 double ed[3] = {0.0, 0.0, 0.0};
310 if (euclideanDelta(yCloud, xi, yi, zi, xj, yj, zj, ed)) {
311 return {ed[0], ed[1], ed[2]};
312 }
313#endif
314 return dr;
315 }
316 const auto &box = yCloud.box;
317 const auto &boxLow = yCloud.boxLow;
318 const double xspan = box[0];
319 const double yspan = box[1];
320 const double zspan = box[2];
321 const double xlo_b = boxLow.size() > 0 ? boxLow[0] : 0.0;
322 const double ylo_b = boxLow.size() > 1 ? boxLow[1] : 0.0;
323 const double zlo_b = boxLow.size() > 2 ? boxLow[2] : 0.0;
324 const double xy = box[3];
325 const double xz = box[4];
326 const double yz = box[5];
327 const double xmin = std::min(std::min(0.0, xy), std::min(xz, xy + xz));
328 const double xmax = std::max(std::max(0.0, xy), std::max(xz, xy + xz));
329 const double ymin = std::min(0.0, yz);
330 const double ymax = std::max(0.0, yz);
331 const double lx = xspan - xmax + xmin;
332 const double ly = yspan - ymax + ymin;
333 const double lz = zspan;
334 const double ox = xlo_b - xmin;
335 const double oy = ylo_b - ymin;
336 const double oz = zlo_b;
337 const double sz_i = (zi - oz) / lz;
338 const double sy_i = (yi - oy - yz * sz_i) / ly;
339 const double sx_i = (xi - ox - xy * sy_i - xz * sz_i) / lx;
340 const double sz_j = (zj - oz) / lz;
341 const double sy_j = (yj - oy - yz * sz_j) / ly;
342 const double sx_j = (xj - ox - xy * sy_j - xz * sz_j) / lx;
343 double dsx = sx_i - sx_j;
344 double dsy = sy_i - sy_j;
345 double dsz = sz_i - sz_j;
346 dsx -= std::round(dsx);
347 dsy -= std::round(dsy);
348 dsz -= std::round(dsz);
349 return {lx * dsx + xy * dsy + xz * dsz, ly * dsy + yz * dsz, lz * dsz};
350}
351
352// Generic function for getting the unwrapped distance
362inline double
364 const molSys::PointCloud<molSys::Point<double>, double> &yCloud,
365 int iatom, int jatom) {
366 const auto &pi = yCloud.pts[static_cast<std::size_t>(iatom)];
367 const auto &pj = yCloud.pts[static_cast<std::size_t>(jatom)];
368 if (b.ok) {
369 const double r2 = fracDistSq(b, pi.x, pi.y, pi.z, pj.x, pj.y, pj.z);
370 if (smithInside(b, r2)) {
371 return r2;
372 }
373#ifdef SEAMS_HAS_MINIMAGE
374 double ed[3] = {0.0, 0.0, 0.0};
375 if (euclideanDelta(yCloud, pi.x, pi.y, pi.z, pj.x, pj.y, pj.z, ed)) {
376 return ed[0] * ed[0] + ed[1] * ed[1] + ed[2] * ed[2];
377 }
378#endif
379 return r2;
380 }
381 if (yCloud.box.size() >= 6) {
382 const auto dr =
383 triclinicMinImage(yCloud, pi.x, pi.y, pi.z, pj.x, pj.y, pj.z);
384 return dr[0] * dr[0] + dr[1] * dr[1] + dr[2] * dr[2];
385 }
386 std::array<double, 3> dr;
387 double r2 = 0.0;
388 dr[0] = std::fabs(pi.x - pj.x);
389 dr[1] = std::fabs(pi.y - pj.y);
390 dr[2] = std::fabs(pi.z - pj.z);
391 for (int k = 0; k < 3; k++) {
392 dr[static_cast<std::size_t>(k)] -=
393 yCloud.box[static_cast<std::size_t>(k)] *
394 std::round(dr[static_cast<std::size_t>(k)] /
395 yCloud.box[static_cast<std::size_t>(k)]);
396 r2 += dr[static_cast<std::size_t>(k)] * dr[static_cast<std::size_t>(k)];
397 }
398 return r2;
399}
400
401inline double
403 int iatom, int jatom) {
404 return periodicDistSq(makeFracBox(yCloud), yCloud, iatom, jatom);
405}
406
416inline double
418 int iatom, int jatom) {
419 return std::sqrt(periodicDistSq(yCloud, iatom, jatom));
420}
421
422// Tilt batches share one mi_cell. mi_dist2_many is the fractional
423// image for every candidate. A result outside the Smith ball is
424// replaced by the Euclidean image. Orthorhombic batches stay on
425// periodicDistSq; the Highway kernel is the ortho difference path.
427 const molSys::PointCloud<molSys::Point<double>, double> &yCloud, int iatom,
428 const int *jatom, std::size_t n, double *distSq) {
429 const FracBox b = makeFracBox(yCloud);
430#ifdef SEAMS_HAS_MINIMAGE
431 if (n > 0 && b.ok && b.triclinic) {
432 mi_cell cell;
433 if (pointCloudCell(yCloud, &cell)) {
434 const auto &pi = yCloud.pts[static_cast<std::size_t>(iatom)];
435 const double p[3] = {pi.x, pi.y, pi.z};
436 std::vector<double> qs(n * 3);
437 for (std::size_t k = 0; k < n; ++k) {
438 const auto &pj = yCloud.pts[static_cast<std::size_t>(jatom[k])];
439 qs[3 * k] = pj.x;
440 qs[3 * k + 1] = pj.y;
441 qs[3 * k + 2] = pj.z;
442 }
443 if (mi_dist2_many(&cell, p, qs.data(), n, distSq) == 0) {
444 for (std::size_t k = 0; k < n; ++k) {
445 if (smithInside(b, distSq[k])) {
446 continue;
447 }
448 const double q[3] = {qs[3 * k], qs[3 * k + 1], qs[3 * k + 2]};
449 double ed[3] = {0.0, 0.0, 0.0};
450 if (mi_displacement_euclidean(&cell, q, p, ed) == 0) {
451 distSq[k] = ed[0] * ed[0] + ed[1] * ed[1] + ed[2] * ed[2];
452 }
453 }
454 return;
455 }
456 }
457 }
458#endif
459 for (std::size_t k = 0; k < n; k++) {
460 distSq[k] = periodicDistSq(b, yCloud, iatom, jatom[k]);
461 }
462}
463
464// Bound spans, then tilt when box.size() >= 6.
465inline std::string formatDumpBox(const std::vector<double> &box) {
466 std::ostringstream oss;
467 if (box.size() >= 3) {
468 oss << box[0] << ' ' << box[1] << ' ' << box[2];
469 }
470 if (box.size() >= 6) {
471 oss << " xy " << box[3] << " xz " << box[4] << " yz " << box[5];
472 }
473 return oss.str();
474}
475
476// ITEM line plus three bound lines. Tilt is a third field per line.
478 std::ostream &os,
479 const molSys::PointCloud<molSys::Point<double>, double> &yCloud) {
480 const bool tilt = yCloud.box.size() >= 6;
481 if (tilt) {
482 os << "ITEM: BOX BOUNDS xy xz yz pp pp pp\n";
483 } else {
484 os << "ITEM: BOX BOUNDS pp pp pp\n";
485 }
486 for (int k = 0; k < 3; k++) {
487 const double lo = (static_cast<std::size_t>(k) < yCloud.boxLow.size())
488 ? yCloud.boxLow[k]
489 : 0.0;
490 const double len = (static_cast<std::size_t>(k) < yCloud.box.size())
491 ? yCloud.box[k]
492 : 0.0;
493 os << lo << ' ' << lo + len;
494 if (tilt) {
495 os << ' ' << yCloud.box[static_cast<std::size_t>(k + 3)];
496 }
497 os << '\n';
498 }
499}
500
512inline std::array<double, 3> relDistFromPoint(
513 const FracBox &b,
514 const molSys::PointCloud<molSys::Point<double>, double> &yCloud, int iatom,
515 double xj, double yj, double zj) {
516 if (b.ok) {
517 const auto &pi = yCloud.pts[static_cast<std::size_t>(iatom)];
518 const auto dr = fracDelta(b, pi.x, pi.y, pi.z, xj, yj, zj);
519 const double r2 = dr[0] * dr[0] + dr[1] * dr[1] + dr[2] * dr[2];
520 if (smithInside(b, r2)) {
521 return dr;
522 }
523#ifdef SEAMS_HAS_MINIMAGE
524 double ed[3] = {0.0, 0.0, 0.0};
525 if (euclideanDelta(yCloud, pi.x, pi.y, pi.z, xj, yj, zj, ed)) {
526 return {ed[0], ed[1], ed[2]};
527 }
528#endif
529 return dr;
530 }
531 if (yCloud.box.size() >= 6) {
532 return triclinicMinImage(yCloud, yCloud.pts[iatom].x, yCloud.pts[iatom].y,
533 yCloud.pts[iatom].z, xj, yj, zj);
534 }
535
536 std::array<double, 3> dr = {yCloud.pts[iatom].x - xj, yCloud.pts[iatom].y - yj,
537 yCloud.pts[iatom].z - zj};
538 for (int k = 0; k < 3; k++) {
539 if (dr[k] < -yCloud.box[k] * 0.5) {
540 dr[k] += yCloud.box[k];
541 }
542 if (dr[k] >= yCloud.box[k] * 0.5) {
543 dr[k] -= yCloud.box[k];
544 }
545 }
546 return dr;
547}
548
549inline std::array<double, 3> relDistFromPoint(
550 const molSys::PointCloud<molSys::Point<double>, double> &yCloud, int iatom,
551 double xj, double yj, double zj) {
552 return relDistFromPoint(makeFracBox(yCloud), yCloud, iatom, xj, yj, zj);
553}
554
556 const molSys::PointCloud<molSys::Point<double>, double> &yCloud, int iatom,
557 const std::vector<double> &singlePoint) {
558 const auto dr =
559 relDistFromPoint(yCloud, iatom, singlePoint[0], singlePoint[1],
560 singlePoint[2]);
561 return std::sqrt(dr[0] * dr[0] + dr[1] * dr[1] + dr[2] * dr[2]);
562}
563
564// Generic function for getting the distance (no PBCs applied)
574inline double
575distance(const molSys::PointCloud<molSys::Point<double>, double> &yCloud, int iatom,
576 int jatom) {
577 std::array<double, 3> dr;
578 double r2 = 0.0; // Squared absolute distance
579
580 // Get x1-x2 etc
581 dr[0] = fabs(yCloud.pts[iatom].x - yCloud.pts[jatom].x);
582 dr[1] = fabs(yCloud.pts[iatom].y - yCloud.pts[jatom].y);
583 dr[2] = fabs(yCloud.pts[iatom].z - yCloud.pts[jatom].z);
584
585 // Get the squared absolute distance
586 for (int k = 0; k < 3; k++) {
587 r2 += pow(dr[k], 2.0);
588 }
589
590 return sqrt(r2);
591}
592
593// Generic function for getting the relative coordinates
604inline std::array<double, 3>
605relDist(const molSys::PointCloud<molSys::Point<double>, double> &yCloud, int iatom,
606 int jatom) {
607 return relDistFromPoint(yCloud, iatom, yCloud.pts[jatom].x,
608 yCloud.pts[jatom].y, yCloud.pts[jatom].z);
609}
610
611// Function for sorting according to atom ID
612// Comparator for std::sort
621 const molSys::Point<double> &b) {
622 return a.atomID < b.atomID;
623}
624
626[[nodiscard]] int prettyPrintYoda(const molSys::PointCloud<molSys::Point<double>, double> &yCloud,
627 std::string outFile);
628
630[[nodiscard]] int unwrappedCoordShift(
631 const molSys::PointCloud<molSys::Point<double>, double> &yCloud, int iatomIndex,
632 int jatomIndex, double *x_i, double *y_i, double *z_i, double *x_j,
633 double *y_j, double *z_j);
634
637double angDistDegQuaternions(std::vector<double> quat1,
638 std::vector<double> quat2);
639
645inline std::vector<std::string> tokenizer(std::string line) {
646 std::istringstream iss(line);
647 std::vector<std::string> tokens{std::istream_iterator<std::string>{iss},
648 std::istream_iterator<std::string>{}};
649 return tokens;
650}
651
656inline std::vector<double> tokenizerDouble(std::string line) {
657 std::istringstream iss(line);
658 std::vector<double> tokens;
659 double number; // Each number being read in from the line
660 while (iss >> number) {
661 tokens.push_back(number);
662 }
663 return tokens;
664}
665
670inline std::vector<int> tokenizerInt(std::string line) {
671 std::istringstream iss(line);
672 std::vector<int> tokens;
673 int number; // Each number being read in from the line
674 while (iss >> number) {
675 tokens.push_back(number);
676 }
677 return tokens;
678}
679
684inline bool file_exists(const std::string &name) {
685 return std::filesystem::exists(name);
686}
687
696inline std::vector<std::complex<double>>
697avgVector(std::vector<std::complex<double>> v, int l, int neigh) {
698 if (neigh == 0) {
699 return v;
700 }
701 for (int m = 0; m < 2 * l + 1; m++) {
702 v[m] = (1.0 / static_cast<double>(neigh)) * v[m];
703 }
704
705 return v;
706}
707
708} // namespace gen
709
710#endif // SEAMS_GENERIC_H_
double fracDistSq(const FracBox &b, double xi, double yi, double zi, double xj, double yj, double zj)
Definition generic.hpp:231
double distance(const molSys::PointCloud< molSys::Point< double >, double > &yCloud, int iatom, int jatom)
Inline generic function for obtaining the wrapped distance between two particles WITHOUT applying PBC...
Definition generic.hpp:575
std::vector< std::complex< double > > avgVector(std::vector< std::complex< double > > v, int l, int neigh)
Calculates the complex vector, normalized by the number of nearest neighbours, of length .
Definition generic.hpp:697
void writeDumpBoxBounds(std::ostream &os, const molSys::PointCloud< molSys::Point< double >, double > &yCloud)
Definition generic.hpp:477
std::array< double, 3 > relDistFromPoint(const FracBox &b, const molSys::PointCloud< molSys::Point< double >, double > &yCloud, int iatom, double xj, double yj, double zj)
Inline generic function for obtaining the unwrapped periodic distance between one particle and anothe...
Definition generic.hpp:512
std::array< double, 3 > relDist(const molSys::PointCloud< molSys::Point< double >, double > &yCloud, int iatom, int jatom)
Inline generic function for getting the relative unwrapped distance between two particles for each di...
Definition generic.hpp:605
double periodicDist(const 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:417
double eigenVecAngle(std::vector< double > OO, std::vector< double > OH)
Eigen function for getting the angle (in radians) between the O–O and O-H vectors.
double calcMedian(std::vector< double > *input)
Inline generic function for calculating the median given a vector of the values.
Definition generic.hpp:87
std::array< double, 3 > triclinicMinImage(const molSys::PointCloud< molSys::Point< double >, double > &yCloud, double xi, double yi, double zi, double xj, double yj, double zj)
Definition generic.hpp:298
std::string formatDumpBox(const std::vector< double > &box)
Definition generic.hpp:465
FracBox makeFracBox(const molSys::PointCloud< molSys::Point< double >, double > &yCloud)
Definition generic.hpp:154
std::vector< double > tokenizerDouble(std::string line)
Function for tokenizing line strings into a vector of doubles.
Definition generic.hpp:656
double halfMin
Definition generic.hpp:148
constexpr double pi
Uses Boost to get the value of pi.
Definition generic.hpp:64
bool smithInside(const FracBox &b, double r2)
Definition generic.hpp:241
bool file_exists(const std::string &name)
Function for checking if a file exists or not.
Definition generic.hpp:684
std::vector< std::string > tokenizer(std::string line)
Function for tokenizing line strings into words (strings) delimited by whitespace.
Definition generic.hpp:645
int prettyPrintYoda(const molSys::PointCloud< molSys::Point< double >, double > &yCloud, std::string outFile)
Generic function for printing all the struct information.
std::array< double, 3 > fracDelta(const FracBox &b, double xi, double yi, double zi, double xj, double yj, double zj)
Definition generic.hpp:203
double periodicDistSq(const FracBox &b, const 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:363
double angDistDegQuaternions(std::vector< double > quat1, std::vector< double > quat2)
void batchPeriodicDistSq(const molSys::PointCloud< molSys::Point< double >, double > &yCloud, int iatom, const int *jatom, std::size_t n, double *distSq)
Definition generic.hpp:426
int unwrappedCoordShift(const molSys::PointCloud< molSys::Point< double >, double > &yCloud, int iatomIndex, int jatomIndex, double *x_i, double *y_i, double *z_i, double *x_j, double *y_j, double *z_j)
Shift particles (unwrapped coordinates).
std::vector< int > tokenizerInt(std::string line)
Function for tokenizing line strings into a vector of ints.
Definition generic.hpp:670
double radDeg(double angle)
Inline function for converting radians->degrees.
Definition generic.hpp:71
bool compareByAtomID(const molSys::Point< double > &a, const molSys::Point< double > &b)
Inline generic function for sorting or comparing two particles, according to the atom ID when the ent...
Definition generic.hpp:620
double getAverageWithoutOutliers(std::vector< double > inpVec)
Get the average, after excluding the outliers, using quartiles.
double unWrappedDistFromPoint(const molSys::PointCloud< molSys::Point< double >, double > &yCloud, int iatom, const std::vector< double > &singlePoint)
Definition generic.hpp:555
The main molecular system handler.
Small generic functions that are shared by all namespaces.
Definition generic.hpp:59
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