LCOV - code coverage report
Current view: top level - multicolvar - BridgedMultiColvarFunction.cpp (source / functions) Hit Total Coverage
Test: plumed test coverage Lines: 61 67 91.0 %
Date: 2026-03-30 13:16:06 Functions: 9 11 81.8 %

          Line data    Source code
       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
       2             :    Copyright (c) 2014-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 "BridgedMultiColvarFunction.h"
      23             : #include "core/PlumedMain.h"
      24             : #include "core/ActionSet.h"
      25             : #include "CatomPack.h"
      26             : 
      27             : namespace PLMD {
      28             : namespace multicolvar {
      29             : 
      30          96 : void BridgedMultiColvarFunction::registerKeywords( Keywords& keys ) {
      31          96 :   MultiColvarBase::registerKeywords( keys );
      32         192 :   keys.add("compulsory","DATA","The multicolvar that calculates the set of base quantities that we are interested in");
      33          96 : }
      34             : 
      35          44 : BridgedMultiColvarFunction::BridgedMultiColvarFunction(const ActionOptions&ao):
      36             :   Action(ao),
      37          44 :   MultiColvarBase(ao) {
      38             :   std::string mlab;
      39          44 :   parse("DATA",mlab);
      40          44 :   mycolv = plumed.getActionSet().selectWithLabel<MultiColvarBase*>(mlab);
      41          44 :   if(!mycolv) {
      42           0 :     error("action labeled " + mlab + " does not exist or is not a multicolvar");
      43             :   }
      44             : 
      45             :   // When using numerical derivatives here we must use numerical derivatives
      46             :   // in base multicolvar
      47          44 :   if( checkNumericalDerivatives() ) {
      48           1 :     mycolv->useNumericalDerivatives();
      49             :   }
      50             : 
      51          44 :   myBridgeVessel = mycolv->addBridgingVessel( this );
      52          44 :   addDependency(mycolv);
      53          44 :   weightHasDerivatives=true;
      54          44 :   usespecies=mycolv->usespecies;
      55             :   // Number of tasks is the same as the number in the underlying MultiColvar
      56       20060 :   for(unsigned i=0; i<mycolv->getFullNumberOfTasks(); ++i) {
      57       20016 :     addTaskToList( mycolv->getTaskCode(i) );
      58             :   }
      59          44 : }
      60             : 
      61          45 : void BridgedMultiColvarFunction::turnOnDerivatives() {
      62          45 :   BridgedMultiColvarFunction* check = dynamic_cast<BridgedMultiColvarFunction*>( mycolv );
      63          45 :   if( check ) {
      64           0 :     if( check->getNumberOfAtoms()>0 ) {
      65           0 :       error("cannot calculate required derivatives of this quantity");
      66             :     }
      67             :   }
      68          45 :   MultiColvarBase::turnOnDerivatives();
      69          45 : }
      70             : 
      71      100985 : void BridgedMultiColvarFunction::transformBridgedDerivatives( const unsigned& current, MultiValue& invals, MultiValue& outvals ) const {
      72      100985 :   completeTask( current, invals, outvals );
      73             : 
      74             :   // Now update the outvals derivatives lists
      75      100985 :   if( derivativesAreRequired() ) {
      76             :     outvals.emptyActiveMembers();
      77       94076 :     if( mycolv->isDensity() ) {
      78      173680 :       for(unsigned j=0; j<3; ++j) {
      79      130260 :         outvals.putIndexInActiveArray( 3*current+j );
      80             :       }
      81      434200 :       for(unsigned j=invals.getNumberOfDerivatives()-9; j<invals.getNumberOfDerivatives(); ++j) {
      82             :         outvals.putIndexInActiveArray(j);
      83             :       }
      84             :     } else {
      85     3766585 :       for(unsigned j=0; j<invals.getNumberActive(); ++j) {
      86     3715929 :         outvals.putIndexInActiveArray( invals.getActiveIndex(j) );
      87             :       }
      88             :     }
      89      342431 :     for(unsigned j=invals.getNumberOfDerivatives(); j<outvals.getNumberOfDerivatives(); ++j) {
      90             :       outvals.putIndexInActiveArray( j );
      91             :     }
      92             :     outvals.completeUpdate();
      93             :   }
      94      100985 : }
      95             : 
      96       13042 : void BridgedMultiColvarFunction::performTask( const unsigned& taskIndex, const unsigned& current, MultiValue& myvals ) const {
      97             :   // This allows us to speed up the code as we don't need to reallocate memory on every call of perform task
      98       13042 :   MultiValue& invals=myBridgeVessel->getTemporyMultiValue();
      99       26080 :   if( invals.getNumberOfValues()!=mycolv->getNumberOfQuantities() ||
     100       13038 :       invals.getNumberOfDerivatives()!=mycolv->getNumberOfDerivatives() ) {
     101           4 :     invals.resize( mycolv->getNumberOfQuantities(), mycolv->getNumberOfDerivatives() );
     102             :   }
     103       13042 :   invals.clearAll();
     104       13042 :   mycolv->performTask( taskIndex, current, invals );
     105       13042 :   transformBridgedDerivatives( taskIndex, invals, myvals );
     106       13042 : }
     107             : 
     108          60 : void BridgedMultiColvarFunction::calculateNumericalDerivatives( ActionWithValue* a ) {
     109          60 :   if(!a) {
     110          60 :     a=dynamic_cast<ActionWithValue*>(this);
     111          60 :     plumed_massert(a,"cannot compute numerical derivatives for an action without values");
     112             :   }
     113          60 :   if( myBridgeVessel ) {
     114          60 :     myBridgeVessel->completeNumericalDerivatives();
     115             :   } else {
     116           0 :     error("numerical derivatives are not implemented");
     117             :   }
     118          60 : }
     119             : 
     120          21 : void BridgedMultiColvarFunction::applyBridgeForces( const std::vector<double>& bb ) {
     121          21 :   if( getNumberOfAtoms()==0 ) {
     122             :     return ;
     123             :   }
     124             : 
     125             :   std::vector<Vector>& f( modifyForces() );
     126          42 :   for(unsigned i=0; i<getNumberOfAtoms(); ++i) {
     127          21 :     f[i][0]+=bb[3*i+0];
     128          21 :     f[i][1]+=bb[3*i+1];
     129          21 :     f[i][2]+=bb[3*i+2];
     130             :   }
     131          21 :   applyForces();
     132             : }
     133             : 
     134          34 : bool BridgedMultiColvarFunction::isPeriodic() {
     135          34 :   return mycolv->isPeriodic();
     136             : }
     137             : 
     138           0 : void BridgedMultiColvarFunction::deactivate_task( const unsigned& taskno ) {
     139           0 :   plumed_merror("This should never be called");
     140             : }
     141             : 
     142       11462 : void BridgedMultiColvarFunction::getCentralAtomPack( const unsigned& basn, const unsigned& curr, CatomPack& mypack ) {
     143       11462 :   return mycolv->getCentralAtomPack( basn, curr, mypack );
     144             : }
     145             : 
     146             : }
     147             : }

Generated by: LCOV version 1.16