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 : #if defined(VESIN_SHARED) 32 : #if defined(VESIN_EXPORTS) 33 : #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__) 34 : #define VESIN_API __attribute__((visibility("default"))) 35 : #elif defined(_MSC_VER) 36 : #define VESIN_API __declspec(dllexport) 37 : #else 38 : #define VESIN_API 39 : #endif 40 : #else 41 : #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__) 42 : #define VESIN_API __attribute__((visibility("default"))) 43 : #elif defined(_MSC_VER) 44 : #define VESIN_API __declspec(dllimport) 45 : #else 46 : #define VESIN_API 47 : #endif 48 : #endif 49 : #else 50 : #define VESIN_API 51 : #endif 52 : 53 : #ifdef __cplusplus 54 : namespace PLMD { 55 : namespace metatomic { 56 : namespace vesin { 57 : extern "C" { 58 : #endif 59 : 60 : /// Options for a neighbor list calculation 61 : struct VesinOptions { 62 : /// Spherical cutoff, only pairs below this cutoff will be included 63 : double cutoff; 64 : /// Should the returned neighbor list be a full list (include both `i -> j` 65 : /// and `j -> i` pairs) or a half list (include only `i -> j`)? 66 : bool full; 67 : /// Should the neighbor list be sorted? If yes, the returned pairs will be 68 : /// sorted using lexicographic order. 69 : bool sorted; 70 : 71 : /// Should the returned `VesinNeighborList` contain `shifts`? 72 : bool return_shifts; 73 : /// Should the returned `VesinNeighborList` contain `distances`? 74 : bool return_distances; 75 : /// Should the returned `VesinNeighborList` contain `vector`? 76 : bool return_vectors; 77 : }; 78 : 79 : /// Device on which the data can be 80 : enum VesinDevice { 81 : /// Unknown device, used for default initialization and to indicate no 82 : /// allocated data. 83 : VesinUnknownDevice = 0, 84 : /// CPU device 85 : VesinCPU = 1, 86 : }; 87 : 88 : 89 : /// The actual neighbor list 90 : /// 91 : /// This is organized as a list of pairs, where each pair can contain the 92 : /// following data: 93 : /// 94 : /// - indices of the points in the pair; 95 : /// - distance between points in the pair, accounting for periodic boundary 96 : /// conditions; 97 : /// - vector between points in the pair, accounting for periodic boundary 98 : /// conditions; 99 : /// - periodic shift that created the pair. This is only relevant when using 100 : /// periodic boundary conditions, and contains the number of bounding box we 101 : /// need to cross to create the pair. If the positions of the points are `r_i` 102 : /// and `r_j`, the bounding box is described by a matrix of three vectors `H`, 103 : /// and the periodic shift is `S`, the distance vector for a given pair will 104 : /// be given by `r_ij = r_j - r_i + S @ H`. 105 : /// 106 : /// Under periodic boundary conditions, two atoms can be part of multiple pairs, 107 : /// each pair having a different periodic shift. 108 : struct VESIN_API VesinNeighborList { 109 : #ifdef __cplusplus 110 15 : VesinNeighborList(): 111 : length(0), 112 : device(VesinUnknownDevice), 113 : pairs(nullptr), 114 : shifts(nullptr), 115 : distances(nullptr), 116 : vectors(nullptr) 117 : {} 118 : #endif 119 : 120 : /// Number of pairs in this neighbor list 121 : size_t length; 122 : /// Device used for the data allocations 123 : VesinDevice device; 124 : /// Array of pairs (storing the indices of the first and second point in the 125 : /// pair), containing `length` elements. 126 : size_t (*pairs)[2]; 127 : /// Array of box shifts, one for each `pair`. This is only set if 128 : /// `options.return_pairs` was `true` during the calculation. 129 : int32_t (*shifts)[3]; 130 : /// Array of pair distance (i.e. distance between the two points), one for 131 : /// each pair. This is only set if `options.return_distances` was `true` 132 : /// during the calculation. 133 : double *distances; 134 : /// Array of pair vector (i.e. vector between the two points), one for 135 : /// each pair. This is only set if `options.return_vector` was `true` 136 : /// during the calculation. 137 : double (*vectors)[3]; 138 : 139 : // TODO: custom memory allocators? 140 : }; 141 : 142 : /// Free all allocated memory inside a `VesinNeighborList`, according the it's 143 : /// `device`. 144 : void VESIN_API vesin_free(struct VesinNeighborList* neighbors); 145 : 146 : /// Compute a neighbor list. 147 : /// 148 : /// The data is returned in a `VesinNeighborList`. For an initial call, the 149 : /// `VesinNeighborList` should be zero-initialized (or default-initalized in 150 : /// C++). The `VesinNeighborList` can be re-used across calls to this functions 151 : /// to re-use memory allocations, and once it is no longer needed, users should 152 : /// call `vesin_free` to release the corresponding memory. 153 : /// 154 : /// @param points positions of all points in the system; 155 : /// @param n_points number of elements in the `points` array 156 : /// @param box bounding box for the system. If the system is non-periodic, 157 : /// this is ignored. This should contain the three vectors of the bounding 158 : /// box, one vector per row of the matrix. 159 : /// @param periodic is the system using periodic boundary conditions? 160 : /// @param device device where the `points` and `box` data is allocated. 161 : /// @param options options for the calculation 162 : /// @param neighbors non-NULL pointer to `VesinNeighborList` that will be used 163 : /// to store the computed list of neighbors. 164 : /// @param error_message Pointer to a `char*` that wil be set to the error 165 : /// message if this function fails. This does not need to be freed when no 166 : /// longer needed. 167 : int VESIN_API vesin_neighbors( 168 : const double (*points)[3], 169 : size_t n_points, 170 : const double box[3][3], 171 : bool periodic, 172 : VesinDevice device, 173 : struct VesinOptions options, 174 : struct VesinNeighborList* neighbors, 175 : const char** error_message 176 : ); 177 : 178 : 179 : #ifdef __cplusplus 180 : 181 : } // extern "C" 182 : } // namespace vesin 183 : } // namespace metatomic 184 : } // namespace PLMD 185 : 186 : #endif 187 : 188 : #endif