LCOV - code coverage report
Current view: top level - tools - Grid.h (source / functions) Hit Total Coverage
Test: plumed test coverage Lines: 88 88 100.0 %
Date: 2024-10-18 14:00:25 Functions: 24 25 96.0 %

          Line data    Source code
       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
       2             :    Copyright (c) 2011-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_Grid_h
      23             : #define __PLUMED_tools_Grid_h
      24             : 
      25             : #include <vector>
      26             : #include <array>
      27             : #include <string>
      28             : #include <map>
      29             : #include <cmath>
      30             : #include <memory>
      31             : #include <cstddef>
      32             : 
      33             : #include "Exception.h"
      34             : 
      35             : namespace PLMD {
      36             : 
      37             : 
      38             : // simple function to enable various weighting
      39             : 
      40             : class WeightBase {
      41             : public:
      42             :   virtual double projectInnerLoop(double &input, double &v)=0;
      43             :   virtual double projectOuterLoop(double &v)=0;
      44             :   virtual ~WeightBase() {}
      45             : };
      46             : 
      47           3 : class BiasWeight:public WeightBase {
      48             : public:
      49             :   double beta,invbeta;
      50             :   double shift=0.0;
      51           3 :   explicit BiasWeight(double v) {beta=v; invbeta=1./beta;}
      52             :   //double projectInnerLoop(double &input, double &v) override {return  input+exp(beta*v);}
      53             :   //double projectOuterLoop(double &v) override {return -invbeta*std::log(v);}
      54       13603 :   double projectInnerLoop(double &input, double &v) override {
      55       13603 :     auto betav=beta*v;
      56       13603 :     auto x=betav-shift;
      57       13603 :     if(x>0) {
      58        1187 :       shift=betav;
      59        1187 :       return input*std::exp(-x)+1;
      60             :     } else {
      61       12416 :       return input+std::exp(x);
      62             :     }
      63             :   }
      64         187 :   double projectOuterLoop(double &v) override {
      65         187 :     auto res=-invbeta*(std::log(v)+shift);
      66         187 :     shift=0.0;
      67         187 :     return res;
      68             :   }
      69             : };
      70             : 
      71             : class ProbWeight:public WeightBase {
      72             : public:
      73             :   double beta,invbeta;
      74             :   explicit ProbWeight(double v) {beta=v; invbeta=1./beta;}
      75             :   double projectInnerLoop(double &input, double &v) override {return  input+v;}
      76             :   double projectOuterLoop(double &v) override {return -invbeta*std::log(v);}
      77             : };
      78             : 
      79             : 
      80             : 
      81             : 
      82             : 
      83             : 
      84             : class Value;
      85             : class IFile;
      86             : class OFile;
      87             : class KernelFunctions;
      88             : class Communicator;
      89             : 
      90             : /// \ingroup TOOLBOX
      91             : class GridBase
      92             : {
      93             : public:
      94             : // we use a size_t here
      95             : // should be 8 bytes on all 64-bit machines
      96             : // and more portable than "unsigned long long"
      97             :   typedef std::size_t index_t;
      98             : // to restore old implementation (unsigned) use the following instead:
      99             : // typedef unsigned index_t;
     100             : /// Maximum dimension (exaggerated value).
     101             : /// Can be used to replace local std::vectors with std::arrays (allocated on stack).
     102             :   static constexpr std::size_t maxdim=16;
     103             : 
     104             : 
     105             :   /**
     106             :   Auxiliary class for accelerating grid calculations.
     107             : 
     108             :   Many functions in the Grid class have loops running over the dimensions.
     109             :   These loops are always with a little number of iterations, so would likely
     110             :   benefit unrolling. Even better, if the compiler knew the dimension a priori
     111             :   it could remove the loops in most common cases (e.g. dimension=1 or 2).
     112             : 
     113             :   To obtain this, I added this AcceleratorBase class. Specifically:
     114             :   - Any method in the Grid class that is a bottleneck in performance and
     115             :     has a loop can be moved to this auxiliary class.
     116             :   - The method should be declared here as a pure virtual function
     117             :     of class AcceleratorBase. The implementation instead goes in
     118             :     class Accelerator
     119             :   - Class Accelerator is derived from AcceleratorBase but depends on
     120             :     dimension as a template variable.
     121             :   - The function AcceleratorBase::create takes case of constructing
     122             :     accelerators for each possible value of dimension.
     123             : 
     124             :   The trick works because we don't expect dimension to ever be very
     125             :   high. By restricting it to <=16, we can have a limited number of
     126             :   compiled instances. The compiler will choose at runtime which one should
     127             :   be used.
     128             : 
     129             :   This class, as well as the derived classes, are expected to be
     130             :   empty. In other words, they only contain the pointer to a virtual
     131             :   table that the compiler will use to call the proper implementation
     132             :   variant, with the correct dimension.
     133             : 
     134             :   \warning
     135             :   Interface might change at any time.
     136             :   Do not use this outside of class GridBase and children.
     137             :   */
     138             :   class AcceleratorBase {
     139             :   public:
     140             :     /// Creates an accelerator with proper dimension
     141             :     static std::unique_ptr<AcceleratorBase> create(unsigned dim);
     142             :     virtual ~AcceleratorBase() = default;
     143             :     /// Can be used to check which value of dimension was used
     144             :     virtual unsigned getDimension() const=0;
     145             :     virtual std::vector<GridBase::index_t> getNeighbors(const GridBase& grid, const std::vector<unsigned> & nbin_,const std::vector<bool> & pbc_,const unsigned* indices,std::size_t indices_size, const std::vector<unsigned> &nneigh) const=0;
     146             :     virtual GridBase::index_t getIndex(const GridBase& grid, const std::vector<unsigned> & nbin_, const unsigned* indices,std::size_t indices_size) const=0;
     147             :     virtual void getPoint(const std::vector<double> & min_,const std::vector<double> & dx_, const unsigned* indices,std::size_t indices_size,double* point,std::size_t point_size) const=0;
     148             :     virtual void getIndices(const std::vector<unsigned> & nbin_, GridBase::index_t index, unsigned* indices, std::size_t indices_size) const=0;
     149             :     virtual void getIndices(const std::vector<double> & min_,const std::vector<double> & dx_, const std::vector<double> & x, unsigned* rindex_data,std::size_t rindex_size) const=0;
     150             :   };
     151             : 
     152             :   /**
     153             :   Auxiliary class for managing AcceleratorBase.
     154             : 
     155             :   class GridBase should contain a std::unique_ptr<AcceleratorBase>, which
     156             :   can be used to access the specialized versions. However, this would
     157             :   make a GridBase object not copyable. Instead of redefining
     158             :   copy constructor and copy assignment for GridBase, which has a lot of
     159             :   members, we use this wrapper class that just manages the lifetime
     160             :   of the underlying Accelerator object.
     161             : 
     162             :   The underlying object is made accessible through the -> operator,
     163             :   so that one can simply call functions as accelerator->function.
     164             : 
     165             :   \warning
     166             :   Interface might change at any time.
     167             :   Do not use this outside of class GridBase and children.
     168             :   */
     169        2963 :   class AcceleratorHandler {
     170             :     /// This is the underlying pointer.
     171             :     std::unique_ptr<AcceleratorBase> ptr;
     172             :   public:
     173             :     /// Enable access to methods of AcceleratorBase
     174             :     const AcceleratorBase* operator->() const {
     175             :       return ptr.get();
     176             :     }
     177             :     /// Enable access to methods of AcceleratorBase
     178             :     AcceleratorBase* operator->() {
     179             :       return ptr.get();
     180             :     }
     181             :     /// Conversion to bool allows to check if the ptr has been set
     182             :     explicit operator bool() const noexcept {
     183             :       return bool(ptr);
     184             :     }
     185             :     /// Move constructor
     186          49 :     AcceleratorHandler(const AcceleratorHandler& other):
     187          49 :       ptr((other.ptr?AcceleratorBase::create(other->getDimension()):nullptr))
     188          49 :     {}
     189             :     /// Move assignment
     190        1457 :     AcceleratorHandler & operator=(const AcceleratorHandler & other) {
     191        1457 :       if(this!=&other) {
     192             :         ptr.reset();
     193        2914 :         if(other.ptr) ptr=AcceleratorBase::create(other->getDimension());
     194             :       }
     195        1457 :       return *this;
     196             :     }
     197             :     /// Constructor without arguments result in a non-usable accelerator (dimension is unspecified)
     198             :     AcceleratorHandler() = default;
     199             :     /// Constructor with an argument creates an accelerator with a fixed dimensionality
     200        1457 :     AcceleratorHandler(unsigned dimension):
     201        1457 :       ptr(AcceleratorBase::create(dimension))
     202             :     {}
     203             :   };
     204             : 
     205             : protected:
     206             :   AcceleratorHandler accelerator;
     207             :   std::string funcname;
     208             :   std::vector<std::string> argnames;
     209             :   std::vector<std::string> str_min_, str_max_;
     210             :   std::vector<double> min_,max_,dx_;
     211             :   std::vector<unsigned> nbin_;
     212             :   std::vector<bool> pbc_;
     213             :   index_t maxsize_;
     214             :   unsigned dimension_;
     215             :   bool dospline_, usederiv_;
     216             :   std::string fmt_; // format for output
     217             : /// get "neighbors" for spline
     218             :   unsigned getSplineNeighbors(const unsigned* indices, std::size_t indices_size, index_t* neighbors, std::size_t neighbors_size)const;
     219             : // std::vector<index_t> getSplineNeighbors(const std::vector<unsigned> & indices)const;
     220             : 
     221             : 
     222             : public:
     223             : /// this constructor here is Value-aware
     224             :   GridBase(const std::string& funcl, const std::vector<Value*> & args, const std::vector<std::string> & gmin,
     225             :            const std::vector<std::string> & gmax, const std::vector<unsigned> & nbin, bool dospline,
     226             :            bool usederiv);
     227             : /// this constructor here is not Value-aware
     228             :   GridBase(const std::string& funcl, const std::vector<std::string> &names, const std::vector<std::string> & gmin,
     229             :            const std::vector<std::string> & gmax, const std::vector<unsigned> & nbin, bool dospline,
     230             :            bool usederiv, const std::vector<bool> &isperiodic, const std::vector<std::string> &pmin,
     231             :            const std::vector<std::string> &pmax );
     232             : /// this is the real initializator
     233             :   void Init(const std::string & funcl, const std::vector<std::string> &names, const std::vector<std::string> & gmin,
     234             :             const std::vector<std::string> & gmax, const std::vector<unsigned> & nbin, bool dospline, bool usederiv,
     235             :             const std::vector<bool> &isperiodic, const std::vector<std::string> &pmin, const std::vector<std::string> &pmax);
     236             : /// get lower boundary
     237             :   std::vector<std::string> getMin() const;
     238             : /// get upper boundary
     239             :   std::vector<std::string> getMax() const;
     240             : /// get bin size
     241             :   std::vector<double> getDx() const;
     242             :   double getDx(index_t j) const ;
     243             : /// get bin volume
     244             :   double getBinVolume() const;
     245             : /// get number of bins
     246             :   std::vector<unsigned> getNbin() const;
     247             : /// get if periodic
     248             :   std::vector<bool> getIsPeriodic() const;
     249             : /// get grid dimension
     250             :   unsigned getDimension() const;
     251             : /// get argument names  of this grid
     252             :   std::vector<std::string> getArgNames() const;
     253             : /// get if the grid has derivatives
     254     1986398 :   bool hasDerivatives() const {return usederiv_;}
     255             : 
     256             : /// methods to handle grid indices
     257             :   void getIndices(index_t index, std::vector<unsigned>& rindex) const;
     258             :   void getIndices(index_t index, unsigned* rindex_data, std::size_t rindex_size) const;
     259             :   void getIndices(const std::vector<double> & x, std::vector<unsigned>& rindex) const;
     260             :   void getIndices(const std::vector<double> & x, unsigned* rindex_data,std::size_t rindex_size) const;
     261             :   std::vector<unsigned> getIndices(index_t index) const;
     262             :   std::vector<unsigned> getIndices(const std::vector<double> & x) const;
     263             :   index_t getIndex(const unsigned* indices,std::size_t indices_size) const;
     264             :   index_t getIndex(const std::vector<unsigned> & indices) const;
     265             :   index_t getIndex(const std::vector<double> & x) const;
     266             :   std::vector<double> getPoint(index_t index) const;
     267             :   std::vector<double> getPoint(const std::vector<unsigned> & indices) const;
     268             :   std::vector<double> getPoint(const std::vector<double> & x) const;
     269             : /// faster versions relying on preallocated vectors
     270             :   void getPoint(index_t index,std::vector<double> & point) const;
     271             :   void getPoint(const std::vector<unsigned> & indices,std::vector<double> & point) const;
     272             :   void getPoint(const std::vector<double> & x,std::vector<double> & point) const;
     273             :   void getPoint(const unsigned* indices_data,std::size_t indices_size,std::vector<double> & point) const;
     274             :   void getPoint(const unsigned* indices_data,std::size_t indices_size,double* point,std::size_t point_size) const;
     275             : 
     276             : /// get neighbors
     277             :   std::vector<index_t> getNeighbors(index_t index,const std::vector<unsigned> & neigh) const;
     278             :   std::vector<index_t> getNeighbors(const std::vector<unsigned> & indices,const std::vector<unsigned> & neigh) const;
     279             :   std::vector<index_t> getNeighbors(const std::vector<double> & x,const std::vector<unsigned> & neigh) const;
     280             : /// get nearest neighbors (those separated by exactly one lattice unit)
     281             :   std::vector<index_t> getNearestNeighbors(const index_t index) const;
     282             :   std::vector<index_t> getNearestNeighbors(const std::vector<unsigned> &indices) const;
     283             : 
     284             : /// write header for grid file
     285             :   void writeHeader(OFile& file);
     286             : 
     287             : /// read grid from file
     288             :   static std::unique_ptr<GridBase> create(const std::string&,const std::vector<Value*>&,IFile&,bool,bool,bool);
     289             : /// read grid from file and check boundaries are what is expected from input
     290             :   static std::unique_ptr<GridBase> create(const std::string&,const std::vector<Value*>&, IFile&,
     291             :                                           const std::vector<std::string>&,const std::vector<std::string>&,
     292             :                                           const std::vector<unsigned>&,bool,bool,bool);
     293             : /// get grid size
     294             :   virtual index_t getSize() const=0;
     295             : /// get grid value
     296             :   virtual double getValue(index_t index) const=0;
     297             :   double getValue(const std::vector<unsigned> & indices) const;
     298             :   double getValue(const std::vector<double> & x) const;
     299             : /// get grid value and derivatives
     300             :   virtual double getValueAndDerivatives(index_t index, double* der, std::size_t der_size) const=0;
     301             :   double getValueAndDerivatives(index_t index, std::vector<double>& der) const;
     302             :   double getValueAndDerivatives(const std::vector<unsigned> & indices, std::vector<double>& der) const;
     303             :   double getValueAndDerivatives(const std::vector<double> & x, std::vector<double>& der) const;
     304             : 
     305             : /// set grid value
     306             :   virtual void setValue(index_t index, double value)=0;
     307             :   void setValue(const std::vector<unsigned> & indices, double value);
     308             : /// set grid value and derivatives
     309             :   virtual void setValueAndDerivatives(index_t index, double value, std::vector<double>& der)=0;
     310             :   void setValueAndDerivatives(const std::vector<unsigned> & indices, double value, std::vector<double>& der);
     311             : /// add to grid value
     312             :   virtual void addValue(index_t index, double value)=0;
     313             :   void addValue(const std::vector<unsigned> & indices, double value);
     314             : /// add to grid value and derivatives
     315             :   virtual void addValueAndDerivatives(index_t index, double value, std::vector<double>& der)=0;
     316             :   void addValueAndDerivatives(const std::vector<unsigned> & indices, double value, std::vector<double>& der);
     317             : /// add a kernel function to the grid
     318             :   void addKernel( const KernelFunctions& kernel );
     319             : 
     320             : /// get minimum value
     321             :   virtual double getMinValue() const = 0;
     322             : /// get maximum value
     323             :   virtual double getMaxValue() const = 0;
     324             : 
     325             : /// dump grid on file
     326             :   virtual void writeToFile(OFile&)=0;
     327             : /// dump grid to gaussian cube file
     328             :   void writeCubeFile(OFile&, const double& lunit);
     329             : 
     330        3012 :   virtual ~GridBase() = default;
     331             : 
     332             : /// set output format
     333         197 :   void setOutputFmt(const std::string & ss) {fmt_=ss;}
     334             : /// reset output format to the default %14.9f format
     335             :   void resetToDefaultOutputFmt() {fmt_="%14.9f";}
     336             : ///
     337             : /// Find the maximum over paths of the minimum value of the gridded function along the paths
     338             : /// for all paths of neighboring grid lattice points from a source point to a sink point.
     339             :   double findMaximalPathMinimum(const std::vector<double> &source, const std::vector<double> &sink);
     340             : };
     341             : 
     342             : class Grid : public GridBase
     343             : {
     344             :   std::vector<double> grid_;
     345             :   std::vector<double> der_;
     346             :   double contour_location=0.0;
     347             : public:
     348        1323 :   Grid(const std::string& funcl, const std::vector<Value*> & args, const std::vector<std::string> & gmin,
     349             :        const std::vector<std::string> & gmax,
     350        1323 :        const std::vector<unsigned> & nbin, bool dospline, bool usederiv):
     351        1323 :     GridBase(funcl,args,gmin,gmax,nbin,dospline,usederiv)
     352             :   {
     353        1323 :     grid_.assign(maxsize_,0.0);
     354        1323 :     if(usederiv_) der_.assign(maxsize_*dimension_,0.0);
     355        1323 :   }
     356             : /// this constructor here is not Value-aware
     357         128 :   Grid(const std::string& funcl, const std::vector<std::string> &names, const std::vector<std::string> & gmin,
     358             :        const std::vector<std::string> & gmax, const std::vector<unsigned> & nbin, bool dospline,
     359             :        bool usederiv, const std::vector<bool> &isperiodic, const std::vector<std::string> &pmin,
     360         128 :        const std::vector<std::string> &pmax ):
     361         128 :     GridBase(funcl,names,gmin,gmax,nbin,dospline,usederiv,isperiodic,pmin,pmax)
     362             :   {
     363         128 :     grid_.assign(maxsize_,0.0);
     364         128 :     if(usederiv_) der_.assign(maxsize_*dimension_,0.0);
     365         128 :   }
     366             :   index_t getSize() const override;
     367             : /// this is to access to Grid:: version of these methods (allowing overloading of virtual methods)
     368             :   using GridBase::getValue;
     369             :   using GridBase::getValueAndDerivatives;
     370             :   using GridBase::setValue;
     371             :   using GridBase::setValueAndDerivatives;
     372             :   using GridBase::addValue;
     373             :   using GridBase::addValueAndDerivatives;
     374             : /// get grid value
     375             :   double getValue(index_t index) const override;
     376             : /// get grid value and derivatives
     377             :   double getValueAndDerivatives(index_t index, double* der, std::size_t der_size) const override;
     378             : /// set grid value
     379             :   void setValue(index_t index, double value) override;
     380             : /// set grid value and derivatives
     381             :   void setValueAndDerivatives(index_t index, double value, std::vector<double>& der) override;
     382             : /// add to grid value
     383             :   void addValue(index_t index, double value) override;
     384             : /// add to grid value and derivatives
     385             :   void addValueAndDerivatives(index_t index, double value, std::vector<double>& der) override;
     386             : 
     387             : /// get minimum value
     388             :   double getMinValue() const override;
     389             : /// get maximum value
     390             :   double getMaxValue() const override;
     391             : /// Scale all grid values and derivatives by a constant factor
     392             :   void scaleAllValuesAndDerivatives( const double& scalef );
     393             : /// Takes the scalef times the logarithm of all grid values and derivatives
     394             :   void logAllValuesAndDerivatives( const double& scalef );
     395             : /// dump grid on file
     396             :   void writeToFile(OFile&) override;
     397             : 
     398             : /// Set the minimum value of the grid to zero and translates accordingly
     399             :   void setMinToZero();
     400             : /// apply function: takes  pointer to  function that accepts a double and apply
     401             :   void applyFunctionAllValuesAndDerivatives( double (*func)(double val), double (*funcder)(double valder) );
     402             : /// Get the difference from the contour
     403             :   double getDifferenceFromContour(const std::vector<double> & x, std::vector<double>& der) const ;
     404             : /// Find a set of points on a contour in the function
     405             :   void findSetOfPointsOnContour(const double& target, const std::vector<bool>& nosearch, unsigned& npoints, std::vector<std::vector<double> >& points );
     406             : /// Since this method returns a concrete Grid, it should be here and not in GridBase - GB
     407             : /// project a high dimensional grid onto a low dimensional one: this should be changed at some time
     408             : /// to enable many types of weighting
     409             :   Grid project( const std::vector<std::string> & proj, WeightBase *ptr2obj  );
     410             :   void projectOnLowDimension(double &val, std::vector<int> &varHigh, WeightBase* ptr2obj );
     411             :   void mpiSumValuesAndDerivatives( Communicator& comm );
     412             : /// Integrate the function calculated on the grid
     413             :   double integrate( std::vector<unsigned>& npoints );
     414             :   void clear();
     415             : };
     416             : 
     417             : 
     418             : class SparseGrid : public GridBase
     419             : {
     420             : 
     421             :   std::map<index_t,double> map_;
     422             :   std::map< index_t,std::vector<double> > der_;
     423             : 
     424             : public:
     425           6 :   SparseGrid(const std::string& funcl, const std::vector<Value*> & args, const std::vector<std::string> & gmin,
     426             :              const std::vector<std::string> & gmax,
     427           6 :              const std::vector<unsigned> & nbin, bool dospline, bool usederiv):
     428           6 :     GridBase(funcl,args,gmin,gmax,nbin,dospline,usederiv) {}
     429             : 
     430             :   index_t getSize() const override;
     431             :   index_t getMaxSize() const;
     432             : 
     433             : /// this is to access to Grid:: version of these methods (allowing overloading of virtual methods)
     434             :   using GridBase::getValue;
     435             :   using GridBase::getValueAndDerivatives;
     436             :   using GridBase::setValue;
     437             :   using GridBase::setValueAndDerivatives;
     438             :   using GridBase::addValue;
     439             :   using GridBase::addValueAndDerivatives;
     440             : 
     441             : /// get grid value
     442             :   double getValue(index_t index) const override;
     443             : /// get grid value and derivatives
     444             :   double getValueAndDerivatives(index_t index, double* der, std::size_t der_size) const override;
     445             : 
     446             : /// set grid value
     447             :   void setValue(index_t index, double value) override;
     448             : /// set grid value and derivatives
     449             :   void setValueAndDerivatives(index_t index, double value, std::vector<double>& der) override;
     450             : /// add to grid value
     451             :   void addValue(index_t index, double value) override;
     452             : /// add to grid value and derivatives
     453             :   void addValueAndDerivatives(index_t index, double value, std::vector<double>& der) override;
     454             : 
     455             : /// get minimum value
     456             :   double getMinValue() const override;
     457             : /// get maximum value
     458             :   double getMaxValue() const override;
     459             : /// dump grid on file
     460             :   void writeToFile(OFile&) override;
     461             : 
     462          18 :   virtual ~SparseGrid() = default;
     463             : };
     464             : 
     465             : 
     466             : inline
     467     5900587 : GridBase::index_t GridBase::getIndex(const unsigned* indices,std::size_t indices_size) const {
     468             :   plumed_dbg_assert(accelerator);
     469     5900587 :   return accelerator->getIndex(*this,nbin_,indices,indices_size);
     470             : }
     471             : 
     472             : inline
     473     4791554 : GridBase::index_t GridBase::getIndex(const std::vector<unsigned> & indices) const {
     474             :   plumed_dbg_assert(indices.size()==dimension_);
     475     4791554 :   return getIndex(indices.data(),indices.size());
     476             : }
     477             : 
     478             : inline
     479     1100069 : GridBase::index_t GridBase::getIndex(const std::vector<double> & x) const {
     480             :   plumed_dbg_assert(x.size()==dimension_);
     481             :   std::array<unsigned,maxdim> indices;
     482     1100069 :   getIndices(x,indices.data(),dimension_);
     483     1100069 :   return getIndex(indices.data(),dimension_);
     484             : }
     485             : 
     486             : inline
     487     7877712 : std::vector<unsigned> GridBase::getIndices(index_t index) const {
     488     7877712 :   std::vector<unsigned> indices(dimension_);
     489     7877712 :   getIndices(index,indices.data(),indices.size());
     490     7877712 :   return indices;
     491             : }
     492             : 
     493             : inline
     494    37819738 : void GridBase::getIndices(index_t index, unsigned* indices, std::size_t indices_size) const {
     495    37819738 :   plumed_assert(indices_size==dimension_);
     496    37819738 :   plumed_assert(accelerator);
     497    37819738 :   accelerator->getIndices(nbin_,index,indices,dimension_);
     498    37819738 : }
     499             : 
     500             : inline
     501             : void GridBase::getIndices(index_t index, std::vector<unsigned>& indices) const {
     502             :   if (indices.size()!=dimension_) indices.resize(dimension_);
     503             :   getIndices(index,indices.data(),indices.size());
     504             : }
     505             : 
     506             : inline
     507             : std::vector<unsigned> GridBase::getIndices(const std::vector<double> & x) const {
     508             :   plumed_dbg_assert(x.size()==dimension_);
     509             :   std::vector<unsigned> indices(dimension_);
     510             :   getIndices(x,indices);
     511             :   return indices;
     512             : }
     513             : 
     514             : inline
     515             : void GridBase::getIndices(const std::vector<double> & x, std::vector<unsigned>& indices) const {
     516             :   indices.resize(dimension_);
     517             :   getIndices(x,indices.data(),indices.size());
     518             : }
     519             : 
     520             : inline
     521     1103807 : void GridBase::getIndices(const std::vector<double> & x, unsigned* rindex_data,std::size_t rindex_size) const {
     522             :   plumed_dbg_assert(x.size()==dimension_);
     523             :   plumed_dbg_assert(rindex_size==dimension_);
     524     1103807 :   accelerator->getIndices(min_,dx_,x,rindex_data,rindex_size);
     525     1103807 : }
     526             : 
     527             : inline
     528    32656902 : void GridBase::getPoint(const unsigned* indices,std::size_t indices_size,double* point,std::size_t point_size) const {
     529             :   plumed_dbg_assert(indices_size==dimension_);
     530             :   plumed_dbg_assert(point_size==dimension_);
     531             :   plumed_dbg_assert(accelerator);
     532    32656902 :   accelerator->getPoint(min_,dx_,indices,indices_size,point,point_size);
     533    32656902 : }
     534             : 
     535             : inline
     536     2720102 : std::vector<double> GridBase::getPoint(const std::vector<unsigned> & indices) const {
     537             :   plumed_dbg_assert(indices.size()==dimension_);
     538     2720102 :   std::vector<double> x(dimension_);
     539     2720102 :   getPoint(indices,x);
     540     2720102 :   return x;
     541             : }
     542             : 
     543             : inline
     544    28822337 : std::vector<double> GridBase::getPoint(index_t index) const {
     545             :   plumed_dbg_assert(index<maxsize_);
     546    28822337 :   std::vector<double> x(dimension_);
     547    28822337 :   getPoint(index,x);
     548    28822337 :   return x;
     549             : }
     550             : 
     551             : inline
     552             : std::vector<double> GridBase::getPoint(const std::vector<double> & x) const {
     553             :   plumed_dbg_assert(x.size()==dimension_);
     554             :   std::vector<double> r(dimension_);
     555             :   getPoint(x,r);
     556             :   return r;
     557             : }
     558             : 
     559             : inline
     560    29933062 : void GridBase::getPoint(index_t index,std::vector<double> & point) const {
     561             :   plumed_dbg_assert(index<maxsize_);
     562             :   std::array<unsigned,maxdim> indices;
     563    29933062 :   getIndices(index,indices.data(),dimension_);
     564    29933062 :   getPoint(indices.data(),dimension_,point);
     565    29933062 : }
     566             : 
     567             : inline
     568     2720102 : void GridBase::getPoint(const std::vector<unsigned> & indices,std::vector<double> & point) const {
     569             :   plumed_dbg_assert(indices.size()==dimension_);
     570             :   plumed_dbg_assert(point.size()==dimension_);
     571     2720102 :   getPoint(indices.data(),indices.size(),point.data(),point.size());
     572     2720102 : }
     573             : 
     574             : inline
     575    29933062 : void GridBase::getPoint(const unsigned* indices_data,std::size_t indices_size,std::vector<double> & point) const {
     576             :   plumed_dbg_assert(indices_size==dimension_);
     577             :   plumed_dbg_assert(point.size()==dimension_);
     578    29933062 :   getPoint(indices_data,indices_size,point.data(),point.size());
     579    29933062 : }
     580             : 
     581             : inline
     582             : void GridBase::getPoint(const std::vector<double> & x,std::vector<double> & point) const {
     583             :   plumed_dbg_assert(x.size()==dimension_);
     584             :   std::array<unsigned,maxdim> indices;
     585             :   getIndices(x,indices.data(),dimension_);
     586             :   getPoint(indices.data(),dimension_,point.data(),point.size());
     587             : }
     588             : 
     589             : inline
     590             : std::vector<GridBase::index_t> GridBase::getNeighbors(const std::vector<unsigned> &indices,const std::vector<unsigned> &nneigh)const {
     591             :   plumed_dbg_assert(accelerator);
     592             :   return accelerator->getNeighbors(*this,nbin_,pbc_,indices.data(),indices.size(),nneigh);
     593             : }
     594             : 
     595             : inline
     596        4223 : std::vector<GridBase::index_t> GridBase::getNeighbors(const std::vector<double> & x,const std::vector<unsigned> & nneigh)const {
     597             :   plumed_dbg_assert(x.size()==dimension_ && nneigh.size()==dimension_);
     598             :   std::array<unsigned,maxdim> indices;
     599             :   plumed_dbg_assert(accelerator);
     600        4223 :   accelerator->getIndices(min_,dx_,x,indices.data(),dimension_);
     601        4223 :   return accelerator->getNeighbors(*this,nbin_,pbc_,indices.data(),dimension_,nneigh);
     602             : }
     603             : 
     604             : inline
     605       19153 : std::vector<GridBase::index_t> GridBase::getNeighbors(index_t index,const std::vector<unsigned> & nneigh)const {
     606             :   plumed_dbg_assert(index<maxsize_ && nneigh.size()==dimension_);
     607             :   std::array<unsigned,maxdim> indices;
     608             :   plumed_dbg_assert(accelerator);
     609       19153 :   accelerator->getIndices(nbin_,index,indices.data(),dimension_);
     610       19153 :   return accelerator->getNeighbors(*this,nbin_,pbc_,indices.data(),dimension_,nneigh);
     611             : }
     612             : 
     613             : 
     614             : 
     615             : 
     616             : 
     617             : }
     618             : 
     619             : #endif

Generated by: LCOV version 1.16