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