API map

Lookup for the C++ identifiers in src/include/internal. Generated pages under api/ are the Doxygen comments from those headers, converted by doxyrest, the same path as rgpot. This is not a dump of pydseams.yoda and it is not a tutorial.

Fronts

Four fronts, one engine (libyodaLib). Flags live on seams CLI. Formats live on data formats.

Front

Package

First call

CLI

this repo (seams)

seams read FILE, seams chill-plus FILE, seams cages FILE

Python Frame

PydSEAMSlib

pydseams.Frame from pydseams.read(...)

Lua

yodaStruct

require("dseams")

Compiled Python

PydSEAMSlib

pydseams.yoda (_core and cyoda are aliases)

Doxyrest wiring

pixi run -e docs doxybuild runs from docs/source:

  1. doxygen Doxyfile_seams.cfgINPUT is ../../src/include/internal (EXTRACT_ALL=YES, private members off). src/include/external and tests/ are excluded.

  2. doxyrest -c doxyrest-config.lua – reads xml/index.xml, writes =api/index.rst~ with title API Reference.

The book includes that tree as api/index (Reference toctree), not as a second hand list of functions.

C++ (doxygen)

The groups below are Breathe of the same XML. That is the interned API, not a hand table.

enum class BondGraph

Bond graph for TUM.

Chosen at runtime so the three published assignments can be compared on the same frames. cutoff: pairs inside the distance cutoff (2020 graph). knn: mutual k-nearest (TUM v2 without hysteresis). knn-union: union k-nearest (the completion graph of the seeded rule).

Values:

enumerator Cutoff
enumerator KnnMutual
enumerator KnnUnion
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.

Inefficient \(O(n^2)\) implementation of neighbour lists when there are two different types of atoms The neighbour list does not differentiate between the types of atoms

std::vector<std::vector<int>> neighListO(double rcutoff, const molSys::PointCloud<molSys::Point<double>, double> &yCloud, int typeI)

Inefficient \(O(n^2)\) implementation of neighbour lists You can only use this for neighbour lists with one type.

std::vector<std::vector<int>> halfNeighList(double rcutoff, const molSys::PointCloud<molSys::Point<double>, double> &yCloud, int typeI = 1)

Inefficient \(O(n^2)\) implementation of neighbour lists You can only use this for neighbour lists with one type.

std::vector<std::vector<int>> neighbourListByIndex(const molSys::PointCloud<molSys::Point<double>, double> &yCloud, const std::vector<std::vector<int>> &nList)

The following function outputs a neighbour list using indices and NOT atom IDs.

Converts the neighbour list build with atom IDs into a neighbour list of atom indices, according to the pointCloud

std::vector<std::vector<int>> getNewNeighbourListByIndex(const molSys::PointCloud<molSys::Point<double>, double> &yCloud, double cutoff)

Gets a neighbour list by index, according to a pointCloud given as the input.

Assume no slices or other skullduggery

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.

The default intersection symmetrization (mutual = true) bonds i and j only when each lists the other among its k nearest; the union alternative bonds on either nomination. In a crystal the first shell is mutual and the two coincide; on disordered packings the mutual graph is sparser, which starves accidental ring structure &#8212; measured on the dense null, mutual scores zero false crystal where union reaches 2.5%. Nominations are a periodic linked-cell k-nearest search via linkcell (Allen and Tildesley): vesin is cutoff-only and KD-trees have no minimum-image convention. candidateCutoff is only a cell-size hint. On an undistorted tetrahedral lattice with k = 4 this graph equals the first-shell cutoff graph. Rows are by atom ID with the leading self entry, like neighListO.

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.

Seeded affiliation needs both; building them separately repeats the cell list.

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: returns {max_i d_k(i), min_i d_{k+1}(i)} over particles of the type.

When max_i d_k(i) <= rcutoff <= min_i d_{k+1}(i), the two graphs coincide edge for edge and every downstream graph predicate is identical. Brute force, intended for validation.

int clearNeighbourList(std::vector<std::vector<int>> &nList)

Erases memory for a vector of vectors for the neighbour list.

BondGraph bondGraphFromName(const std::string &name)
const char *bondGraphName(BondGraph graph)
SkinNeighborList(double cutoff, double skin, int typeI, BondGraph graph = BondGraph::KnnMutual, int k = 4)

graph selects cutoff vs k-nearest (mutual or union).

k is the neighbour count for the knn graphs (default 4).

inline BondGraph graph() const
const std::vector<std::vector<int>> &update(const molSys::PointCloud<molSys::Point<double>, double> &yCloud)

Refresh from a new frame.

The returned list is ID-keyed with a leading self entry, the same shape as neighListO.

inline bool lastRebuilt() const
inline int lastChangedAtoms() const

Atoms whose cutoff bond set changed on the last update.

inline const std::vector<std::vector<int>> &bonds() const
class SkinNeighborList
#include <neighbours.hpp>

Persistent neighbour list with a LAMMPS skin.

Vesin (or the brute-force fallback) builds candidates at cutoff+skin, which is the ghost halo: periodic images already sit in that shell. The cell list is rebuilt only when some atom has moved more than skin/2 from the last rebuild, the Verlet trigger. The bond graph for rings is the candidate pairs whose current distance is inside the analysis cutoff.

std::vector<std::complex<double>> ylm
std::vector<YlmAtom> ptq
double staggeredMax
double eclipsedMin

c_ij at or below this is staggered

double eclipsedMax

Lower edge of the eclipsed band.

int coordinationNumber

Upper edge of the eclipsed band.

std::vector<double> ql
std::vector<double> qlBar

Local \(q_l(i)\).

BondClassifier chillRule()

The CHILL rule set (Moore et al., PCCP 12, 4124, 2010): strict staggered bound, narrow eclipsed band, four nearest neighbours.

BondClassifier chillPlusRule()

The CHILL+ rule set (Nguyen and Molinero, JPCB 119, 9369, 2015): wider eclipsed band for interfacial and clathrate recognition.

BondClassifier bondClassifier(const std::string &name)

Look up a registered rule set by name.

“CHILL” and “CHILL+” are always present; registerBondClassifier adds more. Throws std::out_of_range for unknown names.

