LCOV - code coverage report
Current view: top level - vesselbase - StoreDataVessel.cpp (source / functions) Hit Total Coverage
Test: plumed test coverage Lines: 84 90 93.3 %
Date: 2021-11-18 15:22:58 Functions: 17 17 100.0 %

          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 : }

Generated by: LCOV version 1.14