23 #include "core/PlumedMain.h"
24 #include "core/ActionSet.h"
25 #include "core/SetupMolInfo.h"
26 #include "vesselbase/Vessel.h"
27 #include "tools/Pbc.h"
33 namespace multicolvar{
35 void MultiColvar::registerKeywords(
Keywords& keys ){
36 MultiColvarBase::registerKeywords( keys );
37 keys.
reserve(
"numbered",
"ATOMS",
"the atoms involved in each of the collective variables you wish to calculate. "
38 "Keywords like ATOMS1, ATOMS2, ATOMS3,... should be listed and one CV will be "
39 "calculated for each ATOM keyword you specify (all ATOM keywords should "
40 "define the same number of atoms). The eventual number of quantities calculated by this "
41 "action will depend on what functions of the distribution you choose to calculate.");
43 keys.
reserve(
"atoms-3",
"SPECIES",
"this keyword is used for colvars such as coordination number. In that context it specifies that plumed should calculate "
44 "one coordination number for each of the atoms specified. Each of these coordination numbers specifies how many of the "
45 "other specified atoms are within a certain cutoff of the central atom.");
46 keys.
reserve(
"atoms-4",
"SPECIESA",
"this keyword is used for colvars such as the coordination number. In that context it species that plumed should calculate "
47 "one coordination number for each of the atoms specified in SPECIESA. Each of these cooordination numbers specifies how many "
48 "of the atoms specifies using SPECIESB is within the specified cutoff");
49 keys.
reserve(
"atoms-4",
"SPECIESB",
"this keyword is used for colvars such as the coordination number. It must appear with SPECIESA. For a full explanation see "
50 "the documentation for that keyword");
51 keys.
addFlag(
"VERBOSE",
false,
"write a more detailed output");
84 std::vector<AtomNumber> t; std::vector<unsigned> newlist;
87 if( t.empty() )
break;
90 log.
printf(
" Colvar %d is calculated from atoms : ", i);
91 for(
unsigned j=0;j<t.size();++j)
log.
printf(
"%d ",t[j].serial() );
95 if( i==1 && natoms<0 ) natoms=t.size();
96 if( t.size()!=natoms ){
98 error(key + ss +
" keyword has the wrong number of atoms");
100 for(
unsigned j=0;j<natoms;++j){
101 newlist.push_back( natoms*(i-1)+j );
115 }
else if( natoms==3 ){
116 if( !
keywords.
exists(
"GROUPA") )
error(
"use GROUPA, GROUPB and GROUPC keywords as well as GROUP");
117 if( !
keywords.
exists(
"GROUPB") )
error(
"use GROUPA, GROUPB and GROUPC keywords as well as GROUP");
118 if( !
keywords.
exists(
"GROUPC") )
error(
"use GROUPA, GROUPB and GROUPC keywords as well as GROUP");
120 error(
"Cannot use groups keyword unless the number of atoms equals 2 or 3");
123 std::vector<AtomNumber> t;
126 for(
unsigned i=0;i<t.size();++i)
all_atoms.addIndexToList( t[i] );
127 std::vector<unsigned> newlist;
129 for(
unsigned i=1;i<t.size();++i){
130 for(
unsigned j=0;j<i;++j){
131 newlist.push_back(i); newlist.push_back(j);
addColvar( newlist ); newlist.clear();
134 }
else if(natoms==3){
135 for(
unsigned i=2;i<t.size();++i){
136 for(
unsigned j=1;j<i;++j){
137 for(
unsigned k=0;k<j;++k){
138 newlist.push_back(i); newlist.push_back(j);
139 newlist.push_back(k);
addColvar( newlist );
146 log.
printf(
" constructing colvars from %d atoms : ", t.size() );
147 for(
unsigned i=0;i<t.size();++i)
log.
printf(
"%d ",t[i].serial() );
153 }
else if(natoms==3){
156 plumed_merror(
"can only use groups for colvars involving 2 or 3 atoms");
162 plumed_assert(
all_atoms.fullSize()==0 );
164 std::vector<AtomNumber> t1, t2; std::vector<unsigned> newlist;
166 if( t1.empty() )
error(
"missing atom specification " + key1);
167 if ( t2.empty() )
error(
"missing atom specification " + key2);
168 for(
unsigned i=0;i<t1.size();++i)
all_atoms.addIndexToList( t1[i] );
169 for(
unsigned i=0;i<t2.size();++i)
all_atoms.addIndexToList( t2[i] );
170 for(
unsigned i=0;i<t1.size();++i){
171 for(
unsigned j=0;j<t2.size();++j){
172 newlist.push_back(i); newlist.push_back( t1.size() + j );
addColvar( newlist ); newlist.clear();
176 log.
printf(
" constructing colvars from two groups containing %d and %d atoms respectively\n",t1.size(),t2.size() );
177 log.
printf(
" group %s contains atoms : ", key1.c_str() );
178 for(
unsigned i=0;i<t1.size();++i)
log.
printf(
"%d ",t1[i].serial() );
180 log.
printf(
" group %s contains atoms : ", key2.c_str() );
181 for(
unsigned i=0;i<t2.size();++i)
log.
printf(
"%d ",t2[i].serial() );
187 plumed_assert(
all_atoms.fullSize()==0 );
189 std::vector<AtomNumber> t1, t2, t3; std::vector<unsigned> newlist;
191 if( t1.empty() )
error(
"missing atom specification " + key1);
192 if( t2.empty() )
error(
"missing atom specification " + key2);
193 for(
unsigned i=0;i<t1.size();++i)
all_atoms.addIndexToList( t1[i] );
194 for(
unsigned i=0;i<t2.size();++i)
all_atoms.addIndexToList( t2[i] );
196 if( t3.empty() && !allow2 ){
197 error(
"missing atom specification " + key3);
198 }
else if( t3.empty() ){
199 for(
unsigned i=0;i<t1.size();++i){
200 for(
unsigned j=1;j<t2.size();++j){
201 for(
unsigned k=0;k<j;++k){
202 newlist.push_back( t1.size() + j );
203 newlist.push_back(i);
204 newlist.push_back( t1.size() + k );
210 log.
printf(
" constructing colvars from two groups containing %d and %d atoms respectively\n",t1.size(),t2.size() );
211 log.
printf(
" group %s contains atoms : ", key1.c_str() );
212 for(
unsigned i=0;i<t1.size();++i)
log.
printf(
"%d ",t1[i].serial() );
214 log.
printf(
" group %s contains atoms : ", key2.c_str() );
215 for(
unsigned i=0;i<t2.size();++i)
log.
printf(
"%d ",t2[i].serial() );
219 for(
unsigned i=0;i<t3.size();++i)
all_atoms.addIndexToList( t3[i] );
220 for(
unsigned i=0;i<t1.size();++i){
221 for(
unsigned j=0;j<t2.size();++j){
222 for(
unsigned k=0;k<t3.size();++k){
223 newlist.push_back( t1.size() + j );
224 newlist.push_back(i);
225 newlist.push_back( t1.size() + t2.size() + k );
231 log.
printf(
" constructing colvars from three groups containing %d, %d and %d atoms respectively\n",t1.size(),t2.size(),t3.size() );
232 log.
printf(
" group %s contains atoms : ", key1.c_str() );
233 for(
unsigned i=0;i<t1.size();++i)
log.
printf(
"%d ",t1[i].serial() );
235 log.
printf(
" group %s contains atoms : ", key2.c_str() );
236 for(
unsigned i=0;i<t2.size();++i)
log.
printf(
"%d ",t2[i].serial() );
238 log.
printf(
" group %s contains atoms : ", key3.c_str() );
239 for(
unsigned i=0;i<t3.size();++i)
log.
printf(
"%d ",t3[i].serial() );
248 std::vector<AtomNumber> t;
252 for(
unsigned i=0;i<t.size();++i)
all_atoms.addIndexToList( t[i] );
253 std::vector<unsigned> newlist;
255 for(
unsigned i=0;i<t.size();++i){
256 newlist.push_back(i);
257 for(
unsigned j=0;j<t.size();++j){
258 if(i!=j) newlist.push_back(j);
263 log.
printf(
" generating colvars from %d atoms of a particular type\n",t.size() );
265 for(
unsigned i=0;i<t.size();++i)
log.
printf(
"%d ",t[i].serial() );
271 for(
unsigned i=0;i<t.size();++i){
272 newlist.push_back(i);
addColvar( newlist ); newlist.clear();
277 plumed_merror(
"SPECIES keyword is not for density or coordination like CV");
280 std::vector<AtomNumber> t1,t2;
284 if ( t2.empty() )
error(
"SPECIESB keyword defines no atoms or is missing. Use either SPECIESA and SPECIESB or just SPECIES");
286 for(
unsigned i=0;i<t1.size();++i)
all_atoms.addIndexToList( t1[i] );
287 for(
unsigned i=0;i<t2.size();++i)
all_atoms.addIndexToList( t2[i] );
288 std::vector<unsigned> newlist;
289 for(
unsigned i=0;i<t1.size();++i){
290 newlist.push_back(i);
291 for(
unsigned j=0;j<t2.size();++j){
292 if( t1[i]!=t2[j] ) newlist.push_back( t1.size() + j );
297 log.
printf(
" generating colvars from a group of %d central atoms and %d other atoms\n",t1.size(), t2.size() );
299 for(
unsigned i=0;i<t1.size();++i)
log.
printf(
"%d ",t1[i].serial() );
302 for(
unsigned i=0;i<t2.size();++i)
log.
printf(
"%d ",t2[i].serial() );
void parseFlag(const std::string &key, bool &t)
Parse one keyword as boolean flag.
Log & log
Reference to the log stream.
void readAtoms(int &natoms)
Read in all the keywords that can be used to define atoms.
unsigned getNAtoms() const
Get the number of atoms in this particular colvar.
void readAtomsLikeKeyword(const std::string &key, int &natoms)
Read in ATOMS keyword.
Class implementing fixed size vectors of doubles.
void addColvar(const std::vector< unsigned > &newatoms)
Add a collective variable.
void resizeDynamicArrays()
Resize all the dynamic arrays (used at neighbor list update time and during setup) ...
void error(const std::string &msg) const
Crash calculation and print documentation.
double doCalculation(const unsigned &j)
Do the calculation.
void parseAtomList(const std::string &key, std::vector< AtomNumber > &t)
Parse a list of atoms without a numbered keyword.
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) ...
void sortActiveList()
This sorts the elements in the active list.
unsigned getAtomIndex(const unsigned &) const
Return the index of an atom.
void runAllTasks()
Calculate the values of all the vessels.
void setupMultiColvarBase()
Finish setting up the multicolvar base.
virtual double compute(const unsigned &j)=0
Actually compute the colvar.
void updateIndex(const unsigned &ii)
This can be used for a fast version of updateActiveMembers in which only a subset of the indexes are ...
DynamicList< unsigned > atomsWithCatomDer
This class holds the keywords and their documentation.
virtual Vector getCentralAtom()=0
Get the position of the central atom.
void emptyActiveMembers()
Empty the list of active members.
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.
void readTwoGroups(const std::string &key1, const std::string &key2)
Read two group keywords.
int printf(const char *fmt,...)
Formatted output with explicit format - a la printf.
Base class for all the input Actions.
bool verbose_output
Have atoms been read in.
void reserve(const std::string &t, const std::string &k, const std::string &d, const bool isvessel=false)
Reserve a keyword.
DynamicList< unsigned > taskList
The list of tasks we have to perform.
bool exists(const std::string &k) const
Check if there is a keyword with name k.
Vector calculateCentralAtomPosition()
Calculate the position of the central atom.
void readThreeGroups(const std::string &key1, const std::string &key2, const std::string &key3, const bool &allow2)
Read three groups.
void requestAtoms(const std::vector< AtomNumber > &a)
Request an array of atoms.
DynamicList< unsigned > atoms_with_derivatives
A dynamic list containing those atoms with derivatives.
DynamicList< AtomNumber > all_atoms
The list of all the atoms involved in the colvar.
void readGroupsKeyword(int &natoms)
Read in the various GROUP keywords.
void readSpeciesKeyword(int &natoms)
Read in the various SPECIES keywords.
bool serial
Do all calculations in serial.
void reset_style(const std::string &k, const std::string &style)
Change the style of a keyword.
const Keywords & keywords
virtual void calculate()
Calculate the multicolvar.
unsigned getNumberActive() const
Return the number of elements that are currently active.
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.