LCOV - code coverage report
Current view: top level - tools - LinkCells.h (source / functions) Hit Total Coverage
Test: plumed test coverage Lines: 4 4 100.0 %
Date: 2026-11-05 10:19:04 Functions: 1 1 100.0 %

          Line data    Source code
       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
       2             :    Copyright (c) 2014-2023 The plumed team
       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
       4             : 
       5             :    See http://www.plumed.org for more information.
       6             : 
       7             :    This file is part of plumed, version 2.
       8             : 
       9             :    plumed is free software: you can redistribute it and/or modify
      10             :    it under the terms of the GNU Lesser General Public License as published by
      11             :    the Free Software Foundation, either version 3 of the License, or
      12             :    (at your option) any later version.
      13             : 
      14             :    plumed is distributed in the hope that it will be useful,
      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      17             :    GNU Lesser General Public License for more details.
      18             : 
      19             :    You should have received a copy of the GNU Lesser General Public License
      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
      22             : #ifndef __PLUMED_tools_LinkCells_h
      23             : #define __PLUMED_tools_LinkCells_h
      24             : 
      25             : #include <limits>
      26             : #include <vector>
      27             : #include <array>
      28             : #include "View.h"
      29             : #include "Vector.h"
      30             : #include "Pbc.h"
      31             : 
      32             : namespace PLMD {
      33             : 
      34             : class Communicator;
      35             : 
      36             : /// \ingroup TOOLBOX
      37             : /// A class for doing link cells
      38          82 : class LinkCells {
      39             : public:
      40             :   ///This struct contains the configuration of cells
      41             :   struct CellCollection {
      42             : /// The start of each block corresponding to each link cell
      43             :     std::vector<unsigned> lcell_starts;
      44             : /// The number of atoms in each link cell
      45             :     std::vector<unsigned> lcell_tots;
      46             : /// The atoms ordered by link cells
      47             :     std::vector<unsigned> lcell_lists;
      48             :     ///return the sum of the number of atoms in the n cells with most atoms
      49             :     unsigned getMaximimumCombination(unsigned numCells=27) const;
      50             :     ///returns a const view of the on indexes the given cell
      51    16003445 :     inline View<const unsigned> getCellIndexes(const unsigned cellno) const {
      52    16003445 :       return {lcell_lists.data()+lcell_starts[cellno],lcell_tots[cellno]};
      53             :       // this will make the debug test fail in the case of
      54             :       // a series of empty cells in the end of the array,
      55             :       // because lcell_starts[cellno] will be==cell_lists.size()
      56             :       // the option abuve have the same problem, but it is masked
      57             :       // with pointer arithmetic
      58             :       // and should be ignored by the size passed being 0
      59             :       //return {&lcell_lists[lcell_starts[cellno]],lcell_tots[cellno]};
      60             :     }
      61             :   };
      62             : private:
      63             : /// Minimum number of atoms per thread when finding the cells of the atoms
      64             :   static constexpr unsigned minAtomsPerThread=4096;
      65             : /// Maximum total number of cells
      66             :   static constexpr double maxNumberOfCells=1048576;
      67             : /// Check that the link cells were set up correctly
      68             :   bool cutoffwasset=false;
      69             : /// Are there periodic boundary conditions setup
      70             :   bool nopbc=false;
      71             : /// The cutoff to use for the sizes of the cells
      72             :   double link_cutoff=0.0;
      73             : /// The pbc we are using for link cells
      74             :   Pbc mypbc;
      75             : /// The location of the origin if we are not using periodic boundary conditions
      76             :   Vector origin;
      77             : /// The number of cells in each direction
      78             :   std::array<unsigned,3> ncells{0,0,0};
      79             : /// The number of cells to stride through to get the link cells
      80             :   std::array<unsigned,3> nstride{1,0,0};
      81             : /// Work vector with the list of cells each atom is inside
      82             :   std::vector<unsigned> allcells;
      83             : ///The collection of indexes per cell created by buildCellLists
      84             :   CellCollection innerCollection;
      85             :   void createCells(const PLMD::Tensor&);
      86             : /// Find the index of the cell of a position, without checks:
      87             : /// returns getNumberOfCells() if the position is not in a cell
      88             :   unsigned findCellUnchecked( Vector pos ) const noexcept;
      89             : public:
      90             : /// The communicator is not used: the cells are built locally on every process
      91             : /// (the argument is kept for backward compatibility)
      92             :   explicit LinkCells( Communicator& comm );
      93             : /// Have the link cells been enabled
      94             :   bool enabled() const ;
      95             : /// Set the value of the cutoff
      96             :   void setCutoff( double lcut );
      97             : /// Get the value of the cutoff
      98             :   double getCutoff() const ;
      99             : /// Get the total number of link cells
     100             :   unsigned getNumberOfCells() const ;
     101             : ///Get the number of cells per dimension
     102             :   const std::array<unsigned,3>& getCellLimits() const ;
     103             : /// Get the number of atoms in the cell that contains the most atoms
     104             :   unsigned getMaxInCell() const ;
     105             : /// Sets up the cells ignoring the pbcs
     106             : ///
     107             : /// This creates an orthogonal box that encloses all the atoms
     108             :   void setupCells( View<const Vector> pos);
     109             :   template <typename T>
     110             :   inline void setupCells( const T& pos ) {
     111             :     setupCells(make_const_view(pos));
     112             :   }
     113             : /// Sets up the cells using the box stored in the Pbc object
     114             :   void setupCells( const Pbc& pbc );
     115             : ///setups the cells
     116             : ///
     117             : /// Usually it only uses the pbcs
     118             : /// if the pbc box is  null (three zero vectors) it builds an orthorhombic box from the given positions
     119             :   void setupCells( View<const Vector> pos,
     120             :                    const Pbc& pbc );
     121             :   template <typename T>
     122             :   inline void setupCells( const T& pos,
     123             :                           const Pbc& pbc ) {
     124             :     setupCells(make_const_view(pos),pbc);
     125             :   }
     126             : /// Build the link cell lists
     127             :   void buildCellLists( View<const Vector> pos,
     128             :                        View<const unsigned> indices,
     129             :                        const Pbc& pbc );
     130             :   template <typename T,typename Y>
     131             :   inline void buildCellLists( const T& pos,
     132             :                               const Y& indices,
     133             :                               const Pbc& pbc ) {
     134             :     buildCellLists(make_const_view(pos), make_const_view(indices),pbc);
     135             :   }
     136             : // Reset the passed collection on the positions and the passed indexes, needs setupCells to be launched in advance
     137             :   void resetCollection( CellCollection& collection,
     138             :                         View<const Vector> pos,
     139             :                         View<const unsigned> indices );
     140             : // Returns a collection on the positions and the passed indexes, needs setupCells to be launched in advance
     141             :   CellCollection getCollection(View<const Vector> pos,
     142             :                                View<const unsigned> indices );
     143             :   template <typename T,typename Y>
     144             :   inline CellCollection getCollection(const T& pos,
     145             :                                       const Y& indices) {
     146             :     return getCollection(make_const_view(pos),
     147             :                          make_const_view(indices));
     148             :   }
     149             : /// Take three indices and return the index of the corresponding cell
     150             :   unsigned convertIndicesToIndex( std::array<unsigned,3> cellCoord) const;
     151             : /// Find the cell index in which this position is contained
     152             :   unsigned findCell( const Vector& pos ) const ;
     153             : /// Find the cell in which this position is contained
     154             :   std::array<unsigned,3> findMyCell( Vector pos ) const ;
     155             : /// Returns the "coordinate" of the cell index, assumes that cellIndex < getNumberOfCells()
     156             :   std::array<unsigned,3> findMyCell( unsigned cellIndex ) const ;
     157             : /// Get the list of cells we need to surround the a particular cell
     158             : ///
     159             : /// usePbc toggles the use of pbcs for the input cell (celln)
     160             :   void addRequiredCells( const std::array<unsigned,3>& celn,
     161             :                          unsigned& ncells_required,
     162             :                          std::vector<unsigned>& cells_required,
     163             :                          bool usePbc=true) const ;
     164             : /// Retrieve the atoms in a list of cells
     165             :   void retrieveAtomsInCells( unsigned ncells_required,
     166             :                              View<const unsigned> cells_required,
     167             :                              unsigned& natomsper,
     168             :                              std::vector<unsigned>& atoms,
     169             :                              unsigned avoidIndex=std::numeric_limits<unsigned>::max()) const ;
     170             : /// Retrieve the atoms we need to consider
     171             :   void retrieveNeighboringAtoms( const Vector& pos,
     172             :                                  std::vector<unsigned>& cell_list,
     173             :                                  unsigned& natomsper,
     174             :                                  std::vector<unsigned>& atoms ) const ;
     175             : /// Create a neighbour list for the specified input atoms
     176             : ///
     177             : /// @param nat number of atoms
     178             : /// @param pos position of the "central atoms"
     179             : /// @param ind indexes of the central atoms
     180             : /// @param tind temporary indexes
     181             : /// @param neigh_pos position of the candidate neighbors
     182             : /// @param neigh_ind indexes of the candidate neighbors
     183             : /// @param pbc
     184             : /// @param natoms_per_list *output* number of atom per list (mapped on tind) `nlist[tind[i]]=natoms[i]`
     185             : /// @param nlist *output* list of the central atoms plus their neighbors
     186             : /// @param applyCutoff if true only the candidates whose (minimum image) distance from the
     187             : ///        central atom is not larger than the link cell cutoff are kept. The cells are at
     188             : ///        least as wide as the cutoff, so without this the lists hold all the atoms of the
     189             : ///        27 cells around the central atom, up to ~2-3 cutoffs away: with a short cutoff
     190             : ///        in a dense system most of them are beyond it. Use it only when the quantity
     191             : ///        computed from the list is exactly zero beyond the cutoff.
     192             :   void createNeighborList( unsigned nat,
     193             :                            View<const Vector> pos,
     194             :                            View<const unsigned> ind,
     195             :                            View<const unsigned> tind,
     196             :                            View<const Vector> neigh_pos,
     197             :                            View<const unsigned> neigh_ind,
     198             :                            const Pbc& pbc,
     199             :                            unsigned& natoms_per_list,
     200             :                            std::vector<std::size_t>& nlist,
     201             :                            const bool applyCutoff=false ) ;
     202             : };
     203             : 
     204             : inline
     205             : bool LinkCells::enabled() const {
     206             :   return cutoffwasset;
     207             : }
     208             : 
     209             : inline
     210             : unsigned LinkCells::getNumberOfCells() const {
     211    15953118 :   return ncells[0]*ncells[1]*ncells[2];
     212             : }
     213             : 
     214             : inline
     215             : const std::array<unsigned,3>& LinkCells::getCellLimits() const {
     216             :   return ncells;
     217             : }
     218             : }
     219             : 
     220             : #endif

Generated by: LCOV version 1.16