All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
CoordinationBase.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 "CoordinationBase.h"
23 #include "tools/NeighborList.h"
24 #include "tools/Communicator.h"
25 
26 #include <string>
27 
28 using namespace std;
29 
30 namespace PLMD{
31 namespace colvar{
32 
33 void CoordinationBase::registerKeywords( Keywords& keys ){
34  Colvar::registerKeywords(keys);
35  keys.addFlag("SERIAL",false,"Perform the calculation in serial - for debug purpose");
36  keys.addFlag("PAIR",false,"Pair only 1st element of the 1st group with 1st element in the second, etc");
37  keys.addFlag("NLIST",false,"Use a neighbour list to speed up the calculation");
38  keys.add("optional","NL_CUTOFF","The cutoff for the neighbour list");
39  keys.add("optional","NL_STRIDE","The frequency with which we are updating the atoms in the neighbour list");
40  keys.add("atoms","GROUPA","First list of atoms");
41  keys.add("atoms","GROUPB","Second list of atoms");
42 }
43 
44 CoordinationBase::CoordinationBase(const ActionOptions&ao):
46 pbc(true),
47 serial(false),
48 invalidateList(true),
49 firsttime(true)
50 {
51 
52  parseFlag("SERIAL",serial);
53 
54  vector<AtomNumber> ga_lista,gb_lista;
55  parseAtomList("GROUPA",ga_lista);
56  parseAtomList("GROUPB",gb_lista);
57 
58  bool nopbc=!pbc;
59  parseFlag("NOPBC",nopbc);
60  pbc=!nopbc;
61 
62 // pair stuff
63  bool dopair=false;
64  parseFlag("PAIR",dopair);
65 
66 // neighbor list stuff
67  bool doneigh=false;
68  double nl_cut=0.0;
69  int nl_st=0;
70  parseFlag("NLIST",doneigh);
71  if(doneigh){
72  parse("NL_CUTOFF",nl_cut);
73  if(nl_cut<=0.0) error("NL_CUTOFF should be explicitly specified and positive");
74  parse("NL_STRIDE",nl_st);
75  if(nl_st<=0) error("NL_STRIDE should be explicitly specified and positive");
76  }
77 
79  if(doneigh) nl= new NeighborList(ga_lista,gb_lista,dopair,pbc,getPbc(),nl_cut,nl_st);
80  else nl= new NeighborList(ga_lista,gb_lista,dopair,pbc,getPbc());
81 
83 
84  log.printf(" between two groups of %d and %d atoms\n",ga_lista.size(),gb_lista.size());
85  log.printf(" first group:\n");
86  for(unsigned int i=0;i<ga_lista.size();++i){
87  if ( (i+1) % 25 == 0 ) log.printf(" \n");
88  log.printf(" %d", ga_lista[i].serial());
89  }
90  log.printf(" \n second group:\n");
91  for(unsigned int i=0;i<gb_lista.size();++i){
92  if ( (i+1) % 25 == 0 ) log.printf(" \n");
93  log.printf(" %d", gb_lista[i].serial());
94  }
95  log.printf(" \n");
96  if(pbc) log.printf(" using periodic boundary conditions\n");
97  else log.printf(" without periodic boundary conditions\n");
98  if(dopair) log.printf(" with PAIR option\n");
99  if(doneigh){
100  log.printf(" using neighbor lists with\n");
101  log.printf(" update every %d steps and cutoff %lf\n",nl_st,nl_cut);
102  }
103 }
104 
106  delete nl;
107 }
108 
110  if(nl->getStride()>0){
111  if(getExchangeStep()) error("Neighbor lists for this collective variable are not compatible with replica exchange, sorry for that!");
112  if(firsttime || (getStep()%nl->getStride()==0)){
114  invalidateList=true;
115  firsttime=false;
116  }else{
118  invalidateList=false;
119  if(getExchangeStep()) error("Neighbor lists should be updated on exchange steps - choose a NL_STRIDE which divides the exchange stride!");
120  }
121  }
122 }
123 
124 // calculator
126 {
127 
128  double ncoord=0.;
129  Tensor virial;
130  vector<Vector> deriv(getNumberOfAtoms());
131 // deriv.resize(getPositions().size());
132 
133  if(nl->getStride()>0 && invalidateList){
134  nl->update(getPositions());
135  }
136 
137  unsigned stride=comm.Get_size();
138  unsigned rank=comm.Get_rank();
139  if(serial){
140  stride=1;
141  rank=0;
142  }else{
143  stride=comm.Get_size();
144  rank=comm.Get_rank();
145  }
146 
147  for(unsigned int i=rank;i<nl->size();i+=stride) { // sum over close pairs
148 
149  Vector distance;
150  unsigned i0=nl->getClosePair(i).first;
151  unsigned i1=nl->getClosePair(i).second;
152  if(pbc){
153  distance=pbcDistance(getPosition(i0),getPosition(i1));
154  } else {
155  distance=delta(getPosition(i0),getPosition(i1));
156  }
157 
158  double dfunc=0.;
159  ncoord += pairing(distance.modulo(), dfunc,i0,i1);
160 
161  deriv[i0] = deriv[i0] + (-dfunc)*distance ;
162  deriv[i1] = deriv[i1] + dfunc*distance ;
163  virial=virial+(-dfunc)*Tensor(distance,distance);
164  }
165 
166  if(!serial){
167  comm.Sum(&ncoord,1);
168  if(!deriv.empty()) comm.Sum(&deriv[0][0],3*deriv.size());
169  comm.Sum(&virial[0][0],9);
170  }
171 
172  for(unsigned i=0;i<deriv.size();++i) setAtomsDerivatives(i,deriv[i]);
173  setValue (ncoord);
174  setBoxDerivatives (virial);
175 
176 }
177 }
178 }
const Vector & getPosition(int) const
Get position of i-th atom.
void parseFlag(const std::string &key, bool &t)
Parse one keyword as boolean flag.
Definition: Action.cpp:104
void setNotPeriodic()
Set your default value to have no periodicity.
std::vector< PLMD::AtomNumber > & getFullAtomList()
Return the list of all atoms. These are needed to rebuild the neighbor list.
Log & log
Reference to the log stream.
Definition: Action.h:93
double modulo() const
Compute the modulo.
Definition: Vector.h:325
Class implementing fixed size matrices of doubles.
Definition: Tensor.h:70
virtual void prepare()
Prepare an Action for calculation This can be used by Action if they need some special preparation be...
Class implementing fixed size vectors of doubles.
Definition: Vector.h:74
void setAtomsDerivatives(int, const Vector &)
Definition: Colvar.h:97
void error(const std::string &msg) const
Crash calculation and print documentation.
Definition: Action.cpp:195
const std::vector< Vector > & getPositions() const
Get the array of all positions.
STL namespace.
void parseAtomList(const std::string &key, std::vector< AtomNumber > &t)
Parse a list of atoms without a numbered keyword.
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
Communicator & comm
Definition: Action.h:158
void addValueWithDerivatives()
Add a value with the name label that has derivatives.
void requestAtoms(const std::vector< AtomNumber > &a)
Definition: Colvar.cpp:44
void update(const std::vector< PLMD::Vector > &positions)
Update the neighbor list and prepare the new list of atoms that will be requested to the main code...
#define PLUMED_COLVAR_INIT(ao)
Definition: Colvar.h:29
const Pbc & getPbc() const
Get reference to Pbc.
void setBoxDerivatives(const Tensor &)
Definition: Colvar.h:102
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
int Get_rank() const
Obtain the rank of the present process.
A class that implements neighbor lists from two lists or a single list of atoms.
Definition: NeighborList.h:36
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
std::pair< unsigned, unsigned > getClosePair(unsigned i) const
Get the i-th pair of the neighbor list.
bool getExchangeStep() const
Check if we are on an exchange step.
Definition: Action.cpp:217
VectorGeneric< n > delta(const VectorGeneric< n > &v1, const VectorGeneric< n > &v2)
Definition: Vector.h:262
void setValue(const double &d)
Set the default value (the one without name)
virtual void calculate()
Calculate an Action.
long int getStep() const
Return the present timestep.
Definition: Action.cpp:169
unsigned getStride() const
Get the update stride of the neighbor list.
std::vector< PLMD::AtomNumber > & getReducedAtomList()
Update the indexes in the neighbor list to match the ordering in the new positions array and return t...
Vector pbcDistance(const Vector &, const Vector &) const
Compute the pbc distance between two positions.
Tensor3d Tensor
Definition: Tensor.h:425
int Get_size() const
Obtain the number of processes.
virtual double pairing(double distance, double &dfunc, unsigned i, unsigned j) const =0
unsigned getNumberOfAtoms() const
Get number of available atoms.
void Sum(T *, int)
Wrapper for MPI_Allreduce with MPI_SUM.
Definition: Communicator.h:124
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
unsigned size() const
Get the size of the neighbor list.