LCOV - code coverage report
Current view: top level - tools - Grid.h (source / functions) Hit Total Coverage
Test: plumed test coverage Lines: 32 32 100.0 %
Date: 2024-10-11 08:09:47 Functions: 8 9 88.9 %

          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 <string>
      27             : #include <map>
      28             : #include <cmath>
      29             : #include <memory>
      30             : #include <cstddef>
      31             : 
      32             : namespace PLMD {
      33             : 
      34             : 
      35             : // simple function to enable various weighting
      36             : 
      37             : class WeightBase {
      38             : public:
      39             :   virtual double projectInnerLoop(double &input, double &v)=0;
      40             :   virtual double projectOuterLoop(double &v)=0;
      41             :   virtual ~WeightBase() {}
      42             : };
      43             : 
      44           3 : class BiasWeight:public WeightBase {
      45             : public:
      46             :   double beta,invbeta;
      47             :   double shift=0.0;
      48           3 :   explicit BiasWeight(double v) {beta=v; invbeta=1./beta;}
      49             :   //double projectInnerLoop(double &input, double &v) override {return  input+exp(beta*v);}
      50             :   //double projectOuterLoop(double &v) override {return -invbeta*std::log(v);}
      51       13603 :   double projectInnerLoop(double &input, double &v) override {
      52       13603 :     auto betav=beta*v;
      53       13603 :     auto x=betav-shift;
      54       13603 :     if(x>0) {
      55        1187 :       shift=betav;
      56        1187 :       return input*std::exp(-x)+1;
      57             :     } else {
      58       12416 :       return input+std::exp(x);
      59             :     }
      60             :   }
      61         187 :   double projectOuterLoop(double &v) override {
      62         187 :     auto res=-invbeta*(std::log(v)+shift);
      63         187 :     shift=0.0;
      64         187 :     return res;
      65             :   }
      66             : };
      67             : 
      68             : class ProbWeight:public WeightBase {
      69             : public:
      70             :   double beta,invbeta;
      71             :   explicit ProbWeight(double v) {beta=v; invbeta=1./beta;}
      72             :   double projectInnerLoop(double &input, double &v) override {return  input+v;}
      73             :   double projectOuterLoop(double &v) override {return -invbeta*std::log(v);}
      74             : };
      75             : 
      76             : 
      77             : 
      78             : 
      79             : 
      80             : 
      81             : class Value;
      82             : class IFile;
      83             : class OFile;
      84             : class KernelFunctions;
      85             : class Communicator;
      86             : 
      87             : /// \ingroup TOOLBOX
      88             : class GridBase
      89             : {
      90             : public:
      91             : // we use a size_t here
      92             : // should be 8 bytes on all 64-bit machines
      93             : // and more portable than "unsigned long long"
      94             :   typedef std::size_t index_t;
      95             : // to restore old implementation (unsigned) use the following instead:
      96             : // typedef unsigned index_t;
      97             : /// Maximum dimension (exaggerated value).
      98             : /// Can be used to replace local std::vectors with std::arrays (allocated on stack).
      99             :   static constexpr std::size_t maxdim=64;
     100             : protected:
     101             :   std::string funcname;
     102             :   std::vector<std::string> argnames;
     103             :   std::vector<std::string> str_min_, str_max_;
     104             :   std::vector<double> min_,max_,dx_;
     105             :   std::vector<unsigned> nbin_;
     106             :   std::vector<bool> pbc_;
     107             :   index_t maxsize_;
     108             :   unsigned dimension_;
     109             :   bool dospline_, usederiv_;
     110             :   std::string fmt_; // format for output
     111             : /// get "neighbors" for spline
     112             :   void getSplineNeighbors(const std::vector<unsigned> & indices, std::vector<index_t>& neigh, unsigned& nneigh )const;
     113             : // std::vector<index_t> getSplineNeighbors(const std::vector<unsigned> & indices)const;
     114             : 
     115             : 
     116             : public:
     117             : /// this constructor here is Value-aware
     118             :   GridBase(const std::string& funcl, const std::vector<Value*> & args, const std::vector<std::string> & gmin,
     119             :            const std::vector<std::string> & gmax, const std::vector<unsigned> & nbin, bool dospline,
     120             :            bool usederiv);
     121             : /// this constructor here is not Value-aware
     122             :   GridBase(const std::string& funcl, const std::vector<std::string> &names, const std::vector<std::string> & gmin,
     123             :            const std::vector<std::string> & gmax, const std::vector<unsigned> & nbin, bool dospline,
     124             :            bool usederiv, const std::vector<bool> &isperiodic, const std::vector<std::string> &pmin,
     125             :            const std::vector<std::string> &pmax );
     126             : /// this is the real initializator
     127             :   void Init(const std::string & funcl, const std::vector<std::string> &names, const std::vector<std::string> & gmin,
     128             :             const std::vector<std::string> & gmax, const std::vector<unsigned> & nbin, bool dospline, bool usederiv,
     129             :             const std::vector<bool> &isperiodic, const std::vector<std::string> &pmin, const std::vector<std::string> &pmax);
     130             : /// get lower boundary
     131             :   std::vector<std::string> getMin() const;
     132             : /// get upper boundary
     133             :   std::vector<std::string> getMax() const;
     134             : /// get bin size
     135             :   std::vector<double> getDx() const;
     136             :   double getDx(index_t j) const ;
     137             : /// get bin volume
     138             :   double getBinVolume() const;
     139             : /// get number of bins
     140             :   std::vector<unsigned> getNbin() const;
     141             : /// get if periodic
     142             :   std::vector<bool> getIsPeriodic() const;
     143             : /// get grid dimension
     144             :   unsigned getDimension() const;
     145             : /// get argument names  of this grid
     146             :   std::vector<std::string> getArgNames() const;
     147             : /// get if the grid has derivatives
     148     1986398 :   bool hasDerivatives() const {return usederiv_;}
     149             : 
     150             : /// methods to handle grid indices
     151             :   void getIndices(index_t index, std::vector<unsigned>& rindex) const;
     152             :   void getIndices(const std::vector<double> & x, std::vector<unsigned>& rindex) const;
     153             :   std::vector<unsigned> getIndices(index_t index) const;
     154             :   std::vector<unsigned> getIndices(const std::vector<double> & x) const;
     155             :   index_t getIndex(const std::vector<unsigned> & indices) const;
     156             :   index_t getIndex(const std::vector<double> & x) const;
     157             :   std::vector<double> getPoint(index_t index) const;
     158             :   std::vector<double> getPoint(const std::vector<unsigned> & indices) const;
     159             :   std::vector<double> getPoint(const std::vector<double> & x) const;
     160             : /// faster versions relying on preallocated vectors
     161             :   void getPoint(index_t index,std::vector<double> & point) const;
     162             :   void getPoint(const std::vector<unsigned> & indices,std::vector<double> & point) const;
     163             :   void getPoint(const std::vector<double> & x,std::vector<double> & point) const;
     164             : 
     165             : /// get neighbors
     166             :   std::vector<index_t> getNeighbors(index_t index,const std::vector<unsigned> & neigh) const;
     167             :   std::vector<index_t> getNeighbors(const std::vector<unsigned> & indices,const std::vector<unsigned> & neigh) const;
     168             :   std::vector<index_t> getNeighbors(const std::vector<double> & x,const std::vector<unsigned> & neigh) const;
     169             : /// get nearest neighbors (those separated by exactly one lattice unit)
     170             :   std::vector<index_t> getNearestNeighbors(const index_t index) const;
     171             :   std::vector<index_t> getNearestNeighbors(const std::vector<unsigned> &indices) const;
     172             : 
     173             : /// write header for grid file
     174             :   void writeHeader(OFile& file);
     175             : 
     176             : /// read grid from file
     177             :   static std::unique_ptr<GridBase> create(const std::string&,const std::vector<Value*>&,IFile&,bool,bool,bool);
     178             : /// read grid from file and check boundaries are what is expected from input
     179             :   static std::unique_ptr<GridBase> create(const std::string&,const std::vector<Value*>&, IFile&,
     180             :                                           const std::vector<std::string>&,const std::vector<std::string>&,
     181             :                                           const std::vector<unsigned>&,bool,bool,bool);
     182             : /// get grid size
     183             :   virtual index_t getSize() const=0;
     184             : /// get grid value
     185             :   virtual double getValue(index_t index) const=0;
     186             :   double getValue(const std::vector<unsigned> & indices) const;
     187             :   double getValue(const std::vector<double> & x) const;
     188             : /// get grid value and derivatives
     189             :   virtual double getValueAndDerivatives(index_t index, std::vector<double>& der) const=0;
     190             :   double getValueAndDerivatives(const std::vector<unsigned> & indices, std::vector<double>& der) const;
     191             :   double getValueAndDerivatives(const std::vector<double> & x, std::vector<double>& der) const;
     192             : 
     193             : /// set grid value
     194             :   virtual void setValue(index_t index, double value)=0;
     195             :   void setValue(const std::vector<unsigned> & indices, double value);
     196             : /// set grid value and derivatives
     197             :   virtual void setValueAndDerivatives(index_t index, double value, std::vector<double>& der)=0;
     198             :   void setValueAndDerivatives(const std::vector<unsigned> & indices, double value, std::vector<double>& der);
     199             : /// add to grid value
     200             :   virtual void addValue(index_t index, double value)=0;
     201             :   void addValue(const std::vector<unsigned> & indices, double value);
     202             : /// add to grid value and derivatives
     203             :   virtual void addValueAndDerivatives(index_t index, double value, std::vector<double>& der)=0;
     204             :   void addValueAndDerivatives(const std::vector<unsigned> & indices, double value, std::vector<double>& der);
     205             : /// add a kernel function to the grid
     206             :   void addKernel( const KernelFunctions& kernel );
     207             : 
     208             : /// get minimum value
     209             :   virtual double getMinValue() const = 0;
     210             : /// get maximum value
     211             :   virtual double getMaxValue() const = 0;
     212             : 
     213             : /// dump grid on file
     214             :   virtual void writeToFile(OFile&)=0;
     215             : /// dump grid to gaussian cube file
     216             :   void writeCubeFile(OFile&, const double& lunit);
     217             : 
     218        2994 :   virtual ~GridBase() {}
     219             : 
     220             : /// set output format
     221         197 :   void setOutputFmt(const std::string & ss) {fmt_=ss;}
     222             : /// reset output format to the default %14.9f format
     223             :   void resetToDefaultOutputFmt() {fmt_="%14.9f";}
     224             : ///
     225             : /// Find the maximum over paths of the minimum value of the gridded function along the paths
     226             : /// for all paths of neighboring grid lattice points from a source point to a sink point.
     227             :   double findMaximalPathMinimum(const std::vector<double> &source, const std::vector<double> &sink);
     228             : };
     229             : 
     230             : class Grid : public GridBase
     231             : {
     232             :   std::vector<double> grid_;
     233             :   std::vector<double> der_;
     234             :   double contour_location=0.0;
     235             : public:
     236        1314 :   Grid(const std::string& funcl, const std::vector<Value*> & args, const std::vector<std::string> & gmin,
     237             :        const std::vector<std::string> & gmax,
     238        1314 :        const std::vector<unsigned> & nbin, bool dospline, bool usederiv):
     239        1314 :     GridBase(funcl,args,gmin,gmax,nbin,dospline,usederiv)
     240             :   {
     241        1314 :     grid_.assign(maxsize_,0.0);
     242        1314 :     if(usederiv_) der_.assign(maxsize_*dimension_,0.0);
     243        1314 :   }
     244             : /// this constructor here is not Value-aware
     245         128 :   Grid(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,
     247             :        bool usederiv, const std::vector<bool> &isperiodic, const std::vector<std::string> &pmin,
     248         128 :        const std::vector<std::string> &pmax ):
     249         128 :     GridBase(funcl,names,gmin,gmax,nbin,dospline,usederiv,isperiodic,pmin,pmax)
     250             :   {
     251         128 :     grid_.assign(maxsize_,0.0);
     252         128 :     if(usederiv_) der_.assign(maxsize_*dimension_,0.0);
     253         128 :   }
     254             :   index_t getSize() const override;
     255             : /// this is to access to Grid:: version of these methods (allowing overloading of virtual methods)
     256             :   using GridBase::getValue;
     257             :   using GridBase::getValueAndDerivatives;
     258             :   using GridBase::setValue;
     259             :   using GridBase::setValueAndDerivatives;
     260             :   using GridBase::addValue;
     261             :   using GridBase::addValueAndDerivatives;
     262             : /// get grid value
     263             :   double getValue(index_t index) const override;
     264             : /// get grid value and derivatives
     265             :   double getValueAndDerivatives(index_t index, std::vector<double>& der) const override;
     266             : 
     267             : /// set grid value
     268             :   void setValue(index_t index, double value) override;
     269             : /// set grid value and derivatives
     270             :   void setValueAndDerivatives(index_t index, double value, std::vector<double>& der) override;
     271             : /// add to grid value
     272             :   void addValue(index_t index, double value) override;
     273             : /// add to grid value and derivatives
     274             :   void addValueAndDerivatives(index_t index, double value, std::vector<double>& der) override;
     275             : 
     276             : /// get minimum value
     277             :   double getMinValue() const override;
     278             : /// get maximum value
     279             :   double getMaxValue() const override;
     280             : /// Scale all grid values and derivatives by a constant factor
     281             :   void scaleAllValuesAndDerivatives( const double& scalef );
     282             : /// Takes the scalef times the logarithm of all grid values and derivatives
     283             :   void logAllValuesAndDerivatives( const double& scalef );
     284             : /// dump grid on file
     285             :   void writeToFile(OFile&) override;
     286             : 
     287             : /// Set the minimum value of the grid to zero and translates accordingly
     288             :   void setMinToZero();
     289             : /// apply function: takes  pointer to  function that accepts a double and apply
     290             :   void applyFunctionAllValuesAndDerivatives( double (*func)(double val), double (*funcder)(double valder) );
     291             : /// Get the difference from the contour
     292             :   double getDifferenceFromContour(const std::vector<double> & x, std::vector<double>& der) const ;
     293             : /// Find a set of points on a contour in the function
     294             :   void findSetOfPointsOnContour(const double& target, const std::vector<bool>& nosearch, unsigned& npoints, std::vector<std::vector<double> >& points );
     295             : /// Since this method returns a concrete Grid, it should be here and not in GridBase - GB
     296             : /// project a high dimensional grid onto a low dimensional one: this should be changed at some time
     297             : /// to enable many types of weighting
     298             :   Grid project( const std::vector<std::string> & proj, WeightBase *ptr2obj  );
     299             :   void projectOnLowDimension(double &val, std::vector<int> &varHigh, WeightBase* ptr2obj );
     300             :   void mpiSumValuesAndDerivatives( Communicator& comm );
     301             : /// Integrate the function calculated on the grid
     302             :   double integrate( std::vector<unsigned>& npoints );
     303             :   void clear();
     304             : };
     305             : 
     306             : 
     307             : class SparseGrid : public GridBase
     308             : {
     309             : 
     310             :   std::map<index_t,double> map_;
     311             :   std::map< index_t,std::vector<double> > der_;
     312             : 
     313             : public:
     314           6 :   SparseGrid(const std::string& funcl, const std::vector<Value*> & args, const std::vector<std::string> & gmin,
     315             :              const std::vector<std::string> & gmax,
     316           6 :              const std::vector<unsigned> & nbin, bool dospline, bool usederiv):
     317           6 :     GridBase(funcl,args,gmin,gmax,nbin,dospline,usederiv) {}
     318             : 
     319             :   index_t getSize() const override;
     320             :   index_t getMaxSize() const;
     321             : 
     322             : /// this is to access to Grid:: version of these methods (allowing overloading of virtual methods)
     323             :   using GridBase::getValue;
     324             :   using GridBase::getValueAndDerivatives;
     325             :   using GridBase::setValue;
     326             :   using GridBase::setValueAndDerivatives;
     327             :   using GridBase::addValue;
     328             :   using GridBase::addValueAndDerivatives;
     329             : 
     330             : /// get grid value
     331             :   double getValue(index_t index) const override;
     332             : /// get grid value and derivatives
     333             :   double getValueAndDerivatives(index_t index, std::vector<double>& der) const override;
     334             : 
     335             : /// set grid value
     336             :   void setValue(index_t index, double value) override;
     337             : /// set grid value and derivatives
     338             :   void setValueAndDerivatives(index_t index, double value, std::vector<double>& der) override;
     339             : /// add to grid value
     340             :   void addValue(index_t index, double value) override;
     341             : /// add to grid value and derivatives
     342             :   void addValueAndDerivatives(index_t index, double value, std::vector<double>& der) override;
     343             : 
     344             : /// get minimum value
     345             :   double getMinValue() const override;
     346             : /// get maximum value
     347             :   double getMaxValue() const override;
     348             : /// dump grid on file
     349             :   void writeToFile(OFile&) override;
     350             : 
     351          18 :   virtual ~SparseGrid() {}
     352             : };
     353             : }
     354             : 
     355             : #endif

Generated by: LCOV version 1.15