void registerBondClassifier(const std::string &name, const BondClassifier &rule)

Register (or replace) a named rule set at runtime, making the material’s thresholds available to every front end by name.

std::vector<std::string> bondClassifierNames()

Names of every registered rule set.

void classifyBonds(molSys::PointCloud<molSys::Point<double>, double> &yCloud, const std::vector<std::vector<int>> &nList, const BondClassifier &rule, bool isSlice = false)

Compute and classify the bond correlations c_ij under an arbitrary rule set, filling yCloud.pts[i].c_ij.

getCorrel and getCorrelPlus are this engine under their canonical water rules.

void getCorrel(molSys::PointCloud<molSys::Point<double>, double> &yCloud, const std::vector<std::vector<int>> &nList, bool isSlice = false, int coordinationNumber = 4)

Function for getting the bond order correlations \(c_{ij}\) (or \(a_{ij}\) in some treatments) according to the CHILL algorithm.

Parameters:
  • yCloud[inout] The output molSys::PointCloud

  • nList[in] The row-ordered neighbour list, by ID. The first element of each row is the particle ID, followed by the IDs of the neighbours

  • isSlice[in] This decides whether there is a slice or not

  • coordinationNumber[in] How many nearest neighbours the bond sum runs over. The default of four is the coordination CHILL is defined and validated against (tetrahedral water); other values reuse the c_ij machinery for differently coordinated systems, and a non-positive value gives each atom its own count from its neighbour-list row. The ice-classification tables in getIceType remain four-bond rules

void getIceTypeNoPrint(molSys::PointCloud<molSys::Point<double>, double> &yCloud, const std::vector<std::vector<int>> &nList, bool isSlice = false)

Function that classifies every particle’s molSys::atom_state_type ice type, according to the CHILL algorithm.

Does not print out the information.

Parameters:
  • yCloud[inout] The output molSys::PointCloud

  • isSlice[in] This decides whether there is a slice or not

  • nList[in] Row-ordered neighbour list by atom ID

void getIceType(molSys::PointCloud<molSys::Point<double>, double> &yCloud, const std::vector<std::vector<int>> &nList, std::string path, int firstFrame, bool isSlice = false, std::string outputFileName = "chill.txt")

Function that classifies every particle’s molSys::atom_state_type ice type, according to the CHILL algorithm.

Parameters:
  • yCloud[inout] The output molSys::PointCloud

  • nList[in] Row-ordered neighbour list by atom ID

  • path[in] Path to the output directory to which ice types are written out to

  • firstFrame[in] First frame to be analyzed

  • isSlice[in] This decides whether there is a slice or not

  • outputFileName[in] Name of the output file, to which the ice types will be written out.

void getCorrelPlus(molSys::PointCloud<molSys::Point<double>, double> &yCloud, const std::vector<std::vector<int>> &nList, bool isSlice = false, int coordinationNumber = 4)

Gets c_ij and then classifies bond types according to the CHILL+ algorithm.

coordinationNumber as in getCorrel: four is the validated CHILL+ water scheme, non-positive keeps each atom’s whole neighbour row

void getIceTypePlus(molSys::PointCloud<molSys::Point<double>, double> &yCloud, const std::vector<std::vector<int>> &nList, std::string path, int firstFrame, bool isSlice = false, std::string outputFileName = "chillPlus.txt")

Classifies each atom according to the CHILL+ algorithm.

void getIceTypePlusNoPrint(molSys::PointCloud<molSys::Point<double>, double> &yCloud, const std::vector<std::vector<int>> &nList, bool isSlice = false)

CHILL+ ice types on the cloud. Does not write a file.

std::vector<double> getq6(molSys::PointCloud<molSys::Point<double>, double> &yCloud, const std::vector<std::vector<int>> &nList, bool isSlice = false)

q6 can distinguish between water and ice.

Use this for the largest ice cluster

void reclassifyWater(molSys::PointCloud<molSys::Point<double>, double> &yCloud, std::vector<double> &q6)

‘Test’ condition for classifying hexagonal ice using averaged q6 and q3 Checks water According to https://!pubs.rsc.org/en/content/articlehtml/2011/cp/c1cp22167a Gets c_ij and then classifies bond types according to the CHILL+ algorithm

int printIceType(molSys::PointCloud<molSys::Point<double>, double> &yCloud, std::string path, int firstFrame, bool isSlice = false, std::string outputFileName = "superChill.txt")

Prints out the iceType for a particular frame onto the terminal.

bool isInterfacial(molSys::PointCloud<molSys::Point<double>, double> &yCloud, const std::vector<std::vector<int>> &nList, int iatom, int num_staggrd, int num_eclipsd, bool chillPlus = false)

Interfacial ice.

Moore CHILL uses a neighbour with exactly two staggered bonds; Nguyen CHILL+ uses a neighbour with more than one. Pass chillPlus=true for the latter.

int numStaggered(molSys::PointCloud<molSys::Point<double>, double> &yCloud, const std::vector<std::vector<int>> &nList, int jatom)

Finds the number of staggered bonds for a given atom of index jatom.

SteinhardtQl steinhardtQl(const molSys::PointCloud<molSys::Point<double>, double> &yCloud, const std::vector<std::vector<int>> &nList, int orderL)

Local and neighbour-averaged Steinhardt parameters of degree 3, 4 or 6.

Local ql is Steinhardt, Nelson and Ronchetti; qlBar is the Lechner-Dellago average of q_lm over the particle and its neighbours. The compute path flattens the neighbour list to CSR so the same kernel can run on the host (OpenMP), across MPI ranks (atom split plus Allgatherv of q_lm), or under OpenMP target offload when the build provides a device.

std::vector<std::complex<double>> spheriHarmo(int orderL, std::array<double, 2> radialCoord)
std::array<double, 2> radialCoord(std::array<double, 3> cartCoord)
std::vector<std::complex<double>> lookupTableQ3Vec(std::array<double, 2> angles)

Lookup table for Q3.

std::complex<double> lookupTableQ3(int m, std::array<double, 2> angles)

Lookup table for Q3 (m=0 to m=6)

