Line data Source code
1 : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 : Copyright (c) 2011-2018 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 : #include "core/ActionPilot.h"
23 : #include "core/ActionWithArguments.h"
24 : #include "core/ActionRegister.h"
25 :
26 : using namespace std;
27 :
28 : namespace PLMD {
29 : namespace generic {
30 :
31 : //+PLUMEDOC PRINTANALYSIS PRINT
32 : /*
33 : Print quantities to a file.
34 :
35 : This directive can be used multiple times
36 : in the input so you can print files with different strides or print different quantities
37 : to different files. You can control the buffering of output using the \subpage FLUSH keyword.
38 :
39 : \par Examples
40 :
41 : The following input instructs plumed to print the distance between atoms 3 and 5 on a file
42 : called COLVAR every 10 steps, and the distance and total energy on a file called COLVAR_ALL
43 : every 1000 steps.
44 : \verbatim
45 : DISTANCE ATOMS=2,5 LABEL=distance
46 : ENERGY LABEL=energy
47 : PRINT ARG=distance STRIDE=10 FILE=COLVAR
48 : PRINT ARG=distance,energy STRIDE=1000 FILE=COLVAR_ALL
49 : \endverbatim
50 : (See also \ref DISTANCE and \ref ENERGY).
51 :
52 : */
53 : //+ENDPLUMEDOC
54 :
55 : class Print :
56 : public ActionPilot,
57 : public ActionWithArguments
58 : {
59 : string file;
60 : OFile ofile;
61 : string fmt;
62 : // small internal utility
63 : /////////////////////////////////////////
64 : // these are crazy things just for debug:
65 : // they allow to change regularly the
66 : // printed argument
67 : int rotate;
68 : int rotateCountdown;
69 : int rotateLast;
70 : vector<Value*> rotateArguments;
71 : /////////////////////////////////////////
72 : public:
73 15658 : void calculate() {}
74 : void prepare();
75 : explicit Print(const ActionOptions&);
76 : static void registerKeywords(Keywords& keys);
77 15586 : void apply() {}
78 : void update();
79 : ~Print();
80 : };
81 :
82 2842 : PLUMED_REGISTER_ACTION(Print,"PRINT")
83 :
84 320 : void Print::registerKeywords(Keywords& keys) {
85 320 : Action::registerKeywords(keys);
86 320 : ActionPilot::registerKeywords(keys);
87 320 : ActionWithArguments::registerKeywords(keys);
88 320 : keys.use("ARG");
89 320 : keys.add("compulsory","STRIDE","1","the frequency with which the quantities of interest should be output");
90 320 : keys.add("optional","FILE","the name of the file on which to output these quantities");
91 320 : keys.add("optional","FMT","the format that should be used to output real numbers");
92 320 : keys.add("hidden","_ROTATE","some funky thing implemented by GBussi");
93 320 : keys.use("RESTART");
94 320 : keys.use("UPDATE_FROM");
95 320 : keys.use("UPDATE_UNTIL");
96 320 : }
97 :
98 319 : Print::Print(const ActionOptions&ao):
99 : Action(ao),
100 : ActionPilot(ao),
101 : ActionWithArguments(ao),
102 : fmt("%f"),
103 319 : rotate(0)
104 : {
105 319 : ofile.link(*this);
106 319 : parse("FILE",file);
107 319 : if(file.length()>0) {
108 319 : ofile.open(file);
109 319 : log.printf(" on file %s\n",file.c_str());
110 : } else {
111 0 : log.printf(" on plumed log file\n");
112 0 : ofile.link(log);
113 : }
114 319 : parse("FMT",fmt);
115 319 : fmt=" "+fmt;
116 319 : log.printf(" with format %s\n",fmt.c_str());
117 319 : for(unsigned i=0; i<getNumberOfArguments(); ++i) ofile.setupPrintValue( getPntrToArgument(i) );
118 : /////////////////////////////////////////
119 : // these are crazy things just for debug:
120 : // they allow to change regularly the
121 : // printed argument
122 319 : parse("_ROTATE",rotate);
123 319 : if(rotate>0) {
124 1 : rotateCountdown=rotate;
125 1 : for(unsigned i=0; i<getNumberOfArguments(); ++i) rotateArguments.push_back( getPntrToArgument(i) );
126 1 : vector<Value*> a(1,rotateArguments[0]);
127 1 : requestArguments(vector<Value*>(1,rotateArguments[0]));
128 1 : rotateLast=0;
129 : }
130 : /////////////////////////////////////////
131 319 : checkRead();
132 319 : }
133 :
134 15730 : void Print::prepare() {
135 : /////////////////////////////////////////
136 : // these are crazy things just for debug:
137 : // they allow to change regularly the
138 : // printed argument
139 15730 : if(rotate>0) {
140 5 : rotateCountdown--;
141 5 : if(rotateCountdown==0) {
142 2 : rotateCountdown=rotate;
143 2 : rotateLast++;
144 2 : rotateLast%=rotateArguments.size();
145 2 : requestArguments(vector<Value*>(1,rotateArguments[rotateLast]));
146 : }
147 : }
148 : /////////////////////////////////////////
149 15730 : }
150 :
151 15568 : void Print::update() {
152 15568 : ofile.fmtField(" %f");
153 15568 : ofile.printField("time",getTime());
154 96588 : for(unsigned i=0; i<getNumberOfArguments(); i++) {
155 81020 : ofile.fmtField(fmt);
156 81020 : ofile.printField( getPntrToArgument(i), getArgument(i) );
157 : //ofile.printField(getPntrToArgument(i)->getName(),getArgument(i));
158 : }
159 15568 : ofile.printField();
160 15568 : }
161 :
162 957 : Print::~Print() {
163 957 : }
164 :
165 : }
166 :
167 :
168 2523 : }
|