All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
CoordinationNumbers.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 "MultiColvar.h"
23 #include "tools/NeighborList.h"
24 #include "core/ActionRegister.h"
25 #include "tools/SwitchingFunction.h"
26 
27 #include <string>
28 #include <cmath>
29 
30 using namespace std;
31 
32 namespace PLMD{
33 namespace multicolvar{
34 
35 //+PLUMEDOC MCOLVAR COORDINATIONNUMBER
36 /*
37 Calculate the coordination numbers of atoms so that you can then calculate functions of the distribution of
38 coordination numbers such as the minimum, the number less than a certain quantity and so on.
39 
40 To make the calculation of coordination numbers differentiable the following function is used:
41 
42 \f[
43 s = \frac{ 1 - \left(\frac{r-d_0}{r_0}\right)^n } { 1 - \left(\frac{r-d_0}{r_0}\right)^m }
44 \f]
45 
46 \par Examples
47 
48 The following input tells plumed to calculate the coordination numbers of atoms 1-100 with themselves.
49 The minimum coordination number is then calculated.
50 \verbatim
51 COORDINATIONNUMBER SPECIES=1-100 R_0=1.0 MIN={BETA=0.1}
52 \endverbatim
53 
54 The following input tells plumed to calculate how many atoms from 1-100 are within 3.0 of each of the atoms
55 from 101-110. In the first 101 is the central atom, in the second 102 is the central atom and so on. The
56 number of coordination numbers more than 6 is then computed.
57 \verbatim
58 COORDINATIONNUMBER SPECIESA=101-110 SPECIESB=1-100 R_0=3.0 MORE_THAN={RATIONAL R_0=6.0 NN=6 MM=12 D_0=0}
59 \endverbatim
60 
61 */
62 //+ENDPLUMEDOC
63 
64 
66 private:
67 // double nl_cut;
69 public:
70  static void registerKeywords( Keywords& keys );
72 // active methods:
73  virtual double compute( const unsigned& j );
74  Vector getCentralAtom();
75 /// Returns the number of coordinates of the field
76  bool isPeriodic(){ return false; }
77 };
78 
79 PLUMED_REGISTER_ACTION(CoordinationNumbers,"COORDINATIONNUMBER")
80 
81 void CoordinationNumbers::registerKeywords( Keywords& keys ){
82  MultiColvar::registerKeywords( keys );
83  keys.use("SPECIES"); keys.use("SPECIESA"); keys.use("SPECIESB");
84  keys.add("compulsory","NN","6","The n parameter of the switching function ");
85  keys.add("compulsory","MM","12","The m parameter of the switching function ");
86  keys.add("compulsory","D_0","0.0","The d_0 parameter of the switching function");
87  keys.add("compulsory","R_0","The r_0 parameter of the switching function");
88  keys.add("optional","SWITCH","This keyword is used if you want to employ an alternative to the continuous swiching function defined above. "
89  "The following provides information on the \\ref switchingfunction that are available. "
90  "When this keyword is present you no longer need the NN, MM, D_0 and R_0 keywords.");
91  // Use actionWithDistributionKeywords
92  keys.use("MEAN"); keys.use("MORE_THAN"); keys.use("LESS_THAN");
93  keys.use("MIN"); keys.use("BETWEEN"); keys.use("HISTOGRAM"); keys.use("MOMENTS");
94 }
95 
96 CoordinationNumbers::CoordinationNumbers(const ActionOptions&ao):
98 {
99  // Read in the switching function
100  std::string sw, errors; parse("SWITCH",sw);
101  if(sw.length()>0){
102  switchingFunction.set(sw,errors);
103  if( errors.length()!=0 ) error("problem reading SWITCH keyword : " + errors );
104  } else {
105  double r_0=-1.0, d_0; int nn, mm;
106  parse("NN",nn); parse("MM",mm);
107  parse("R_0",r_0); parse("D_0",d_0);
108  if( r_0<0.0 ) error("you must set a value for R_0");
109  switchingFunction.set(nn,mm,r_0,d_0);
110  }
111  log.printf(" coordination of central atom and those within %s\n",( switchingFunction.description() ).c_str() );
112 
113  // Read in the atoms
114  int natoms; readAtoms( natoms );
115  // And setup the ActionWithVessel
117 
118  // Create the groups for the neighbor list
119  std::vector<AtomNumber> ga_lista, gb_lista; AtomNumber aa;
120  aa.setIndex(0); ga_lista.push_back(aa);
121  for(unsigned i=1;i<natoms;++i){ aa.setIndex(i); gb_lista.push_back(aa); }
122  // And check everything has been read in correctly
123  checkRead();
124 }
125 
126 double CoordinationNumbers::compute( const unsigned& j ){
127  double value=0, dfunc; Vector distance;
128 
129  // Calculate the coordination number
130  double sw;
131  for(unsigned i=1;i<getNAtoms();++i){
132  distance=getSeparation( getPosition(0), getPosition(i) );
133  sw = switchingFunction.calculate( distance.modulo(), dfunc );
134  if( sw>=getTolerance() ){ // nl_cut<0 ){
135  value += sw; // switchingFunction.calculate( distance.modulo(), dfunc );
136  addAtomsDerivatives( 0, (-dfunc)*distance );
137  addAtomsDerivatives( i, (dfunc)*distance );
138  addBoxDerivatives( (-dfunc)*Tensor(distance,distance) );
139  } else {
140  removeAtomRequest( i, sw );
141  }
142  }
143 
144  return value;
145 }
146 
149  return getPosition(0);
150 }
151 
152 }
153 }
154 
Simple class to store the index of an atom.
Definition: AtomNumber.h:39
double calculate(double x, double &df) const
Log & log
Reference to the log stream.
Definition: Action.h:93
void readAtoms(int &natoms)
Read in all the keywords that can be used to define atoms.
Definition: MultiColvar.cpp:71
Vector getSeparation(const Vector &vec1, const Vector &vec2) const
Get the separation between a pair of vectors.
double modulo() const
Compute the modulo.
Definition: Vector.h:325
void removeAtomRequest(const unsigned &aa, const double &weight)
Update the list of atoms after the neighbor list step.
unsigned getNAtoms() const
Get the number of atoms in this particular colvar.
Class implementing fixed size vectors of doubles.
Definition: Vector.h:74
Vector getCentralAtom()
Get the position of the central atom.
void set(int nn, int mm, double r_0, double d_0)
void error(const std::string &msg) const
Crash calculation and print documentation.
Definition: Action.cpp:195
void checkRead()
Check if Action was properly read.
Definition: Action.cpp:161
STL namespace.
Small class to compure switching functions in the form In the future we might extend it so as to be s...
void readVesselKeywords()
Complete the setup of this object (this routine must be called after construction of ActionWithValue)...
void addCentralAtomDerivatives(const unsigned &iatom, const Tensor &der)
Add derivatives to the central atom position.
Definition: MultiColvar.h:123
static TensorGeneric< n, n > identity()
return an identity tensor
Definition: Tensor.h:318
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
#define PLUMED_MULTICOLVAR_INIT(ao)
Definition: MultiColvar.h:28
void addBoxDerivatives(const Tensor &)
Add some derivatives to the virial.
This class is used to bring the relevant information to the Action constructor.
Definition: Action.h:41
int printf(const char *fmt,...)
Formatted output with explicit format - a la printf.
Definition: OFile.cpp:82
virtual double compute(const unsigned &j)
Actually compute the colvar.
bool isPeriodic()
Returns the number of coordinates of the field.
void addAtomsDerivatives(const int &, const Vector &)
Add some derivatives for an atom.
Definition: MultiColvar.h:113
const Vector & getPosition(unsigned) const
Get the position of atom iatom.
Definition: MultiColvar.h:93
AtomNumber & setIndex(unsigned)
Sets the atom number by index, returning a reference to the AtomNumber itself.
Definition: AtomNumber.h:102
double getTolerance() const
Return the value of the tolerance.
This is the abstract base class to use for creating distributions of colvars and functions thereof...
Definition: MultiColvar.h:39
std::string description() const
Tensor3d Tensor
Definition: Tensor.h:425
Provides the keyword COORDINATIONNUMBER