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

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

Generated by: LCOV version 1.16