LCOV - code coverage report
Current view: top level - vesselbase - ActionWithVessel.h (source / functions) Hit Total Coverage
Test: plumed test coverage Lines: 22 29 75.9 %
Date: 2026-03-30 13:16:06 Functions: 3 6 50.0 %

          Line data    Source code
       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
       2             :    Copyright (c) 2012-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             : #ifndef __PLUMED_vesselbase_ActionWithVessel_h
      23             : #define __PLUMED_vesselbase_ActionWithVessel_h
      24             : 
      25             : #include "core/ActionWithValue.h"
      26             : #include "core/ActionAtomistic.h"
      27             : #include "tools/Exception.h"
      28             : #include "tools/DynamicList.h"
      29             : #include "tools/MultiValue.h"
      30             : #include <vector>
      31             : #include "tools/ForwardDecl.h"
      32             : 
      33             : namespace PLMD {
      34             : class Value;
      35             : class Stopwatch;
      36             : 
      37             : namespace vesselbase {
      38             : 
      39             : class Vessel;
      40             : class BridgeVessel;
      41             : class StoreDataVessel;
      42             : 
      43             : /**
      44             : \ingroup MULTIINHERIT
      45             : This is used to create PLMD::Action objects that are computed by calculating the same function multiple
      46             : times.  This is used in PLMD::MultiColvar.
      47             : */
      48             : 
      49             : class ActionWithVessel : public virtual Action {
      50             :   friend class Vessel;
      51             :   friend class ShortcutVessel;
      52             :   friend class FunctionVessel;
      53             :   friend class StoreDataVessel;
      54             :   friend class BridgeVessel;
      55             :   friend class ActionWithInputVessel;
      56             :   friend class OrderingVessel;
      57             : private:
      58             : /// Do all calculations in serial
      59             :   bool serial;
      60             : /// Lower memory requirements
      61             :   bool lowmem;
      62             : /// Are we skipping the calculation of the derivatives
      63             :   bool noderiv;
      64             : /// This tells plumed that this is used in a bridge
      65             :   bool actionIsBridged;
      66             : /// The maximum number of derivatives we can use before we need to invoke lowmem
      67             :   unsigned maxderivatives;
      68             : /// The tolerance on the accumulators
      69             :   double tolerance;
      70             : /// Tolerance for quantities being put in neighbor lists
      71             :   double nl_tolerance;
      72             : /// Pointers to the functions we are using on each value
      73             :   std::vector<std::unique_ptr<Vessel>> functions;
      74             : /// Tempory storage for forces
      75             :   std::vector<double> tmpforces;
      76             : /// Ths full list of tasks we have to perform
      77             :   std::vector<unsigned> fullTaskList;
      78             : /// The current number of active tasks
      79             :   unsigned nactive_tasks;
      80             : /// The indices of the tasks in the full list of tasks
      81             :   std::vector<unsigned> indexOfTaskInFullList;
      82             : /// The list of currently active tasks
      83             :   std::vector<unsigned> partialTaskList;
      84             : /// The list of atoms involved in derivatives (we keep a copy here to avoid resizing)
      85             :   std::vector<unsigned> der_list;
      86             : /// The buffer that we use (we keep a copy here to avoid resizing)
      87             :   std::vector<double> buffer;
      88             : /// Do we want to output information on the timings of different parts of the calculation
      89             :   bool timers;
      90             :   ForwardDecl<Stopwatch> stopwatch_fwd;
      91             : /// The stopwatch that times the different parts of the calculation
      92             :   Stopwatch& stopwatch=*stopwatch_fwd;
      93             : /// These are used to minmise computational expense in complex functions
      94             :   bool dertime_can_be_off;
      95             : protected:
      96             : /// This is also used to minimise computational expense in complex functions
      97             :   bool dertime;
      98             : /// The terms in the series are locked
      99             :   bool contributorsAreUnlocked;
     100             : /// Does the weight have derivatives
     101             :   bool weightHasDerivatives;
     102             : /// This is used for numerical derivatives of bridge variables
     103             :   unsigned bridgeVariable;
     104             : /// A pointer to the object that stores data
     105             :   StoreDataVessel* mydata;
     106             : /// This list is used to update the neighbor list
     107             :   std::vector<unsigned> taskFlags;
     108             : /// Add a vessel to the list of vessels
     109             :   void addVessel( const std::string& name, const std::string& input, const int numlab=0 );
     110             :   void addVessel( std::unique_ptr<Vessel> vv );
     111             : /// Add a bridging vessel to the list of vessels
     112             :   BridgeVessel* addBridgingVessel( ActionWithVessel* tome );
     113             : /// Complete the setup of this object (this routine must be called after construction of ActionWithValue)
     114             :   void readVesselKeywords();
     115             : /// Turn on the derivatives in the vessel
     116             :   void needsDerivatives();
     117             : /// Return the value of the tolerance
     118             :   double getTolerance() const ;
     119             : /// Return the value for the neighbor list tolerance
     120             :   double getNLTolerance() const ;
     121             : /// Calculate the values of all the vessels
     122             :   void runAllTasks();
     123             : /// Resize all the functions when the number of derivatives change
     124             :   void resizeFunctions();
     125             : /// This loops over all the vessels calculating them and also
     126             : /// sets all the element derivatives equal to zero
     127             :   void calculateAllVessels( const unsigned& taskCode, MultiValue& myvals, MultiValue& bvals, std::vector<double>& buffer, std::vector<unsigned>& der_list );
     128             : /// Retrieve the forces from all the vessels (used in apply)
     129             :   bool getForcesFromVessels( std::vector<double>& forcesToApply );
     130             : /// Is the calculation being done in serial
     131             :   bool serialCalculation() const;
     132             : /// Are we using low memory
     133             :   bool usingLowMem() const ;
     134             : /// Set that we are using low memory
     135             :   void setLowMemOption(const bool& );
     136             : /// Deactivate all the tasks in the task list
     137             :   void deactivateAllTasks();
     138             : /// Get the size of the buffer
     139             :   unsigned getSizeOfBuffer( unsigned& bufsize );
     140             : /// Add a task to the full list
     141             :   void addTaskToList( const unsigned& taskCode );
     142             : public:
     143             :   static void registerKeywords(Keywords& keys);
     144             :   explicit ActionWithVessel(const ActionOptions&ao);
     145             :   ~ActionWithVessel();
     146             :   void lockContributors();
     147             : /// Get the number of tasks that are currently active
     148             :   unsigned getCurrentNumberOfActiveTasks() const ;
     149             : /// Check whether or not a particular task is currently active
     150             :   bool taskIsCurrentlyActive( const unsigned& index ) const ;
     151             : /// Are derivatives required for this quantity
     152             :   bool derivativesAreRequired() const ;
     153             : /// Is this action thread safe
     154        5316 :   virtual bool threadSafe() const {
     155        5316 :     return true;
     156             :   }
     157             : /// Finish running all the calculations
     158             :   virtual void finishComputations( const std::vector<double>& buffer );
     159             : /// Are the base quantities periodic
     160             :   virtual bool isPeriodic()=0;
     161             : /// What are the domains of the base quantities
     162             :   virtual void retrieveDomain( std::string& min, std::string& max);
     163             : /// Get the number of derivatives for final calculated quantity
     164             :   virtual unsigned getNumberOfDerivatives()=0;
     165             : /// Get the number of quantities that are calculated during each task
     166             :   virtual unsigned getNumberOfQuantities() const ;
     167             : /// Get the number of vessels
     168             :   unsigned getNumberOfVessels() const;
     169             : /// Get a pointer to the ith vessel
     170             :   Vessel* getPntrToVessel( const unsigned& i );
     171             : /// Do any jobs that are required before the task list is undertaken
     172             :   virtual void doJobsRequiredBeforeTaskList();
     173             : /// Get the full size of the taskList dynamic list
     174             :   unsigned getFullNumberOfTasks() const ;
     175             : /// Get the position of the ith active task in the full list
     176             :   unsigned getPositionInFullTaskList( const unsigned& ii ) const ;
     177             : /// Get the code for the ii th task in the list
     178             :   unsigned getTaskCode( const unsigned& ii ) const ;
     179             : /// Get the ith of the currently active tasks
     180             :   unsigned getActiveTask( const unsigned& ii ) const ;
     181             : /// Calculate one of the functions in the distribution
     182             :   virtual void performTask( const unsigned&, const unsigned&, MultiValue& ) const=0;
     183             : /// Do the task if we have a bridge
     184             :   virtual void transformBridgedDerivatives( const unsigned& current, MultiValue& invals, MultiValue& outvals ) const;
     185             : /// Ensure that data required in other vessels is stored
     186             :   StoreDataVessel* buildDataStashes( ActionWithVessel* actionThatUses );
     187             : /// Apply forces from bridge vessel - this is rarely used - currently only in ActionVolume
     188           0 :   virtual void applyBridgeForces( const std::vector<double>& bb ) {
     189           0 :     plumed_error();
     190             :   }
     191             : /// These are overwritten in MultiColvarFunction
     192             : //  virtual void activateIndexes( const unsigned&, const unsigned&, const std::vector<unsigned>& ){}
     193             : /// Return a particular named vessel
     194             :   Vessel* getVesselWithName( const std::string& mynam );
     195             : /// Does the weight have derivatives
     196             :   bool weightWithDerivatives() const ;
     197             : /// Return the position in the current task list
     198             :   unsigned getPositionInCurrentTaskList( const unsigned& myind ) const ;
     199             : /// These normalizes vectors and is used in StoreDataVessel
     200           0 :   virtual void normalizeVector( std::vector<double>& vals ) const {
     201           0 :     plumed_error();
     202             :   }
     203           0 :   virtual void normalizeVectorDerivatives( MultiValue& myvals ) const {
     204           0 :     plumed_error();
     205             :   }
     206             : };
     207             : 
     208             : inline
     209             : double ActionWithVessel::getTolerance() const {
     210      700112 :   return tolerance;
     211             : }
     212             : 
     213             : inline
     214             : double ActionWithVessel::getNLTolerance() const {
     215             :   return nl_tolerance;
     216             : }
     217             : 
     218             : inline
     219             : unsigned ActionWithVessel::getNumberOfVessels() const {
     220    12537696 :   return functions.size();
     221             : }
     222             : 
     223             : inline
     224      196791 : unsigned ActionWithVessel::getNumberOfQuantities() const {
     225      196791 :   return 2;
     226             : }
     227             : 
     228             : inline
     229             : Vessel* ActionWithVessel::getPntrToVessel( const unsigned& i ) {
     230             :   plumed_dbg_assert( i<functions.size() );
     231        2502 :   return functions[i].get();
     232             : }
     233             : 
     234             : inline
     235             : unsigned ActionWithVessel::getFullNumberOfTasks() const {
     236    15964093 :   return fullTaskList.size();
     237             : }
     238             : 
     239             : inline
     240             : unsigned ActionWithVessel::getTaskCode( const unsigned& ii ) const {
     241             :   plumed_dbg_assert( ii<fullTaskList.size() );
     242     3352757 :   return fullTaskList[ii];
     243             : }
     244             : 
     245             : inline
     246             : unsigned ActionWithVessel::getCurrentNumberOfActiveTasks() const {
     247       29023 :   return nactive_tasks;
     248             : }
     249             : 
     250             : inline
     251             : unsigned ActionWithVessel::getActiveTask( const unsigned& ii ) const {
     252             :   plumed_dbg_assert( ii<nactive_tasks );
     253       54936 :   return partialTaskList[ii];
     254             : }
     255             : 
     256             : inline
     257             : unsigned ActionWithVessel::getPositionInFullTaskList( const unsigned& ii ) const {
     258             :   plumed_dbg_assert( ii<nactive_tasks );
     259       62238 :   return indexOfTaskInFullList[ii];
     260             : }
     261             : 
     262             : inline
     263             : bool ActionWithVessel::serialCalculation() const {
     264         454 :   return serial;
     265             : }
     266             : 
     267             : inline
     268             : bool ActionWithVessel::usingLowMem() const {
     269      867292 :   return lowmem;
     270             : }
     271             : 
     272             : inline
     273             : void ActionWithVessel::setLowMemOption(const bool& l) {
     274          42 :   lowmem=l;
     275             : }
     276             : 
     277             : inline
     278             : bool ActionWithVessel::derivativesAreRequired() const {
     279      763418 :   return !noderiv;
     280             : }
     281             : 
     282             : inline
     283             : bool ActionWithVessel::weightWithDerivatives() const {
     284       13904 :   return weightHasDerivatives;
     285             : }
     286             : 
     287             : inline
     288      224556 : unsigned ActionWithVessel::getPositionInCurrentTaskList( const unsigned& myind ) const {
     289      224556 :   if( nactive_tasks==fullTaskList.size() ) {
     290      182500 :     return myind;
     291             :   }
     292             : 
     293   253764165 :   for(unsigned i=0; i<nactive_tasks; ++i) {
     294   253764165 :     if( myind==indexOfTaskInFullList[i] ) {
     295             :       return i;
     296             :     }
     297             :   }
     298           0 :   plumed_merror("requested task is not active");
     299             : }
     300             : 
     301             : }
     302             : }
     303             : #endif

Generated by: LCOV version 1.16