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 44 : void DumpVector::registerKeywords( Keywords& keys ) { 62 44 : Action::registerKeywords( keys ); 63 44 : ActionPilot::registerKeywords( keys ); 64 44 : ActionWithArguments::registerKeywords( keys ); keys.use("ARG"); 65 88 : keys.add("compulsory","STRIDE","0","the frequency with which the grid should be output to the file."); 66 88 : keys.add("compulsory","FILE","density","the file on which to write the vetors"); 67 88 : keys.add("optional","FMT","the format that should be used to output real numbers"); 68 88 : keys.addFlag("PRINT_ONE_FILE",false,"output vectors one after the other in a single file"); 69 44 : } 70 : 71 36 : DumpVector::DumpVector(const ActionOptions&ao): 72 : Action(ao), 73 : ActionWithArguments(ao), 74 : ActionPilot(ao), 75 36 : fmt("%f") 76 : { 77 36 : if( getNumberOfArguments()==0 ) error("found no arguments"); 78 108 : buildArgnames(); parse("FILE",filename); parseFlag("PRINT_ONE_FILE", onefile); 79 36 : if(filename.length()==0) error("name out output file was not specified"); 80 : 81 36 : log.printf(" outputting data with label %s to file named %s",getPntrToArgument(0)->getName().c_str(), filename.c_str() ); 82 72 : parse("FMT",fmt); log.printf(" with format %s \n", fmt.c_str() ); fmt = " " + fmt; 83 36 : if( onefile ) log.printf(" printing all grids on a single file \n"); 84 36 : else log.printf(" printing all grids on separate files \n"); 85 36 : } 86 : 87 40 : void DumpVector::buildArgnames() { 88 40 : argnames.resize(0); unsigned nvals = getPntrToArgument(0)->getShape()[0]; 89 : if( getPntrToArgument(0)->getRank()==2 ) nvals = getPntrToArgument(0)->getShape()[0]; 90 97 : for(unsigned i=0; i<getNumberOfArguments(); ++i) { 91 57 : if( getPntrToArgument(i)->getShape()[0]!=nvals ) error("all arguments should have same number of values"); 92 57 : if( getPntrToArgument(i)->getRank()==1 ) { 93 24 : argnames.push_back( getPntrToArgument(i)->getName() ); 94 33 : } else if( getPntrToArgument(i)->getRank()==2 ) { 95 33 : (getPntrToArgument(i)->getPntrToAction())->getMatrixColumnTitles( argnames ); 96 : } 97 57 : getPntrToArgument(i)->buildDataStore(); 98 : } 99 40 : } 100 : 101 46 : void DumpVector::update() { 102 46 : OFile ofile; ofile.link(*this); 103 46 : if( onefile ) ofile.enforceRestart(); 104 92 : else ofile.setBackupString("analysis"); 105 46 : ofile.open( filename ); 106 : 107 : unsigned totargs = 0; 108 116 : for(unsigned i=0; i<getNumberOfArguments(); ++i) { 109 70 : if( getPntrToArgument(i)->getRank()==1 ) totargs += 1; 110 39 : else if( getPntrToArgument(i)->getRank()==2 ) totargs += getPntrToArgument(i)->getShape()[1]; 111 : } 112 46 : if( totargs!=argnames.size() ) buildArgnames(); 113 : 114 46 : unsigned nvals = getPntrToArgument(0)->getShape()[0]; 115 5228 : for(unsigned i=0; i<nvals; ++i) { 116 : unsigned n=0; 117 5182 : ofile.fmtField(" %f"); 118 5182 : ofile.printField("time",getTime()); 119 5182 : ofile.printField("parameter",int(i)); 120 13163 : for(unsigned j=0; j<getNumberOfArguments(); j++) { 121 7981 : if( getPntrToArgument(j)->getRank()==1 ) { 122 4989 : ofile.fmtField(fmt); ofile.printField(argnames[n],getPntrToArgument(j)->get(i) ); n++; 123 2992 : } else if( getPntrToArgument(j)->getRank()==2 ) { 124 2992 : unsigned ncols = getPntrToArgument(j)->getShape()[1]; 125 13725 : for(unsigned k=0; k<ncols; ++k) { ofile.fmtField(fmt); ofile.printField(argnames[n],getPntrToArgument(j)->get(i*ncols+k)); n++; } 126 : } 127 : } 128 5182 : ofile.printField(); 129 : } 130 46 : } 131 : 132 : } 133 : }