diff --git a/lib/colvars/colvar.cpp b/lib/colvars/colvar.cpp index f886f801cd..8f0850c0ff 100644 --- a/lib/colvars/colvar.cpp +++ b/lib/colvars/colvar.cpp @@ -987,9 +987,11 @@ void colvar::calc() } } - if (tasks[task_system_force]) { + if (tasks[task_system_force] && !tasks[task_extended_lagrangian]) { + // If extended Lagrangian is enabled, system force calculation is trivial + // and done together with integration of the extended coordinate. - if (tasks[task_scripted] && !tasks[task_extended_lagrangian]) { + if (tasks[task_scripted]) { // TODO see if this could reasonably be done in a generic way // from generic inverse gradients cvm::error("System force is not implemented for " @@ -1594,7 +1596,7 @@ int colvar::write_output_files() if (acf.size()) { cvm::log("Writing acf to file \""+acf_outfile+"\".\n"); - std::ofstream acf_os(acf_outfile.c_str()); + cvm::ofstream acf_os(acf_outfile.c_str()); if (! acf_os.good()) { cvm::error("Cannot open file \""+acf_outfile+"\".\n", FILE_ERROR); } diff --git a/lib/colvars/colvar.h b/lib/colvars/colvar.h index bb7d70d09c..2a9abb9d47 100644 --- a/lib/colvars/colvar.h +++ b/lib/colvars/colvar.h @@ -457,7 +457,7 @@ protected: /// Timesteps to skip between two values in the running average series size_t runave_stride; /// Name of the file to write the running average - std::ofstream runave_os; + cvm::ofstream runave_os; /// Current value of the running average colvarvalue runave; /// Current value of the square deviation from the running average diff --git a/lib/colvars/colvarbias_abf.cpp b/lib/colvars/colvarbias_abf.cpp index 543be6a95f..d2e35c85fe 100644 --- a/lib/colvars/colvarbias_abf.cpp +++ b/lib/colvars/colvarbias_abf.cpp @@ -76,6 +76,8 @@ colvarbias_abf::colvarbias_abf(std::string const &conf, char const *key) if (!colvars[i]->tasks[colvar::task_extended_lagrangian]) { // request computation of Jacobian force + // ultimately, will be done regardless of extended Lagrangian + // and colvar should then just report zero Jacobian force colvars[i]->enable(colvar::task_Jacobian_force); // request Jacobian force as part as system force @@ -363,30 +365,51 @@ void colvarbias_abf::write_gradients_samples(const std::string &prefix, bool app { std::string samples_out_name = prefix + ".count"; std::string gradients_out_name = prefix + ".grad"; +#ifdef NAMD_VERSION + if (append) + cvm::fatal_error("Error: starting from version 2.10 NAMD does not support any longer appending to output files.\n"); +#else std::ios::openmode mode = (append ? std::ios::app : std::ios::out); +#endif - std::ofstream samples_os; - std::ofstream gradients_os; + cvm::ofstream samples_os; + cvm::ofstream gradients_os; if (!append) cvm::backup_file(samples_out_name.c_str()); +#ifdef NAMD_VERSION + samples_os.open(samples_out_name.c_str()); +#else samples_os.open(samples_out_name.c_str(), mode); - if (!samples_os.good()) cvm::error("Error opening ABF samples file " + samples_out_name + " for writing"); +#endif + if (!samples_os.is_open()) { + cvm::error("Error opening ABF samples file " + samples_out_name + " for writing"); + } samples->write_multicol(samples_os); samples_os.close(); if (!append) cvm::backup_file(gradients_out_name.c_str()); +#ifdef NAMD_VERSION + gradients_os.open(gradients_out_name.c_str()); +#else gradients_os.open(gradients_out_name.c_str(), mode); - if (!gradients_os.good()) cvm::error("Error opening ABF gradient file " + gradients_out_name + " for writing"); +#endif + if (!gradients_os.is_open()) { + cvm::error("Error opening ABF gradient file " + gradients_out_name + " for writing"); + } gradients->write_multicol(gradients_os); gradients_os.close(); if (colvars.size() == 1) { std::string pmf_out_name = prefix + ".pmf"; if (!append) cvm::backup_file(pmf_out_name.c_str()); - std::ofstream pmf_os; + cvm::ofstream pmf_os; // Do numerical integration and output a PMF +#ifdef NAMD_VERSION + pmf_os.open(pmf_out_name.c_str()); +#else pmf_os.open(pmf_out_name.c_str(), mode); - if (!pmf_os.good()) cvm::error("Error opening pmf file " + pmf_out_name + " for writing"); +#endif + if (!pmf_os.is_open()) cvm::error("Error opening pmf file " + pmf_out_name + " for writing"); gradients->write_1D_integral(pmf_os); pmf_os << std::endl; pmf_os.close(); @@ -428,13 +451,13 @@ void colvarbias_abf::read_gradients_samples() cvm::log("Reading sample count from " + samples_in_name + " and gradients from " + gradients_in_name); is.open(samples_in_name.c_str()); - if (!is.good()) cvm::error("Error opening ABF samples file " + samples_in_name + " for reading"); + if (!is.is_open()) cvm::error("Error opening ABF samples file " + samples_in_name + " for reading"); samples->read_multicol(is, true); is.close(); is.clear(); is.open(gradients_in_name.c_str()); - if (!is.good()) cvm::error("Error opening ABF gradient file " + gradients_in_name + " for reading"); + if (!is.is_open()) cvm::error("Error opening ABF gradient file " + gradients_in_name + " for reading"); gradients->read_multicol(is, true); is.close(); } @@ -565,7 +588,7 @@ colvarbias_histogram::colvarbias_histogram(std::string const &conf, char const * /// Destructor colvarbias_histogram::~colvarbias_histogram() { - if (grid_os.good()) grid_os.close(); + if (grid_os.is_open()) grid_os.close(); if (grid) { delete grid; @@ -601,7 +624,7 @@ cvm::real colvarbias_histogram::update() if (cvm::debug()) cvm::log("Histogram bias trying to write grid to disk"); grid_os.open(out_name.c_str()); - if (!grid_os.good()) cvm::error("Error opening histogram file " + out_name + " for writing"); + if (!grid_os.is_open()) cvm::error("Error opening histogram file " + out_name + " for writing"); grid->write_multicol(grid_os); grid_os.close(); } diff --git a/lib/colvars/colvarbias_abf.h b/lib/colvars/colvarbias_abf.h index f9f6cb702b..049bf1b8b9 100644 --- a/lib/colvars/colvarbias_abf.h +++ b/lib/colvars/colvarbias_abf.h @@ -1,3 +1,4 @@ +// -*- c++ -*- /************************************************************************ * Headers for the ABF and histogram biases * ************************************************************************/ @@ -109,7 +110,7 @@ private: int output_freq; void write_grid(); - std::ofstream grid_os; /// Stream for writing grid to disk + cvm::ofstream grid_os; /// Stream for writing grid to disk std::istream& read_restart(std::istream&); std::ostream& write_restart(std::ostream&); diff --git a/lib/colvars/colvarbias_meta.cpp b/lib/colvars/colvarbias_meta.cpp index e8e104366b..c329c04d5a 100644 --- a/lib/colvars/colvarbias_meta.cpp +++ b/lib/colvars/colvarbias_meta.cpp @@ -1582,7 +1582,7 @@ void colvarbias_meta::write_pmf() "."+cvm::to_str(cvm::step_absolute()) : "") + ".pmf"); cvm::backup_file(fes_file_name.c_str()); - std::ofstream fes_os(fes_file_name.c_str()); + cvm::ofstream fes_os(fes_file_name.c_str()); pmf->write_multicol(fes_os); fes_os.close(); } @@ -1606,7 +1606,7 @@ void colvarbias_meta::write_pmf() "."+cvm::to_str(cvm::step_absolute()) : "") + ".pmf"); cvm::backup_file(fes_file_name.c_str()); - std::ofstream fes_os(fes_file_name.c_str()); + cvm::ofstream fes_os(fes_file_name.c_str()); pmf->write_multicol(fes_os); fes_os.close(); } @@ -1621,7 +1621,7 @@ void colvarbias_meta::write_replica_state_file() // write down also the restart for the other replicas: TODO: this // is duplicated code, that could be cleaned up later cvm::backup_file(replica_state_file.c_str()); - std::ofstream rep_state_os(replica_state_file.c_str()); + cvm::ofstream rep_state_os(replica_state_file.c_str()); if (!rep_state_os.good()) cvm::fatal_error("Error: in opening file \""+ replica_state_file+"\" for writing.\n"); diff --git a/lib/colvars/colvarbias_meta.h b/lib/colvars/colvarbias_meta.h index de5b6d2622..e2f175ad92 100644 --- a/lib/colvars/colvarbias_meta.h +++ b/lib/colvars/colvarbias_meta.h @@ -61,7 +61,7 @@ protected: /// Write the hill logfile bool b_hills_traj; /// Logfile of hill management (creation and deletion) - std::ofstream hills_traj_os; + cvm::ofstream hills_traj_os; /// \brief List of hills used on this bias (total); if a grid is /// employed, these don't need to be updated at every time step @@ -223,7 +223,7 @@ protected: std::string replica_hills_file; /// \brief Output stream corresponding to replica_hills_file - std::ofstream replica_hills_os; + cvm::ofstream replica_hills_os; /// Position within replica_hills_file (when reading it) int replica_hills_file_pos; diff --git a/lib/colvars/colvarcomp_coordnums.cpp b/lib/colvars/colvarcomp_coordnums.cpp index 06ec030a7b..7541c8bb23 100644 --- a/lib/colvars/colvarcomp_coordnums.cpp +++ b/lib/colvars/colvarcomp_coordnums.cpp @@ -61,9 +61,9 @@ cvm::real colvar::coordnum::switching_function(cvm::rvector const &r0_vec, if (calculate_gradients) { cvm::real const dFdl2 = (1.0/(1.0-xd))*(en2*(xn/l2) - func*ed2*(xd/l2))*(-1.0); - cvm::rvector const dl2dx = ((2.0/(r0_vec.x*r0_vec.x))*diff.x, - (2.0/(r0_vec.y*r0_vec.y))*diff.y, - (2.0/(r0_vec.z*r0_vec.z))*diff.z); + cvm::rvector const dl2dx((2.0/(r0_vec.x*r0_vec.x))*diff.x, + (2.0/(r0_vec.y*r0_vec.y))*diff.y, + (2.0/(r0_vec.z*r0_vec.z))*diff.z); A1.grad += (-1.0)*dFdl2*dl2dx; A2.grad += dFdl2*dl2dx; } diff --git a/lib/colvars/colvarmodule.cpp b/lib/colvars/colvarmodule.cpp index 69b7d34071..b5fe992e1c 100644 --- a/lib/colvars/colvarmodule.cpp +++ b/lib/colvars/colvarmodule.cpp @@ -60,7 +60,7 @@ int colvarmodule::config_file(char const *config_filename) // open the configfile config_s.open(config_filename); - if (!config_s) { + if (!config_s.is_open()) { cvm::error("Error: in opening configuration file \""+ std::string(config_filename)+"\".\n", FILE_ERROR); @@ -569,7 +569,7 @@ int colvarmodule::calc() { restart_out_name+"\".\n"); proxy->backup_file(restart_out_name.c_str()); restart_out_os.open(restart_out_name.c_str()); - if (!write_restart(restart_out_os)) + if (!restart_out_os.is_open() || !write_restart(restart_out_os)) cvm::error("Error: in writing restart file.\n"); restart_out_os.close(); } @@ -931,12 +931,16 @@ int colvarmodule::open_traj_file(std::string const &file_name) if (cv_traj_append) { cvm::log("Appending to colvar trajectory file \""+file_name+ "\".\n"); +#ifdef NAMD_VERSION + cvm::fatal_error("Error: starting from version 2.10 NAMD does not support any longer appending to output files.\n"); +#else cv_traj_os.open(file_name.c_str(), std::ios::app); +#endif } else { cvm::log("Writing to colvar trajectory file \""+file_name+ "\".\n"); proxy->backup_file(file_name.c_str()); - cv_traj_os.open(file_name.c_str(), std::ios::out); + cv_traj_os.open(file_name.c_str()); } if (!cv_traj_os.is_open()) { diff --git a/lib/colvars/colvarmodule.h b/lib/colvars/colvarmodule.h index 49a65b0794..de23c39273 100644 --- a/lib/colvars/colvarmodule.h +++ b/lib/colvars/colvarmodule.h @@ -4,7 +4,7 @@ #define COLVARMODULE_H #ifndef COLVARS_VERSION -#define COLVARS_VERSION "2015-01-19" +#define COLVARS_VERSION "2015-01-21" #endif #ifndef COLVARS_DEBUG @@ -45,6 +45,10 @@ #include #include +#ifdef NAMD_VERSION +// use Lustre-friendly wrapper to POSIX write() +#include "fstream_namd.h" +#endif class colvarparse; class colvar; @@ -239,6 +243,12 @@ public: /// (Re)initialize the output trajectory and state file (does not write it yet) int setup_output(); +#ifdef NAMD_VERSION + typedef ofstream_namd ofstream; +#else + typedef std::ofstream ofstream; +#endif + /// Read the input restart file std::istream & read_restart(std::istream &is); /// Write the output restart file @@ -443,6 +453,7 @@ public: /// Pseudo-random number with Gaussian distribution static real rand_gaussian(void); + protected: /// Configuration file @@ -452,16 +463,16 @@ protected: colvarparse *parse; /// Name of the trajectory file - std::string cv_traj_name; + std::string cv_traj_name; /// Collective variables output trajectory file - std::ofstream cv_traj_os; + colvarmodule::ofstream cv_traj_os; /// Appending to the existing trajectory file? - bool cv_traj_append; + bool cv_traj_append; /// Output restart file - std::ofstream restart_out_os; + colvarmodule::ofstream restart_out_os; /// \brief Counter for the current depth in the object hierarchy (useg e.g. in output static size_t depth; @@ -470,12 +481,12 @@ protected: static bool use_scripted_forces; public: + /// \brief Pointer to the proxy object, used to retrieve atomic data /// from the hosting program; it is static in order to be accessible /// from static functions in the colvarmodule class static colvarproxy *proxy; - /// Increase the depth (number of indentations in the output) static void increase_depth(); diff --git a/lib/colvars/colvarproxy.h b/lib/colvars/colvarproxy.h index d21bf226b3..47806990b7 100644 --- a/lib/colvars/colvarproxy.h +++ b/lib/colvars/colvarproxy.h @@ -210,8 +210,8 @@ public: protected: - /// \brief Open output files: by default, these are regular ofstream objects. - /// Allows redefinition to implement different behavior (in NAMD, these are ofstream_namd objects) + /// \brief Open output files: by default, these are ofstream objects. + /// Allows redefinition to implement different output mechanisms std::list output_files; /// \brief Identifiers for output_stream objects: by default, these are the names of the files std::list output_stream_names;