LCOV - code coverage report
Current view: top level - vesselbase - ActionWithVessel.h (source / functions) Hit Total Coverage
Test: plumed test coverage Lines: 20 24 83.3 %
Date: 2024-10-11 08:09:47 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        5214 :   virtual bool threadSafe() const { return true; }
     155             : /// Finish running all the calculations
     156             :   virtual void finishComputations( const std::vector<double>& buffer );
     157             : /// Are the base quantities periodic
     158             :   virtual bool isPeriodic()=0;
     159             : /// What are the domains of the base quantities
     160             :   virtual void retrieveDomain( std::string& min, std::string& max);
     161             : /// Get the number of derivatives for final calculated quantity
     162             :   virtual unsigned getNumberOfDerivatives()=0;
     163             : /// Get the number of quantities that are calculated during each task
     164             :   virtual unsigned getNumberOfQuantities() const ;
     165             : /// Get the number of vessels
     166             :   unsigned getNumberOfVessels() const;
     167             : /// Get a pointer to the ith vessel
     168             :   Vessel* getPntrToVessel( const unsigned& i );
     169             : /// Do any jobs that are required before the task list is undertaken
     170             :   virtual void doJobsRequiredBeforeTaskList();
     171             : /// Get the full size of the taskList dynamic list
     172             :   unsigned getFullNumberOfTasks() const ;
     173             : /// Get the position of the ith active task in the full list
     174             :   unsigned getPositionInFullTaskList( const unsigned& ii ) const ;
     175             : /// Get the code for the ii th task in the list
     176             :   unsigned getTaskCode( const unsigned& ii ) const ;
     177             : /// Get the ith of the currently active tasks
     178             :   unsigned getActiveTask( const unsigned& ii ) const ;
     179             : /// Calculate one of the functions in the distribution
     180             :   virtual void performTask( const unsigned&, const unsigned&, MultiValue& ) const=0;
     181             : /// Do the task if we have a bridge
     182             :   virtual void transformBridgedDerivatives( const unsigned& current, MultiValue& invals, MultiValue& outvals ) const;
     183             : /// Ensure that data required in other vessels is stored
     184             :   StoreDataVessel* buildDataStashes( ActionWithVessel* actionThatUses );
     185             : /// Apply forces from bridge vessel - this is rarely used - currently only in ActionVolume
     186           0 :   virtual void applyBridgeForces( const std::vector<double>& bb ) { plumed_error(); }
     187             : /// These are overwritten in MultiColvarFunction
     188             : //  virtual void activateIndexes( const unsigned&, const unsigned&, const std::vector<unsigned>& ){}
     189             : /// Return a particular named vessel
     190             :   Vessel* getVesselWithName( const std::string& mynam );
     191             : /// Does the weight have derivatives
     192             :   bool weightWithDerivatives() const ;
     193             : /// Return the position in the current task list
     194             :   unsigned getPositionInCurrentTaskList( const unsigned& myind ) const ;
     195             : /// These normalizes vectors and is used in StoreDataVessel
     196           0 :   virtual void normalizeVector( std::vector<double>& vals ) const { plumed_error(); }
     197           0 :   virtual void normalizeVectorDerivatives( MultiValue& myvals ) const { plumed_error(); }
     198             : };
     199             : 
     200             : inline
     201             : double ActionWithVessel::getTolerance() const {
     202      698630 :   return tolerance;
     203             : }
     204             : 
     205             : inline
     206             : double ActionWithVessel::getNLTolerance() const {
     207             :   return nl_tolerance;
     208             : }
     209             : 
     210             : inline
     211             : unsigned ActionWithVessel::getNumberOfVessels() const {
     212    12537362 :   return functions.size();
     213             : }
     214             : 
     215             : inline
     216      196787 : unsigned ActionWithVessel::getNumberOfQuantities() const {
     217      196787 :   return 2;
     218             : }
     219             : 
     220             : inline
     221             : Vessel* ActionWithVessel::getPntrToVessel( const unsigned& i ) {
     222             :   plumed_dbg_assert( i<functions.size() );
     223        2501 :   return functions[i].get();
     224             : }
     225             : 
     226             : inline
     227             : unsigned ActionWithVessel::getFullNumberOfTasks() const {
     228    15830229 :   return fullTaskList.size();
     229             : }
     230             : 
     231             : inline
     232             : unsigned ActionWithVessel::getTaskCode( const unsigned& ii ) const {
     233             :   plumed_dbg_assert( ii<fullTaskList.size() );
     234     3509797 :   return fullTaskList[ii];
     235             : }
     236             : 
     237             : inline
     238             : unsigned ActionWithVessel::getCurrentNumberOfActiveTasks() const {
     239       29023 :   return nactive_tasks;
     240             : }
     241             : 
     242             : inline
     243             : unsigned ActionWithVessel::getActiveTask( const unsigned& ii ) const {
     244             :   plumed_dbg_assert( ii<nactive_tasks );
     245       54936 :   return partialTaskList[ii];
     246             : }
     247             : 
     248             : inline
     249             : unsigned ActionWithVessel::getPositionInFullTaskList( const unsigned& ii ) const {
     250             :   plumed_dbg_assert( ii<nactive_tasks );
     251       62238 :   return indexOfTaskInFullList[ii];
     252             : }
     253             : 
     254             : inline
     255             : bool ActionWithVessel::serialCalculation() const {
     256         454 :   return serial;
     257             : }
     258             : 
     259             : inline
     260             : bool ActionWithVessel::usingLowMem() const {
     261      867292 :   return lowmem;
     262             : }
     263             : 
     264             : inline
     265             : void ActionWithVessel::setLowMemOption(const bool& l) {
     266          42 :   lowmem=l;
     267             : }
     268             : 
     269             : inline
     270             : bool ActionWithVessel::derivativesAreRequired() const {
     271      714510 :   return !noderiv;
     272             : }
     273             : 
     274             : inline
     275             : bool ActionWithVessel::weightWithDerivatives() const {
     276       13904 :   return weightHasDerivatives;
     277             : }
     278             : 
     279             : inline
     280      224556 : unsigned ActionWithVessel::getPositionInCurrentTaskList( const unsigned& myind ) const {
     281      224556 :   if( nactive_tasks==fullTaskList.size() ) return myind;
     282             : 
     283   253764165 :   for(unsigned i=0; i<nactive_tasks; ++i) {
     284   253764165 :     if( myind==indexOfTaskInFullList[i] ) return i;
     285             :   }
     286           0 :   plumed_merror("requested task is not active");
     287             : }
     288             : 
     289             : }
     290             : }
     291             : #endif

Generated by: LCOV version 1.15