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