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 "DynamicList.h" 27 : #include <vector> 28 : #include <cstddef> 29 : 30 : namespace PLMD { 31 : 32 : class MultiValue { 33 : private: 34 : /// Used to ensure rapid accumulation of derivatives 35 : DynamicList<unsigned> hasDerivatives; 36 : /// Values of quantities 37 : std::vector<double> values; 38 : /// Number of derivatives per value 39 : unsigned nderivatives; 40 : /// Derivatives 41 : std::vector<double> derivatives; 42 : /// Tempory value 43 : double tmpval; 44 : /// Tempory vector of derivatives (used for calculating quotients 45 : std::vector<double> tmpder; 46 : /// Logical to check if any derivatives were set 47 : bool atLeastOneSet; 48 : /// This is a fudge to save on vector resizing in MultiColvar 49 : std::vector<unsigned> indices, sort_indices; 50 : std::vector<Vector> tmp_atoms; 51 : public: 52 : MultiValue( const std::size_t&, const std::size_t& ); 53 : void resize( const std::size_t&, const std::size_t& ); 54 : /// 55 : std::vector<unsigned>& getIndices(); 56 : std::vector<unsigned>& getSortIndices(); 57 : std::vector<Vector>& getAtomVector(); 58 : /// Get the number of values in the stash 59 : unsigned getNumberOfValues() const ; 60 : /// Get the number of derivatives in the stash 61 : unsigned getNumberOfDerivatives() const ; 62 : /// Set value numbered 63 : void setValue( const unsigned&, const double& ); 64 : /// Add value numbered 65 : void addValue( const unsigned&, const double& ); 66 : /// Add derivative 67 : void addDerivative( const unsigned&, const unsigned&, const double& ); 68 : /// Add to the tempory value 69 : void addTemporyValue( const double& val ); 70 : /// Add tempory derivatives - this is used for calculating quotients 71 : void addTemporyDerivative( const unsigned& jder, const double& der ); 72 : /// Set the value of the derivative 73 : void setDerivative( const unsigned& ival, const unsigned& jder, const double& der); 74 : /// Return the ith value 75 : double get( const unsigned& ) const ; 76 : /// Return a derivative value 77 : double getDerivative( const unsigned&, const unsigned& ) const ; 78 : /// Get one of the tempory derivatives 79 : double getTemporyDerivative( const unsigned& jder ) const ; 80 : /// Clear all values 81 : void clearAll(); 82 : /// Clear the tempory derivatives 83 : void clearTemporyDerivatives(); 84 : /// Clear a value 85 : void clear( const unsigned& ); 86 : /// Functions for accessing active list 87 : bool updateComplete(); 88 : void emptyActiveMembers(); 89 : void putIndexInActiveArray( const unsigned & ); 90 : void updateIndex( const unsigned& ); 91 : void sortActiveList(); 92 : void completeUpdate(); 93 : void updateDynamicList(); 94 : bool isActive( const unsigned& ind ) const ; 95 : /// 96 : unsigned getNumberActive() const ; 97 : /// 98 : unsigned getActiveIndex( const unsigned& ) const ; 99 : /// Transfer derivatives to buffer 100 : void chainRule( const unsigned&, const unsigned&, const unsigned&, const unsigned&, const double&, const unsigned&, std::vector<double>& buffer ); 101 : /// 102 : void copyValues( MultiValue& ) const ; 103 : /// 104 : void copyDerivatives( MultiValue& ); 105 : /// 106 : void quotientRule( const unsigned& nder, const unsigned& oder ); 107 : }; 108 : 109 : inline 110 : unsigned MultiValue::getNumberOfValues() const { 111 172453933 : return values.size(); 112 : } 113 : 114 : inline 115 : unsigned MultiValue::getNumberOfDerivatives() const { 116 42123609 : return nderivatives; //derivatives.ncols(); 117 : } 118 : 119 : inline 120 : double MultiValue::get( const unsigned& ival ) const { 121 : plumed_dbg_assert( ival<=values.size() ); 122 174428519 : return values[ival]; 123 : } 124 : 125 : inline 126 : void MultiValue::setValue( const unsigned& ival, const double& val) { 127 : plumed_dbg_assert( ival<=values.size() ); 128 2362175 : values[ival]=val; 129 : } 130 : 131 : inline 132 : void MultiValue::addValue( const unsigned& ival, const double& val) { 133 : plumed_dbg_assert( ival<=values.size() ); 134 63014961 : values[ival]+=val; 135 : } 136 : 137 : inline 138 1492196192 : void MultiValue::addDerivative( const unsigned& ival, const unsigned& jder, const double& der) { 139 : plumed_dbg_assert( ival<=values.size() && jder<nderivatives ); 140 1492196192 : atLeastOneSet=true; 141 1492196192 : hasDerivatives.activate(jder); 142 1492196192 : derivatives[nderivatives*ival+jder] += der; 143 1492196192 : } 144 : 145 : inline 146 : void MultiValue::addTemporyValue( const double& val ) { 147 2783657 : tmpval += val; 148 : } 149 : 150 : inline 151 36287202 : void MultiValue::addTemporyDerivative( const unsigned& jder, const double& der ) { 152 : plumed_dbg_assert( jder<nderivatives ); 153 36287202 : atLeastOneSet=true; 154 36287202 : hasDerivatives.activate(jder); 155 36287202 : tmpder[jder] += der; 156 36287202 : } 157 : 158 : 159 : inline 160 153445185 : void MultiValue::setDerivative( const unsigned& ival, const unsigned& jder, const double& der) { 161 : plumed_dbg_assert( ival<=values.size() && jder<nderivatives ); 162 153445185 : atLeastOneSet=true; 163 153445185 : hasDerivatives.activate(jder); 164 153445185 : derivatives[nderivatives*ival+jder]=der; 165 153445185 : } 166 : 167 : 168 : inline 169 : double MultiValue::getDerivative( const unsigned& ival, const unsigned& jder ) const { 170 : plumed_dbg_assert( jder<nderivatives && hasDerivatives.isActive(jder) ); 171 546160191 : return derivatives[nderivatives*ival+jder]; 172 : } 173 : 174 : inline 175 : double MultiValue::getTemporyDerivative( const unsigned& jder ) const { 176 : plumed_dbg_assert( jder<nderivatives && hasDerivatives.isActive(jder) ); 177 49704 : return tmpder[jder]; 178 : } 179 : 180 : inline 181 : bool MultiValue::updateComplete() { 182 1782309 : return hasDerivatives.updateComplete(); 183 : } 184 : 185 : inline 186 : void MultiValue::emptyActiveMembers() { 187 1055630 : hasDerivatives.emptyActiveMembers(); 188 : } 189 : 190 : inline 191 : void MultiValue::putIndexInActiveArray( const unsigned& ind ) { 192 35981104 : hasDerivatives.putIndexInActiveArray( ind ); 193 : } 194 : 195 : inline 196 222000 : void MultiValue::updateIndex( const unsigned& ind ) { 197 222000 : if( hasDerivatives.isActive(ind) ) { 198 222000 : hasDerivatives.putIndexInActiveArray( ind ); 199 : } 200 222000 : } 201 : 202 : inline 203 : void MultiValue::sortActiveList() { 204 56305 : hasDerivatives.sortActiveList(); 205 56305 : } 206 : 207 : inline 208 : void MultiValue::completeUpdate() { 209 999325 : hasDerivatives.completeUpdate(); 210 94076 : } 211 : 212 : inline 213 : unsigned MultiValue::getNumberActive() const { 214 44790366 : return hasDerivatives.getNumberActive(); 215 : } 216 : 217 : inline 218 : unsigned MultiValue::getActiveIndex( const unsigned& ind ) const { 219 : plumed_dbg_assert( ind<hasDerivatives.getNumberActive() ); 220 : return hasDerivatives[ind]; 221 : } 222 : 223 : inline 224 : void MultiValue::updateDynamicList() { 225 140764 : if( atLeastOneSet ) { 226 38598 : hasDerivatives.updateActiveMembers(); 227 : } 228 : } 229 : 230 : inline 231 : std::vector<unsigned>& MultiValue::getIndices() { 232 969403 : return indices; 233 : } 234 : 235 : inline 236 : std::vector<unsigned>& MultiValue::getSortIndices() { 237 449463 : return sort_indices; 238 : } 239 : 240 : inline 241 : std::vector<Vector>& MultiValue::getAtomVector() { 242 734994 : return tmp_atoms; 243 : } 244 : 245 : inline 246 : bool MultiValue::isActive( const unsigned& ind ) const { 247 425431400 : return hasDerivatives.isActive( ind ); 248 : } 249 : 250 : } 251 : #endif