Line data Source code
1 : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 : Copyright (c) 2014-2018 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 113078 : 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 171937347 : unsigned MultiValue::getNumberOfValues() const {
110 171937347 : return values.size();
111 : }
112 :
113 : inline
114 30236803 : unsigned MultiValue::getNumberOfDerivatives() const {
115 30236803 : return nderivatives; //derivatives.ncols();
116 : }
117 :
118 : inline
119 172551914 : double MultiValue::get( const unsigned& ival ) const {
120 : plumed_dbg_assert( ival<=values.size() );
121 172551914 : return values[ival];
122 : }
123 :
124 : inline
125 1846166 : void MultiValue::setValue( const unsigned& ival, const double& val) {
126 : plumed_dbg_assert( ival<=values.size() );
127 1846166 : values[ival]=val;
128 1847985 : }
129 :
130 : inline
131 56323571 : void MultiValue::addValue( const unsigned& ival, const double& val) {
132 : plumed_dbg_assert( ival<=values.size() );
133 56323571 : values[ival]+=val;
134 56324281 : }
135 :
136 : inline
137 1249133217 : void MultiValue::addDerivative( const unsigned& ival, const unsigned& jder, const double& der) {
138 1249133217 : plumed_dbg_assert( ival<=values.size() && jder<nderivatives ); atLeastOneSet=true;
139 1249133217 : hasDerivatives.activate(jder); derivatives[nderivatives*ival+jder] += der;
140 1249878045 : }
141 :
142 : inline
143 2688839 : void MultiValue::addTemporyValue( const double& val ) {
144 2688839 : tmpval += val;
145 2688839 : }
146 :
147 : inline
148 34227933 : void MultiValue::addTemporyDerivative( const unsigned& jder, const double& der ) {
149 34227933 : plumed_dbg_assert( jder<nderivatives ); atLeastOneSet=true;
150 34227933 : hasDerivatives.activate(jder); tmpder[jder] += der;
151 34229641 : }
152 :
153 :
154 : inline
155 142505121 : void MultiValue::setDerivative( const unsigned& ival, const unsigned& jder, const double& der) {
156 142505121 : plumed_dbg_assert( ival<=values.size() && jder<nderivatives ); atLeastOneSet=true;
157 142505121 : hasDerivatives.activate(jder); derivatives[nderivatives*ival+jder]=der;
158 142552035 : }
159 :
160 :
161 : inline
162 595518822 : double MultiValue::getDerivative( const unsigned& ival, const unsigned& jder ) const {
163 : plumed_dbg_assert( jder<nderivatives && hasDerivatives.isActive(jder) );
164 595518822 : return derivatives[nderivatives*ival+jder];
165 : }
166 :
167 : inline
168 42576 : double MultiValue::getTemporyDerivative( const unsigned& jder ) const {
169 : plumed_dbg_assert( jder<nderivatives && hasDerivatives.isActive(jder) );
170 42576 : return tmpder[jder];
171 : }
172 :
173 : inline
174 1081628 : bool MultiValue::updateComplete() {
175 1081628 : return hasDerivatives.updateComplete();
176 : }
177 :
178 : inline
179 819583 : void MultiValue::emptyActiveMembers() {
180 819583 : hasDerivatives.emptyActiveMembers();
181 819919 : }
182 :
183 : inline
184 76181921 : void MultiValue::putIndexInActiveArray( const unsigned& ind ) {
185 76181921 : hasDerivatives.putIndexInActiveArray( ind );
186 76190865 : }
187 :
188 : inline
189 221028 : void MultiValue::updateIndex( const unsigned& ind ) {
190 221028 : if( hasDerivatives.isActive(ind) ) hasDerivatives.putIndexInActiveArray( ind );
191 220229 : }
192 :
193 : inline
194 53988 : void MultiValue::sortActiveList() {
195 53988 : hasDerivatives.sortActiveList();
196 53988 : }
197 :
198 : inline
199 766438 : void MultiValue::completeUpdate() {
200 766438 : hasDerivatives.completeUpdate();
201 766927 : }
202 :
203 : inline
204 38879922 : unsigned MultiValue::getNumberActive() const {
205 38879922 : return hasDerivatives.getNumberActive();
206 : }
207 :
208 : inline
209 38386233 : unsigned MultiValue::getActiveIndex( const unsigned& ind ) const {
210 : plumed_dbg_assert( ind<hasDerivatives.getNumberActive() );
211 38386233 : return hasDerivatives[ind];
212 : }
213 :
214 : inline
215 137562 : void MultiValue::updateDynamicList() {
216 137562 : if( atLeastOneSet ) hasDerivatives.updateActiveMembers();
217 137562 : }
218 :
219 : inline
220 582828 : std::vector<unsigned>& MultiValue::getIndices() {
221 582828 : return indices;
222 : }
223 :
224 : inline
225 420502 : std::vector<unsigned>& MultiValue::getSortIndices() {
226 420502 : return sort_indices;
227 : }
228 :
229 : inline
230 17839263 : std::vector<Vector>& MultiValue::getAtomVector() {
231 17839263 : return tmp_atoms;
232 : }
233 :
234 : inline
235 33002861 : bool MultiValue::isActive( const unsigned& ind ) const {
236 33002861 : return hasDerivatives.isActive( ind );
237 : }
238 :
239 : }
240 : #endif
|