std::vector<std::complex<double>> lookupTableQ4Vec(std::array<double, 2> angles)

Lookup table for Q4.

std::complex<double> lookupTableQ4(int m, std::array<double, 2> angles)

Lookup table for Q4 (m=0 to m=8)

std::vector<std::complex<double>> lookupTableQ6Vec(std::array<double, 2> angles)

Lookup table for Q6.

std::vector<std::complex<double>> lookupTableQ8Vec(std::array<double, 2> angles)

Lookup table for Q8.

std::complex<double> lookupTableQ8(int m, std::array<double, 2> angles)

Lookup table for Q8 (m=0 to m=16)

std::complex<double> lookupTableQ6(int m, std::array<double, 2> angles)

Lookup table for Q6 (m=0 to m=12)

struct YlmAtom
#include <bop.hpp>

This contains a complex vector of length \(2l+1\).

Contains specifically:

  • A complex vector, projecting the orientational structure of a single pair with each of the four nearest neighbours, on the basis of spherical harmonics

struct QlmAtom
#include <bop.hpp>

This is the local orientational bond order parameter \(q_{lm}\), of length \(2l+1\).

This complex vector is averaged over the four nearest neighbours, according to the following equation:

\[q_{lm}(i) = \frac{1}{N_b(i)} \Sigma_{j=1}^{N_b(i)} Y_{lm}(r_{ij}) \]

Here, \(N_b(i)=4\) is the number of nearest neighbours for the molecule \(i\). This struct contains specifically:

  • A complex vector of length \(2l+1\), calculated according to the equation above

struct BondClassifier
#include <bop.hpp>

One rule set for classifying bond correlations \(c_{ij}\).

A bond is staggered when \(c_{ij} \le\) staggeredMax, eclipsed when it falls in [eclipsedMin, eclipsedMax], and out of range otherwise. The CHILL and CHILL+ water rules are two instances; other hydrogen-bonded or tetrahedral materials register their own thresholds and coordination.

struct SteinhardtQl
#include <bop.hpp>

Per-particle Steinhardt order parameters of a single degree \(l\).

Holds both the local parameter and its neighbour-averaged counterpart. The averaged form of Lechner and Dellago folds in the second coordination shell, which separates the distributions of competing structures far more cleanly than the local form alone.

int atomIndex
std::vector<int> neighListIndex

This is the index according to pointCloud.

bool inGraph = true

Contains the INDICES (not the atomIDs) of the neighbouring vertices.

std::vector<Vertex> pts
std::vector<std::vector<int>> rings

Collection of vertices.

The index of each should be the same as that in pointCloud

std::vector<std::vector<int>> ringNetwork(const std::vector<std::vector<int>> &nList, int maxDepth)

Returns a vector of vectors containing the rings (of all sizes), by atom index, given the neighbour list also by index (preferably the hydrogen-bonded neighbour list).

Internally uses the Graph and Vertex objects.

Graph populateGraphFromNListID(molSys::PointCloud<molSys::Point<double>, double> &yCloud, const std::vector<std::vector<int>> &neighHbondList)

Creates a graph object and fills it with the information from a neighbour list and pointCloud created before.

NOTE: the neighbourListIndex contains the indices and NOT the atom IDs as in the neighbour list

Graph populateGraphFromIndices(const std::vector<std::vector<int>> &nList)

Creates a graph object and fills it with the information from a neighbour list of INDICES NOT ATOM IDs created before.

NOTE: the neighbourListIndex contains the indices and NOT the atom IDs as in the neighbour list

void restoreEdgesFromIndices(Graph &fullGraph, const std::vector<std::vector<int>> &nList)

Re-fills the neighbour lists of a graph object from a neighbour list of INDICES NOT ATOM IDs created before.

NOTE: the neighbourListIndex contains the indices and NOT the atom IDs as in the neighbour list

Graph countAllRingsFromIndex(const std::vector<std::vector<int>> &neighHbondList, int maxDepth)

Creates a vector of vectors of all possible rings.

void removeNonSPrings(Graph &fullGraph)

Removes the non-SP rings, using the Franzblau shortest path criterion.

int findRings(Graph &fullGraph, int v, std::vector<int> &visited, int maxDepth, int depth, int root = -1)

Main function that searches for all rings.

int shortestPath(Graph &fullGraph, int v, int goal, std::vector<int> &path, std::vector<int> &visited, int maxDepth, int depth = 1)

Calculates the shortest path.

Graph clearGraph(Graph &currentGraph)

Function for clearing vectors in Graph after multiple usage.

explicit RingUpdater(int maxDepth)
~RingUpdater()
RingUpdater(RingUpdater&&) noexcept
RingUpdater &operator=(RingUpdater&&) noexcept
RingUpdater(const RingUpdater&) = delete
RingUpdater &operator=(const RingUpdater&) = delete
const std::vector<std::vector<int>> &update(const std::vector<std::vector<int>> &nList)

Primitive rings for this frame’s neighbour list (row-ordered, by index, first element of each row the vertex itself)

int lastRecomputedSources() const

Sources re-enumerated by the last update; the full vertex count on the first frame, zero when nothing changed.

int lastBallsRefreshed() const

Vertices whose bounded balls were rebuilt on the last update.

struct Vertex
#include <franzblau.hpp>

This is a collection of elements, for each point, required for graph traversal.

Contains specifically the members:

  • atomIndex : This is the index according to the PointCloud.

  • neighListIndex : A vector of indices (not IDs) of the neighboring vertices.

  • inGraph : Bool qualifier, which is true by default. Setting it to false removes the vertex from the graph.

struct Graph
#include <franzblau.hpp>

This is a per-frame object, containing all the vertices for the particular frame, along with the vector of rings generated.

Contains specifically the members:

  • pts : Collection of vertices. The index of each should be the index according to the PointCloud.

  • rings : A row-ordered vector of vectors for the rings generated, containing the indices (not IDs) of each member of the rings.

class RingUpdater
#include <franzblau.hpp>

Exact frame-to-frame maintenance of the primitive ring network.

