LCOV - code coverage report
Current view: top level - core - Value.h (source / functions) Hit Total Coverage
Test: plumed test coverage Lines: 35 37 94.6 %
Date: 2020-11-18 11:20:57 Functions: 5 5 100.0 %

          Line data    Source code
       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
       2             :    Copyright (c) 2011-2019 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_core_Value_h
      23             : #define __PLUMED_core_Value_h
      24             : 
      25             : #include <vector>
      26             : #include <string>
      27             : #include <map>
      28             : #include "tools/Exception.h"
      29             : #include "tools/Tools.h"
      30             : #include "tools/AtomNumber.h"
      31             : #include "tools/Vector.h"
      32             : 
      33             : namespace PLMD {
      34             : 
      35             : class ActionWithValue;
      36             : 
      37             : /// \ingroup TOOLBOX
      38             : /// A class for holding the value of a function together with its derivatives.
      39             : /// Typically, an  object of type PLMD::ActionWithValue will contain one
      40             : /// object of type PLUMD::Value that will be named after the label.  If the
      41             : /// PLMD::ActionWithValue is part of a class that calculates multiple components
      42             : /// then the class will contain multiple that will be called label.component-name
      43             : /// This class is used to pass information between different PLMD::Action
      44             : /// objects.  However, if you find a use for a tempory PLMD::Value in some method
      45             : /// you are implementing please feel free to use it.
      46     2455190 : class Value {
      47             :   friend class ActionWithValue;
      48             : /// This copies the contents of a value into a second value (just the derivatives and value)
      49             :   friend void copy( const Value& val1, Value& val2 );
      50             : /// This copies the contents of a value into a second value (but second value is a pointer)
      51             :   friend void copy( const Value& val, Value* val2 );
      52             : /// This adds some derivatives onto the value
      53             :   friend void add( const Value& val1, Value* valout );
      54             : /// This calculates val1*val2 and sorts out the derivatives
      55             :   friend void product( const Value& val1, const Value& val2, Value& valout );
      56             : /// This calculates va1/val2 and sorts out the derivatives
      57             :   friend void quotient( const Value& val1, const Value& val2, Value* valout );
      58             : private:
      59             : /// The action in which this quantity is calculated
      60             :   ActionWithValue* action;
      61             : /// Had the value been set
      62             :   bool value_set;
      63             : /// The value of the quantity
      64             :   double value;
      65             : /// The force acting on this quantity
      66             :   double inputForce;
      67             : /// A flag telling us we have a force acting on this quantity
      68             :   bool hasForce;
      69             : /// The derivatives of the quantity stored in value
      70             :   std::vector<double> derivatives;
      71             :   std::map<AtomNumber,Vector> gradients;
      72             : /// The name of this quantiy
      73             :   std::string name;
      74             : /// Does this quanity have derivatives
      75             :   bool hasDeriv;
      76             : /// Is this quantity periodic
      77             :   enum {unset,periodic,notperiodic} periodicity;
      78             : /// Various quantities that describe the domain of this value
      79             :   std::string str_min, str_max;
      80             :   double min,max;
      81             :   double max_minus_min;
      82             :   double inv_max_minus_min;
      83             : /// Complete the setup of the periodicity
      84             :   void setupPeriodicity();
      85             : // bring value within PBCs
      86             :   void applyPeriodicity();
      87             : public:
      88             : /// A constructor that can be used to make Vectors of values
      89             :   Value();
      90             : /// A constructor that is used throughout the code to setup the value poiters
      91             :   Value(ActionWithValue* av, const std::string& name, const bool withderiv);
      92             : /// Set the value of the function
      93             :   void set(double);
      94             : /// Add something to the value of the function
      95             :   void add(double);
      96             : /// Get the value of the function
      97             :   double get() const;
      98             : /// Find out if the value has been set
      99             :   bool valueHasBeenSet() const;
     100             : /// Check if the value is periodic
     101             :   bool isPeriodic() const;
     102             : /// Set the function not periodic
     103             :   void setNotPeriodic();
     104             : /// Set the domain of the function
     105             :   void setDomain(const std::string&, const std::string&);
     106             : /// Get the domain of the quantity
     107             :   void getDomain(std::string&,std::string&) const;
     108             : /// Get the domain of the quantity
     109             :   void getDomain(double&,double&) const;
     110             : /// Get the name of the quantity
     111             :   const std::string& getName() const;
     112             : /// Check whether or not this particular quantity has derivatives
     113             :   bool hasDerivatives()const;
     114             : /// Get the number of derivatives that this particular value has
     115             :   unsigned getNumberOfDerivatives() const;
     116             : /// Set the number of derivatives
     117             :   void resizeDerivatives(int n);
     118             : /// Set all the derivatives to zero
     119             :   void clearDerivatives();
     120             : /// Add some derivative to the ith component of the derivatives array
     121             :   void addDerivative(unsigned i,double d);
     122             : /// Set the value of the ith component of the derivatives array
     123             :   void setDerivative(unsigned i, double d);
     124             : /// Apply the chain rule to the derivatives
     125             :   void chainRule(double df);
     126             : /// Get the derivative with respect to component n
     127             :   double getDerivative(const unsigned n) const;
     128             : /// Clear the input force on the variable
     129             :   void clearInputForce();
     130             : /// Add some force on this value
     131             :   void  addForce(double f);
     132             : /// Get the value of the force on this colvar
     133             :   double getForce() const ;
     134             : /// Apply the forces to the derivatives using the chain rule (if there are no forces this routine returns false)
     135             :   bool applyForce( std::vector<double>& forces ) const ;
     136             : /// Calculate the difference between the instantaneous value of the function and some other point: other_point-inst_val
     137             :   double difference(double)const;
     138             : /// Calculate the difference between two values of this function: d2 -d1
     139             :   double difference(double d1,double d2)const;
     140             : /// This returns the pointer to the action where this value is calculated
     141             :   ActionWithValue* getPntrToAction();
     142             : /// Bring back one value into the correct pbc if needed, else give back the value
     143             :   double bringBackInPbc(double d1)const;
     144             : /// This sets up the gradients
     145             :   void setGradients();
     146             :   static double projection(const Value&,const Value&);
     147             : };
     148             : 
     149             : void copy( const Value& val1, Value& val2 );
     150             : void copy( const Value& val1, Value* val2 );
     151             : void add( const Value& val1, Value* valout );
     152             : 
     153             : inline
     154    39215596 : void Value::applyPeriodicity() {
     155    39215596 :   if(periodicity==periodic) {
     156    30688010 :     value=min+difference(min,value);
     157    30688010 :     if(value<min)value+=max_minus_min;
     158             :   }
     159    39215596 : }
     160             : 
     161             : inline
     162             : void product( const Value& val1, const Value& val2, Value& valout ) {
     163             :   plumed_assert( val1.derivatives.size()==val2.derivatives.size() );
     164             :   if( valout.derivatives.size()!=val1.derivatives.size() ) valout.resizeDerivatives( val1.derivatives.size() );
     165             :   valout.value_set=false;
     166             :   valout.clearDerivatives();
     167             :   double u=val1.value;
     168             :   double v=val2.value;
     169             :   for(unsigned i=0; i<val1.derivatives.size(); ++i) {
     170             :     valout.addDerivative(i, u*val2.derivatives[i] + v*val1.derivatives[i] );
     171             :   }
     172             :   valout.set( u*v );
     173             : }
     174             : 
     175             : inline
     176             : void quotient( const Value& val1, const Value& val2, Value* valout ) {
     177             :   plumed_assert( val1.derivatives.size()==val2.derivatives.size() );
     178             :   if( valout->derivatives.size()!=val1.derivatives.size() ) valout->resizeDerivatives( val1.derivatives.size() );
     179             :   valout->value_set=false;
     180             :   valout->clearDerivatives();
     181             :   double u=val1.get();
     182             :   double v=val2.get();
     183             :   for(unsigned i=0; i<val1.getNumberOfDerivatives(); ++i) {
     184             :     valout->addDerivative(i, v*val1.getDerivative(i) - u*val2.getDerivative(i) );
     185             :   }
     186             :   valout->chainRule( 1/(v*v) ); valout->set( u / v );
     187             : }
     188             : 
     189             : inline
     190             : void Value::set(double v) {
     191    39089215 :   value_set=true;
     192    39215596 :   value=v;
     193    39215596 :   applyPeriodicity();
     194             : }
     195             : 
     196             : inline
     197             : void Value::add(double v) {
     198             :   value_set=true;
     199             :   value+=v;
     200             :   applyPeriodicity();
     201             : }
     202             : 
     203             : inline
     204             : double Value::get()const {
     205    42061876 :   return value;
     206             : }
     207             : 
     208             : inline
     209             : bool Value::valueHasBeenSet() const {
     210           0 :   return value_set;
     211             : }
     212             : 
     213             : inline
     214             : const std::string& Value::getName()const {
     215     3245018 :   return name;
     216             : }
     217             : 
     218             : inline
     219      338586 : unsigned Value::getNumberOfDerivatives() const {
     220      338586 :   plumed_massert(hasDeriv,"the derivatives array for this value has zero size");
     221      338586 :   return derivatives.size();
     222             : }
     223             : 
     224             : inline
     225             : double Value::getDerivative(const unsigned n) const {
     226             :   plumed_dbg_massert(n<derivatives.size(),"you are asking for a derivative that is out of bounds");
     227    82785980 :   return derivatives[n];
     228             : }
     229             : 
     230             : inline
     231             : bool Value::hasDerivatives() const {
     232       13030 :   return hasDeriv;
     233             : }
     234             : 
     235             : inline
     236             : void Value::resizeDerivatives(int n) {
     237  4102745976 :   if(hasDeriv) derivatives.resize(n);
     238             : }
     239             : 
     240             : inline
     241             : void Value::addDerivative(unsigned i,double d) {
     242             :   plumed_dbg_massert(i<derivatives.size(),"derivative is out of bounds");
     243   129695818 :   derivatives[i]+=d;
     244             : }
     245             : 
     246             : inline
     247             : void Value::setDerivative(unsigned i, double d) {
     248             :   plumed_dbg_massert(i<derivatives.size(),"derivative is out of bounds");
     249      110981 :   derivatives[i]=d;
     250             : }
     251             : 
     252             : inline
     253             : void Value::chainRule(double df) {
     254       48790 :   for(unsigned i=0; i<derivatives.size(); ++i) derivatives[i]*=df;
     255             : }
     256             : 
     257             : inline
     258             : void Value::clearInputForce() {
     259      426184 :   hasForce=false;
     260      426184 :   inputForce=0.0;
     261             : }
     262             : 
     263             : inline
     264             : void Value::clearDerivatives() {
     265      433601 :   value_set=false;
     266      867202 :   std::fill(derivatives.begin(), derivatives.end(), 0);
     267             : }
     268             : 
     269             : inline
     270             : void Value::addForce(double f) {
     271             :   plumed_dbg_massert(hasDerivatives(),"forces can only be added to values with derivatives");
     272      118645 :   hasForce=true;
     273      118645 :   inputForce+=f;
     274             : }
     275             : 
     276             : inline
     277             : double Value::getForce() const {
     278        4698 :   return inputForce;
     279             : }
     280             : /// d2-d1
     281             : inline
     282    86277149 : double Value::difference(double d1,double d2)const {
     283    86277149 :   if(periodicity==notperiodic) {
     284    21544706 :     return d2-d1;
     285    64732443 :   } else if(periodicity==periodic) {
     286    64732443 :     double s=(d2-d1)*inv_max_minus_min;
     287             :     // remember: pbc brings the difference in a range of -0.5:0.5
     288             :     s=Tools::pbc(s);
     289    64732443 :     return s*max_minus_min;
     290           0 :   } else plumed_merror("periodicity should be set to compute differences");
     291             : }
     292             : 
     293             : inline
     294             : double Value::bringBackInPbc(double d1)const {
     295         690 :   return min+max_minus_min/2.+difference(min+max_minus_min/2., d1);
     296             : }
     297             : 
     298             : inline
     299             : double Value::difference(double d)const {
     300    41605998 :   return difference(get(),d);
     301             : }
     302             : 
     303             : }
     304             : 
     305             : #endif
     306             : 

Generated by: LCOV version 1.13