LCOV - code coverage report
Current view: top level - multicolvar - MultiColvarBase.h (source / functions) Hit Total Coverage
Test: plumed test coverage Lines: 29 33 87.9 %
Date: 2018-12-19 07:49:13 Functions: 12 16 75.0 %

          Line data    Source code
       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
       2             :    Copyright (c) 2013-2018 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_multicolvar_MultiColvarBase_h
      23             : #define __PLUMED_multicolvar_MultiColvarBase_h
      24             : 
      25             : #include "core/ActionAtomistic.h"
      26             : #include "core/ActionWithValue.h"
      27             : #include "tools/DynamicList.h"
      28             : #include "tools/LinkCells.h"
      29             : #include "vesselbase/StoreDataVessel.h"
      30             : #include "vesselbase/ActionWithVessel.h"
      31             : #include <vector>
      32             : 
      33             : namespace PLMD {
      34             : namespace multicolvar {
      35             : 
      36             : class AtomValuePack;
      37             : class CatomPack;
      38             : class BridgedMultiColvarFunction;
      39             : class ActionVolume;
      40             : 
      41             : class MultiColvarBase :
      42             :   public ActionAtomistic,
      43             :   public ActionWithValue,
      44             :   public vesselbase::ActionWithVessel
      45             : {
      46             :   friend class BridgedMultiColvarFunction;
      47             :   friend class VolumeGradientBase;
      48             :   friend class MultiColvarFilter;
      49             :   friend class AtomValuePack;
      50             : private:
      51             : /// Use periodic boundary conditions
      52             :   bool usepbc;
      53             : /// The forces we are going to apply to things
      54             :   std::vector<double> forcesToApply;
      55             : /// We use this to say that all the atoms in the third block should are in the tasks
      56             :   bool allthirdblockintasks;
      57             : /// In certain cases we can make three atom link cells faster
      58             :   bool uselinkforthree;
      59             : /// Number of atoms that are active on this step
      60             :   unsigned nactive_atoms;
      61             : /// Stuff for link cells - this is used to make coordination number like variables faster
      62             :   LinkCells linkcells;
      63             : /// Link cells for third block of atoms
      64             :   LinkCells threecells;
      65             : /// Number of atoms that are being used for central atom position
      66             :   unsigned ncentral;
      67             : /// Bool vector telling us which atoms are required to calculate central atom position
      68             :   std::vector<bool> use_for_central_atom;
      69             : /// 1/number of atoms involved in central atoms
      70             :   double numberForCentralAtom;
      71             : /// Ensures that setup is only performed once per loop
      72             :   bool setup_completed;
      73             : /// Ensures that retrieving of atoms is only done once per calculation loop
      74             :   bool atomsWereRetrieved;
      75             : /// Add derivatives of center of mass position
      76             :   void addComDerivatives( const int& ival, const unsigned& iatom, const Vector& der, multicolvar::AtomValuePack& myatoms ) const ;
      77             : protected:
      78             : /// This is used to keep track of what is calculated where
      79             :   std::vector< std::pair<unsigned,unsigned> > atom_lab;
      80             : /// The vessels in these multicolvars in which the data is stored
      81             :   std::vector<vesselbase::StoreDataVessel*> mybasedata;
      82             : /// The multicolvars from which we construct these quantities
      83             :   std::vector<MultiColvarBase*> mybasemulticolvars;
      84             : /// This remembers where the boundaries are for the tasks. It makes link cells work fast
      85             :   Matrix<std::pair<unsigned,unsigned> > bookeeping;
      86             : /// Function that recursively checks if filters have been used in the input to a multicolvar
      87             : /// we need this to ensure that setupLinkCells is run in calculate with some actions
      88             :   bool filtersUsedAsInput();
      89             : /// This resizes the arrays that are used for link cell update
      90             :   void resizeBookeepingArray( const unsigned& num1, const unsigned& num2 );
      91             : /// Are we doing sums of matrix rows
      92             :   bool matsums;
      93             : /// Using the species keyword to read in atoms
      94             :   bool usespecies;
      95             : /// Number of atoms in each block
      96             :   unsigned nblock;
      97             : /// This is used when turning cvcodes into atom numbers
      98             :   std::vector<unsigned> decoder;
      99             : /// Blocks of atom numbers
     100             :   std::vector< std::vector<unsigned> > ablocks;
     101             : /// Add a task to the list of tasks
     102             :   void addTaskToList( const unsigned& taskCode );
     103             : /// Finish setting up the multicolvar base
     104             :   void setupMultiColvarBase( const std::vector<AtomNumber>& atoms );
     105             : /// Add some derivatives to a particular component of a particular atom
     106             :   void addAtomDerivatives( const int&, const unsigned&, const Vector&, multicolvar::AtomValuePack& ) const ;
     107             : /// Add derivative of the input value
     108             :   void mergeInputDerivatives( const unsigned& ival, const unsigned& start, const unsigned& end, const unsigned& jatom,
     109             :                               const std::vector<double>& der, MultiValue& myder, AtomValuePack& myatoms ) const ;
     110             : /// This is used to accumulate functions of the coordination sphere.  Ensures weights are taken into account
     111             :   void accumulateSymmetryFunction( const int& ival, const unsigned& iatom, const double& val, const Vector& der, const Tensor& vir, multicolvar::AtomValuePack& myatoms ) const ;
     112             : /// Set which atoms are to be used to calculate the central atom position
     113             :   void setAtomsForCentralAtom( const std::vector<bool>& catom_ind );
     114             : /// Set the value of the cutoff for the link cells
     115             :   void setLinkCellCutoff( const double& lcut, double tcut=-1.0 );
     116             : /// Setup the link cells and neighbour list stuff
     117             :   void setupActiveTaskSet( std::vector<unsigned>& active_tasks, const std::string& input_label );
     118             : /// Setup link cells in order to make this calculation faster
     119             :   void setupLinkCells();
     120             : /// Get the cutoff for the link cells
     121             :   double getLinkCellCutoff()  const ;
     122             : /// This does setup of link cell stuff that is specific to the non-use of the usespecies keyword
     123             :   void setupNonUseSpeciesLinkCells( const unsigned& );
     124             : /// Get the separation between a pair of vectors
     125             :   Vector getSeparation( const Vector& vec1, const Vector& vec2 ) const ;
     126             : /// This sets up the list of atoms that are involved in this colvar
     127             :   bool setupCurrentAtomList( const unsigned& taskCode, AtomValuePack& myatoms ) const ;
     128             : /// Decode indices if there are 2 or 3 atoms involved
     129             :   void decodeIndexToAtoms( const unsigned& taskCode, std::vector<unsigned>& atoms ) const ;
     130             : /// Read in some atoms
     131             :   bool parseMultiColvarAtomList(const std::string& key, const int& num, std::vector<AtomNumber>& t);
     132             : /// Read in two groups of atoms and setup multicolvars to calculate
     133             :   void readTwoGroups( const std::string& key0, const std::string& key1, const std::string& key2, std::vector<AtomNumber>& all_atoms );
     134             : /// Read in three groups of atoms
     135             :   void readGroupKeywords( const std::string& key0, const std::string& key1, const std::string& key2, const std::string& key3,
     136             :                           const bool& no_third_dim_accum, const bool& symmetric, std::vector<AtomNumber>& all_atoms );
     137             : /// Read in three groups of atoms and construct CVs involving at least one
     138             :   void readThreeGroups( const std::string& key1, const std::string& key2, const std::string& key3,
     139             :                         const bool& allow2, const bool& no_third_dim_accum, std::vector<AtomNumber>& all_atoms );
     140             : public:
     141             :   explicit MultiColvarBase(const ActionOptions&);
     142         264 :   ~MultiColvarBase() {}
     143             :   static void registerKeywords( Keywords& keys );
     144             : /// Turn on the derivatives
     145             :   virtual void turnOnDerivatives();
     146             : /// Do we use pbc to calculate this quantity
     147             :   bool usesPbc() const ;
     148             : /// Apply PBCs over a set of distance vectors
     149             :   void applyPbc(std::vector<Vector>& dlist, unsigned max_index=0) const;
     150             : /// Is it safe to use multithreading
     151        4114 :   bool threadSafe() const { return !(mybasemulticolvars.size()>0); }
     152             : /// Do some setup before the calculation
     153             :   void prepare();
     154             : /// This is overwritten here in order to make sure that we do not retrieve atoms multiple times
     155             :   void retrieveAtoms();
     156             : /// Do the calculation
     157             :   virtual void calculate();
     158             : /// Calculate numerical derivatives
     159             :   virtual void calculateNumericalDerivatives( ActionWithValue* a=NULL );
     160             : /// Perform one of the tasks
     161             :   virtual void performTask( const unsigned&, const unsigned&, MultiValue& ) const ;
     162             : /// Update the active atoms
     163             :   virtual void updateActiveAtoms( AtomValuePack& myatoms ) const ;
     164             : /// This gets the position of an atom for the link cell setup
     165             :   virtual Vector getPositionOfAtomForLinkCells( const unsigned& iatom ) const ;
     166             : /// Returns the position where we should assume the center is for link cell calculations
     167             :   virtual Vector getLinkCellPosition( const std::vector<unsigned>& atoms ) const ;
     168             : /// And a virtual function which actually computes the colvar
     169             :   virtual double doCalculation( const unsigned& tindex, AtomValuePack& myatoms ) const ;
     170             : /// Get the absolute index of the central atom
     171             :   virtual AtomNumber getAbsoluteIndexOfCentralAtom( const unsigned& i ) const ;
     172             : /// This is replaced once we have a function to calculate the cv
     173             :   virtual double compute( const unsigned& tindex, AtomValuePack& myatoms ) const=0;
     174             : /// Apply the forces from this action
     175             :   virtual void apply();
     176             : /// Get the number of derivatives for this action
     177             :   virtual unsigned getNumberOfDerivatives();  // N.B. This is replacing the virtual function in ActionWithValue
     178             : /// Checks if an task is being performed at the present time
     179             :   virtual bool isCurrentlyActive( const unsigned& code );
     180             : ///
     181             :   virtual CatomPack getCentralAtomPack( const unsigned& basn, const unsigned& curr );
     182             : /// Get the index where the central atom is stored
     183             :   virtual Vector getCentralAtomPos( const unsigned& curr );
     184             : /// You can use this to screen contributions that are very small so we can avoid expensive (and pointless) calculations
     185             :   virtual double calculateWeight( const unsigned& taskCode, const double& weight, AtomValuePack& myatoms ) const ;
     186             : /// Is this a density?
     187     1786529 :   virtual bool isDensity() const { return false; }
     188             : /// Is the iatom'th stored value currently active
     189             :   bool storedValueIsActive( const unsigned& iatom );
     190             : /// This is true if multicolvar is calculating a vector or if the multicolvar is the density
     191           0 :   virtual bool hasDifferentiableOrientation() const { return false; }
     192             : /// This makes sure we are not calculating the director when we do LocalAverage
     193           0 :   virtual void doNotCalculateDirector() {}
     194             : /// Ensure that derivatives are only calculated when needed
     195             :   bool doNotCalculateDerivatives() const ;
     196             : /// Get the icolv th base multicolvar
     197             :   MultiColvarBase* getBaseMultiColvar( const unsigned& icolv ) const ;
     198             : /// Get the number of base multicolvars
     199             :   unsigned getNumberOfBaseMultiColvars() const ;
     200             : /// Get an input data
     201             :   virtual void getInputData( const unsigned& ind, const bool& normed, const multicolvar::AtomValuePack& myatoms, std::vector<double>& orient ) const ;
     202             : /// Retrieve the input derivatives
     203             :   virtual MultiValue& getInputDerivatives( const unsigned& iatom, const bool& normed, const multicolvar::AtomValuePack& myatoms ) const ;
     204             : };
     205             : 
     206             : inline
     207      450734 : bool MultiColvarBase::isCurrentlyActive( const unsigned& code ) {
     208      450734 :   if( setup_completed && atom_lab[code].first>0 ) {
     209       17628 :     unsigned mmc=atom_lab[code].first - 1;
     210       17628 :     return mybasedata[mmc]->storedValueIsActive( atom_lab[code].second );
     211             :   }
     212      433106 :   return true;
     213             : }
     214             : 
     215             : inline
     216         156 : AtomNumber MultiColvarBase::getAbsoluteIndexOfCentralAtom( const unsigned& iatom ) const {
     217             :   plumed_dbg_assert( iatom<atom_lab.size() );
     218         156 :   if( atom_lab[iatom].first>0  ) {
     219           0 :     unsigned mmc=atom_lab[iatom].first - 1;
     220           0 :     return mybasemulticolvars[mmc]->getAbsoluteIndexOfCentralAtom( atom_lab[iatom].second );
     221             :   }
     222             :   plumed_dbg_assert( usespecies );
     223         156 :   return ActionAtomistic::getAbsoluteIndex( atom_lab[getTaskCode(iatom)].second );
     224             : }
     225             : 
     226             : inline
     227    16752585 : Vector MultiColvarBase::getPositionOfAtomForLinkCells( const unsigned& iatom ) const {
     228             :   plumed_dbg_assert( iatom<atom_lab.size() );
     229    16752585 :   if( atom_lab[iatom].first>0  ) {
     230     2028377 :     unsigned mmc=atom_lab[iatom].first - 1;
     231     2028377 :     return mybasemulticolvars[mmc]->getCentralAtomPos( atom_lab[iatom].second );
     232             :   }
     233    14729701 :   return ActionAtomistic::getPosition( atom_lab[iatom].second );
     234             : }
     235             : 
     236             : inline
     237      191434 : Vector MultiColvarBase::getLinkCellPosition( const std::vector<unsigned>& atoms ) const {
     238      191434 :   return getPositionOfAtomForLinkCells( atoms[0] );
     239             : }
     240             : 
     241             : inline
     242     5505989 : unsigned MultiColvarBase::getNumberOfDerivatives() {
     243     5505989 :   return 3*getNumberOfAtoms()+9;
     244             : }
     245             : 
     246             : inline
     247      191424 : bool MultiColvarBase::usesPbc() const {
     248      191424 :   return usepbc;
     249             : }
     250             : 
     251             : inline
     252    62755853 : bool MultiColvarBase::doNotCalculateDerivatives() const {
     253    62755853 :   if( !dertime ) return true;
     254    62494223 :   return ActionWithValue::doNotCalculateDerivatives();
     255             : }
     256             : 
     257             : inline
     258          33 : unsigned MultiColvarBase::getNumberOfBaseMultiColvars() const {
     259          33 :   return mybasemulticolvars.size();
     260             : }
     261             : 
     262             : inline
     263       23965 : MultiColvarBase* MultiColvarBase::getBaseMultiColvar( const unsigned& icolv ) const {
     264             :   plumed_dbg_assert( icolv<mybasemulticolvars.size() );
     265       23965 :   return mybasemulticolvars[icolv];
     266             : }
     267             : 
     268             : 
     269             : }
     270             : }
     271             : 
     272             : #endif

Generated by: LCOV version 1.13