Consecutive trajectory frames share almost all of their bond topology. Rings are stored partitioned by their lowest-indexed member, and on a new frame only sources within a proven locality radius of a changed edge are re-enumerated: a ring’s members and every path that can decide its primitivity lie within a bounded neighbourhood of its source, so a source far enough from every change keeps its rings unchanged. The output equals a full recomputation exactly, at a cost that scales with the edge churn between frames rather than with system size.

enum class strucType

Values:

enumerator unclassified

The ring is unclassified, which may be either water or a deformed type which cannot be classified by the criteria.

enumerator DDC

The ring belongs to a double-diamond cage (DDC).

enumerator HCbasal

The ring belongs only to a hexagonal cage (HC).

Specifically, the ring is purely a basal ring of an HC.

enumerator HCprismatic

The ring belongs only to a hexagonal cage (HC); specifically the ring is purely a prismatic ring of an HC.

It is not shared by a DDC.

enumerator bothBasal

The ring belongs to both a DDC and HC.

It is a ‘mixed’ ring. The ring is also one of the basal rings of the HC of which it is part. A mixed ring must be a peripheral ring of the DDC of which it is part by definition.

enumerator bothPrismatic

The ring belongs to both a DDC and HC and is, thus, a ‘mixed’ ring.

The ring is also one of the prismatic rings of the HC of which it is part. A mixed ring must be a peripheral ring of the DDC of which it is part by definition (can never be an equatorial ring of a DDC and also be part of an HC).

enumerator Prism

The ring belongs to a prism block, classified according to the prism identification scheme.

enumerator deformedPrism
enumerator mixedPrismRing
int topoUnitMatchingBulk(std::string path, const std::vector<std::vector<int>> &rings, const std::vector<std::vector<int>> &nList, molSys::PointCloud<molSys::Point<double>, double> &yCloud, int firstFrame, bool printClusters, bool onlyTetrahedral, std::string templatePath = "templates")

Topological unit matching for bulk water.

If printClusters is true, individual clusters of connected cages are printed.

Eigen::MatrixXd buildRefHC(const std::string &fileName)

Build a reference Hexagonal cage, reading in from a template XYZ file.

Eigen::MatrixXd buildRefDDC(const std::string &fileName)

Build a reference Double-Diamond cage, reading in from a template XYZ file.

int shapeMatchHC(molSys::PointCloud<molSys::Point<double>, double> &yCloud, const Eigen::MatrixXd &refPoints, cage::Cage cageUnit, const std::vector<std::vector<int>> &rings, const std::vector<std::vector<int>> &nList, std::vector<double> &quat, double &rmsd)

Shape-matching for a target HC.

int shapeMatchDDC(molSys::PointCloud<molSys::Point<double>, double> &yCloud, const Eigen::MatrixXd &refPoints, const std::vector<cage::Cage> &cageList, int cageIndex, const std::vector<std::vector<int>> &rings, std::vector<double> &quat, double &rmsd)

Shape-matching for a target DDC.

int updateRMSDatom(const std::vector<std::vector<int>> &rings, cage::Cage cageUnit, double rmsd, std::vector<double> &rmsdPerAtom, std::vector<int> &noOfCommonAtoms, const std::vector<cage::iceType> &atomTypes)

Calulate the RMSD for each ring, using RMSD values (rmsd) obtained from the shape-matching of each cage.

int averageRMSDatom(std::vector<double> &rmsdPerAtom, std::vector<int> &noOfCommonAtoms)

Average the RMSD per atom.

std::vector<cage::Cage> topoBulkCriteria(std::string path, const std::vector<std::vector<int>> &rings, const std::vector<std::vector<int>> &nList, molSys::PointCloud<molSys::Point<double>, double> &yCloud, int firstFrame, int &numHC, int &numDDC, std::vector<ring::strucType> &ringType)

Topological network methods Finds the HCs and DDCs for the system.

int clusterCages(molSys::PointCloud<molSys::Point<double>, double> &yCloud, std::string path, const std::vector<std::vector<int>> &rings, const std::vector<cage::Cage> &cageList, int numHC, int numDDC)

Clustering Clusters cages using the Stillinger algorithm and prints out individual XYZ files of clusters.

std::vector<int> atomsFromCages(const std::vector<std::vector<int>> &rings, const std::vector<cage::Cage> &cageList, const std::vector<int> &clusterCages)

Gets the atoms in the cages of a given cluster.

std::vector<std::vector<int>> getSingleRingSize(const std::vector<std::vector<int>> &rings, int ringSize)

Returns a vector of vectors of rings of a single size.

bool hasCommonElements(std::vector<int> ring1, std::vector<int> ring2)

Check to see if two vectors have common elements or not True, if common elements are present and false if there are no common elements.

bool compareRings(std::vector<int> ring1, std::vector<int> ring2)

Compares two disordered vectors and checks to see if they contain the same elements.

bool findTripletInRing(const std::vector<int> &ring, const std::vector<int> &triplet)

Searches a particular ring for a triplet.

bool commonElementsInThreeRings(const std::vector<int> &ring1, const std::vector<int> &ring2, const std::vector<int> &ring3)

Common elements in 3 rings.

std::vector<int> findsCommonElements(const std::vector<int> &ring1, const std::vector<int> &ring2)

Returns the common elements of two rings.

int clearRingList(std::vector<std::vector<int>> &rings)

Erases memory for a vector of vectors for a list of rings.

int assignPolygonType(const std::vector<std::vector<int>> &rings, std::vector<int> &atomTypes, const std::vector<int> &nRings)

Assign an atomType (equal to the number of nodes in the ring) given n-membered rings.

molSys::PointCloud<molSys::Point<double>, double> getPointCloudOneAtomType(molSys::PointCloud<molSys::Point<double>, double> &yCloud, molSys::PointCloud<molSys::Point<double>, double> &outCloud, int atomTypeI, bool isSlice = false, std::array<double, 3> coordLow = std::array<double, 3>{0, 0, 0}, std::array<double, 3> coordHigh = std::array<double, 3>{0, 0, 0})

Given a pointCloud containing certain atom types, this returns a pointCloud containing atoms of only the desired type.

