Line data Source code
1 : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 : Copyright (c) 2016-2023 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/ActionWithArguments.h" 23 : #include "core/ActionWithValue.h" 24 : #include "core/ActionPilot.h" 25 : #include "core/ActionRegister.h" 26 : #include "core/PlumedMain.h" 27 : #include "tools/Communicator.h" 28 : #include "tools/OFile.h" 29 : 30 : namespace PLMD { 31 : namespace generic { 32 : 33 : //+PLUMEDOC PRINTANALYSIS DUMPVECTOR 34 : /* 35 : Print a vector to a file 36 : 37 : \par Examples 38 : 39 : */ 40 : //+ENDPLUMEDOC 41 : 42 : class DumpVector : 43 : public ActionWithArguments, 44 : public ActionPilot { 45 : private: 46 : bool onefile; 47 : std::vector<std::string> argnames; 48 : std::string fmt, filename; 49 : void buildArgnames(); 50 : public: 51 : static void registerKeywords( Keywords& keys ); 52 : explicit DumpVector(const ActionOptions&ao); 53 72 : ~DumpVector() {} 54 16 : void calculate() override {} 55 16 : void apply() override {} 56 : void update() override ; 57 : }; 58 : 59 : PLUMED_REGISTER_ACTION(DumpVector,"DUMPVECTOR") 60 : 61 46 : void DumpVector::registerKeywords( Keywords& keys ) { 62 46 : Action::registerKeywords( keys ); 63 46 : ActionPilot::registerKeywords( keys ); 64 46 : ActionWithArguments::registerKeywords( keys ); 65 46 : keys.use("ARG"); 66 92 : keys.add("compulsory","STRIDE","0","the frequency with which the grid should be output to the file."); 67 92 : keys.add("compulsory","FILE","density","the file on which to write the vetors"); 68 92 : keys.add("optional","FMT","the format that should be used to output real numbers"); 69 92 : keys.addFlag("PRINT_ONE_FILE",false,"output vectors one after the other in a single file"); 70 46 : } 71 : 72 36 : DumpVector::DumpVector(const ActionOptions&ao): 73 : Action(ao), 74 : ActionWithArguments(ao), 75 : ActionPilot(ao), 76 36 : fmt("%f") { 77 36 : if( getNumberOfArguments()==0 ) { 78 0 : error("found no arguments"); 79 : } 80 36 : buildArgnames(); 81 36 : parse("FILE",filename); 82 72 : parseFlag("PRINT_ONE_FILE", onefile); 83 36 : if(filename.length()==0) { 84 0 : error("name out output file was not specified"); 85 : } 86 : 87 36 : log.printf(" outputting data with label %s to file named %s",getPntrToArgument(0)->getName().c_str(), filename.c_str() ); 88 36 : parse("FMT",fmt); 89 36 : log.printf(" with format %s \n", fmt.c_str() ); 90 36 : fmt = " " + fmt; 91 36 : if( onefile ) { 92 0 : log.printf(" printing all grids on a single file \n"); 93 : } else { 94 36 : log.printf(" printing all grids on separate files \n"); 95 : } 96 36 : } 97 : 98 40 : void DumpVector::buildArgnames() { 99 40 : argnames.resize(0); 100 : unsigned nvals = getPntrToArgument(0)->getShape()[0]; 101 : if( getPntrToArgument(0)->getRank()==2 ) { 102 : nvals = getPntrToArgument(0)->getShape()[0]; 103 : } 104 97 : for(unsigned i=0; i<getNumberOfArguments(); ++i) { 105 57 : if( getPntrToArgument(i)->getShape()[0]!=nvals ) { 106 0 : error("all arguments should have same number of values"); 107 : } 108 57 : if( getPntrToArgument(i)->getRank()==1 ) { 109 24 : argnames.push_back( getPntrToArgument(i)->getName() ); 110 33 : } else if( getPntrToArgument(i)->getRank()==2 ) { 111 33 : (getPntrToArgument(i)->getPntrToAction())->getMatrixColumnTitles( argnames ); 112 : } 113 57 : getPntrToArgument(i)->buildDataStore(); 114 : } 115 40 : } 116 : 117 46 : void DumpVector::update() { 118 46 : OFile ofile; 119 46 : ofile.link(*this); 120 46 : if( onefile ) { 121 0 : ofile.enforceRestart(); 122 : } else { 123 92 : ofile.setBackupString("analysis"); 124 : } 125 46 : ofile.open( filename ); 126 : 127 : unsigned totargs = 0; 128 116 : for(unsigned i=0; i<getNumberOfArguments(); ++i) { 129 70 : if( getPntrToArgument(i)->getRank()==1 ) { 130 31 : totargs += 1; 131 39 : } else if( getPntrToArgument(i)->getRank()==2 ) { 132 39 : totargs += getPntrToArgument(i)->getShape()[1]; 133 : } 134 : } 135 46 : if( totargs!=argnames.size() ) { 136 4 : buildArgnames(); 137 : } 138 : 139 46 : unsigned nvals = getPntrToArgument(0)->getShape()[0]; 140 5228 : for(unsigned i=0; i<nvals; ++i) { 141 : unsigned n=0; 142 5182 : ofile.fmtField(" %f"); 143 5182 : ofile.printField("time",getTime()); 144 5182 : ofile.printField("parameter",int(i)); 145 13163 : for(unsigned j=0; j<getNumberOfArguments(); j++) { 146 7981 : if( getPntrToArgument(j)->getRank()==1 ) { 147 4989 : ofile.fmtField(fmt); 148 4989 : ofile.printField(argnames[n],getPntrToArgument(j)->get(i) ); 149 4989 : n++; 150 2992 : } else if( getPntrToArgument(j)->getRank()==2 ) { 151 2992 : unsigned ncols = getPntrToArgument(j)->getShape()[1]; 152 13725 : for(unsigned k=0; k<ncols; ++k) { 153 10733 : ofile.fmtField(fmt); 154 10733 : ofile.printField(argnames[n],getPntrToArgument(j)->get(i*ncols+k)); 155 10733 : n++; 156 : } 157 : } 158 : } 159 5182 : ofile.printField(); 160 : } 161 46 : } 162 : 163 : } 164 : }