All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
Driver.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 "CLTool.h"
23 #include "CLToolRegister.h"
24 #include "tools/Tools.h"
25 #include "wrapper/Plumed.h"
26 #include "tools/Communicator.h"
27 #include "tools/Random.h"
28 #include <cstdio>
29 #include <cstring>
30 #include <vector>
31 #include "tools/Units.h"
32 #include "tools/PDB.h"
33 
34 using namespace std;
35 
36 namespace PLMD {
37 namespace cltools{
38 
39 //+PLUMEDOC TOOLS driver
40 /*
41 driver is a tool that allows one to to use plumed to post-process an existing trajectory.
42 
43 The input to driver is specified using the command line arguments described below.
44 
45 In addition, you can use the special \subpage READ command inside your plumed input
46 to read in colvar files that were generated during your MD simulation. The values
47 read in can then be treated like calculated colvars.
48 
49 \par Examples
50 
51 The following command tells plumed to postprocess the trajectory contained in trajectory.xyz
52  by performing the actions described in the input file plumed.dat. If an action that takes the
53 stride keyword is given a stride equal to \f$n\f$ then it will be performed only on every \f$n\f$th
54 frame in the trajectory file.
55 \verbatim
56 plumed driver --plumed plumed.dat --ixyz trajectory.xyz
57 \endverbatim
58 
59 The following command tells plumed to postprocess the trajectory contained in trajectory.xyz.
60  by performing the actions described in the input file plumed.dat. Here though
61 --trajectory-stride is set equal to the frequency with which frames were output during the trajectory
62 and the --timestep is equal to the simulation timestep. As such the STRIDE parameters in the plumed.dat
63 files are no longer ignored and any files output resemble those that would have been generated
64 had we run the calculation we are running with driver when the MD simulation was running.
65 \verbatim
66 plumed driver --plumed plumed.dat --ixyz trajectory.xyz --trajectory-stride 100 --timestep 0.001
67 \endverbatim
68 
69 */
70 //+ENDPLUMEDOC
71 
72 template<typename real>
73 class Driver : public CLTool {
74 public:
75  static void registerKeywords( Keywords& keys );
76  Driver(const CLToolOptions& co );
77  int main(FILE* in,FILE*out,Communicator& pc);
78  string description()const;
79 };
80 
81 template<typename real>
83  CLTool::registerKeywords( keys );
84  keys.addFlag("--help-debug",false,"print special options that can be used to create regtests");
85  keys.add("compulsory","--plumed","plumed.dat","specify the name of the plumed input file");
86  keys.add("compulsory","--timestep","1.0","the timestep that was used in the calculation that produced this trajectory in picoseconds");
87  keys.add("compulsory","--trajectory-stride","1","the frequency with which frames were output to this trajectory during the simulation");
88  keys.add("compulsory","--multi","0","set number of replicas for multi environment (needs mpi)");
89  keys.addFlag("--noatoms",false,"don't read in a trajectory. Just use colvar files as specified in plumed.dat");
90  keys.add("atoms","--ixyz","the trajectory in xyz format");
91  keys.add("atoms","--igro","the trajectory in gro format");
92  keys.add("optional","--length-units","units for length, either as a string or a number");
93  keys.add("optional","--dump-forces","dump the forces on a file");
94  keys.add("optional","--dump-forces-fmt","( default=%%f ) the format to use to dump the forces");
95  keys.add("optional","--pdb","provides a pdb with masses and charges");
96  keys.add("optional","--box","comma-separated box dimensions (3 for orthorombic, 9 for generic)");
97  keys.add("hidden","--debug-float","turns on the single precision version (to check float interface)");
98  keys.add("hidden","--debug-dd","use a fake domain decomposition");
99  keys.add("hidden","--debug-pd","use a fake particle decomposition");
100  keys.add("hidden","--debug-grex","use a fake gromacs-like replica exchange, specify exchange stride");
101  keys.add("hidden","--debug-grex-log","log file for debug=grex");
102 }
103 
104 template<typename real>
106 CLTool(co)
107 {
109 }
110 
111 template<typename real>
112 string Driver<real>::description()const{ return "analyze trajectories with plumed"; }
113 
114 template<typename real>
115 int Driver<real>::main(FILE* in,FILE*out,Communicator& pc){
116 
117  Units units;
118  PDB pdb;
119 
120 // Parse everything
121  bool printhelpdebug; parseFlag("--help-debug",printhelpdebug);
122  if( printhelpdebug ){
123  fprintf(out,"%s",
124  "Additional options for debug (only to be used in regtest):\n"
125  " [--debug-float] : turns on the single precision version (to check float interface)\n"
126  " [--debug-dd] : use a fake domain decomposition\n"
127  " [--debug-pd] : use a fake particle decomposition\n"
128  );
129  return 0;
130  }
131  // Are we reading trajectory data
132  bool noatoms; parseFlag("--noatoms",noatoms);
133 
134  std::string fakein;
135  bool debugfloat=parse("--debug-float",fakein);
136  if(debugfloat && sizeof(real)!=sizeof(float)){
137  CLTool* cl=cltoolRegister().create(CLToolOptions("driver-float")); //new Driver<float>(*this);
138  cl->setInputData(this->getInputData());
139  int ret=cl->main(in,out,pc);
140  delete cl;
141  return ret;
142  }
143 
144  bool debug_pd=parse("--debug-pd",fakein);
145  bool debug_dd=parse("--debug-dd",fakein);
146  if( debug_pd || debug_dd ){
147  if(noatoms) error("cannot debug without atoms");
148  }
149 
150 // set up for multi replica driver:
151  int multi=0;
152  parse("--multi",multi);
153  Communicator intracomm;
154  Communicator intercomm;
155  if(multi){
156  int ntot=pc.Get_size();
157  int nintra=ntot/multi;
158  if(multi*nintra!=ntot) error("invalid number of processes for multi environment");
159  pc.Split(pc.Get_rank()/nintra,pc.Get_rank(),intracomm);
160  pc.Split(pc.Get_rank()%nintra,pc.Get_rank(),intercomm);
161  } else {
162  intracomm.Set_comm(pc.Get_comm());
163  }
164 
165 // set up for debug replica exchange:
166  bool debug_grex=parse("--debug-grex",fakein);
167  int grex_stride=0;
168  FILE*grex_log=NULL;
169  if(debug_grex){
170  if(noatoms) error("must have atoms to debug_grex");
171  if(multi<2) error("--debug_grex needs --multi with at least two replicas");
172  Tools::convert(fakein,grex_stride);
173  string n; Tools::convert(intercomm.Get_rank(),n);
174  string file;
175  parse("--debug-grex-log",file);
176  if(file.length()>0){
177  file+="."+n;
178  grex_log=fopen(file.c_str(),"w");
179  }
180  }
181 
182 // Read the plumed input file name
183  string plumedFile; parse("--plumed",plumedFile);
184 // the timestep
185  double t; parse("--timestep",t);
186  real timestep=real(t);
187 // the stride
188  unsigned stride; parse("--trajectory-stride",stride);
189 // are we writing forces
190  string dumpforces(""), dumpforcesFmt("%f");;
191  if(!noatoms) parse("--dump-forces",dumpforces);
192  if(dumpforces!="") parse("--dump-forces-fmt",dumpforcesFmt);
193 
194  string trajectory_fmt;
195 
196 // Read in an xyz file
197  string trajectoryFile(""), pdbfile("");
198  bool pbc_cli_given=false; vector<double> pbc_cli_box(9,0.0);
199  if(!noatoms){
200  std::string traj_xyz; parse("--ixyz",traj_xyz);
201  std::string traj_gro; parse("--igro",traj_gro);
202  if(traj_xyz.length()>0 && traj_gro.length()>0){
203  fprintf(stderr,"ERROR: cannot provide more than one trajectory file\n");
204  if(grex_log)fclose(grex_log);
205  return 1;
206  }
207  if(traj_xyz.length()>0 && trajectoryFile.length()==0){
208  trajectoryFile=traj_xyz;
209  trajectory_fmt="xyz";
210  }
211  if(traj_gro.length()>0 && trajectoryFile.length()==0){
212  trajectoryFile=traj_gro;
213  trajectory_fmt="gro";
214  }
215  if(trajectoryFile.length()==0){
216  fprintf(stderr,"ERROR: missing trajectory data\n");
217  if(grex_log)fclose(grex_log);
218  return 1;
219  }
220  string lengthUnits(""); parse("--length-units",lengthUnits);
221  if(lengthUnits.length()>0) units.setLength(lengthUnits);
222 
223  parse("--pdb",pdbfile);
224  if(pdbfile.length()>0){
225  bool check=pdb.read(pdbfile,false,1.0);
226  if(!check) error("error reading pdb file");
227  }
228 
229  string pbc_cli_list; parse("--box",pbc_cli_list);
230  if(pbc_cli_list.length()>0) {
231  pbc_cli_given=true;
232  vector<string> words=Tools::getWords(pbc_cli_list,",");
233  if(words.size()==3){
234  for(int i=0;i<3;i++) sscanf(words[i].c_str(),"%100lf",&(pbc_cli_box[4*i]));
235  } else if(words.size()==9) {
236  for(int i=0;i<9;i++) sscanf(words[i].c_str(),"%100lf",&(pbc_cli_box[i]));
237  } else {
238  string msg="ERROR: cannot parse command-line box "+pbc_cli_list;
239  fprintf(stderr,"%s\n",msg.c_str());
240  return 1;
241  }
242 
243  }
244  }
245 
246  if( debug_dd && debug_pd ) error("cannot use debug-dd and debug-pd at the same time");
247  if(debug_pd || debug_dd){
248  if( !Communicator::initialized() ) error("needs mpi for debug-pd");
249  }
250 
251  Plumed p;
252  int rr=sizeof(real);
253  p.cmd("setRealPrecision",&rr);
254  int checknatoms=-1;
255  int step=0;
257  if(multi){
258  if(intracomm.Get_rank()==0) p.cmd("GREX setMPIIntercomm",&intercomm.Get_comm());
259  p.cmd("GREX setMPIIntracomm",&intracomm.Get_comm());
260  p.cmd("GREX init");
261  }
262  p.cmd("setMPIComm",&intracomm.Get_comm());
263  }
264  p.cmd("setMDLengthUnits",&units.getLength());
265  p.cmd("setMDEngine","driver");
266  p.cmd("setTimestep",&timestep);
267  p.cmd("setPlumedDat",plumedFile.c_str());
268  p.cmd("setLog",out);
269 
270  if(multi){
271  string n;
272  Tools::convert(intercomm.Get_rank(),n);
273  trajectoryFile+="."+n;
274  }
275 
276  FILE* fp=NULL; FILE* fp_forces=NULL;
277  if(!noatoms){
278  if (trajectoryFile=="-")
279  fp=in;
280  else {
281  fp=fopen(trajectoryFile.c_str(),"r");
282  if(!fp){
283  string msg="ERROR: Error opening XYZ file "+trajectoryFile;
284  fprintf(stderr,"%s\n",msg.c_str());
285  return 1;
286  }
287  }
288 
289  if(dumpforces.length()>0){
290  if(Communicator::initialized() && pc.Get_size()>1){
291  string n;
292  Tools::convert(pc.Get_rank(),n);
293  dumpforces+="."+n;
294  }
295  fp_forces=fopen(dumpforces.c_str(),"w");
296  }
297  }
298 
299  std::string line;
300  std::vector<real> coordinates;
301  std::vector<real> forces;
302  std::vector<real> masses;
303  std::vector<real> charges;
304  std::vector<real> cell;
305  std::vector<real> virial;
306 
307 // variables to test particle decomposition
308  int pd_nlocal;
309  int pd_start;
310 // variables to test random decomposition (=domain decomposition)
311  std::vector<int> dd_gatindex;
312  std::vector<int> dd_g2l;
313  std::vector<real> dd_masses;
314  std::vector<real> dd_charges;
315  std::vector<real> dd_forces;
316  std::vector<real> dd_coordinates;
317  int dd_nlocal;
318 // random stream to choose decompositions
319  Random rnd;
320 
321  while(true){
322  if(!noatoms){
323  if(!Tools::getline(fp,line)) break;
324  }
325 
326  int natoms;
327  bool first_step=false;
328  if(!noatoms){
329  if(trajectory_fmt=="gro") if(!Tools::getline(fp,line)) error("premature end of trajectory file");
330  sscanf(line.c_str(),"%100d",&natoms);
331  }
332  if(checknatoms<0 && !noatoms){
333  pd_nlocal=natoms;
334  pd_start=0;
335  first_step=true;
336  masses.assign(natoms,real(1.0));
337  charges.assign(natoms,real(0.0));
338  if(pdbfile.length()>0){
339  for(unsigned i=0;i<pdb.size();++i){
340  AtomNumber an=pdb.getAtomNumbers()[i];
341  unsigned index=an.index();
342  if( index>=unsigned(natoms) ) error("atom index in pdb exceeds the number of atoms in trajectory");
343  masses[index]=pdb.getOccupancy()[i];
344  charges[index]=pdb.getBeta()[i];
345  }
346  }
347  } else if( checknatoms<0 && noatoms ){
348  natoms=0;
349  }
350  if( checknatoms<0 ){
351  checknatoms=natoms;
352  p.cmd("setNatoms",&natoms);
353  p.cmd("init");
354  }
355  if(checknatoms!=natoms){
356  std::string stepstr; Tools::convert(step,stepstr);
357  error("number of atoms in frame " + stepstr + " does not match number of atoms in first frame");
358  }
359 
360  coordinates.assign(3*natoms,real(0.0));
361  forces.assign(3*natoms,real(0.0));
362  cell.assign(9,real(0.0));
363  virial.assign(9,real(0.0));
364 
365  if( first_step || rnd.U01()>0.5){
366  if(debug_pd){
367  int npe=intracomm.Get_size();
368  vector<int> loc(npe,0);
369  vector<int> start(npe,0);
370  for(int i=0;i<npe-1;i++){
371  int cc=(natoms*2*rnd.U01())/npe;
372  if(start[i]+cc>natoms) cc=natoms-start[i];
373  loc[i]=cc;
374  start[i+1]=start[i]+loc[i];
375  }
376  loc[npe-1]=natoms-start[npe-1];
377  intracomm.Bcast(&loc[0],npe,0);
378  intracomm.Bcast(&start[0],npe,0);
379  pd_nlocal=loc[intracomm.Get_rank()];
380  pd_start=start[intracomm.Get_rank()];
381  if(intracomm.Get_rank()==0){
382  fprintf(out,"\nDRIVER: Reassigning particle decomposition\n");
383  fprintf(out,"DRIVER: "); for(int i=0;i<npe;i++) fprintf(out,"%d ",loc[i]); printf("\n");
384  fprintf(out,"DRIVER: "); for(int i=0;i<npe;i++) fprintf(out,"%d ",start[i]); printf("\n");
385  }
386  p.cmd("setAtomsNlocal",&pd_nlocal);
387  p.cmd("setAtomsContiguous",&pd_start);
388  } else if(debug_dd){
389  int npe=intracomm.Get_size();
390  int rank=intracomm.Get_rank();
391  dd_charges.assign(natoms,0.0);
392  dd_masses.assign(natoms,0.0);
393  dd_gatindex.assign(natoms,-1);
394  dd_g2l.assign(natoms,-1);
395  dd_coordinates.assign(3*natoms,0.0);
396  dd_forces.assign(3*natoms,0.0);
397  dd_nlocal=0;
398  for(int i=0;i<natoms;++i){
399  double r=rnd.U01()*npe;
400  int n; for(n=0;n<npe;n++) if(n+1>r)break;
401  plumed_assert(n<npe);
402  if(n==rank){
403  dd_gatindex[dd_nlocal]=i;
404  dd_g2l[i]=dd_nlocal;
405  dd_charges[dd_nlocal]=charges[i];
406  dd_masses[dd_nlocal]=masses[i];
407  dd_nlocal++;
408  }
409  }
410  if(intracomm.Get_rank()==0){
411  fprintf(out,"\nDRIVER: Reassigning particle decomposition\n");
412  }
413  p.cmd("setAtomsNlocal",&dd_nlocal);
414  p.cmd("setAtomsGatindex",&dd_gatindex[0]);
415  }
416  }
417 
418  int plumedStopCondition=0;
419  p.cmd("setStep",&step);
420  p.cmd("setStopFlag",&plumedStopCondition);
421  if(!noatoms){
422  if(trajectory_fmt=="xyz"){
423  if(!Tools::getline(fp,line)) error("premature end of trajectory file");
424 
425  std::vector<double> celld(9,0.0);
426  if(pbc_cli_given==false) {
427  std::vector<std::string> words;
428  words=Tools::getWords(line);
429  if(words.size()==3){
430  sscanf(line.c_str(),"%100lf %100lf %100lf",&celld[0],&celld[4],&celld[8]);
431  } else if(words.size()==9){
432  sscanf(line.c_str(),"%100lf %100lf %100lf %100lf %100lf %100lf %100lf %100lf %100lf",
433  &celld[0], &celld[1], &celld[2],
434  &celld[3], &celld[4], &celld[5],
435  &celld[6], &celld[7], &celld[8]);
436  } else error("needed box in second line of xyz file");
437  } else { // from command line
438  celld=pbc_cli_box;
439  }
440  for(unsigned i=0;i<9;i++)cell[i]=real(celld[i]);
441  }
442  int ddist=0;
443  // Read coordinates
444  for(int i=0;i<natoms;i++){
445  bool ok=Tools::getline(fp,line);
446  if(!ok) error("premature end of trajectory file");
447  double cc[3];
448  if(trajectory_fmt=="xyz"){
449  char dummy[1000];
450  int ret=std::sscanf(line.c_str(),"%999s %100lf %100lf %100lf",dummy,&cc[0],&cc[1],&cc[2]);
451  if(ret!=4) error("cannot read line"+line);
452  } else if(trajectory_fmt=="gro"){
453  // do the gromacs way
454  if(!i){
455  //
456  // calculate the distance between dots (as in gromacs gmxlib/confio.c, routine get_w_conf )
457  //
458  const char *p1, *p2, *p3;
459  p1 = strchr(line.c_str(), '.');
460  if (p1 == NULL) error("seems there are no coordinates in the gro file");
461  p2 = strchr(&p1[1], '.');
462  if (p2 == NULL) error("seems there is only one coordinates in the gro file");
463  ddist = p2 - p1;
464  p3 = strchr(&p2[1], '.');
465  if (p3 == NULL)error("seems there are only two coordinates in the gro file");
466  if (p3 - p2 != ddist)error("not uniform spacing in fields in the gro file");
467  }
468  Tools::convert(line.substr(20,ddist),cc[0]);
469  Tools::convert(line.substr(20+ddist,ddist),cc[1]);
470  Tools::convert(line.substr(20+ddist+ddist,ddist),cc[2]);
471  } else plumed_error();
472  if(!debug_pd || ( i>=pd_start && i<pd_start+pd_nlocal) ){
473  coordinates[3*i]=real(cc[0]);
474  coordinates[3*i+1]=real(cc[1]);
475  coordinates[3*i+2]=real(cc[2]);
476  }
477  }
478  if(trajectory_fmt=="gro"){
479  if(!Tools::getline(fp,line)) error("premature end of trajectory file");
480  std::vector<string> words=Tools::getWords(line);
481  if(words.size()<3) error("cannot understand box format");
482  Tools::convert(words[0],cell[0]);
483  Tools::convert(words[1],cell[4]);
484  Tools::convert(words[2],cell[8]);
485  if(words.size()>3) Tools::convert(words[3],cell[1]);
486  if(words.size()>4) Tools::convert(words[4],cell[2]);
487  if(words.size()>5) Tools::convert(words[5],cell[3]);
488  if(words.size()>6) Tools::convert(words[6],cell[5]);
489  if(words.size()>7) Tools::convert(words[7],cell[6]);
490  if(words.size()>8) Tools::convert(words[8],cell[7]);
491  }
492 
493  if(debug_dd){
494  for(int i=0;i<dd_nlocal;++i){
495  int kk=dd_gatindex[i];
496  dd_coordinates[3*i+0]=coordinates[3*kk+0];
497  dd_coordinates[3*i+1]=coordinates[3*kk+1];
498  dd_coordinates[3*i+2]=coordinates[3*kk+2];
499  }
500  p.cmd("setForces",&dd_forces[0]);
501  p.cmd("setPositions",&dd_coordinates[0]);
502  p.cmd("setMasses",&dd_masses[0]);
503  p.cmd("setCharges",&dd_charges[0]);
504  } else {
505  p.cmd("setForces",&forces[3*pd_start]);
506  p.cmd("setPositions",&coordinates[3*pd_start]);
507  p.cmd("setMasses",&masses[pd_start]);
508  p.cmd("setCharges",&charges[pd_start]);
509  }
510  p.cmd("setBox",&cell[0]);
511  p.cmd("setVirial",&virial[0]);
512  }
513  p.cmd("calc");
514 
515 // this is necessary as only processor zero is adding to the virial:
516  intracomm.Bcast(&virial[0],9,0);
517  if(debug_pd) intracomm.Sum(&forces[0],natoms*3);
518  if(debug_dd){
519  for(int i=0;i<dd_nlocal;i++){
520  forces[3*dd_gatindex[i]+0]=dd_forces[3*i+0];
521  forces[3*dd_gatindex[i]+1]=dd_forces[3*i+1];
522  forces[3*dd_gatindex[i]+2]=dd_forces[3*i+2];
523  }
524  dd_forces.assign(3*natoms,0.0);
525  intracomm.Sum(&forces[0],natoms*3);
526  }
527  if(debug_grex &&step%grex_stride==0){
528  p.cmd("GREX savePositions");
529  if(intracomm.Get_rank()>0){
530  p.cmd("GREX prepare");
531  } else {
532  int r=intercomm.Get_rank();
533  int n=intercomm.Get_size();
534  int partner=r+(2*((r+step/grex_stride)%2))-1;
535  if(partner<0)partner=0;
536  if(partner>=n) partner=n-1;
537  p.cmd("GREX setPartner",&partner);
538  p.cmd("GREX calculate");
539  p.cmd("GREX shareAllDeltaBias");
540  for(int i=0;i<n;i++){
541  string s; Tools::convert(i,s);
542  real a; s="GREX getDeltaBias "+s; p.cmd(s.c_str(),&a);
543  if(grex_log) fprintf(grex_log," %f",a);
544  }
545  if(grex_log) fprintf(grex_log,"\n");
546  }
547  }
548 
549 
550  if(fp_forces){
551  fprintf(fp_forces,"%d\n",natoms);
552  string fmt=dumpforcesFmt+" "+dumpforcesFmt+" "+dumpforcesFmt+"\n";
553  fprintf(fp_forces,fmt.c_str(),virial[0],virial[4],virial[8]);
554  fmt="X "+fmt;
555  for(int i=0;i<natoms;i++)
556  fprintf(fp_forces,fmt.c_str(),forces[3*i],forces[3*i+1],forces[3*i+2]);
557  }
558 
559  if(noatoms && plumedStopCondition) break;
560 
561  step+=stride;
562  }
563  p.cmd("runFinalJobs");
564 
565  if(fp_forces) fclose(fp_forces);
566  if(fp && fp!=in)fclose(fp);
567  if(grex_log) fclose(grex_log);
568 
569  return 0;
570 }
571 
572 }
573 }
Simple class to store the index of an atom.
Definition: AtomNumber.h:39
void cmd(const char *key, const void *val=NULL)
Send a command to this plumed object.
Definition: Plumed.h:455
void Split(int, int, Communicator &) const
Wrapper to MPI_Comm_split.
bool read(const std::string &file, bool naturalUnits, double scale)
Read the pdb from a file, scaling positions by a factor scale.
Definition: PDB.cpp:144
static bool initialized()
Tests if MPI library is initialized.
int main(FILE *in, FILE *out, Communicator &pc)
virtual function mapping to the specific main for each tool
Definition: Driver.cpp:115
static bool getline(FILE *, std::string &line)
Get a line from the file pointer ifile.
Definition: Tools.cpp:190
int main(int argc, char **argv)
This main uses only the interface published in Plumed.h.
Definition: main.cpp:38
void Bcast(T *, int, int)
Definition: Communicator.h:134
MPI_Comm & Get_comm()
Reference to MPI communicator.
void setLength(const std::string &)
Set lengh units from string.
Definition: Units.cpp:57
static bool convert(const std::string &str, double &t)
Convert a string to a double, reading it.
Definition: Tools.cpp:74
virtual int main(FILE *in, FILE *out, Communicator &pc)=0
virtual function mapping to the specific main for each tool
Class containing wrappers to MPI.
Definition: Communicator.h:44
STL namespace.
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
double U01()
Definition: Random.cpp:74
void const char const char int * n
Definition: Matrix.h:42
string description() const
virtual function returning a one-line descriptor for the tool
Definition: Driver.cpp:112
This is the abstract base class to use for implementing new command line tool, within it there is inf...
Definition: CLTool.h:55
This class holds the keywords and their documentation.
Definition: Keywords.h:36
const std::vector< double > & getBeta() const
Access to the beta array.
Definition: PDB.cpp:39
Small utility class that contains information about units.
Definition: Units.h:41
int Get_rank() const
Obtain the rank of the present process.
static std::vector< std::string > getWords(const std::string &line, const char *sep=NULL, int *parlevel=NULL, const char *parenthesis="{")
Split the line in words using separators.
Definition: Tools.cpp:112
CLTool * create(const CLToolOptions &ao)
Create an CLTool of the type indicated in the options.
const std::vector< double > & getOccupancy() const
Access to the occupancy array.
Definition: PDB.cpp:35
void setInputData(const std::map< std::string, std::string > &inputData)
Set the input data:
Definition: CLTool.h:71
C++ wrapper for plumed.
Definition: Plumed.h:314
Minimalistic pdb parser.
Definition: PDB.h:38
unsigned index() const
Returns the index number.
Definition: AtomNumber.h:89
CLToolRegister & cltoolRegister()
static int dummy
Definition: Plumed.c:80
const double & getLength() const
Get length units as double.
Definition: Units.h:95
enum PLMD::CLTool::@0 inputdata
How is the input specified on the command line or in an input file.
void Set_comm(MPI_Comm)
Set from a real MPI communicator.
unsigned size() const
Returns the number of atoms.
Definition: PDB.cpp:72
const std::vector< AtomNumber > & getAtomNumbers() const
Access to the indexes.
Definition: PDB.cpp:47
int Get_size() const
Obtain the number of processes.
void const char const char int double * a
Definition: Matrix.h:42
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