void moleculesInSingleSlice(molSys::PointCloud<molSys::Point<double>, double> &yCloud, bool clearPreviousSliceSelection = true, std::array<double, 3> coordLow = std::array<double, 3>{0, 0, 0}, std::array<double, 3> coordHigh = std::array<double, 3>{0, 0, 0})

Given a pointCloud set the inSlice bool for every atom, if the molecules are inside the specified (single) region.

If even one atom of a molecule is inside the region, then all atoms of that molecule will be inside the region (irrespective of type)

void atomsInSingleSlice(molSys::PointCloud<molSys::Point<double>, double> &yCloud, bool clearPreviousSliceSelection = true, std::array<double, 3> coordLow = std::array<double, 3>{0, 0, 0}, std::array<double, 3> coordHigh = std::array<double, 3>{0, 0, 0})

Given a pointCloud set the inSlice bool for every atom, if the atoms are inside the specified (single) region.

Does not handle atoms in molecules straddling the boundary

void setAtomsWithSameMolID(molSys::PointCloud<molSys::Point<double>, double> &yCloud, const std::unordered_multimap<int, int> &molIDAtomIDmap, int molID, bool inSliceValue = true)

Given a particular molecule ID and a pointCloud set the inSlice bool for all atoms, with that molecule ID.

void getEdgeMoleculesInRings(const std::vector<std::vector<int>> &rings, molSys::PointCloud<molSys::Point<double>, double> &oCloud, molSys::PointCloud<molSys::Point<double>, double> &yCloud, std::array<double, 3> coordLow, std::array<double, 3> coordHigh, bool identicalCloud = false)

Select edge molecules and atoms which are part of rings, such that rings formed with even one atom in the slice will be included in the selection Modifies the inSlice bool of a given PointCloud (this may be the same) as the given oxygen atom PointCloud which was used to construct the neighbour list used to construct the rings vector of vectors.

