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 172403989 : return values.size(); 112 : } 113 : 114 : inline 115 : unsigned MultiValue::getNumberOfDerivatives() const { 116 30912249 : return nderivatives; //derivatives.ncols(); 117 : } 118 : 119 : inline 120 : double MultiValue::get( const unsigned& ival ) const { 121 : plumed_dbg_assert( ival<=values.size() ); 122 173450639 : 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 1829471 : 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 62229581 : values[ival]+=val; 135 : } 136 : 137 : inline 138 1359057860 : void MultiValue::addDerivative( const unsigned& ival, const unsigned& jder, const double& der) { 139 1359057860 : plumed_dbg_assert( ival<=values.size() && jder<nderivatives ); atLeastOneSet=true; 140 1359057860 : hasDerivatives.activate(jder); derivatives[nderivatives*ival+jder] += der; 141 1359057860 : } 142 : 143 : inline 144 : void MultiValue::addTemporyValue( const double& val ) { 145 2752543 : tmpval += val; 146 : } 147 : 148 : inline 149 35718834 : void MultiValue::addTemporyDerivative( const unsigned& jder, const double& der ) { 150 35718834 : plumed_dbg_assert( jder<nderivatives ); atLeastOneSet=true; 151 35718834 : hasDerivatives.activate(jder); tmpder[jder] += der; 152 35718834 : } 153 : 154 : 155 : inline 156 145611693 : void MultiValue::setDerivative( const unsigned& ival, const unsigned& jder, const double& der) { 157 145611693 : plumed_dbg_assert( ival<=values.size() && jder<nderivatives ); atLeastOneSet=true; 158 145611693 : hasDerivatives.activate(jder); derivatives[nderivatives*ival+jder]=der; 159 145611693 : } 160 : 161 : 162 : inline 163 : double MultiValue::getDerivative( const unsigned& ival, const unsigned& jder ) const { 164 : plumed_dbg_assert( jder<nderivatives && hasDerivatives.isActive(jder) ); 165 535797285 : return derivatives[nderivatives*ival+jder]; 166 : } 167 : 168 : inline 169 : double MultiValue::getTemporyDerivative( const unsigned& jder ) const { 170 : plumed_dbg_assert( jder<nderivatives && hasDerivatives.isActive(jder) ); 171 49704 : return tmpder[jder]; 172 : } 173 : 174 : inline 175 : bool MultiValue::updateComplete() { 176 1621195 : return hasDerivatives.updateComplete(); 177 : } 178 : 179 : inline 180 : void MultiValue::emptyActiveMembers() { 181 932792 : hasDerivatives.emptyActiveMembers(); 182 : } 183 : 184 : inline 185 : void MultiValue::putIndexInActiveArray( const unsigned& ind ) { 186 32660076 : hasDerivatives.putIndexInActiveArray( ind ); 187 : } 188 : 189 : inline 190 222000 : void MultiValue::updateIndex( const unsigned& ind ) { 191 222000 : if( hasDerivatives.isActive(ind) ) hasDerivatives.putIndexInActiveArray( ind ); 192 222000 : } 193 : 194 : inline 195 : void MultiValue::sortActiveList() { 196 56305 : hasDerivatives.sortActiveList(); 197 56305 : } 198 : 199 : inline 200 : void MultiValue::completeUpdate() { 201 876487 : hasDerivatives.completeUpdate(); 202 94076 : } 203 : 204 : inline 205 : unsigned MultiValue::getNumberActive() const { 206 41498512 : return hasDerivatives.getNumberActive(); 207 : } 208 : 209 : inline 210 : unsigned MultiValue::getActiveIndex( const unsigned& ind ) const { 211 : plumed_dbg_assert( ind<hasDerivatives.getNumberActive() ); 212 : return hasDerivatives[ind]; 213 : } 214 : 215 : inline 216 : void MultiValue::updateDynamicList() { 217 140764 : if( atLeastOneSet ) hasDerivatives.updateActiveMembers(); 218 : } 219 : 220 : inline 221 : std::vector<unsigned>& MultiValue::getIndices() { 222 919363 : return indices; 223 : } 224 : 225 : inline 226 : std::vector<unsigned>& MultiValue::getSortIndices() { 227 447981 : return sort_indices; 228 : } 229 : 230 : inline 231 : std::vector<Vector>& MultiValue::getAtomVector() { 232 678709 : return tmp_atoms; 233 : } 234 : 235 : inline 236 : bool MultiValue::isActive( const unsigned& ind ) const { 237 423929148 : return hasDerivatives.isActive( ind ); 238 : } 239 : 240 : } 241 : #endif