All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
MultiColvarBase.cpp
Go to the documentation of this file.
1 /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2  Copyright (c) 2013 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-code.org for more information.
6 
7  This file is part of plumed, version 2.0.
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 "MultiColvarBase.h"
23 #include "vesselbase/Vessel.h"
24 #include "tools/Pbc.h"
25 #include <vector>
26 #include <string>
27 
28 using namespace std;
29 
30 namespace PLMD{
31 namespace multicolvar{
32 
33 void MultiColvarBase::registerKeywords( Keywords& keys ){
34  Action::registerKeywords( keys );
35  ActionWithValue::registerKeywords( keys );
36  ActionAtomistic::registerKeywords( keys );
37  keys.addFlag("NOPBC",false,"ignore the periodic boundary conditions when calculating distances");
38  ActionWithVessel::registerKeywords( keys );
39  keys.use("NL_TOL");
40  keys.add("hidden","NL_STRIDE","the frequency with which the neighbor list should be updated. Between neighbour list update steps all quantities "
41  "that contributed less than TOL at the previous neighbor list update step are ignored.");
42  keys.setComponentsIntroduction("This Action can be used to calculate the following quantities by employing the keywords listed below. "
43  "You must select which from amongst these quantities you wish to calculate - this command cannot be run "
44  "unless one of the quantities below is being calculated."
45  "These quantities can then be referenced elsewhere in the input file by using this Action's label "
46  "followed by a dot and the name of the quantity. Some amongst them can be calculated multiple times "
47  "with different parameters. In this case the quantities calculated can be referenced elsewhere in the "
48  "input by using the name of the quantity followed by a numerical identifier "
49  "e.g. <em>label</em>.less_than-1, <em>label</em>.less_than-2 etc.");
50 }
51 
52 MultiColvarBase::MultiColvarBase(const ActionOptions&ao):
53 Action(ao),
54 ActionAtomistic(ao),
55 ActionWithValue(ao),
56 ActionWithVessel(ao),
57 usepbc(false),
58 updateFreq(0),
59 lastUpdate(0)
60 {
61  if( keywords.exists("NOPBC") ){
62  bool nopbc=!usepbc; parseFlag("NOPBC",nopbc);
63  usepbc=!nopbc;
64  }
65  if( keywords.exists("NL_STRIDE") ) parse("NL_STRIDE",updateFreq);
66  if(updateFreq>0) log.printf(" Updating contributors every %d steps.\n",updateFreq);
67  else log.printf(" Updating contributors every step.\n");
68 }
69 
70 void MultiColvarBase::addColvar( const std::vector<unsigned>& newatoms ){
72  for(unsigned i=0;i<newatoms.size();++i) newlist.addIndexToList( newatoms[i] );
74  colvar_atoms.push_back( newlist );
75 }
76 
78  // Activate everything
80  for(unsigned i=0;i<colvar_atoms.size();++i) colvar_atoms[i].activateAll();
81  // Resize stuff in derived classes
83  // Resize local arrays
85  // And resize the local vessels
87 }
88 
90  bool updatetime=false;
94  lockContributors(); updatetime=true;
95  }
96  if( updateFreq>0 && (getStep()-lastUpdate)>=updateFreq ){
98  for(unsigned i=0;i<taskList.getNumberActive();++i) colvar_atoms[i].activateAll();
99  unlockContributors(); updatetime=true; lastUpdate=getStep();
100  }
101  if(updatetime){
102  // Resize stuff in derived classes
104  // Resize local arrays
106  // Resize vessels
107  resizeFunctions();
108  }
109 }
110 
113  for(unsigned i=0;i<getNumberOfAtoms();++i) atoms_with_derivatives.addIndexToList( i );
115  // Set up stuff for central atoms
117  for(unsigned i=0;i<getNumberOfAtoms();++i) atomsWithCatomDer.addIndexToList( i );
119  central_derivs.resize( getNumberOfAtoms() );
120  for(unsigned i=0;i<central_derivs.size();++i) central_derivs[i].zero();
121  // Resize tempory forces array
123 }
124 
125 void MultiColvarBase::performTask( const unsigned& j ){
126  // Currently no atoms have derivatives so deactivate those that are active
128 
129  // Do nothing if there are no active atoms in the colvar
130  if( colvar_atoms[current].getNumberActive()==0 ){
131  setElementValue(1,0.0);
132  return;
133  }
134  // Do a quick check on the size of this contribution
135  calculateWeight();
136  if( getElementValue(1)<getTolerance() ) return;
137 
138  // Compute everything
139  double vv=doCalculation( j );
140  // Set the value of this element in ActionWithVessel
141  setElementValue( 0, vv );
142  return;
143 }
144 
147 
148  // Prepare to retrieve central atom
149  for(unsigned i=0;i<atomsWithCatomDer.getNumberActive();++i){
150  central_derivs[ atomsWithCatomDer[i] ].zero();
151  }
153 
154  // Retrieve the central atom position
156 }
157 
158 void MultiColvarBase::addCentralAtomDerivatives( const unsigned& iatom, const Tensor& der ){
159  plumed_dbg_assert( iatom<getNumberOfAtoms() );
161  central_derivs[iatom] += der;
162 }
163 
164 double MultiColvarBase::getCentralAtomDerivative( const unsigned& iatom, const unsigned jcomp, const Vector& df ) const {
165  plumed_dbg_assert( atomsWithCatomDer.isActive(iatom) && jcomp<3 );
166  return df[0]*central_derivs[iatom](0,jcomp) + df[1]*central_derivs[iatom](1,jcomp) + df[2]*central_derivs[iatom](2,jcomp);
167 }
168 
169 Vector MultiColvarBase::getSeparation( const Vector& vec1, const Vector& vec2 ) const {
170  if(usepbc){ return pbcDistance( vec1, vec2 ); }
171  else{ return delta( vec1, vec2 ); }
172 }
173 
174 void MultiColvarBase::mergeDerivatives( const unsigned& ider, const double& df ){
175  unsigned vstart=getNumberOfDerivatives()*ider;
176  for(unsigned i=0;i<atoms_with_derivatives.getNumberActive();++i){
177  unsigned iatom=3*atoms_with_derivatives[i];
178  accumulateDerivative( iatom, df*getElementDerivative(vstart+iatom) ); iatom++;
179  accumulateDerivative( iatom, df*getElementDerivative(vstart+iatom) ); iatom++;
180  accumulateDerivative( iatom, df*getElementDerivative(vstart+iatom) );
181  }
182  unsigned nvir=3*getNumberOfAtoms();
183  for(unsigned j=0;j<9;++j){
184  accumulateDerivative( nvir, df*getElementDerivative(vstart+nvir) ); nvir++;
185  }
186 }
187 
188 void MultiColvarBase::clearDerivativesAfterTask( const unsigned& ider ){
189  unsigned vstart=getNumberOfDerivatives()*ider;
190  for(unsigned i=0;i<atoms_with_derivatives.getNumberActive();++i){
191  unsigned iatom=vstart+3*atoms_with_derivatives[i];
192  setElementDerivative( iatom, 0.0 ); iatom++;
193  setElementDerivative( iatom, 0.0 ); iatom++;
194  setElementDerivative( iatom, 0.0 );
195  }
196  unsigned nvir=vstart+3*getNumberOfAtoms();
197  for(unsigned j=0;j<9;++j){
198  setElementDerivative( nvir, 0.0 ); nvir++;
199  }
200 }
201 
204 }
205 
207  // Look to see if vectors have already been created
208  StoreCentralAtomsVessel* mycatoms;
209  for(unsigned i=0;i<getNumberOfVessels();++i){
210  mycatoms=dynamic_cast<StoreCentralAtomsVessel*>( getPntrToVessel(i) );
211  if( mycatoms ) return mycatoms;
212  }
213 
214  // Create the vessel
215  vesselbase::VesselOptions da("","",0,"",this);
217  addVessel(sv); resizeFunctions(); // This makes sure resizing of vessels is done
218  return sv;
219 }
220 
221 }
222 }
void setupMPICommunication(Communicator &comm)
Setup MPI communication if things are activated/deactivated on different nodes.
Definition: DynamicList.h:241
void setComponentsIntroduction(const std::string &instr)
Set the text that introduces how the components for this action are introduced.
Definition: Keywords.cpp:561
std::vector< Tensor > central_derivs
void parseFlag(const std::string &key, bool &t)
Parse one keyword as boolean flag.
Definition: Action.cpp:104
unsigned current
The numerical index of the task we are curently performing.
void addCentralAtomDerivatives(const unsigned &iatom, const Tensor &der)
Add derivative of central atom position wrt to position of iatom'th atom.
Log & log
Reference to the log stream.
Definition: Action.h:93
Vector getSeparation(const Vector &vec1, const Vector &vec2) const
Get the separation between a pair of vectors.
TensorGeneric< m, n > transpose() const
return the transpose matrix
Definition: Tensor.h:325
void mpi_gatherActiveMembers(Communicator &comm, std::vector< DynamicList< U > > &ll)
Definition: DynamicList.h:318
void prepare()
Prepare for the calculation.
Class implementing fixed size matrices of doubles.
Definition: Tensor.h:70
Class implementing fixed size vectors of doubles.
Definition: Vector.h:74
void resizeLocalArrays()
This resizes the local arrays after neighbor list updates and during initialization.
void setElementDerivative(const unsigned &, const double &)
Set the derivative of the jth element wrt to a numbered element.
STL namespace.
double getElementDerivative(const unsigned &) const
Retrieve the derivative of the quantity in the sum wrt to a numbered element.
void add(const std::string &t, const std::string &k, const std::string &d)
Add a new keyword of type t with name k and description d.
Definition: Keywords.cpp:167
void addVessel(const std::string &name, const std::string &input, const int numlab=0, const std::string thislab="")
Add a vessel to the list of vessels.
Communicator & comm
Definition: Action.h:158
void activate(const unsigned ii)
Make something active.
Definition: DynamicList.h:263
void clearDerivativesAfterTask(const unsigned &ider)
void addColvar(const std::vector< unsigned > &newatoms)
Add a colvar to the set of colvars we are calculating (in practise just a list of atoms) ...
virtual void calculateWeight()
You can use this to screen contributions that are very small so we can avoid expensive (and pointless...
void setupMultiColvarBase()
Finish setting up the multicolvar base.
bool getForcesFromVessels(std::vector< double > &forcesToApply)
Retrieve the forces from all the vessels (used in apply)
const Pbc & getPbc() const
Get reference to Pbc.
std::vector< double > forcesToApply
The forces we are going to apply to things.
void apply()
Apply the forces from this action.
Used to create a PLMD::Action that has some scalar or vectorial output that may or may not have some ...
DynamicList< unsigned > atomsWithCatomDer
void parse(const std::string &key, T &t)
Parse one keyword as generic type.
Definition: Action.h:273
This class holds the keywords and their documentation.
Definition: Keywords.h:36
void clear()
Clear the list.
Definition: DynamicList.h:214
std::vector< DynamicList< unsigned > > colvar_atoms
The lists of the atoms involved in each of the individual colvars note these refer to the atoms in al...
This class is used to bring the relevant information to the Action constructor.
Definition: Action.h:41
virtual Vector calculateCentralAtomPosition()=0
A virtual routine to get the position of the central atom - used for things like cv gradient...
Action used to create objects that access the positions of the atoms from the MD code.
void addIndexToList(const T &ii)
Add something to the active list.
Definition: DynamicList.h:235
StoreCentralAtomsVessel * getCentralAtoms()
Return a pointer to the vessel that stores the positions of all the central atoms.
void mergeDerivatives(const unsigned &ider, const double &df)
These replace the functions in ActionWithVessel to make the code faster.
bool usepbc
Use periodic boundary conditions.
int printf(const char *fmt,...)
Formatted output with explicit format - a la printf.
Definition: OFile.cpp:82
void setElementValue(const unsigned &, const double &)
Set the value of the element.
Base class for all the input Actions.
Definition: Action.h:60
VectorGeneric< n > delta(const VectorGeneric< n > &v1, const VectorGeneric< n > &v2)
Definition: Vector.h:262
bool isActive(const unsigned &) const
Find out if a member is active.
Definition: DynamicList.h:220
virtual void unlockContributors()
Used to make sure we are calculating everything during neighbor list update step. ...
void accumulateDerivative(const unsigned &ider, const double &df)
This is used to accumulate the derivatives when we merge using chainRuleForElementDerivatives.
void use(const std::string &k)
Use one of the reserved keywords.
Definition: Keywords.cpp:154
const Tensor & getInvBox() const
Returns the inverse matrix of box.
Definition: Pbc.cpp:218
DynamicList< unsigned > taskList
The list of tasks we have to perform.
Vector retrieveCentralAtomPos()
Retrieve the position of the central atom.
This class is used to pass the input to Vessels.
Definition: Vessel.h:53
unsigned getNumberOfVessels() const
Get the number of vessels.
double getTolerance() const
Return the value of the tolerance.
long int getStep() const
Return the present timestep.
Definition: Action.cpp:169
bool exists(const std::string &k) const
Check if there is a keyword with name k.
Definition: Keywords.cpp:239
void int double * da
Definition: Matrix.h:47
Tensor ibox
Variables used for central atoms.
friend void mpi_gatherActiveMembers(Communicator &, std::vector< DynamicList< U > > &)
This gathers data split across nodes list of Dynamic lists.
Definition: DynamicList.h:318
virtual double doCalculation(const unsigned &j)=0
And a virtual function which actually computes the colvar.
Vector pbcDistance(const Vector &, const Vector &) const
Compute the pbc distance between two positions.
DynamicList< unsigned > atoms_with_derivatives
A dynamic list containing those atoms with derivatives.
void performTask(const unsigned &j)
Perform one of the tasks.
unsigned getNumberOfDerivatives()
Get the number of derivatives for this action.
void setForcesOnAtoms(const std::vector< double > &forcesToApply, unsigned ind=0)
Add the forces to the atoms.
unsigned getNumberOfAtoms() const
Get number of available atoms.
double getCentralAtomDerivative(const unsigned &iatom, const unsigned jcomp, const Vector &df) const
Retrieve derivative of central atom position wrt jcomp'th component of position of iatom'th atom...
const Keywords & keywords
Definition: Action.h:161
void deactivateAll()
Make everything in the list inactive.
Definition: DynamicList.h:255
bool contributorsAreUnlocked
The terms in the series are locked.
void resizeFunctions()
Resize all the functions when the number of derivatives change.
void activateAll()
Make everything in the list active.
Definition: DynamicList.h:270
int updateFreq
Everything for controlling the updating of neighbor lists.
unsigned getNumberActive() const
Return the number of elements that are currently active.
Definition: DynamicList.h:230
void addFlag(const std::string &k, const bool def, const std::string &d)
Add a falg with name k that is by default on if def is true and off if def is false. d should provide a description of the flag.
Definition: Keywords.cpp:193
Vessel * getPntrToVessel(const unsigned &i)
Get a pointer to the ith vessel.
double getElementValue(const unsigned &ival) const
Get the value of this element.