We assume that the PointCloud structs have the inSlice bool values set according to the presence of the atom in the slice (this can be done using the gen::moleculesInSingleSlice function.

void printSliceGetEdgeMoleculesInRings(std::string path, const std::vector<std::vector<int>> &rings, molSys::PointCloud<molSys::Point<double>, double> &oCloud, molSys::PointCloud<molSys::Point<double>, double> &yCloud, std::array<double, 3> coordLow, std::array<double, 3> coordHigh, bool identicalCloud = false)

Master function for selecting edge molecules and atoms which are part of rings, such that rings formed with even one atom in the slice will be included in the selection Modifies the inSlice bool of a given PointCloud (this may be the same) as the given oxygen atom PointCloud which was used to construct the neighbour list used to construct the rings vector of vectors (calls ring::getEdgeMoleculesInRings) Prints out molecule IDs individually of molecules in the slice, and also prints out a LAMMPS data file of just the molecules and atoms in the slice.

std::vector<int> findPrisms(const std::vector<std::vector<int>> &rings, std::vector<strucType> &ringType, int &nPerfectPrisms, int &nImperfectPrisms, const std::vector<std::vector<int>> &nList, molSys::PointCloud<molSys::Point<double>, double> &yCloud, std::vector<double> &rmsdPerAtom, bool doShapeMatching = false)

Find out which rings are prisms.

Returns a vector containing all the ring IDs which are prisms

bool basalPrismConditions(const std::vector<std::vector<int>> &nList, std::vector<int> &basal1, std::vector<int> &basal2)

Tests whether two rings are basal rings (true) or not (false) for a prism (strict criterion)

bool relaxedPrismConditions(const std::vector<std::vector<int>> &nList, std::vector<int> &basal1, std::vector<int> &basal2)

Reduced criterion: Two candidate basal rings of a prism block should have at least one bond between them.

bool discardExtraTetragonBlocks(std::vector<int> &basal1, std::vector<int> &basal2, molSys::PointCloud<molSys::Point<double>, double> &yCloud)

Checks whether two 4-membered rings are parallel in one dimension or not to prevent overcounting.

std::vector<std::vector<int>> keepAxialRingsOnly(const std::vector<std::vector<int>> &rings, molSys::PointCloud<molSys::Point<double>, double> &yCloud)

Saves only axial rings out of all possible rings.

int prismAnalysis(std::string path, const std::vector<std::vector<int>> &rings, const std::vector<std::vector<int>> &nList, molSys::PointCloud<molSys::Point<double>, double> &yCloud, int maxDepth, int &atomID, int firstFrame, int currentFrame, bool doShapeMatching = false)

Find out which rings are prisms, looping through all ring sizes upto the maxDepth The input ringsAllSizes array has rings of every size.

int assignPrismType(const std::vector<std::vector<int>> &rings, const std::vector<int> &listPrism, int ringSize, const std::vector<ring::strucType> &ringType, std::vector<int> &atomTypes, std::vector<ring::strucType> &atomState)

Assign an atomType (equal to the number of nodes in the ring) given a vector with a list of indices of rings comprising the prisms.

int deformedPrismTypes(const std::vector<ring::strucType> &atomState, std::vector<int> &atomTypes, int maxDepth)

Get the atom type values for deformed prisms.

int rmAxialTranslations(molSys::PointCloud<molSys::Point<double>, double> &yCloud, int &atomID, int firstFrame, int currentFrame)

Shift the entire ice nanotube and remove axial translations.

int polygonRingAnalysis(std::string path, std::vector<std::vector<int>> rings, std::vector<std::vector<int>> nList, molSys::PointCloud<molSys::Point<double>, double> &yCloud, int maxDepth, double sheetArea, int firstFrame)

Find out which rings are prisms, looping through all ring sizes upto the maxDepth The input ringsAllSizes array has rings of every size.

enum class cageType

Values:

enumerator HexC

The type for a hexagonal cage.

enumerator DoubleDiaC

The type for a double-diamond cage.

enum class iceType

Values:

enumerator dummy

Type for an atom which does not belong to any kind of cage.

enumerator hc

Type for an atom which belongs to an HC.

enumerator ddc

Type for an atom which belongs to a DDC.

enumerator mixed

Type for an atom which is part of a mixed ring, shared by both a DDC and an HC.

enumerator pnc
enumerator mixed2
cageType type
std::vector<int> rings

type of the cage : can be DDC or HC

struct Cage
#include <cage.hpp>

This contains a cage, with the constituent rings.

Contains specifically the members:

  • Cage classifier or qualifier, for each cage (can be a DDC or HC)

  • Vector of rings in the cage

std::vector<std::vector<int>> populateHbonds(std::string filename, molSys::PointCloud<molSys::Point<double>, double> &yCloud, const std::vector<std::vector<int>> &nList, int targetFrame, int Htype, double distCutoff = 2.42, double angleCutoff = 30.0)

Create a vector of vectors (similar to the neighbour list conventions) containing the hydrogen bond connectivity information.

Decides the existence of the hydrogen bond depending on the O&#8212;O and O&#8212;H vectors from the neighbour list already constructed. The geometric criterion defaults to the water values (acceptor&#8212;H distance below 2.42 Angstrom, O-O-H angle below 30 degrees); other hydrogen-bonded systems pass their own thresholds

std::vector<std::vector<int>> populateHbondsWithInputClouds(molSys::PointCloud<molSys::Point<double>, double> &yCloud, molSys::PointCloud<molSys::Point<double>, double> &hCloud, const std::vector<std::vector<int>> &nList, double distCutoff = 2.42, double angleCutoff = 30.0)

Create a vector of vectors (similar to the neighbour list conventions) containing the hydrogen bond connectivity information.

Decides the existence of the hydrogen bond depending on the O&#8212;O and O&#8212;H vectors from the neighbour list already constructed, taking a PointCloud for the H atoms as input

double getHbondDistanceOH(const molSys::PointCloud<molSys::Point<double>, double> &oCloud, const molSys::PointCloud<molSys::Point<double>, double> &hCloud, int oAtomIndex, int hAtomIndex)

Calculates the distance of the hydrogen bond between O and H (of different atoms), given the respective pointClouds and the indices to each atom.

std::vector<std::vector<int>> populateBonds(const std::vector<std::vector<int>> &nList, const molSys::PointCloud<molSys::Point<double>, double> &yCloud)

Create a vector of vectors containing bond connectivity information.

May contain duplicates! Gets the bond information from the vector of vectors containing the neighbour list by index

std::vector<std::vector<int>> populateBonds(const std::vector<std::vector<int>> &nList, const molSys::PointCloud<molSys::Point<double>, double> &yCloud, const std::vector<cage::iceType> &atomTypes)

Create a vector of vectors containing bond connectivity information Gets the bond information from the vector of vectors containing the neighbour list by index.

Bonds between dummy atoms are not filled.

std::vector<std::vector<int>> createBondsFromCages(const std::vector<std::vector<int>> &rings, std::vector<cage::Cage> &cageList, cage::cageType type, int &nRings)

Creates a vector of vectors containing bond connectivity information from the rings vector of vectors and cage information.

std::vector<std::vector<int>> trimBonds(std::vector<std::vector<int>> bonds)

Remove duplicate bonds.

std::vector<std::string> getInpFileList(std::string inputFolder)

Get file list inside the input folder.

int nLammpsFrames(const std::string &filename)

Number of ITEM: TIMESTEP frames in a LAMMPS dump, or 0 if the file cannot be read.

The first full count per path walks the file once and later reads seek, matching chemfiles Trajectory::nsteps and readcon’s frame-offset table. Sequential load_frame walks reuse a live cursor the way LAMMPS ReaderNative does on rerun.

void dropLammpsDumpIndex(const std::string &filename)

Drop a cached dump session (tests that rewrite a path in place).

void forEachLammpsFrame(const std::string &filename, int first, int last, int typeFilter, const std::function<void(int, molSys::PointCloud<molSys::Point<double>, double>&)> &fn, int nThreads = 0)

Call fn(frame, cloud) for each frame in [first, last] (1-based, inclusive).

last <= 0 means every ITEM: TIMESTEP. typeFilter <= 0 keeps every atom. nThreads <= 0 uses the OpenMP default; 1 is serial. Each worker opens its own handle and seeks the shared offset table. Incremental RingUpdater / AffiliationUpdater state cannot be shared across workers: use the batch classifiers.

molSys::PointCloud<molSys::Point<double>, double> readLammpsTrj(std::string filename, int targetFrame, molSys::PointCloud<molSys::Point<double>, double> &yCloud, bool isSlice = false, std::array<double, 3> coordLow = std::array<double, 3>{0, 0, 0}, std::array<double, 3> coordHigh = std::array<double, 3>{0, 0, 0})

Function for reading in a specified frame (frame number and not timestep value)

molSys::PointCloud<molSys::Point<double>, double> readLammpsTrjO(std::string filename, int targetFrame, molSys::PointCloud<molSys::Point<double>, double> &yCloud, int typeO, bool isSlice = false, std::array<double, 3> coordLow = std::array<double, 3>{0, 0, 0}, std::array<double, 3> coordHigh = std::array<double, 3>{0, 0, 0})

Function for reading in a specified frame (frame number and not timestep value) / This only reads in oxygen atoms.

molSys::PointCloud<molSys::Point<double>, double> readLammpsTrjreduced(std::string filename, int targetFrame, molSys::PointCloud<molSys::Point<double>, double> &yCloud, int typeI, bool isSlice = false, std::array<double, 3> coordLow = std::array<double, 3>{0, 0, 0}, std::array<double, 3> coordHigh = std::array<double, 3>{0, 0, 0})

Function that reads in only atoms pf the desired type and ignores all atoms which are not in the slice as well.

molSys::PointCloud<molSys::Point<double>, double> readXYZ(std::string filename)

Function for reading in atom coordinates from an XYZ file.

std::vector<std::vector<int>> readBonds(std::string filename)

Reads bonds into a vector of vectors from a file with a specific format.

inline bool atomInSlice(double x, double y, double z, std::array<double, 3> coordLow, std::array<double, 3> coordHigh)
int largestIceCluster(std::string path, molSys::PointCloud<molSys::Point<double>, double> &yCloud, molSys::PointCloud<molSys::Point<double>, double> &iceCloud, const std::vector<std::vector<int>> &nList, std::vector<bool> &isIce, std::vector<int> &clusterID, std::vector<int> &nClusters, std::unordered_map<int, int> &indexNumber, int firstFrame)

Finds the largest ice cluster.

int singleClusterLinkedList(molSys::PointCloud<molSys::Point<double>, double> &iceCloud, const std::vector<std::vector<int>> &nList, std::vector<int> &linkedList)

Get the linked list of a cluster, given by iceCloud, for a single cluster.

Required for cluster re-centering

int clusterAnalysis(std::string path, molSys::PointCloud<molSys::Point<double>, double> &iceCloud, molSys::PointCloud<molSys::Point<double>, double> &yCloud, const std::vector<std::vector<int>> &nList, std::vector<std::vector<int>> &iceNeighbourList, double cutoff, int firstFrame, std::string bopAnalysis = "q6")

Does the cluster analysis of ice particles in the system.

Returns a pointCloud of the largest ice cluster. The neighbour list returned is BY INDEX of the largest ice cluster pointCloud.

int recenterClusterCloud(molSys::PointCloud<molSys::Point<double>, double> &iceCloud, const std::vector<std::vector<int>> &nList)

Recenters the coordinates of a pointCloud.

double pi = std::numbers::pi

Uses Boost to get the value of pi.

inline double radDeg(double angle)

Inline function for converting radians->degrees.

Parameters:

angle[in] The input angle, in radians

Returns:

The input angle, in degrees

double eigenVecAngle(std::vector<double> OO, std::vector<double> OH)

Eigen function for getting the angle (in radians) between the O&#8212;O and O-H vectors.

double getAverageWithoutOutliers(std::vector<double> inpVec)

Get the average, after excluding the outliers, using quartiles.

inline double calcMedian(std::vector<double> *input)

Inline generic function for calculating the median given a vector of the values.

Parameters:
  • yCloud[in] The input PointCloud, which contains the particle coordinates, simulation box lengths etc.

  • input[in] The input vector with the values

Returns:

The median value

inline 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)
inline double periodicDistSq(const molSys::PointCloud<molSys::Point<double>, double> &yCloud, int iatom, int jatom)

