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