1 /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2    Copyright (c) 2011-2021 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.org for more information.
6 
7    This file is part of plumed, version 2.
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 #ifndef __PLUMED_core_PlumedMain_h
23 #define __PLUMED_core_PlumedMain_h
24 
25 #include "WithCmd.h"
26 #include "tools/ForwardDecl.h"
27 #include <cstdio>
28 #include <string>
29 #include <vector>
30 #include <set>
31 #include <stack>
32 #include <memory>
33 #include <map>
34 
35 // !!!!!!!!!!!!!!!!!!!!!!    DANGER   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!11
36 // THE FOLLOWING ARE DEFINITIONS WHICH ARE NECESSARY FOR DYNAMIC LOADING OF THE PLUMED KERNEL:
37 // This section should be consistent with the Plumed.h file.
38 // Since the Plumed.h file may be included in host MD codes, **NEVER** MODIFY THE CODE DOWN HERE
39 
40 /* Generic function pointer */
41 typedef void (*plumed_function_pointer)(void);
42 
43 /* Holder for function pointer */
44 typedef struct {
45   plumed_function_pointer p;
46 } plumed_function_holder;
47 
48 // END OF DANGER
49 ////////////////////////////////////////////////////////////
50 
51 namespace PLMD {
52 
53 
54 
55 class ActionAtomistic;
56 class ActionPilot;
57 class Log;
58 class Atoms;
59 class ActionSet;
60 class DLLoader;
61 class Communicator;
62 class Stopwatch;
63 class Citations;
64 class ExchangePatterns;
65 class FileBase;
66 class DataFetchingObject;
67 
68 /**
69 Main plumed object.
70 In MD engines this object is not manipulated directly but it is wrapped in
71 plumed or PLMD::Plumed objects. Its main method is cmd(),
72 which defines completely the external plumed interface.
73 It does not contain any static data.
74 */
75 class PlumedMain:
76   public WithCmd
77 {
78 /// Pointers to files opened in actions associated to this object.
79 /// Notice that with the current implementation this should be at the top of this
80 /// structure. Indeed, this should be destroyed *after* all the actions allocated
81 /// in this PlumedMain object have been destroyed.
82   std::set<FileBase*> files;
83 /// Forward declaration.
84   ForwardDecl<Communicator> comm_fwd;
85 public:
86 /// Communicator for plumed.
87 /// Includes all the processors used by plumed.
88   Communicator&comm=*comm_fwd;
89 
90 private:
91 /// Forward declaration.
92   ForwardDecl<Communicator> multi_sim_comm_fwd;
93 public:
94   Communicator&multi_sim_comm=*multi_sim_comm_fwd;
95 
96 private:
97 /// Error handler.
98 /// Pointer to a function that is called an exception thrown within
99 /// the library is about to leave the library.
100 /// Can be used to remap exceptions in case the plumed wrapper was compiled
101 /// with a different version of the C++ standard library.
102 /// Should only be called from \ref plumed_plumedmain_cmd().
103   typedef struct {
104     void* ptr;
105     void(*handler)(void* ptr,int code,const char*);
106   } plumed_error_handler;
107 
108   plumed_error_handler error_handler= {NULL,NULL};
109 
110 /// Forward declaration.
111   ForwardDecl<DLLoader> dlloader_fwd;
112   DLLoader& dlloader=*dlloader_fwd;
113 
114   std::unique_ptr<WithCmd> cltool;
115 
116   std::unique_ptr<WithCmd> grex;
117 /// Flag to avoid double initialization
118   bool  initialized;
119 /// Name of MD engine
120   std::string MDEngine;
121 
122 /// Forward declaration.
123   ForwardDecl<Log> log_fwd;
124 /// Log stream
125   Log& log=*log_fwd;
126 
127 /// Forward declaration.
128 /// Should be placed after log since its constructor takes a log reference as an argument.
129   ForwardDecl<Stopwatch> stopwatch_fwd;
130   Stopwatch& stopwatch=*stopwatch_fwd;
131 
132 /// Forward declaration.
133   ForwardDecl<Citations> citations_fwd;
134 /// tools/Citations.holder
135   Citations& citations=*citations_fwd;
136 
137 /// Present step number.
138   long int step;
139 
140 /// Condition for plumed to be active.
141 /// At every step, PlumedMain is checking if there are Action's requiring some work.
142 /// If at least one Action requires some work, this variable is set to true.
143   bool active;
144 
145 /// Name of the input file
146   std::string plumedDat;
147 
148 /// Object containing data we would like to grab and pass back
149   std::unique_ptr<DataFetchingObject> mydatafetcher;
150 
151 /// End of input file.
152 /// Set to true to terminate reading
153   bool endPlumed;
154 
155 /// Forward declaration.
156   ForwardDecl<Atoms> atoms_fwd;
157 /// Object containing information about atoms (such as positions,...).
158   Atoms&    atoms=*atoms_fwd;           // atomic coordinates
159 
160 /// Forward declaration.
161   ForwardDecl<ActionSet> actionSet_fwd;
162 /// Set of actions found in plumed.dat file
163   ActionSet& actionSet=*actionSet_fwd;
164 
165 /// Set of Pilot actions.
166 /// These are the action the, if they are Pilot::onStep(), can trigger execution
167   std::vector<ActionPilot*> pilots;
168 
169 /// Suffix string for file opening, useful for multiple simulations in the same directory
170   std::string suffix;
171 
172 /// The total bias (=total energy of the restraints)
173   double bias;
174 
175 /// The total work.
176 /// This computed by accumulating the change in external potentials.
177   double work;
178 
179 /// Forward declaration.
180   ForwardDecl<ExchangePatterns> exchangePatterns_fwd;
181 /// Class of possible exchange patterns, used for BIASEXCHANGE but also for future parallel tempering
182   ExchangePatterns& exchangePatterns=*exchangePatterns_fwd;
183 
184 /// Set to true if on an exchange step
185   bool exchangeStep;
186 
187 /// Flag for restart
188   bool restart;
189 
190 /// Flag for checkpointig
191   bool doCheckPoint;
192 
193 
194 /// Stuff to make plumed stop the MD code cleanly
195   int* stopFlag;
196   bool stopNow;
197 
198 /// Stack for update flags.
199 /// Store information used in class \ref generic::UpdateIf
200   std::stack<bool> updateFlags;
201 
202 public:
203 /// Flag to switch off virial calculation (for debug and MD codes with no barostat)
204   bool novirial;
205 
206 /// Flag to switch on detailed timers
207   bool detailedTimers;
208 
209 /// Generic map string -> double
210 /// intended to pass information across Actions
211   std::map<std::string,double> passMap;
212 
213 /// Add a citation, returning a string containing the reference number, something like "[10]"
214   std::string cite(const std::string&);
215 
216 /// Get number of threads that can be used by openmp
217   unsigned getNumThreads()const;
218 
219 /// Get a reasonable number of threads so as to access to an array of size s located at x
220   template<typename T>
221   unsigned getGoodNumThreads(const T*x,unsigned s)const;
222 
223 /// Get a reasonable number of threads so as to access to vector v;
224   template<typename T>
225   unsigned getGoodNumThreads(const std::vector<T> & v)const;
226 
227 public:
228   PlumedMain();
229 // this is to access to WithCmd versions of cmd (allowing overloading of a virtual method)
230   using WithCmd::cmd;
231   /**
232    cmd method, accessible with standard Plumed.h interface.
233    \param key The name of the command to be executed.
234    \param val The argument of the command to be executed.
235    It is called as plumed_cmd() or as PLMD::Plumed::cmd()
236    It is the interpreter for plumed commands. It basically contains the definition of the plumed interface.
237    If you want to add a new functionality to the interface between plumed
238    and an MD engine, this is the right place
239    Notice that this interface should always keep retro-compatibility
240   */
241   void cmd(const std::string&key,void*val=NULL) override;
242   ~PlumedMain();
243   /**
244     Read an input file.
245     \param str name of the file
246   */
247   void readInputFile(std::string str);
248   /**
249     Read an input string.
250     \param str name of the string
251   */
252   void readInputWords(const std::vector<std::string> &  str);
253 
254   /**
255     Read an input string.
256     \param str name of the string
257     At variance with readInputWords(), this is splitting the string into words
258   */
259   void readInputLine(const std::string & str);
260 
261   /**
262     Read an input buffer.
263     \param str name of the string
264     Same as readInputFile, but first write str on a temporary file and then read
265     that files. At variance with readInputLine, it can take care of comments and
266     continuation lines.
267   */
268   void readInputLines(const std::string & str);
269 
270   /**
271     Initialize the object.
272     Should be called once.
273   */
274   void init();
275   /**
276     Prepare the calculation.
277     Here it is checked which are the active Actions and communication of the relevant atoms is initiated.
278     Shortcut for prepareDependencies() + shareData()
279   */
280   void prepareCalc();
281   /**
282     Prepare the list of active Actions and needed atoms.
283     Scan the Actions to see which are active and which are not, so as to prepare a list of
284     the atoms needed at this step.
285   */
286   void prepareDependencies();
287   /**
288     Share the needed atoms.
289     In asynchronous implementations, this method sends the required atoms to all the plumed processes,
290     without waiting for the communication to complete.
291   */
292   void shareData();
293   /**
294     Perform the calculation.
295     Shortcut for waitData() + justCalculate() + justApply().
296     Equivalently: waitData() + justCalculate() + backwardPropagate() + update().
297   */
298   void performCalc();
299   /**
300     Perform the calculation without update()
301     Shortcut for: waitData() + justCalculate() + backwardPropagate()
302   */
303   void performCalcNoUpdate();
304   /**
305     Complete PLUMED calculation.
306     Shortcut for prepareCalc() + performCalc()
307   */
308   void calc();
309   /**
310     Scatters the needed atoms.
311     In asynchronous implementations, this method waits for the communications started in shareData()
312     to be completed. Otherwise, just send around needed atoms.
313   */
314   void waitData();
315   /**
316     Perform the forward loop on active actions.
317   */
318   void justCalculate();
319   /**
320     Backward propagate and update.
321     Shortcut for backwardPropagate() + update()
322     I leave it here for backward compatibility
323   */
324   void justApply();
325   /**
326     Perform the backward loop on active actions.
327     Needed to apply the forces back.
328   */
329   void backwardPropagate();
330   /**
331     Call the update() method.
332   */
333   void update();
334   /**
335     If there are calculations that need to be done at the very end of the calculations this
336     makes sures they are done
337   */
338   void runJobsAtEndOfCalculation();
339 /// Reference to atoms object
340   Atoms& getAtoms();
341 /// Reference to the list of Action's
342   const ActionSet & getActionSet()const;
343 /// Referenge to the log stream
344   Log & getLog();
345 /// Return the number of the step
getStep()346   long int getStep()const {return step;}
347 /// Stop the run
348   void exit(int c=0);
349 /// Load a shared library
350   void load(const std::string&);
351 /// Get the suffix string
352   const std::string & getSuffix()const;
353 /// Set the suffix string
354   void setSuffix(const std::string&);
355 /// get the value of the bias
356   double getBias()const;
357 /// get the value of the work
358   double getWork()const;
359 /// Opens a file.
360 /// Similar to plain fopen, but, if it finds an error in opening the file, it also tries with
361 /// path+suffix.  This trick is useful for multiple replica simulations.
362   FILE* fopen(const char *path, const char *mode);
363 /// Closes a file opened with PlumedMain::fopen()
364   int fclose(FILE*fp);
365 /// Insert a file
366   void insertFile(FileBase&);
367 /// Erase a file
368   void eraseFile(FileBase&);
369 /// Flush all files
370   void fflush();
371 /// Check if restarting
372   bool getRestart()const;
373 /// Set restart flag
setRestart(bool f)374   void setRestart(bool f) {restart=f;}
375 /// Check if checkpointing
376   bool getCPT()const;
377 /// Set exchangeStep flag
378   void setExchangeStep(bool f);
379 /// Get exchangeStep flag
380   bool getExchangeStep()const;
381 /// Stop the calculation cleanly (both the MD code and plumed)
382   void stop();
383 /// Enforce active flag.
384 /// This is a (bit dirty) hack to solve a bug. When there is no active ActionPilot,
385 /// several shortcuts are used. However, these shortcuts can block GREX module.
386 /// This function allows to enforce active plumed when doing exchanges,
387 /// thus fixing the bug.
388   void resetActive(bool active);
389 
390 /// Access to exchange patterns
getExchangePatterns()391   ExchangePatterns& getExchangePatterns() {return exchangePatterns;}
392 
393 /// Push a state to update flags
394   void updateFlagsPush(bool);
395 /// Pop a state from update flags
396   void updateFlagsPop();
397 /// Get top of update flags
398   bool updateFlagsTop();
399 /// Set end of input file
400   void setEndPlumed();
401 /// Call error handler.
402 /// Should only be called from \ref plumed_plumedmain_cmd().
403 /// If the error handler was not set, returns false.
404   bool callErrorHandler(int code,const char* msg)const;
405 };
406 
407 /////
408 // FAST INLINE METHODS:
409 
410 inline
getActionSet()411 const ActionSet & PlumedMain::getActionSet()const {
412   return actionSet;
413 }
414 
415 inline
getAtoms()416 Atoms& PlumedMain::getAtoms() {
417   return atoms;
418 }
419 
420 inline
getSuffix()421 const std::string & PlumedMain::getSuffix()const {
422   return suffix;
423 }
424 
425 inline
setSuffix(const std::string & s)426 void PlumedMain::setSuffix(const std::string&s) {
427   suffix=s;
428 }
429 
430 inline
getRestart()431 bool PlumedMain::getRestart()const {
432   return restart;
433 }
434 
435 inline
getCPT()436 bool PlumedMain::getCPT()const {
437   return doCheckPoint;
438 }
439 
440 inline
setExchangeStep(bool s)441 void PlumedMain::setExchangeStep(bool s) {
442   exchangeStep=s;
443 }
444 
445 inline
getExchangeStep()446 bool PlumedMain::getExchangeStep()const {
447   return exchangeStep;
448 }
449 
450 inline
resetActive(bool active)451 void PlumedMain::resetActive(bool active) {
452   this->active=active;
453 }
454 
455 inline
updateFlagsPush(bool on)456 void PlumedMain::updateFlagsPush(bool on) {
457   updateFlags.push(on);
458 }
459 
460 inline
updateFlagsPop()461 void PlumedMain::updateFlagsPop() {
462   updateFlags.pop();
463 }
464 
465 inline
updateFlagsTop()466 bool PlumedMain::updateFlagsTop() {
467   return updateFlags.top();
468 }
469 
470 inline
setEndPlumed()471 void PlumedMain::setEndPlumed() {
472   endPlumed=true;
473 }
474 
475 inline
callErrorHandler(int code,const char * msg)476 bool PlumedMain::callErrorHandler(int code,const char* msg)const {
477   if(error_handler.handler) {
478     error_handler.handler(error_handler.ptr,code,msg);
479     return true;
480   } else return false;
481 }
482 
483 
484 }
485 
486 #endif
487 
488