Inline generic function for obtaining the unwrapped periodic distance between two particles, whose indices (not IDs) have been given.

Parameters:
  • yCloud[in] The input PointCloud, which contains the particle coordinates, simulation box lengths etc.

  • iatom[in] The index of the \( i^{th} \) atom.

  • jatom[in] The index of the \( j^{th} \) atom.

Returns:

The unwrapped periodic distance.

inline 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, whose indices (not IDs) have been given.

Parameters:
  • yCloud[in] The input PointCloud, which contains the particle coordinates, simulation box lengths etc.

  • iatom[in] The index of the \( i^{th} \) atom.

  • jatom[in] The index of the \( j^{th} \) atom.

Returns:

The unwrapped periodic distance.

inline double unWrappedDistFromPoint(const molSys::PointCloud<molSys::Point<double>, double> &yCloud, int iatom, std::vector<double> singlePoint)

Inline generic function for obtaining the unwrapped periodic distance between one particle and another point, whose index has been given.

Parameters:
  • yCloud[in] The input PointCloud, which contains the particle coordinates, simulation box lengths etc.

  • iatom[in] The index of the \( i^{th} \) atom.

  • singlePoint[in] Vector containing coordinate values

Returns:

The unwrapped periodic distance.

inline 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 PBCs, whose indices (not IDs) have been given.

Parameters:
  • yCloud[in] The input PointCloud, which contains the particle coordinates, simulation box lengths etc.

  • iatom[in] The index of the \( i^{th} \) atom.

  • jatom[in] The index of the \( j^{th} \) atom.

Returns:

The wrapped distance.

inline 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 dimension.

The indices (not IDs) of the particles have been given.

Parameters:
  • yCloud[in] The input PointCloud, which contains the particle coordinates, simulation box lengths etc.

  • iatom[in] The index of the \( i^{th} \) atom.

  • jatom[in] The index of the \( j^{th} \) atom.

Returns:

The unwrapped relative distances for each dimension.

inline 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 entire Point objects have been passed.

Parameters:
  • a[in] The input Point for A.

  • b[in] The input Point for B.

Returns:

True if the atom ID of A is less than the atom ID of B

int prettyPrintYoda(const molSys::PointCloud<molSys::Point<double>, double> &yCloud, std::string outFile)

Generic function for printing all the struct information.

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)

double angDistDegQuaternions(std::vector<double> quat1, std::vector<double> quat2)

Function for getting the angular distance between two quaternions.

Returns the result in degrees

inline std::vector<std::string> tokenizer(std::string line)

Function for tokenizing line strings into words (strings) delimited by whitespace.

This returns a vector with the words in it.

Parameters:

line[in] The string containing the line to be tokenized

inline std::vector<double> tokenizerDouble(std::string line)

Function for tokenizing line strings into a vector of doubles.

Parameters:

line[in] The string containing the line to be tokenized

inline std::vector<int> tokenizerInt(std::string line)

Function for tokenizing line strings into a vector of ints.

Parameters:

line[in] The string containing the line to be tokenized

inline bool file_exists(const std::string &name)

Function for checking if a file exists or not.

Parameters:

name[in] The name of the file

inline 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 \(2l+1\).

Parameters:
  • v[in] The complex vector to be normalized, of length \(2l+1\)

  • l[in] A free integer parameter

  • neigh[in] The number of nearest neighbours

Returns:

length \(2l+1\), normalized by the number of nearest neighbours

int rdf2Danalysis_AA(std::string path, std::vector<double> &rdfValues, const molSys::PointCloud<molSys::Point<double>, double> &yCloud, double cutoff, double binwidth, int firstFrame, int finalFrame)

Main function for calculating the RDF for the same type of particle: calls other functions for initializing, sampling and normalizing the RDF.

std::vector<int> sampleRDF_AA(const molSys::PointCloud<molSys::Point<double>, double> &yCloud, double cutoff, double binwidth, int nbin)

Samples the RDF histogram at every step.

int normalizeRDF(int nopA, std::vector<double> &rdfValues, std::vector<int> histogram, double binwidth, int nbin, std::vector<double> volumeLengths, int nIter)

Normalize the histogram.

