LCOV - code coverage report
Current view: top level - metatomic - vesin.h (source / functions) Hit Total Coverage
Test: plumed test coverage Lines: 1 7 14.3 %
Date: 2026-06-05 17:04:24 Functions: 0 0 -

          Line data    Source code
       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
       2             : Copyright (c) 2024 The METATOMIC-PLUMED team
       3             : (see the PEOPLE-METATOMIC file at the root of this folder for a list of names)
       4             : 
       5             : See https://docs.metatensor.org/metatomic/ for more information about the
       6             : metatomic package that this module allows you to call from PLUMED.
       7             : 
       8             : This file is part of METATOMIC-PLUMED module.
       9             : 
      10             : The METATOMIC-PLUMED module is free software: you can redistribute it and/or modify
      11             : it under the terms of the GNU Lesser General Public License as published by
      12             : the Free Software Foundation, either version 3 of the License, or
      13             : (at your option) any later version.
      14             : 
      15             : The METATOMIC-PLUMED module is distributed in the hope that it will be useful,
      16             : but WITHOUT ANY WARRANTY; without even the implied warranty of
      17             : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      18             : GNU Lesser General Public License for more details.
      19             : 
      20             : You should have received a copy of the GNU Lesser General Public License
      21             : along with the METATOMIC-PLUMED module. If not, see <http://www.gnu.org/licenses/>.
      22             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
      23             : #ifndef __PLUMED_metatomic_vesin_h
      24             : #define __PLUMED_metatomic_vesin_h
      25             : /*INDENT-OFF*/
      26             : 
      27             : 
      28             : #include <cstddef>
      29             : #include <cstdint>
      30             : 
      31             : // clang-format off
      32             : #if defined(VESIN_SHARED)
      33             :     #if defined(VESIN_EXPORTS)
      34             :         #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
      35             :             #define VESIN_API __attribute__((visibility("default")))
      36             :         #elif defined(_MSC_VER)
      37             :             #define VESIN_API __declspec(dllexport)
      38             :         #else
      39             :             #define VESIN_API
      40             :         #endif
      41             :     #else
      42             :         #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
      43             :             #define VESIN_API __attribute__((visibility("default")))
      44             :         #elif defined(_MSC_VER)
      45             :             #define VESIN_API __declspec(dllimport)
      46             :         #else
      47             :             #define VESIN_API
      48             :         #endif
      49             :     #endif
      50             : #else
      51             :     #define VESIN_API
      52             : #endif
      53             : // clang-format on
      54             : 
      55             : #ifdef __cplusplus
      56             : namespace PLMD {
      57             : namespace metatomic {
      58             : namespace vesin {
      59             : extern "C" {
      60             : #endif
      61             : 
      62             : /// Algorithm to use for neighbor list construction
      63             : enum VesinAlgorithm {
      64             :     /// Automatically select algorithm based on system characteristics (number
      65             :     /// of points, size of the box, …), this is the default and recommended
      66             :     /// option.
      67             :     VesinAutoAlgorithm = 0,
      68             :     /// Brute-force O(n^2) algorithm, this requires minimum image convention in
      69             :     /// CUDA, and is not available on CPU.
      70             :     VesinBruteForce = 1,
      71             :     /// Cell list algorithm with O(n) scaling
      72             :     VesinCellList = 2,
      73             : };
      74             : 
      75             : /// Options for a neighbor list calculation
      76             : struct VesinOptions {
      77             :     /// Spherical cutoff, only pairs below this cutoff will be included
      78             :     double cutoff;
      79             :     /// Should the returned neighbor list be a full list (include both `i -> j`
      80             :     /// and `j -> i` pairs) or a half list (include only `i -> j`)?
      81             :     bool full;
      82             :     /// Should the neighbor list be sorted? If `true`, the returned pairs will
      83             :     /// be sorted by the first point index (`i`). The order of the second point
      84             :     /// index (`j`) and shifts in the list of pairs is unspecified.
      85             :     bool sorted;
      86             :     /// Which algorithm to use for the calculation
      87             :     VesinAlgorithm algorithm;
      88             : 
      89             :     /// Should the returned `VesinNeighborList` contain `shifts`?
      90             :     bool return_shifts;
      91             :     /// Should the returned `VesinNeighborList` contain `distances`?
      92             :     bool return_distances;
      93             :     /// Should the returned `VesinNeighborList` contain `vector`?
      94             :     bool return_vectors;
      95             : };
      96             : 
      97             : /// Device on which the data can be
      98             : enum VesinDeviceKind {
      99             :     /// Unknown device, used for default initialization and to indicate no
     100             :     /// allocated data.
     101             :     VesinUnknownDevice = 0,
     102             :     /// CPU device
     103             :     VesinCPU = 1,
     104             :     // CUDA device
     105             :     VesinCUDA = 2,
     106             : };
     107             : 
     108             : /// Represents a device on which data can be allocated.
     109             : ///
     110             : /// This structure combines the device type (CPU or CUDA) with an optional
     111             : /// device index. For CPU allocations, `device_id` is always 0. For CUDA
     112             : /// allocations, `device_id` specifies which GPU to use (e.g., 0, 1, 2).
     113             : ///
     114             : /// Example usage:
     115             : /// ```c
     116             : /// VesinDevice cpu { VesinCPU, 0 };
     117             : /// VesinDevice gpu0 { VesinCUDA, 0 };
     118             : /// VesinDevice gpu1 { VesinCUDA, 1 };
     119             : /// ```
     120             : struct VesinDevice {
     121             :     /// Type of the device
     122             :     VesinDeviceKind type;
     123             :     /// Device index (0 for CPU, GPU index for CUDA)
     124             :     int device_id = 0;
     125             : };
     126             : 
     127             : /// The actual neighbor list
     128             : ///
     129             : /// This is organized as a list of pairs, where each pair can contain the
     130             : /// following data:
     131             : ///
     132             : /// - indices of the points in the pair;
     133             : /// - distance between points in the pair, accounting for periodic boundary
     134             : ///   conditions;
     135             : /// - vector between points in the pair, accounting for periodic boundary
     136             : ///   conditions;
     137             : /// - periodic shift that created the pair. This is only relevant when using
     138             : ///   periodic boundary conditions, and contains the number of bounding box we
     139             : ///   need to cross to create the pair. If the positions of the points are `r_i`
     140             : ///   and `r_j`, the bounding box is described by a matrix of three vectors `H`,
     141             : ///   and the periodic shift is `S`, the distance vector for a given pair will
     142             : ///   be given by `r_ij = r_j - r_i + S @ H`.
     143             : ///
     144             : /// Under periodic boundary conditions, two atoms can be part of multiple pairs,
     145             : /// each pair having a different periodic shift.
     146             : struct VESIN_API VesinNeighborList {
     147             : #ifdef __cplusplus
     148           8 :     VesinNeighborList():
     149           0 :         length(0),
     150           0 :         device({VesinUnknownDevice, 0}),
     151           0 :         pairs(nullptr),
     152           0 :         shifts(nullptr),
     153           0 :         distances(nullptr),
     154           0 :         vectors(nullptr) {}
     155             : #endif
     156             : 
     157             :     /// Number of pairs in this neighbor list
     158             :     size_t length;
     159             :     /// Device used for the data allocations
     160             :     VesinDevice device;
     161             :     /// Array of pairs (storing the indices of the first and second point in the
     162             :     /// pair), containing `length` elements.
     163             :     size_t (*pairs)[2];
     164             :     /// Array of box shifts, one for each `pair`. This is only set if
     165             :     /// `options.return_pairs` was `true` during the calculation.
     166             :     int32_t (*shifts)[3];
     167             :     /// Array of pair distance (i.e. distance between the two points), one for
     168             :     /// each pair. This is only set if `options.return_distances` was `true`
     169             :     /// during the calculation.
     170             :     double* distances;
     171             :     /// Array of pair vector (i.e. vector between the two points), one for
     172             :     /// each pair. This is only set if `options.return_vector` was `true`
     173             :     /// during the calculation.
     174             :     double (*vectors)[3];
     175             : 
     176             :     /// Private pointer used to hold additional internal data
     177             :     void* opaque = nullptr;
     178             : 
     179             :     // TODO: custom memory allocators?
     180             : };
     181             : 
     182             : /// Free all allocated memory inside a `VesinNeighborList`, according the it's
     183             : /// `device`.
     184             : void VESIN_API vesin_free(struct VesinNeighborList* neighbors);
     185             : 
     186             : /// Compute a neighbor list.
     187             : ///
     188             : /// The data is returned in a `VesinNeighborList`. For an initial call, the
     189             : /// `VesinNeighborList` should be zero-initialized (or default-initalized in
     190             : /// C++). The `VesinNeighborList` can be re-used across calls to this functions
     191             : /// to re-use memory allocations, and once it is no longer needed, users should
     192             : /// call `vesin_free` to release the corresponding memory.
     193             : ///
     194             : /// @param points positions of all points in the system;
     195             : /// @param n_points number of elements in the `points` array
     196             : /// @param box bounding box for the system. If the system is non-periodic,
     197             : ///     this is ignored. This should contain the three vectors of the bounding
     198             : ///     box, one vector per row of the matrix.
     199             : /// @param periodic is the system using periodic boundary conditions? This
     200             : //      should be an array of three booleans, one for each dimension.
     201             : /// @param device device where the `points` and `box` data is allocated.
     202             : /// @param options options for the calculation
     203             : /// @param neighbors non-NULL pointer to `VesinNeighborList` that will be used
     204             : ///     to store the computed list of neighbors.
     205             : /// @param error_message Pointer to a `char*` that wil be set to the error
     206             : ///     message if this function fails. This does not need to be freed when no
     207             : ///     longer needed.
     208             : int VESIN_API vesin_neighbors(
     209             :     const double (*points)[3],
     210             :     size_t n_points,
     211             :     const double box[3][3],
     212             :     const bool periodic[3],
     213             :     VesinDevice device,
     214             :     struct VesinOptions options,
     215             :     struct VesinNeighborList* neighbors,
     216             :     const char** error_message
     217             : );
     218             : 
     219             : #ifdef __cplusplus
     220             : 
     221             : } // extern "C"
     222             : } // namespace vesin
     223             : } // namespace metatomic
     224             : } // namespace PLMD
     225             : 
     226             : #endif
     227             : 
     228             : #endif

Generated by: LCOV version 1.16