Line data Source code
1 : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 : Copyright (c) 2011-2019 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 : Output file is either appended or backed up depending on the presence of the \ref RESTART action. 39 : A per-action `RESTART` keyword can be used as well. 40 : 41 : Notice that printing happens in the so-called "update" phase. This implies that printing 42 : is affected by the presence of \ref UPDATE_IF actions. In addition, one might decide to start 43 : and stop printing at preassigned values of time using the `UPDATE_FROM` and `UPDATE_UNTIL` keywords. 44 : Keep into account that even on steps when the action is not updated (and thus the file is not printed) 45 : the argument will be activated. In other words, if you use `UPDATE_FROM` to start printing at a given time, 46 : the collective variables this PRINT statement depends on will be computed also before that time. 47 : 48 : \par Examples 49 : 50 : The following input instructs plumed to print the distance between atoms 3 and 5 on a file 51 : called COLVAR every 10 steps, and the distance and total energy on a file called COLVAR_ALL 52 : every 1000 steps. 53 : \plumedfile 54 : # compute distance: 55 : distance: DISTANCE ATOMS=2,5 56 : # compute total energy (potential) 57 : energy: ENERGY 58 : # print distance on a file 59 : PRINT ARG=distance STRIDE=10 FILE=COLVAR 60 : # print both variables on another file 61 : PRINT ARG=distance,energy STRIDE=1000 FILE=COLVAR_ALL 62 : \endplumedfile 63 : 64 : Notice that \ref DISTANCE and \ref ENERGY are computed respectively every 10 and 1000 steps, that is 65 : only when required. 66 : 67 : */ 68 : //+ENDPLUMEDOC 69 : 70 : class Print : 71 : public ActionPilot, 72 : public ActionWithArguments 73 : { 74 : string file; 75 : OFile ofile; 76 : string fmt; 77 : // small internal utility 78 : ///////////////////////////////////////// 79 : // these are crazy things just for debug: 80 : // they allow to change regularly the 81 : // printed argument 82 : int rotate; 83 : int rotateCountdown; 84 : int rotateLast; 85 : vector<Value*> rotateArguments; 86 : ///////////////////////////////////////// 87 : public: 88 35333 : void calculate() override {} 89 : void prepare() override; 90 : explicit Print(const ActionOptions&); 91 : static void registerKeywords(Keywords& keys); 92 35225 : void apply() override {} 93 : void update() override; 94 : ~Print(); 95 : }; 96 : 97 9220 : PLUMED_REGISTER_ACTION(Print,"PRINT") 98 : 99 695 : void Print::registerKeywords(Keywords& keys) { 100 695 : Action::registerKeywords(keys); 101 695 : ActionPilot::registerKeywords(keys); 102 695 : ActionWithArguments::registerKeywords(keys); 103 1390 : keys.use("ARG"); 104 3475 : keys.add("compulsory","STRIDE","1","the frequency with which the quantities of interest should be output"); 105 2780 : keys.add("optional","FILE","the name of the file on which to output these quantities"); 106 2780 : keys.add("optional","FMT","the format that should be used to output real numbers"); 107 2780 : keys.add("hidden","_ROTATE","some funky thing implemented by GBussi"); 108 1390 : keys.use("RESTART"); 109 1390 : keys.use("UPDATE_FROM"); 110 1390 : keys.use("UPDATE_UNTIL"); 111 695 : } 112 : 113 694 : Print::Print(const ActionOptions&ao): 114 : Action(ao), 115 : ActionPilot(ao), 116 : ActionWithArguments(ao), 117 : fmt("%f"), 118 1388 : rotate(0) 119 : { 120 694 : ofile.link(*this); 121 1388 : parse("FILE",file); 122 694 : if(file.length()>0) { 123 694 : ofile.open(file); 124 694 : log.printf(" on file %s\n",file.c_str()); 125 : } else { 126 0 : log.printf(" on plumed log file\n"); 127 0 : ofile.link(log); 128 : } 129 1388 : parse("FMT",fmt); 130 1388 : fmt=" "+fmt; 131 694 : log.printf(" with format %s\n",fmt.c_str()); 132 10274 : for(unsigned i=0; i<getNumberOfArguments(); ++i) ofile.setupPrintValue( getPntrToArgument(i) ); 133 : ///////////////////////////////////////// 134 : // these are crazy things just for debug: 135 : // they allow to change regularly the 136 : // printed argument 137 1388 : parse("_ROTATE",rotate); 138 694 : if(rotate>0) { 139 1 : rotateCountdown=rotate; 140 11 : for(unsigned i=0; i<getNumberOfArguments(); ++i) rotateArguments.push_back( getPntrToArgument(i) ); 141 1 : vector<Value*> a(1,rotateArguments[0]); 142 2 : requestArguments(vector<Value*>(1,rotateArguments[0])); 143 1 : rotateLast=0; 144 : } 145 : ///////////////////////////////////////// 146 694 : checkRead(); 147 694 : } 148 : 149 35456 : void Print::prepare() { 150 : ///////////////////////////////////////// 151 : // these are crazy things just for debug: 152 : // they allow to change regularly the 153 : // printed argument 154 35456 : if(rotate>0) { 155 5 : rotateCountdown--; 156 5 : if(rotateCountdown==0) { 157 2 : rotateCountdown=rotate; 158 2 : rotateLast++; 159 2 : rotateLast%=rotateArguments.size(); 160 6 : requestArguments(vector<Value*>(1,rotateArguments[rotateLast])); 161 : } 162 : } 163 : ///////////////////////////////////////// 164 35456 : } 165 : 166 34606 : void Print::update() { 167 69212 : ofile.fmtField(" %f"); 168 69212 : ofile.printField("time",getTime()); 169 203701 : for(unsigned i=0; i<getNumberOfArguments(); i++) { 170 169095 : ofile.fmtField(fmt); 171 338190 : ofile.printField( getPntrToArgument(i), getArgument(i) ); 172 : } 173 34606 : ofile.printField(); 174 34606 : } 175 : 176 3470 : Print::~Print() { 177 1388 : } 178 : 179 : } 180 : 181 : 182 5874 : }