Line data Source code
1 : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 : Copyright (c) 2013-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 : #include "StoreDataVessel.h"
23 :
24 : namespace PLMD {
25 : namespace vesselbase {
26 :
27 29 : void StoreDataVessel::registerKeywords( Keywords& keys ) {
28 58 : Vessel::registerKeywords(keys); keys.remove("LABEL");
29 29 : }
30 :
31 119 : StoreDataVessel::StoreDataVessel( const VesselOptions& da ):
32 : Vessel(da),
33 : max_lowmem_stash(3),
34 : vecsize(0),
35 238 : nspace(0)
36 : {
37 119 : ActionWithValue* myval=dynamic_cast<ActionWithValue*>( getAction() );
38 119 : if( !myval ) hasderiv=false;
39 119 : else hasderiv=!myval->doNotCalculateDerivatives();
40 119 : }
41 :
42 122 : void StoreDataVessel::addActionThatUses( ActionWithVessel* actionThatUses ) {
43 122 : userActions.push_back( actionThatUses );
44 122 : }
45 :
46 1340 : void StoreDataVessel::resize() {
47 2244 : if( getAction()->lowmem || !getAction()->derivativesAreRequired() ) {
48 822 : nspace = 1;
49 822 : active_der.resize( max_lowmem_stash * ( 1 + getAction()->getNumberOfDerivatives() ) );
50 : } else {
51 1036 : if( getAction()->getNumberOfDerivatives()>getAction()->maxderivatives ) {
52 0 : error("not enough memory to store derivatives for action " + getAction()->getLabel() + " use LOWMEM option");
53 : }
54 518 : nspace = 1 + getAction()->maxderivatives;
55 1036 : active_der.resize( getNumberOfStoredValues() * ( 1 + getAction()->maxderivatives ) );
56 : }
57 1340 : vecsize=getAction()->getNumberOfQuantities();
58 : plumed_dbg_assert( vecsize>0 );
59 1340 : resizeBuffer( getNumberOfStoredValues()*vecsize*nspace );
60 1340 : local_buffer.resize( getNumberOfStoredValues()*vecsize*nspace );
61 1340 : }
62 :
63 142159 : void StoreDataVessel::storeValues( const unsigned& myelem, MultiValue& myvals, std::vector<double>& buffer ) const {
64 : plumed_dbg_assert( vecsize>0 );
65 142159 : unsigned jelem = getAction()->getPositionInCurrentTaskList( myelem ); plumed_dbg_assert( jelem<getNumberOfStoredValues() );
66 142159 : unsigned ibuf = bufstart + jelem * vecsize * nspace;
67 1619591 : for(unsigned icomp=0; icomp<vecsize; ++icomp) {
68 1477432 : buffer[ibuf] += myvals.get(icomp); ibuf+=nspace;
69 : }
70 142159 : }
71 :
72 5262 : void StoreDataVessel::storeDerivatives( const unsigned& myelem, MultiValue& myvals, std::vector<double>& buffer, std::vector<unsigned>& der_list ) const {
73 : plumed_dbg_assert( vecsize>0 && getAction()->derivativesAreRequired() && myelem<getAction()->getFullNumberOfTasks() );
74 5262 : unsigned jelem = getAction()->getPositionInCurrentTaskList( myelem );
75 :
76 5262 : if( getAction()->getFullNumberOfTasks()==getNumberOfStoredValues() ) {
77 10524 : der_list[jelem]=myvals.getNumberActive();
78 5262 : unsigned kder = getNumberOfStoredValues() + jelem * ( nspace - 1 );
79 379020 : for(unsigned j=0; j<myvals.getNumberActive(); ++j) { der_list[kder] = myvals.getActiveIndex(j); kder++; }
80 : } else {
81 : // This ensures that active indices are gathered correctly if
82 : // we have multiple tasks contributing to a stored quantity
83 0 : unsigned kder = getNumberOfStoredValues() + jelem * ( nspace - 1 );
84 0 : for(unsigned j=0; j<myvals.getNumberActive(); ++j) {
85 : bool found=false; unsigned jder = myvals.getActiveIndex(j);
86 0 : for(unsigned k=0; k<der_list[jelem]; ++k) {
87 0 : if( der_list[kder+k]==jder ) { found=true; break; }
88 : }
89 0 : if(!found) { der_list[kder+der_list[jelem]]=jder; der_list[jelem]++; }
90 : }
91 : }
92 :
93 : // Store the values of the components and the derivatives
94 26310 : for(unsigned icomp=0; icomp<vecsize; ++icomp) {
95 10524 : unsigned ibuf = bufstart + jelem * ( vecsize*nspace ) + icomp*nspace + 1;
96 758040 : for(unsigned j=0; j<myvals.getNumberActive(); ++j) {
97 : unsigned jder=myvals.getActiveIndex(j);
98 747516 : buffer[ibuf] += myvals.getDerivative( icomp, jder ); ibuf++;
99 : }
100 : }
101 5262 : }
102 :
103 1580345 : void StoreDataVessel::retrieveSequentialValue( const unsigned& jelem, const bool& normed, std::vector<double>& values ) const {
104 : plumed_dbg_assert( values.size()==vecsize );
105 1580345 : unsigned ibuf = jelem * vecsize * nspace;
106 30223010 : for(unsigned i=0; i<vecsize; ++i) { values[i]=local_buffer[ibuf]; ibuf+=nspace; }
107 3804657 : if( normed && values.size()>2 ) getAction()->normalizeVector( values );
108 1580345 : }
109 :
110 1139908 : void StoreDataVessel::retrieveValueWithIndex( const unsigned& myelem, const bool& normed, std::vector<double>& values ) const {
111 : plumed_dbg_assert( values.size()==vecsize );
112 1139908 : unsigned jelem = getStoreIndex( myelem );
113 1139908 : retrieveSequentialValue( jelem, normed, values );
114 1139908 : }
115 :
116 330248 : double StoreDataVessel::retrieveWeightWithIndex( const unsigned& myelem ) const {
117 : plumed_dbg_assert( vecsize>0 );
118 660496 : unsigned jelem = getStoreIndex( myelem ); unsigned ibuf = jelem * vecsize * nspace; return local_buffer[ibuf];
119 : }
120 :
121 157788 : void StoreDataVessel::retrieveDerivatives( const unsigned& myelem, const bool& normed, MultiValue& myvals ) {
122 : plumed_dbg_assert( myvals.getNumberOfValues()==vecsize && myvals.getNumberOfDerivatives()==getAction()->getNumberOfDerivatives() );
123 :
124 157788 : myvals.clearAll();
125 157788 : if( getAction()->lowmem ) {
126 : recalculateStoredQuantity( myelem, myvals );
127 135845 : if( normed ) getAction()->normalizeVectorDerivatives( myvals );
128 : } else {
129 56130 : unsigned jelem = getAction()->getPositionInCurrentTaskList( myelem );
130 : // Retrieve the derivatives for elements 0 and 1 - weight and norm
131 168390 : for(unsigned icomp=0; icomp<vecsize; ++icomp) {
132 112260 : unsigned ibuf = jelem * ( vecsize*nspace ) + icomp*nspace + 1;
133 112260 : unsigned kder = getNumberOfStoredValues() + jelem * ( nspace - 1 );
134 1544910 : for(unsigned j=0; j<active_der[jelem]; ++j) {
135 1320390 : myvals.addDerivative( icomp, active_der[kder], local_buffer[ibuf] );
136 440130 : kder++; ibuf++;
137 : }
138 : }
139 56130 : if( normed ) getAction()->normalizeVectorDerivatives( myvals );
140 : // Now ensure appropriate parts of list are activated
141 : myvals.emptyActiveMembers();
142 56130 : unsigned kder = getNumberOfStoredValues() + jelem * ( nspace - 1 );
143 772455 : for(unsigned j=0; j<active_der[jelem]; ++j) { myvals.putIndexInActiveArray( active_der[kder] ); kder++; }
144 : myvals.sortActiveList();
145 : }
146 157788 : }
147 :
148 142159 : void StoreDataVessel::calculate( const unsigned& current, MultiValue& myvals, std::vector<double>& buffer, std::vector<unsigned>& der_list ) const {
149 :
150 142159 : if( myvals.get(0)>epsilon ) {
151 142159 : storeValues( current, myvals, buffer );
152 178271 : if( !(getAction()->lowmem) && getAction()->derivativesAreRequired() ) storeDerivatives( current, myvals, buffer, der_list );
153 : }
154 :
155 142159 : return;
156 : }
157 :
158 2303 : void StoreDataVessel::finish( const std::vector<double>& buffer ) {
159 : // Store the buffer locally
160 6475792 : for(unsigned i=0; i<local_buffer.size(); ++i) local_buffer[i]=buffer[bufstart+i];
161 2303 : }
162 :
163 :
164 671 : void StoreDataVessel::setActiveValsAndDerivatives( const std::vector<unsigned>& der_index ) {
165 1342 : if( !getAction()->lowmem && getAction()->derivativesAreRequired() ) {
166 674299 : for(unsigned i=0; i<der_index.size(); ++i) active_der[i]=der_index[i];
167 : }
168 671 : }
169 :
170 136 : void StoreDataVessel::resizeTemporyMultiValues( const unsigned& nvals ) {
171 656 : for(unsigned i=0; i<nvals; ++i) my_tmp_vals.push_back( MultiValue(0,0) );
172 136 : }
173 :
174 54972 : MultiValue& StoreDataVessel::getTemporyMultiValue( const unsigned& ind ) {
175 109944 : plumed_dbg_assert( ind<my_tmp_vals.size() ); return my_tmp_vals[ind];
176 : }
177 :
178 : }
179 4839 : }
|