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

          Line data    Source code
       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
       2             :    Copyright (c) 2014-2023 The plumed team
       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
       4             : 
       5             :    See http://www.plumed.org for more information.
       6             : 
       7             :    This file is part of plumed, version 2.
       8             : 
       9             :    plumed is free software: you can redistribute it and/or modify
      10             :    it under the terms of the GNU Lesser General Public License as published by
      11             :    the Free Software Foundation, either version 3 of the License, or
      12             :    (at your option) any later version.
      13             : 
      14             :    plumed is distributed in the hope that it will be useful,
      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      17             :    GNU Lesser General Public License for more details.
      18             : 
      19             :    You should have received a copy of the GNU Lesser General Public License
      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
      22             : #ifndef __PLUMED_tools_MultiValue_h
      23             : #define __PLUMED_tools_MultiValue_h
      24             : 
      25             : #include "Exception.h"
      26             : #include "Vector.h"
      27             : #include "Tensor.h"
      28             : #include <vector>
      29             : #include <cstddef>
      30             : 
      31             : namespace PLMD {
      32             : 
      33             : class MultiValue {
      34             :   friend class ActionWithVector;
      35             : private:
      36             : /// The index of the task we are currently performing
      37             :   std::size_t task_index, task2_index;
      38             : /// Values of quantities
      39             :   std::vector<double> values;
      40             : /// Number of derivatives per value
      41             :   unsigned nderivatives;
      42             : /// Derivatives
      43             :   std::vector<double> derivatives;
      44             : /// Matrix asserting which values have derivatives
      45             :   std::vector<bool> hasderiv;
      46             : /// Tempory value
      47             :   double tmpval;
      48             : /// Lists of active variables
      49             :   std::vector<unsigned> nactive, active_list;
      50             : /// Tempory vector of derivatives (used for calculating quotients
      51             :   std::vector<double> tmpder;
      52             : /// Logical to check if any derivatives were set
      53             :   bool atLeastOneSet;
      54             : /// Are we in this for a call on vectors
      55             :   bool vector_call;
      56             :   unsigned nindices, nsplit;
      57             : /// This allows us to store matrix elements
      58             :   unsigned nmatrix_cols;
      59             :   std::vector<double> matrix_row_stash;
      60             :   std::vector<double> matrix_force_stash;
      61             :   std::vector<unsigned> matrix_bookeeping;
      62             : /// These are used to store the indices that have derivatives wrt to at least one
      63             : /// of the elements in a matrix
      64             :   std::vector<unsigned> matrix_row_nderivatives;
      65             :   std::vector<std::vector<unsigned> > matrix_row_derivative_indices;
      66             : /// This is a fudge to save on vector resizing in MultiColvar
      67             :   std::vector<unsigned> indices;
      68             :   std::vector<Vector> tmp_atoms;
      69             :   std::vector<std::vector<Vector> > tmp_atom_der;
      70             :   std::vector<Tensor> tmp_atom_virial;
      71             :   std::vector<std::vector<double> > tmp_vectors;
      72             : public:
      73       26332 :   MultiValue( const std::size_t& nvals, const std::size_t& nder, const std::size_t& nmat=0, const std::size_t& maxcol=0, const std::size_t& nbook=0 );
      74          36 :   void resize( const std::size_t& nvals, const std::size_t& nder, const std::size_t& nmat=0, const std::size_t& maxcol=0, const std::size_t& nbook=0 );
      75             : /// Set the task index prior to the loop
      76             :   void setTaskIndex( const std::size_t& tindex );
      77             : ///
      78             :   std::size_t getTaskIndex() const ;
      79             : ///
      80             :   void setSecondTaskIndex( const std::size_t& tindex );
      81             : /// Get the task index
      82             :   std::size_t getSecondTaskIndex() const ;
      83             : ///
      84             :   void setSplitIndex( const std::size_t& nat );
      85             :   std::size_t getSplitIndex() const ;
      86             : ///
      87             :   void setNumberOfIndices( const std::size_t& nat );
      88             :   std::size_t getNumberOfIndices() const ;
      89             : ///
      90             :   std::vector<unsigned>& getIndices();
      91             :   std::vector<Vector>& getAtomVector();
      92             : /// Get the number of values in the stash
      93             :   unsigned getNumberOfValues() const ;
      94             : /// Get the number of derivatives in the stash
      95             :   unsigned getNumberOfDerivatives() const ;
      96             : /// Get references to some memory. These vectors allow us to
      97             : /// avoid doing lots of resizing of vectors in MultiColvarTemplate
      98             :   std::vector<Vector>& getFirstAtomVector();
      99             :   std::vector<std::vector<Vector> >& getFirstAtomDerivativeVector();
     100             :   const std::vector<std::vector<Vector> >& getConstFirstAtomDerivativeVector() const ;
     101             :   std::vector<Tensor>& getFirstAtomVirialVector();
     102             :   void resizeTemporyVector(const unsigned& n );
     103             :   std::vector<double>& getTemporyVector(const unsigned& ind );
     104             : ///
     105             :   bool inVectorCall() const ;
     106             : /// Set value numbered
     107             :   void setValue( const std::size_t&,  const double& );
     108             : /// Add value numbered
     109             :   void addValue( const std::size_t&,  const double& );
     110             : /// Add derivative
     111             :   void addDerivative( const std::size_t&, const std::size_t&, const double& );
     112             : /// Set the value of the derivative
     113             :   void setDerivative( const std::size_t& ival, const std::size_t& jder, const double& der);
     114             : /// Return the ith value
     115             :   double get( const std::size_t& ) const ;
     116             : /// Return a derivative value
     117             :   double getDerivative( const std::size_t&, const std::size_t& ) const ;
     118             : /// Clear all values
     119             :   void clearAll();
     120             : /// Clear the derivatives
     121             :   void clearDerivatives( const unsigned& );
     122             : /// Clear a value
     123             :   void clear( const unsigned& );
     124             : /// Functions for accessing active list
     125             :   bool updateComplete();
     126             :   void emptyActiveMembers();
     127             :   void putIndexInActiveArray( const unsigned & );
     128             :   void updateIndex( const unsigned& );
     129             : ///
     130             :   void updateIndex( const std::size_t&, const std::size_t& );
     131             : ///
     132             :   unsigned getActiveIndex( const std::size_t&, const std::size_t& ) const ;
     133             : ///
     134             :   void clearActiveMembers( const std::size_t& ival );
     135             : ///
     136             :   unsigned getNumberActive( const std::size_t& ival ) const ;
     137             : ///
     138             :   unsigned getActiveIndex( const unsigned& ) const ;
     139             : /// Get the matrix bookeeping array
     140             :   const std::vector<unsigned> & getMatrixBookeeping() const ;
     141             :   void stashMatrixElement( const unsigned& nmat, const unsigned& rowstart, const unsigned& jcol, const double& val );
     142             :   double getStashedMatrixElement( const unsigned& nmat, const unsigned& jcol ) const ;
     143             : /// Get the bookeeping stuff for the derivatives wrt to rows of matrix
     144             :   void setNumberOfMatrixRowDerivatives( const unsigned& nmat, const unsigned& nind );
     145             :   unsigned getNumberOfMatrixRowDerivatives( const unsigned& nmat ) const ;
     146             :   std::vector<unsigned>& getMatrixRowDerivativeIndices( const unsigned& nmat );
     147             : /// Stash the forces on the matrix
     148             :   void addMatrixForce( const unsigned& imat, const unsigned& jind, const double& f );
     149             :   double getStashedMatrixForce( const unsigned& imat, const unsigned& jind ) const ;
     150             : };
     151             : 
     152             : inline
     153             : unsigned MultiValue::getNumberOfValues() const {
     154             :   return values.size();
     155             : }
     156             : 
     157             : inline
     158             : unsigned MultiValue::getNumberOfDerivatives() const {
     159      163849 :   return nderivatives; //derivatives.ncols();
     160             : }
     161             : 
     162             : inline
     163             : double MultiValue::get( const std::size_t& ival ) const {
     164             :   plumed_dbg_assert( ival<=values.size() );
     165   291523266 :   return values[ival];
     166             : }
     167             : 
     168             : inline
     169             : void MultiValue::setValue( const std::size_t& ival,  const double& val) {
     170             :   plumed_dbg_assert( ival<=values.size() );
     171    25017068 :   values[ival]=val;
     172             : }
     173             : 
     174             : inline
     175             : void MultiValue::addValue( const std::size_t& ival,  const double& val) {
     176             :   plumed_dbg_assert( ival<=values.size() );
     177   187549828 :   values[ival]+=val;
     178             : }
     179             : 
     180             : inline
     181  1064975746 : void MultiValue::addDerivative( const std::size_t& ival, const std::size_t& jder, const double& der) {
     182  1064975746 :   plumed_dbg_assert( ival<=values.size() && jder<nderivatives ); atLeastOneSet=true;
     183  1064975746 :   hasderiv[nderivatives*ival+jder]=true; derivatives[nderivatives*ival+jder] += der;
     184  1064975746 : }
     185             : 
     186             : inline
     187             : void MultiValue::setDerivative( const std::size_t& ival, const std::size_t& jder, const double& der) {
     188             :   plumed_dbg_assert( ival<=values.size() && jder<nderivatives ); atLeastOneSet=true;
     189             :   hasderiv[nderivatives*ival+jder]=true; derivatives[nderivatives*ival+jder]=der;
     190             : }
     191             : 
     192             : 
     193             : inline
     194             : double MultiValue::getDerivative( const std::size_t& ival, const std::size_t& jder ) const {
     195             :   plumed_dbg_assert( ival<values.size() && jder<nderivatives );
     196   888496226 :   return derivatives[nderivatives*ival+jder];
     197             : }
     198             : 
     199             : inline
     200  1951191120 : void MultiValue::updateIndex( const std::size_t& ival, const std::size_t& jder ) {
     201             :   plumed_dbg_assert( ival<values.size() && jder<nderivatives );
     202             : #ifdef DNDEBUG
     203             :   for(unsigned i=0; i<nactive[ival]; ++i) plumed_dbg_assert( active_list[nderivatives*ival+nactive[ival]]!=jder );
     204             : #endif
     205  1951191120 :   if( hasderiv[nderivatives*ival+jder] ) {
     206             :     plumed_dbg_assert( nactive[ival]<nderivatives);
     207   557035706 :     active_list[nderivatives*ival+nactive[ival]]=jder;
     208   557035706 :     nactive[ival]++;
     209             :   }
     210  1951191120 : }
     211             : 
     212             : inline
     213             : unsigned MultiValue::getNumberActive( const std::size_t& ival ) const {
     214             :   plumed_dbg_assert( ival<nactive.size() );
     215  1299330336 :   return nactive[ival];
     216             : }
     217             : 
     218             : inline
     219             : unsigned MultiValue::getActiveIndex( const std::size_t& ival, const std::size_t& ind ) const {
     220             :   plumed_dbg_assert( ind<nactive[ival] );
     221  1100607420 :   return active_list[nderivatives*ival+ind];
     222             : }
     223             : 
     224             : inline
     225             : void MultiValue::setSplitIndex( const std::size_t& nat ) {
     226      663993 :   nsplit = nat;
     227             : }
     228             : 
     229             : inline
     230             : std::size_t MultiValue::getSplitIndex() const {
     231   246931070 :   return nsplit;
     232             : }
     233             : 
     234             : inline
     235             : void MultiValue::setNumberOfIndices( const std::size_t& nat ) {
     236      405876 :   nindices = nat;
     237             : }
     238             : 
     239             : inline
     240             : std::size_t MultiValue::getNumberOfIndices() const {
     241    28540953 :   return nindices;
     242             : }
     243             : 
     244             : 
     245             : inline
     246             : bool MultiValue::inVectorCall() const {
     247             :   return (matrix_row_nderivatives.size()>0 && vector_call);
     248             : }
     249             : 
     250             : inline
     251             : void MultiValue::clearActiveMembers( const std::size_t& ival ) {
     252             :   nactive[ival]=0;
     253             : }
     254             : 
     255             : inline
     256             : void MultiValue::setTaskIndex( const std::size_t& tindex ) {
     257    98355224 :   task_index = tindex;
     258             : }
     259             : 
     260             : inline
     261             : std::size_t MultiValue::getTaskIndex() const {
     262    17449808 :   return task_index;
     263             : }
     264             : 
     265             : inline
     266             : void MultiValue::setSecondTaskIndex( const std::size_t& tindex ) {
     267    88130811 :   task2_index = tindex;
     268             : }
     269             : 
     270             : inline
     271             : std::size_t MultiValue::getSecondTaskIndex() const {
     272     6403164 :   return task2_index;
     273             : }
     274             : 
     275             : inline
     276             : std::vector<unsigned>& MultiValue::getIndices() {
     277     1379763 :   return indices;
     278             : }
     279             : 
     280             : inline
     281             : std::vector<Vector>& MultiValue::getAtomVector() {
     282      405876 :   return tmp_atoms;
     283             : }
     284             : 
     285             : inline
     286             : std::vector<Vector>& MultiValue::getFirstAtomVector() {
     287      670728 :   return tmp_atoms;
     288             : }
     289             : 
     290             : inline
     291             : std::vector<std::vector<Vector> >& MultiValue::getFirstAtomDerivativeVector() {
     292     1076604 :   return tmp_atom_der;
     293             : }
     294             : 
     295             : inline
     296             : const std::vector<std::vector<Vector> >& MultiValue::getConstFirstAtomDerivativeVector() const {
     297             :   return tmp_atom_der;
     298             : }
     299             : 
     300             : inline
     301             : std::vector<Tensor>& MultiValue::getFirstAtomVirialVector() {
     302      490140 :   return tmp_atom_virial;
     303             : }
     304             : 
     305             : inline
     306     8598870 : void MultiValue::stashMatrixElement( const unsigned& nmat, const unsigned& rowstart, const unsigned& jcol, const double& val ) {
     307             :   plumed_dbg_assert( jcol<nmatrix_cols && rowstart + matrix_bookeeping[rowstart]<matrix_bookeeping.size() && nmatrix_cols*nmat + matrix_bookeeping[rowstart]<matrix_row_stash.size() );
     308     8598870 :   matrix_bookeeping[rowstart]++; matrix_bookeeping[rowstart + matrix_bookeeping[rowstart]]=jcol; matrix_row_stash[ nmatrix_cols*nmat + jcol] = val;
     309     8598870 : }
     310             : 
     311             : inline
     312             : double MultiValue::getStashedMatrixElement( const unsigned& nmat, const unsigned& jcol ) const {
     313             :   plumed_dbg_assert( nmatrix_cols*nmat + jcol<matrix_row_stash.size() );
     314     7206015 :   return matrix_row_stash[ nmatrix_cols*nmat + jcol ];
     315             : }
     316             : 
     317             : inline
     318             : const std::vector<unsigned> & MultiValue::getMatrixBookeeping() const {
     319             :   return matrix_bookeeping;
     320             : }
     321             : 
     322             : inline
     323             : void MultiValue::setNumberOfMatrixRowDerivatives( const unsigned& nmat, const unsigned& nind ) {
     324             :   plumed_dbg_assert( nmat<matrix_row_nderivatives.size() && nind<=matrix_row_derivative_indices[nmat].size() );
     325    12992400 :   matrix_row_nderivatives[nmat]=nind;
     326             : }
     327             : 
     328             : inline
     329             : unsigned MultiValue::getNumberOfMatrixRowDerivatives( const unsigned& nmat ) const {
     330   108296955 :   plumed_dbg_assert( nmat<matrix_row_nderivatives.size() ); return matrix_row_nderivatives[nmat];
     331             : }
     332             : 
     333             : inline
     334             : std::vector<unsigned>& MultiValue::getMatrixRowDerivativeIndices( const unsigned& nmat ) {
     335     1978950 :   plumed_dbg_assert( nmat<matrix_row_nderivatives.size() ); return matrix_row_derivative_indices[nmat];
     336             : }
     337             : 
     338             : inline
     339             : void MultiValue::addMatrixForce( const unsigned& imat, const unsigned& jind, const double& f ) {
     340    19244157 :   matrix_force_stash[imat*nderivatives + jind]+=f;
     341             : }
     342             : 
     343             : inline
     344             : double MultiValue::getStashedMatrixForce( const unsigned& imat, const unsigned& jind ) const {
     345   842633458 :   return matrix_force_stash[imat*nderivatives + jind];
     346             : }
     347             : 
     348             : inline
     349      490140 : void MultiValue::resizeTemporyVector(const unsigned& n ) {
     350      490140 :   if( n>tmp_vectors.size() ) tmp_vectors.resize(n);
     351      490140 : }
     352             : 
     353             : inline
     354             : std::vector<double>& MultiValue::getTemporyVector(const unsigned& ind ) {
     355             :   plumed_dbg_assert( ind<tmp_vectors.size() );
     356             :   return tmp_vectors[ind];
     357             : }
     358             : 
     359             : }
     360             : #endif

Generated by: LCOV version 1.16