Line data Source code
1 : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 : Copyright (c) 2014-2019 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 224514 : 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 172154129 : return values.size();
111 : }
112 :
113 : inline
114 : unsigned MultiValue::getNumberOfDerivatives() const {
115 31048373 : return nderivatives; //derivatives.ncols();
116 : }
117 :
118 : inline
119 : double MultiValue::get( const unsigned& ival ) const {
120 : plumed_dbg_assert( ival<=values.size() );
121 344302971 : 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 2388879 : 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 115739240 : values[ival]+=val;
134 : }
135 :
136 : inline
137 1308808595 : void MultiValue::addDerivative( const unsigned& ival, const unsigned& jder, const double& der) {
138 1308808595 : plumed_dbg_assert( ival<=values.size() && jder<nderivatives ); atLeastOneSet=true;
139 2617617190 : hasDerivatives.activate(jder); derivatives[nderivatives*ival+jder] += der;
140 1308808595 : }
141 :
142 : inline
143 : void MultiValue::addTemporyValue( const double& val ) {
144 2752171 : tmpval += val;
145 : }
146 :
147 : inline
148 : void MultiValue::addTemporyDerivative( const unsigned& jder, const double& der ) {
149 35713254 : plumed_dbg_assert( jder<nderivatives ); atLeastOneSet=true;
150 71426508 : 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 127331615 : plumed_dbg_assert( ival<=values.size() && jder<nderivatives ); atLeastOneSet=true;
157 289755628 : 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 1245581886 : 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 1384306 : return hasDerivatives.updateComplete();
176 : }
177 :
178 : inline
179 : void MultiValue::emptyActiveMembers() {
180 946777 : hasDerivatives.emptyActiveMembers();
181 : }
182 :
183 : inline
184 : void MultiValue::putIndexInActiveArray( const unsigned& ind ) {
185 78336980 : 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 56130 : hasDerivatives.sortActiveList();
196 : }
197 :
198 : inline
199 : void MultiValue::completeUpdate() {
200 890647 : hasDerivatives.completeUpdate();
201 : }
202 :
203 : inline
204 : unsigned MultiValue::getNumberActive() const {
205 41483825 : 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 140603 : if( atLeastOneSet ) hasDerivatives.updateActiveMembers();
217 : }
218 :
219 : inline
220 : std::vector<unsigned>& MultiValue::getIndices() {
221 683668 : return indices;
222 : }
223 :
224 : inline
225 : std::vector<unsigned>& MultiValue::getSortIndices() {
226 462029 : return sort_indices;
227 : }
228 :
229 : inline
230 : std::vector<Vector>& MultiValue::getAtomVector() {
231 690641 : return tmp_atoms;
232 : }
233 :
234 : inline
235 : bool MultiValue::isActive( const unsigned& ind ) const {
236 421032144 : return hasDerivatives.isActive( ind );
237 : }
238 :
239 : }
240 : #endif
|