LCOV - code coverage report
Current view: top level - vesselbase - StoreDataVessel.cpp (source / functions) Hit Total Coverage
Test: plumed test coverage Lines: 104 114 91.2 %
Date: 2026-03-30 13:16:06 Functions: 15 15 100.0 %

          Line data    Source code
       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
       2             :    Copyright (c) 2013-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             : #include "StoreDataVessel.h"
      23             : 
      24             : namespace PLMD {
      25             : namespace vesselbase {
      26             : 
      27          26 : void StoreDataVessel::registerKeywords( Keywords& keys ) {
      28          26 :   Vessel::registerKeywords(keys);
      29          26 :   keys.remove("LABEL");
      30          26 : }
      31             : 
      32         131 : StoreDataVessel::StoreDataVessel( const VesselOptions& da ):
      33             :   Vessel(da),
      34         131 :   max_lowmem_stash(3),
      35         131 :   vecsize(0),
      36         131 :   nspace(0) {
      37         131 :   ActionWithValue* myval=dynamic_cast<ActionWithValue*>( getAction() );
      38         131 :   if( !myval ) {
      39           0 :     hasderiv=false;
      40             :   } else {
      41         131 :     hasderiv=!myval->doNotCalculateDerivatives();
      42             :   }
      43         131 : }
      44             : 
      45         127 : void StoreDataVessel::addActionThatUses( ActionWithVessel* actionThatUses ) {
      46         127 :   userActions.push_back( actionThatUses );
      47         127 : }
      48             : 
      49        1643 : void StoreDataVessel::resize() {
      50        1643 :   if( getAction()->lowmem || !getAction()->derivativesAreRequired() ) {
      51        1066 :     nspace = 1;
      52        1066 :     active_der.resize( max_lowmem_stash * ( 1 + getAction()->getNumberOfDerivatives() ) );
      53             :   } else {
      54         577 :     if( getAction()->getNumberOfDerivatives()>getAction()->maxderivatives ) {
      55           0 :       error("not enough memory to store derivatives for action " + getAction()->getLabel() + " use LOWMEM option");
      56             :     }
      57         577 :     nspace = 1 + getAction()->maxderivatives;
      58         577 :     active_der.resize( getNumberOfStoredValues() * ( 1 + getAction()->maxderivatives ) );
      59             :   }
      60        1643 :   vecsize=getAction()->getNumberOfQuantities();
      61             :   plumed_dbg_assert( vecsize>0 );
      62        1643 :   resizeBuffer( getNumberOfStoredValues()*vecsize*nspace );
      63        1643 :   local_buffer.resize( getNumberOfStoredValues()*vecsize*nspace );
      64        1643 : }
      65             : 
      66      148022 : void StoreDataVessel::storeValues( const unsigned& myelem, MultiValue& myvals, std::vector<double>& buffer ) const {
      67             :   plumed_dbg_assert( vecsize>0 );
      68      148022 :   unsigned jelem = getAction()->getPositionInCurrentTaskList( myelem );
      69             :   plumed_dbg_assert( jelem<getNumberOfStoredValues() );
      70      148022 :   unsigned ibuf = bufstart + jelem * vecsize * nspace;
      71      898572 :   for(unsigned icomp=0; icomp<vecsize; ++icomp) {
      72      750550 :     buffer[ibuf] += myvals.get(icomp);
      73      750550 :     ibuf+=nspace;
      74             :   }
      75      148022 : }
      76             : 
      77        5321 : void StoreDataVessel::storeDerivatives( const unsigned& myelem, MultiValue& myvals, std::vector<double>& buffer, std::vector<unsigned>& der_list ) const {
      78             :   plumed_dbg_assert( vecsize>0 && getAction()->derivativesAreRequired() && myelem<getAction()->getFullNumberOfTasks() );
      79        5321 :   unsigned jelem = getAction()->getPositionInCurrentTaskList( myelem );
      80             : 
      81        5321 :   if( getAction()->getFullNumberOfTasks()==getNumberOfStoredValues() ) {
      82        5321 :     der_list[jelem]=myvals.getNumberActive();
      83        5321 :     unsigned kder = getNumberOfStoredValues() + jelem * ( nspace - 1 );
      84      193658 :     for(unsigned j=0; j<myvals.getNumberActive(); ++j) {
      85      188337 :       der_list[kder] = myvals.getActiveIndex(j);
      86      188337 :       kder++;
      87             :     }
      88             :   } else {
      89             :     // This ensures that active indices are gathered correctly if
      90             :     // we have multiple tasks contributing to a stored quantity
      91           0 :     unsigned kder = getNumberOfStoredValues() + jelem * ( nspace - 1 );
      92           0 :     for(unsigned j=0; j<myvals.getNumberActive(); ++j) {
      93             :       bool found=false;
      94             :       unsigned jder = myvals.getActiveIndex(j);
      95           0 :       for(unsigned k=0; k<der_list[jelem]; ++k) {
      96           0 :         if( der_list[kder+k]==jder ) {
      97             :           found=true;
      98             :           break;
      99             :         }
     100             :       }
     101           0 :       if(!found) {
     102           0 :         der_list[kder+der_list[jelem]]=jder;
     103           0 :         der_list[jelem]++;
     104             :       }
     105             :     }
     106             :   }
     107             : 
     108             :   // Store the values of the components and the derivatives
     109       16071 :   for(unsigned icomp=0; icomp<vecsize; ++icomp) {
     110       10750 :     unsigned ibuf = bufstart + jelem * ( vecsize*nspace ) + icomp*nspace + 1;
     111      391636 :     for(unsigned j=0; j<myvals.getNumberActive(); ++j) {
     112             :       unsigned jder=myvals.getActiveIndex(j);
     113      380886 :       buffer[ibuf] += myvals.getDerivative( icomp, jder );
     114      380886 :       ibuf++;
     115             :     }
     116             :   }
     117        5321 : }
     118             : 
     119     1611191 : void StoreDataVessel::retrieveSequentialValue( const unsigned& jelem, const bool& normed, std::vector<double>& values ) const {
     120             :   plumed_dbg_assert( values.size()==vecsize );
     121     1611191 :   unsigned ibuf = jelem * vecsize * nspace;
     122    11257662 :   for(unsigned i=0; i<vecsize; ++i) {
     123     9646471 :     values[i]=local_buffer[ibuf];
     124     9646471 :     ibuf+=nspace;
     125             :   }
     126     1611191 :   if( normed && values.size()>2 ) {
     127     1105384 :     getAction()->normalizeVector( values );
     128             :   }
     129     1611191 : }
     130             : 
     131     1149404 : void StoreDataVessel::retrieveValueWithIndex( const unsigned& myelem, const bool& normed, std::vector<double>& values ) const {
     132             :   plumed_dbg_assert( values.size()==vecsize );
     133     1149404 :   unsigned jelem = getStoreIndex( myelem );
     134     1149404 :   retrieveSequentialValue( jelem, normed, values );
     135     1149404 : }
     136             : 
     137      330385 : double StoreDataVessel::retrieveWeightWithIndex( const unsigned& myelem ) const {
     138             :   plumed_dbg_assert( vecsize>0 );
     139      330385 :   unsigned jelem = getStoreIndex( myelem );
     140      330385 :   unsigned ibuf = jelem * vecsize * nspace;
     141      330385 :   return local_buffer[ibuf];
     142             : }
     143             : 
     144      159369 : void StoreDataVessel::retrieveDerivatives( const unsigned& myelem, const bool& normed, MultiValue& myvals ) {
     145             :   plumed_dbg_assert( myvals.getNumberOfValues()==vecsize && myvals.getNumberOfDerivatives()==getAction()->getNumberOfDerivatives() );
     146             : 
     147      159369 :   myvals.clearAll();
     148      159369 :   if( getAction()->lowmem ) {
     149      103064 :     recalculateStoredQuantity( myelem, myvals );
     150      103064 :     if( normed ) {
     151       34187 :       getAction()->normalizeVectorDerivatives( myvals );
     152             :     }
     153             :   } else {
     154       56305 :     unsigned jelem = getAction()->getPositionInCurrentTaskList( myelem );
     155             :     // Retrieve the derivatives for elements 0 and 1 - weight and norm
     156      169383 :     for(unsigned icomp=0; icomp<vecsize; ++icomp) {
     157      113078 :       unsigned ibuf = jelem * ( vecsize*nspace ) + icomp*nspace + 1;
     158      113078 :       unsigned kder = getNumberOfStoredValues() + jelem * ( nspace - 1 );
     159      580640 :       for(unsigned j=0; j<active_der[jelem]; ++j) {
     160      467562 :         myvals.addDerivative( icomp, active_der[kder], local_buffer[ibuf] );
     161      467562 :         kder++;
     162      467562 :         ibuf++;
     163             :       }
     164             :     }
     165       56305 :     if( normed ) {
     166           0 :       getAction()->normalizeVectorDerivatives( myvals );
     167             :     }
     168             :     // Now ensure appropriate parts of list are activated
     169             :     myvals.emptyActiveMembers();
     170       56305 :     unsigned kder = getNumberOfStoredValues() + jelem * ( nspace - 1 );
     171      280933 :     for(unsigned j=0; j<active_der[jelem]; ++j) {
     172      224628 :       myvals.putIndexInActiveArray( active_der[kder] );
     173      224628 :       kder++;
     174             :     }
     175             :     myvals.sortActiveList();
     176             :   }
     177      159369 : }
     178             : 
     179      148022 : void StoreDataVessel::calculate( const unsigned& current, MultiValue& myvals, std::vector<double>& buffer, std::vector<unsigned>& der_list ) const {
     180             : 
     181      148022 :   if( myvals.get(0)>epsilon ) {
     182      148022 :     storeValues( current, myvals, buffer );
     183      148022 :     if( !(getAction()->lowmem) && getAction()->derivativesAreRequired() ) {
     184        5321 :       storeDerivatives( current, myvals, buffer, der_list );
     185             :     }
     186             :   }
     187             : 
     188      148022 :   return;
     189             : }
     190             : 
     191        2542 : void StoreDataVessel::finish( const std::vector<double>& buffer ) {
     192             :   // Store the buffer locally
     193     2186582 :   for(unsigned i=0; i<local_buffer.size(); ++i) {
     194     2184040 :     local_buffer[i]=buffer[bufstart+i];
     195             :   }
     196        2542 : }
     197             : 
     198             : 
     199         690 : void StoreDataVessel::setActiveValsAndDerivatives( const std::vector<unsigned>& der_index ) {
     200         690 :   if( !getAction()->lowmem && getAction()->derivativesAreRequired() ) {
     201      228266 :     for(unsigned i=0; i<der_index.size(); ++i) {
     202      227576 :       active_der[i]=der_index[i];
     203             :     }
     204             :   }
     205         690 : }
     206             : 
     207         143 : void StoreDataVessel::resizeTemporyMultiValues( const unsigned& nvals ) {
     208         416 :   for(unsigned i=0; i<nvals; ++i) {
     209         546 :     my_tmp_vals.push_back( MultiValue(0,0) );
     210             :   }
     211         143 : }
     212             : 
     213       56449 : MultiValue& StoreDataVessel::getTemporyMultiValue( const unsigned& ind ) {
     214             :   plumed_dbg_assert( ind<my_tmp_vals.size() );
     215       56449 :   return my_tmp_vals[ind];
     216             : }
     217             : 
     218             : }
     219             : }

Generated by: LCOV version 1.16