std::vector<double> getSystemLengths(const molSys::PointCloud<molSys::Point<double>, double> &yCloud)

Gets the lengths of the volume slice of the quasi-two-dimensional system.

double getPlaneArea(std::vector<double> volumeLengths)

Gets the plane area from the volume lengths vector.

enum class bond_type

Values:

enumerator staggered

The bond is a staggered bond, according to the \(a(i,j)\) or \(c(i,j)\) value.

enumerator eclipsed

The bond is an eclipsed bond.

enumerator out_of_range

The bond cannot be classified as either staggered or eclipsed.

enum class atom_state_type

Values:

enumerator cubic

Ic, or particle type signifying Cubic Ice.

enumerator hexagonal

Ih, or particle type signifying Hexagonal Ice.

enumerator water

Liquid/amorphous phase.

enumerator interfacial

Interfacial ice: ice-like molecules which do not fulfill the strict criteria of the Ic or Ih phases.

enumerator clathrate

Clathrate ice phase.

enumerator interClathrate

Interfacial clathrate ice phase.

enumerator unclassified

Not classified into any other category.

enumerator reCubic

Reclassified as cubic ice, according to the \(q_6\) order parameter.

enumerator reHex

Reclassified as hexagonal ice, according to the \(q_6\) order parameter.

bond_type classifier
double c_value

Classifier according to CHILL, CHILL+ etc.

int type = 0
int molID = 0
int atomID = 0
T x = 0

type ID, molID, atomID

T y = 0
T z = 0
std::vector<Result> c_ij

coordinates

atom_state_type iceType = atom_state_type::unclassified

Results (contains bond correlation type)

bool inSlice = true

Type of ice/water etc based on cij.

std::vector<S> pts
int currentFrame = 0

Collection of points.

int nop = 0

Current frame number.

std::vector<T> box

Number of atoms.

std::vector<T> boxLow

Periodic box lengths.

std::unordered_map<int, int> idIndexMap

xlo, ylo, zlo

std::unordered_map<int, int> createIDMolIDmap(molSys::PointCloud<molSys::Point<double>, double> &yCloud)

Creates an unordered map, with the atomIDs as keys and molecular IDs as the values.

std::unordered_multimap<int, int> createMolIDAtomIDMultiMap(molSys::PointCloud<molSys::Point<double>, double> &yCloud)

Creates an multimap with molecule IDs of the atoms as the keys and the atom IDs as the values.

More than one atom can have the same molecule ID

std::vector<std::vector<int>> hAtomMolList(molSys::PointCloud<molSys::Point<double>, double> &hCloud, molSys::PointCloud<molSys::Point<double>, double> &oCloud)

Returns a vector of vectors, which contains the molIDs in the first column, and the hydrogen atom indices (not atom IDs) in the row.

int searchMolList(const std::vector<std::vector<int>> &molList, int molIDtoFind)

This function searches a vector of vectors molList, for a particular molecular ID, and returns the index in molList.

molSys::PointCloud<molSys::Point<double>, double> clearPointCloud(molSys::PointCloud<molSys::Point<double>, double> &yCloud)

//! Function for clearing vectors in PointCloud after multiple usage

struct Result
#include <mol_sys.hpp>

This contains the bond classifier of enum class type bond_type, and the bond correlation factor.

Contains specifically the members:

  • Bond classifier or the type of the bond (staggered, eclipsed, out-of-range)

  • Bond correlation factor

template<CoordinateScalar T>
struct Point
#include <mol_sys.hpp>

This contains per-particle information.

Specifically

  • Type ID

  • Molecular ID

  • Atom ID

  • Coordinates

  • Neighbourlist

  • Bond correlation type of type Result

  • Type of atom_state_type iceType

  • In slice bool

template<typename S, CoordinateScalar T>
struct PointCloud
#include <mol_sys.hpp>

This contains a collection of points; contains information for a particular frame.

Specifically

  • A vector of Point structs

  • The current frame number

  • The number of particles in the current frame

  • A vector for the simulation box lengths in each dimension

  • A vector containing the absolute lower box coordinates

Headers

Every file under src/include/internal.

Header

Namespace

Role

mol_sys.hpp

molSys

Point, PointCloud, bond and ice enums

seams_input.hpp

sinp

LAMMPS / XYZ / chemfiles / readcon readers

seams_output.hpp

sout

dump, cage, ring, and cluster writers

neighbours.hpp

nneigh

cutoff, k-nearest, skin neighbour lists

bop.hpp

chill, sph

CHILL, CHILL+, q6, Steinhardt ql

franzblau.hpp

primitive

Franzblau primitive rings

ring.hpp

ring

ring helpers and strucType

topo_bulk.hpp

ring, prism3

HC / DDC search, bulk polygons

topo_one_dim.hpp

ring

ice-nanotube prisms

topo_two_dim.hpp

ring

monolayer polygons

cage.hpp

cage

Cage, cageType, iceType

cage_affiliation.hpp

ring

claim-free HC / DDC flags

cage_canon.hpp

cage

nauty canonical certificates

bulkTUM.hpp

tum3

topological unit matching

bond.hpp

bond

geometric hydrogen bonds

absOrientation.hpp

absor

Horn absolute orientation

pntCorrespondence.hpp

pntToPnt

reference / target point sets

shapeMatch.hpp

match

prism shape-matching

cluster.hpp

clump

Stillinger ice clusters

order_parameter.hpp

topoparam

height% and coverage area

rdf2d.hpp

rdf2

in-plane radial distribution

selection.hpp

gen, ring

type and slice selections

generic.hpp

gen

periodic distance, angles, medians

structure_desc.hpp

chill

SOAP, template overlay, linear classifier

voronoi_qlm.hpp

chill

Voronoi-weighted Steinhardt

ira_sofi.hpp

ira

IRA match and SOFI point groups

sphericart_ylm.hpp

seams::sphericart_ylm

batched Cartesian Y_lm

steinhardt_device.hpp

seams::steinhardt

host / MPI / offload Steinhardt kernel

simd_distance.hpp

seams

Highway periodic distance

pydseams.yoda and dseams.core register the C++ spellings from these headers. The generated pages are api/index.