diff --git a/src/GenericDumpDerivatives.cpp b/src/GenericDumpDerivatives.cpp index f516739b9076d3e35346e6e9ffe301be4f51c49c..1aa3f46e0167e86b46aa778f0d854b4b9ed13cf4 100644 --- a/src/GenericDumpDerivatives.cpp +++ b/src/GenericDumpDerivatives.cpp @@ -102,11 +102,6 @@ fmt("%15.10f") for(unsigned i=1;i<nargs;i++){ if( npar!=getPntrToArgument(i)->getNumberOfDerivatives() ) error("the number of derivatives must be the same in all values being dumped"); } - of.addField("time"); - of.addField("parameter"); - for(unsigned i=0;i<nargs;i++){ - of.addField(getPntrToArgument(i)->getName()); - }; checkRead(); } diff --git a/src/GenericDumpForces.cpp b/src/GenericDumpForces.cpp index 8be1c03ffa3124d2ac73d5aa01448e44e5606930..a4810c10b139383cae3f7d1da3fa203a46e4fcd7 100644 --- a/src/GenericDumpForces.cpp +++ b/src/GenericDumpForces.cpp @@ -91,10 +91,6 @@ ActionWithArguments(ao) of.link(*this); log.printf(" on file %s\n",file.c_str()); if( getNumberOfArguments()==0 ) error("no arguments have been specified"); - of.addField("time"); - for(unsigned i=0;i<getNumberOfArguments();i++){ - of.addField(getPntrToArgument(i)->getName()); - }; checkRead(); } diff --git a/src/GenericDumpProjections.cpp b/src/GenericDumpProjections.cpp index 8d0eb7b52bf1d436829b4105cb08a25baea53a14..5c5457f77f56a33668331381184a906352561513 100644 --- a/src/GenericDumpProjections.cpp +++ b/src/GenericDumpProjections.cpp @@ -79,12 +79,6 @@ fmt("%15.10f") of.open(file.c_str(),"wa"); log.printf(" on file %s\n",file.c_str()); log.printf(" with format %s\n",fmt.c_str()); - of.addField("time"); - for(unsigned i=0;i<getNumberOfArguments();i++){ - for(unsigned j=0;j<getNumberOfArguments();j++){ - of.addField(getPntrToArgument(i)->getName()+"-"+getPntrToArgument(j)->getName()); - } - }; checkRead(); } diff --git a/src/GenericPrint.cpp b/src/GenericPrint.cpp index c2d7bff02b7d1241c279f79977e29d18c18ee8be..009c1d8a365f3c63304f0d8eb749850cb8f7df06 100644 --- a/src/GenericPrint.cpp +++ b/src/GenericPrint.cpp @@ -59,7 +59,6 @@ public ActionWithArguments PlumedOFile ofile; string fmt; // small internal utility - void updateFields(); ///////////////////////////////////////// // these are crazy things just for debug: // they allow to change regularly the @@ -108,7 +107,6 @@ rotate(0) log.printf(" on plumed log file\n"); ofile.link(log); } - updateFields(); parse("FMT",fmt); fmt=" "+fmt; log.printf(" with format %s\n",fmt.c_str()); @@ -123,7 +121,6 @@ rotate(0) vector<Value*> a(1,rotateArguments[0]); requestArguments(vector<Value*>(1,rotateArguments[0])); rotateLast=0; - updateFields(); } ///////////////////////////////////////// checkRead(); @@ -141,7 +138,6 @@ void GenericPrint::prepare(){ rotateLast++; rotateLast%=rotateArguments.size(); requestArguments(vector<Value*>(1,rotateArguments[rotateLast])); - updateFields(); } } ///////////////////////////////////////// @@ -160,14 +156,6 @@ void GenericPrint::update(){ GenericPrint::~GenericPrint(){ } -void GenericPrint::updateFields(){ - ofile.clearFields(); - ofile.addField("time"); - for(unsigned i=0;i<getNumberOfArguments();i++){ - ofile.addField(getPntrToArgument(i)->getName()); - } -} - } diff --git a/src/PlumedFile.cpp b/src/PlumedFile.cpp index 4da1d7dd192f286d5585978b9949306e3b97e1d7..6cccbb783cf7c8e05a225f61bdc52218bb9c7f58 100644 --- a/src/PlumedFile.cpp +++ b/src/PlumedFile.cpp @@ -28,6 +28,8 @@ #include <cstdarg> #include <cstring> +#include <iostream> + using namespace PLMD; void PlumedFileBase::test(){ @@ -37,9 +39,7 @@ void PlumedFileBase::test(){ pof.setLinePrefix("plumed: "); pof.printf("%s\n","test2"); pof.setLinePrefix(""); - pof.addField("x1"); pof.addConstantField("x2").printField("x2",67.0); - pof.addField("x3"); pof.printField("x1",10.0).printField("x3",20.12345678901234567890).printField(); pof.printField("x1",10.0).printField("x3",-1e70*20.12345678901234567890).printField(); pof.printField("x3",10.0).printField("x2",777.0).printField("x1",-1e70*20.12345678901234567890).printField(); @@ -82,8 +82,10 @@ size_t PlumedIFile::llread(char*ptr,size_t s){ if(feof(fp)) leof=1; } if(comm) comm->Bcast(&r,1,0); - if(comm) comm->Bcast(ptr,r,0); - if(comm) comm->Bcast(&leof,r,0); +// I explicitly cast sizes to int, as BCast is getting an int as second argument + if(comm) comm->Bcast(ptr,int(r),0); +// I explicitly cast sizes to int, as BCast is getting an int as second argument + if(comm) comm->Bcast(&leof,int(r),0); if(leof) eof=true; return r; } @@ -165,7 +167,11 @@ PlumedOFile::PlumedOFile(): { fmtField(); buffer=new char[buflen]; +// these are set to zero to avoid valgrind errors + for(unsigned i=0;i<buflen;++i) buffer[i]=0; buffer_string=new char [1000]; +// these are set to zero to avoid valgrind errors + for(unsigned i=0;i<1000;++i) buffer_string[i]=0; } PlumedOFile::~PlumedOFile(){ @@ -185,7 +191,7 @@ PlumedOFile& PlumedOFile::setLinePrefix(const std::string&l){ } int PlumedOFile::printf(const char*fmt,...){ - int pointer=strlen(buffer); + size_t pointer=strlen(buffer); va_list arg; va_start(arg, fmt); int r=std::vsnprintf(&buffer[pointer],buflen-pointer,fmt,arg); @@ -206,27 +212,18 @@ int PlumedOFile::printf(const char*fmt,...){ return r; } -PlumedOFile& PlumedOFile::addField(const std::string&name){ - Field f; - f.name=name; - fields.push_back(f); - fieldChanged=true; - return *this; -} - PlumedOFile& PlumedOFile::addConstantField(const std::string&name){ Field f; f.name=name; - f.constant=true; - fields.push_back(f); - fieldChanged=true; + const_fields.push_back(f); return *this; } PlumedOFile& PlumedOFile::clearFields(){ fields.clear(); - fieldChanged=true; + const_fields.clear(); + previous_fields.clear(); return *this; } @@ -240,13 +237,6 @@ PlumedOFile& PlumedOFile::fmtField(){ return *this; } -unsigned PlumedOFile::findField(const std::string&name)const{ - unsigned i; - for(i=0;i<fields.size();i++) if(fields[i].name==name) break; - if(i>=fields.size()) plumed_merror(name); - return i; -} - PlumedOFile& PlumedOFile::printField(const std::string&name,double v){ sprintf(buffer_string,fieldFmt.c_str(),v); printField(name,buffer_string); @@ -260,36 +250,45 @@ PlumedOFile& PlumedOFile::printField(const std::string&name,int v){ } PlumedOFile& PlumedOFile::printField(const std::string&name,const std::string & v){ - unsigned i=findField(name); - if(fields[i].constant) fieldChanged=true; - fields[i].value=v; - fields[i].set=true; + unsigned i; + for(i=0;i<const_fields.size();i++) if(const_fields[i].name==name) break; + if(i>=const_fields.size()){ + Field field; + field.name=name; + field.value=v; + fields.push_back(field); + } else { + if(const_fields[i].value!=v) fieldChanged=true; + const_fields[i].value=v; + } return *this; } PlumedOFile& PlumedOFile::printField(){ - if(fieldChanged){ - printf("#! FIELDS"); - for(unsigned i=0;i<fields.size();i++){ - if(!fields[i].constant) - printf(" %s",fields[i].name.c_str()); + bool reprint=false; + if(fieldChanged || fields.size()!=previous_fields.size()){ + reprint=true; + } else for(unsigned i=0;i<fields.size();i++){ + if( previous_fields[i].name!=fields[i].name || + (fields[i].constant && fields[i].value!=previous_fields[i].value) ){ + reprint=true; + break; } + } + if(reprint){ + printf("#! FIELDS"); + for(unsigned i=0;i<fields.size();i++) printf(" %s",fields[i].name.c_str()); printf("\n"); - for(unsigned i=0;i<fields.size();i++) - if(fields[i].constant){ - printf("#! SET %s %s",fields[i].name.c_str(),fields[i].value.c_str()); + for(unsigned i=0;i<const_fields.size();i++){ + printf("#! SET %s %s",const_fields[i].name.c_str(),const_fields[i].value.c_str()); printf("\n"); } } - fieldChanged=false; - for(unsigned i=0;i<fields.size();i++){ - plumed_assert(fields[i].set); - if(!fields[i].constant){ - printf("%s",fields[i].value.c_str()); - fields[i].set=false; - } - } + for(unsigned i=0;i<fields.size();i++) printf("%s",fields[i].value.c_str()); printf("\n"); + previous_fields=fields; + fields.clear(); + fieldChanged=false; return *this; } diff --git a/src/PlumedFile.h b/src/PlumedFile.h index 6bc9ff44cb9bf35820fad9673456fb159a68fdcd..37976af70828f148bd0725983eda87d4caaba2d7 100644 --- a/src/PlumedFile.h +++ b/src/PlumedFile.h @@ -163,9 +163,6 @@ public virtual PlumedFileBase{ /// Class identifying a single field for fielded output class Field: public FieldBase{ - public: - bool set; - Field(): set(false) {} }; /// Low-level write size_t llwrite(const char*,size_t); @@ -175,8 +172,12 @@ public virtual PlumedFileBase{ bool fieldChanged; /// Format for fields writing std::string fieldFmt; -/// All the defined fields +/// All the previously defined variable fields + std::vector<Field> previous_fields; +/// All the defined variable fields std::vector<Field> fields; +/// All the defined constant fields + std::vector<Field> const_fields; /// Prefix for line (e.g. "PLUMED: ") std::string linePrefix; /// Temporary ostringstream for << output @@ -199,15 +200,6 @@ public: /// Typically "PLUMED: ". Notice that lines with a prefix cannot /// be parsed using fields in a PlumedIFile. PlumedOFile& setLinePrefix(const std::string&); -/// Add a field. -/// Fields are written as one per column, and a commented header -/// with the list of fields is written whenever the list of fields -/// changes. - PlumedOFile& addField(const std::string&); -/// Add a constant field. -/// Constant fields are typically written on separate lines -/// in the output - PlumedOFile& addConstantField(const std::string&); /// Set the format for writing double precision fields PlumedOFile& fmtField(const std::string&); /// Reset the format for writing double precision fields to its default @@ -218,6 +210,8 @@ public: PlumedOFile& printField(const std::string&,int); /// Set the value of a string field PlumedOFile& printField(const std::string&,const std::string&); +/// + PlumedOFile& addConstantField(const std::string&); /** Close a line. Typically used as \verbatim diff --git a/src/PlumedMain.cpp b/src/PlumedMain.cpp index 30384fbfaefab368d9f840d6c605ead0b57bdb60..2619090b831157069fd666dce41feb034a6e2ee6 100644 --- a/src/PlumedMain.cpp +++ b/src/PlumedMain.cpp @@ -355,6 +355,7 @@ void PlumedMain::readInputFile(std::string str){ plumed_assert(initialized); log.printf("FILE: %s\n",str.c_str()); PlumedIFile ifile; + ifile.link(*this); ifile.open(str,"r"); std::vector<std::string> words; exchangepatterns.setFlag(exchangepatterns.NONE);