Line data Source code
1 : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 : Copyright (c) 2013-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 : #include "StoreDataVessel.h" 23 : 24 : namespace PLMD { 25 : namespace vesselbase { 26 : 27 26 : void StoreDataVessel::registerKeywords( Keywords& keys ) { 28 52 : Vessel::registerKeywords(keys); keys.remove("LABEL"); 29 26 : } 30 : 31 131 : StoreDataVessel::StoreDataVessel( const VesselOptions& da ): 32 : Vessel(da), 33 : max_lowmem_stash(3), 34 : vecsize(0), 35 262 : nspace(0) 36 : { 37 131 : ActionWithValue* myval=dynamic_cast<ActionWithValue*>( getAction() ); 38 131 : if( !myval ) hasderiv=false; 39 131 : else hasderiv=!myval->doNotCalculateDerivatives(); 40 131 : } 41 : 42 127 : void StoreDataVessel::addActionThatUses( ActionWithVessel* actionThatUses ) { 43 127 : userActions.push_back( actionThatUses ); 44 127 : } 45 : 46 1642 : void StoreDataVessel::resize() { 47 2821 : if( getAction()->lowmem || !getAction()->derivativesAreRequired() ) { 48 1066 : nspace = 1; 49 1066 : active_der.resize( max_lowmem_stash * ( 1 + getAction()->getNumberOfDerivatives() ) ); 50 : } else { 51 1152 : if( getAction()->getNumberOfDerivatives()>getAction()->maxderivatives ) { 52 0 : error("not enough memory to store derivatives for action " + getAction()->getLabel() + " use LOWMEM option"); 53 : } 54 576 : nspace = 1 + getAction()->maxderivatives; 55 1152 : active_der.resize( getNumberOfStoredValues() * ( 1 + getAction()->maxderivatives ) ); 56 : } 57 1642 : vecsize=getAction()->getNumberOfQuantities(); 58 : plumed_dbg_assert( vecsize>0 ); 59 1642 : resizeBuffer( getNumberOfStoredValues()*vecsize*nspace ); 60 1642 : local_buffer.resize( getNumberOfStoredValues()*vecsize*nspace ); 61 1642 : } 62 : 63 148017 : void StoreDataVessel::storeValues( const unsigned& myelem, MultiValue& myvals, std::vector<double>& buffer ) const { 64 : plumed_dbg_assert( vecsize>0 ); 65 148017 : unsigned jelem = getAction()->getPositionInCurrentTaskList( myelem ); plumed_dbg_assert( jelem<getNumberOfStoredValues() ); 66 148017 : unsigned ibuf = bufstart + jelem * vecsize * nspace; 67 1649097 : for(unsigned icomp=0; icomp<vecsize; ++icomp) { 68 1501080 : buffer[ibuf] += myvals.get(icomp); ibuf+=nspace; 69 : } 70 148017 : } 71 : 72 5316 : 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 5316 : unsigned jelem = getAction()->getPositionInCurrentTaskList( myelem ); 75 : 76 5316 : if( getAction()->getFullNumberOfTasks()==getNumberOfStoredValues() ) { 77 10632 : der_list[jelem]=myvals.getNumberActive(); 78 5316 : unsigned kder = getNumberOfStoredValues() + jelem * ( nspace - 1 ); 79 381990 : 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 26796 : for(unsigned icomp=0; icomp<vecsize; ++icomp) { 95 10740 : unsigned ibuf = bufstart + jelem * ( vecsize*nspace ) + icomp*nspace + 1; 96 772512 : for(unsigned j=0; j<myvals.getNumberActive(); ++j) { 97 : unsigned jder=myvals.getActiveIndex(j); 98 761772 : buffer[ibuf] += myvals.getDerivative( icomp, jder ); ibuf++; 99 : } 100 : } 101 5316 : } 102 : 103 1609805 : void StoreDataVessel::retrieveSequentialValue( const unsigned& jelem, const bool& normed, std::vector<double>& values ) const { 104 : plumed_dbg_assert( values.size()==vecsize ); 105 1609805 : unsigned ibuf = jelem * vecsize * nspace; 106 30432794 : for(unsigned i=0; i<vecsize; ++i) { values[i]=local_buffer[ibuf]; ibuf+=nspace; } 107 3834409 : if( normed && values.size()>2 ) getAction()->normalizeVector( values ); 108 1609805 : } 109 : 110 1148018 : void StoreDataVessel::retrieveValueWithIndex( const unsigned& myelem, const bool& normed, std::vector<double>& values ) const { 111 : plumed_dbg_assert( values.size()==vecsize ); 112 1148018 : unsigned jelem = getStoreIndex( myelem ); 113 1148018 : retrieveSequentialValue( jelem, normed, values ); 114 1148018 : } 115 : 116 330340 : double StoreDataVessel::retrieveWeightWithIndex( const unsigned& myelem ) const { 117 : plumed_dbg_assert( vecsize>0 ); 118 660680 : unsigned jelem = getStoreIndex( myelem ); unsigned ibuf = jelem * vecsize * nspace; return local_buffer[ibuf]; 119 : } 120 : 121 157958 : void StoreDataVessel::retrieveDerivatives( const unsigned& myelem, const bool& normed, MultiValue& myvals ) { 122 : plumed_dbg_assert( myvals.getNumberOfValues()==vecsize && myvals.getNumberOfDerivatives()==getAction()->getNumberOfDerivatives() ); 123 : 124 157958 : myvals.clearAll(); 125 157958 : if( getAction()->lowmem ) { 126 : recalculateStoredQuantity( myelem, myvals ); 127 135865 : if( normed ) getAction()->normalizeVectorDerivatives( myvals ); 128 : } else { 129 56280 : unsigned jelem = getAction()->getPositionInCurrentTaskList( myelem ); 130 : // Retrieve the derivatives for elements 0 and 1 - weight and norm 131 169308 : for(unsigned icomp=0; icomp<vecsize; ++icomp) { 132 113028 : unsigned ibuf = jelem * ( vecsize*nspace ) + icomp*nspace + 1; 133 113028 : unsigned kder = getNumberOfStoredValues() + jelem * ( nspace - 1 ); 134 1628742 : for(unsigned j=0; j<active_der[jelem]; ++j) { 135 1402686 : myvals.addDerivative( icomp, active_der[kder], local_buffer[ibuf] ); 136 467562 : kder++; ibuf++; 137 : } 138 : } 139 56280 : if( normed ) getAction()->normalizeVectorDerivatives( myvals ); 140 : // Now ensure appropriate parts of list are activated 141 : myvals.emptyActiveMembers(); 142 56280 : unsigned kder = getNumberOfStoredValues() + jelem * ( nspace - 1 ); 143 786444 : for(unsigned j=0; j<active_der[jelem]; ++j) { myvals.putIndexInActiveArray( active_der[kder] ); kder++; } 144 : myvals.sortActiveList(); 145 : } 146 157958 : } 147 : 148 148017 : void StoreDataVessel::calculate( const unsigned& current, MultiValue& myvals, std::vector<double>& buffer, std::vector<unsigned>& der_list ) const { 149 : 150 148017 : if( myvals.get(0)>epsilon ) { 151 148017 : storeValues( current, myvals, buffer ); 152 185839 : if( !(getAction()->lowmem) && getAction()->derivativesAreRequired() ) storeDerivatives( current, myvals, buffer, der_list ); 153 : } 154 : 155 148017 : return; 156 : } 157 : 158 2541 : void StoreDataVessel::finish( const std::vector<double>& buffer ) { 159 : // Store the buffer locally 160 6556452 : for(unsigned i=0; i<local_buffer.size(); ++i) local_buffer[i]=buffer[bufstart+i]; 161 2541 : } 162 : 163 : 164 689 : void StoreDataVessel::setActiveValsAndDerivatives( const std::vector<unsigned>& der_index ) { 165 1378 : if( !getAction()->lowmem && getAction()->derivativesAreRequired() ) { 166 683731 : for(unsigned i=0; i<der_index.size(); ++i) active_der[i]=der_index[i]; 167 : } 168 689 : } 169 : 170 143 : void StoreDataVessel::resizeTemporyMultiValues( const unsigned& nvals ) { 171 689 : for(unsigned i=0; i<nvals; ++i) my_tmp_vals.push_back( MultiValue(0,0) ); 172 143 : } 173 : 174 55018 : MultiValue& StoreDataVessel::getTemporyMultiValue( const unsigned& ind ) { 175 110036 : plumed_dbg_assert( ind<my_tmp_vals.size() ); return my_tmp_vals[ind]; 176 : } 177 : 178 : } 179 5517 : }