diff --git a/doc/PDF/colvars-refman-lammps.pdf b/doc/PDF/colvars-refman-lammps.pdf index 2669b4d16f..a9a1b5624b 100644 Binary files a/doc/PDF/colvars-refman-lammps.pdf and b/doc/PDF/colvars-refman-lammps.pdf differ diff --git a/lib/colvars/colvar.cpp b/lib/colvars/colvar.cpp index 3ed512692e..86448fd5f0 100644 --- a/lib/colvars/colvar.cpp +++ b/lib/colvars/colvar.cpp @@ -196,6 +196,23 @@ colvar::colvar (std::string const &conf) b_Jacobian_force = false; } + if (!tasks[task_scripted]) { + colvarvalue::Type const value_type = (cvcs[0])->type(); + if (cvm::debug()) + cvm::log ("This collective variable is a "+ + colvarvalue::type_desc[value_type]+", corresponding to "+ + cvm::to_str (colvarvalue::dof_num[value_type])+ + " internal degrees of freedom.\n"); + x.type (value_type); + x_reported.type (value_type); + } + + // If using scripted biases, any colvar may receive bias forces + // and will need its gradient + if (cvm::scripted_forces()) { + enable(task_gradients); + } + // check for linear combinations b_linear = !tasks[task_scripted]; @@ -279,17 +296,6 @@ colvar::colvar (std::string const &conf) } } - if (!tasks[task_scripted]) { - colvarvalue::Type const value_type = (cvcs[0])->type(); - if (cvm::debug()) - cvm::log ("This collective variable is a "+ - colvarvalue::type_desc[value_type]+", corresponding to "+ - cvm::to_str (colvarvalue::dof_num[value_type])+ - " internal degrees of freedom.\n"); - x.type (value_type); - x_reported.type (value_type); - } - get_keyval (conf, "width", width, 1.0); if (width <= 0.0) { cvm::error("Error: \"width\" must be positive.\n", INPUT_ERROR); diff --git a/lib/colvars/colvarbias.cpp b/lib/colvars/colvarbias.cpp index 7c21c551c8..62783d2aee 100644 --- a/lib/colvars/colvarbias.cpp +++ b/lib/colvars/colvarbias.cpp @@ -128,19 +128,23 @@ cvm::real colvarbias::energy_difference(std::string const &conf) int colvarbias::bin_num() { cvm::error ("Error: bin_num() not implemented.\n"); - return -1; + return COLVARS_NOT_IMPLEMENTED; } int colvarbias::current_bin() { cvm::error ("Error: current_bin() not implemented.\n"); - return -1; + return COLVARS_NOT_IMPLEMENTED; } int colvarbias::bin_count(int bin_index) { cvm::error ("Error: bin_count() not implemented.\n"); - return -1; + return COLVARS_NOT_IMPLEMENTED; +} +int colvarbias::replica_share() +{ + cvm::error ("Error: replica_share() not implemented.\n"); + return COLVARS_NOT_IMPLEMENTED; } - std::ostream & colvarbias::write_traj_label (std::ostream &os) { diff --git a/lib/colvars/colvarbias.h b/lib/colvars/colvarbias.h index ad24f40f30..887373be91 100644 --- a/lib/colvars/colvarbias.h +++ b/lib/colvars/colvarbias.h @@ -34,9 +34,9 @@ public: /// Calculate the bin index for a given bias. virtual int current_bin(); //// Give the count at a given bin index. - virtual int bin_count(int bin_index); + virtual int bin_count(int bin_index); //// Share information between replicas, whatever it may be. - virtual void replica_share() {}; + virtual int replica_share(); /// Perform analysis tasks virtual inline void analyse() {} diff --git a/lib/colvars/colvarbias_abf.cpp b/lib/colvars/colvarbias_abf.cpp index 812490013c..e992ef693d 100644 --- a/lib/colvars/colvarbias_abf.cpp +++ b/lib/colvars/colvarbias_abf.cpp @@ -282,17 +282,17 @@ cvm::real colvarbias_abf::update() return 0.0; } -void colvarbias_abf::replica_share () { +int colvarbias_abf::replica_share () { int p; if( !cvm::replica_enabled() ) { cvm::error ("Error: shared ABF: No replicas.\n"); - return; + return COLVARS_ERROR; } // We must have stored the last_gradients and last_samples. if (shared_last_step < 0 ) { cvm::error ("Error: shared ABF: Tried to apply shared ABF before any sampling had occurred.\n"); - return; + return COLVARS_ERROR; } // Share gradients for shared ABF. @@ -355,6 +355,8 @@ void colvarbias_abf::replica_share () { last_gradients->copy_grid(*gradients); last_samples->copy_grid(*samples); shared_last_step = cvm::step_absolute(); + + return COLVARS_OK; } void colvarbias_abf::write_gradients_samples (const std::string &prefix, bool append) diff --git a/lib/colvars/colvarbias_abf.h b/lib/colvars/colvarbias_abf.h index b89ca68dec..db141db2d1 100644 --- a/lib/colvars/colvarbias_abf.h +++ b/lib/colvars/colvarbias_abf.h @@ -64,7 +64,7 @@ private: size_t shared_freq; int shared_last_step; // Share between replicas -- may be called independently of update - virtual void replica_share(); + virtual int replica_share(); // Store the last set for shared ABF colvar_grid_gradient *last_gradients; diff --git a/lib/colvars/colvarmodule.cpp b/lib/colvars/colvarmodule.cpp index bdc44ac7aa..38506ac118 100644 --- a/lib/colvars/colvarmodule.cpp +++ b/lib/colvars/colvarmodule.cpp @@ -169,7 +169,7 @@ int colvarmodule::parse_global_params (std::string const &conf) colvarparse::parse_silent); if (use_scripted_forces && !proxy->force_script_defined) { - cvm::fatal_error("User script for scripted colvars forces not found."); + cvm::fatal_error("User script for scripted colvar forces not found."); } return (cvm::get_error() ? COLVARS_ERROR : COLVARS_OK); @@ -1303,7 +1303,7 @@ bool colvarmodule::b_analysis = false; cvm::real colvarmodule::rotation::crossing_threshold = 1.0E-04; std::list colvarmodule::index_group_names; std::list > colvarmodule::index_groups; - +bool colvarmodule::use_scripted_forces = false; // file name prefixes std::string colvarmodule::output_prefix = ""; diff --git a/lib/colvars/colvarmodule.h b/lib/colvars/colvarmodule.h index ad791bc375..34b3668cf8 100644 --- a/lib/colvars/colvarmodule.h +++ b/lib/colvars/colvarmodule.h @@ -4,7 +4,7 @@ #define COLVARMODULE_H #ifndef COLVARS_VERSION -#define COLVARS_VERSION "2014-10-22" +#define COLVARS_VERSION "2014-10-23" #endif #ifndef COLVARS_DEBUG @@ -468,7 +468,7 @@ protected: static size_t depth; /// Use scripted colvars forces? - bool use_scripted_forces; + static bool use_scripted_forces; public: /// \brief Pointer to the proxy object, used to retrieve atomic data @@ -482,6 +482,8 @@ public: /// Decrease the depth (number of indentations in the output) static void decrease_depth(); + + static inline const bool scripted_forces () { return use_scripted_forces; } }; diff --git a/lib/colvars/colvarscript.cpp b/lib/colvars/colvarscript.cpp index 13dffd35d1..df60e34df1 100644 --- a/lib/colvars/colvarscript.cpp +++ b/lib/colvars/colvarscript.cpp @@ -209,14 +209,19 @@ int colvarscript::proc_colvar (int argc, char const *argv[]) { std::string subcmd = argv[2]; if (subcmd == "value") { - result = cvm::to_str(cv->value(), 0, cvm::cv_prec); + result = (cv->value()).to_simple_string(); + return COLVARSCRIPT_OK; + } + + if (subcmd == "width") { + result = cvm::to_str(cv->width, 0, cvm::cv_prec); return COLVARSCRIPT_OK; } if (subcmd == "update") { cv->calc(); cv->update(); - result = cvm::to_str(cv->value(), 0, cvm::cv_prec); + result = (cv->value()).to_simple_string(); return COLVARSCRIPT_OK; } @@ -234,7 +239,7 @@ int colvarscript::proc_colvar (int argc, char const *argv[]) { if (subcmd == "addforce") { if (argc < 4) { - result = "Missing parameter: force value"; + result = "addforce: missing parameter: force value"; return COLVARSCRIPT_ERROR; } std::string f_str = argv[3]; @@ -243,12 +248,12 @@ int colvarscript::proc_colvar (int argc, char const *argv[]) { is.precision(cvm::cv_prec); colvarvalue force (cv->type()); force.is_derivative(); - if (!(is >> force)) { - result = "Error parsing force value"; + if (force.from_simple_string(is.str()) != COLVARS_OK) { + result = "addforce : error parsing force value"; return COLVARSCRIPT_ERROR; } cv->add_bias_force(force); - result = cvm::to_str(force, cvm::cv_width, cvm::cv_prec); + result = force.to_simple_string(); return COLVARSCRIPT_OK; } @@ -282,6 +287,38 @@ int colvarscript::proc_bias (int argc, char const *argv[]) { return COLVARSCRIPT_OK; } + // Subcommands for MW ABF + if (subcmd == "bin") { + int r = b->current_bin(); + if (r < 0) { + result = "Error: calling current_bin() for bias " + b->name; + return COLVARSCRIPT_ERROR; + } + result = cvm::to_str(r); + return COLVARSCRIPT_OK; + } + + if (subcmd == "binnum") { + int r = b->bin_num(); + if (r < 0) { + result = "Error: calling bin_num() for bias " + b->name; + return COLVARSCRIPT_ERROR; + } + result = cvm::to_str(r); + return COLVARSCRIPT_OK; + } + + if (subcmd == "share") { + int r = b->replica_share(); + if (r < 0) { + result = "Error: calling replica_share() for bias " + b->name; + return COLVARSCRIPT_ERROR; + } + result = cvm::to_str(r); + return COLVARSCRIPT_OK; + } + // End commands for MW ABF + if (subcmd == "delete") { // the bias destructor takes care of the cleanup at cvm level delete b; @@ -291,7 +328,16 @@ int colvarscript::proc_bias (int argc, char const *argv[]) { } if (argc >= 4) { -// std::string param = argv[3]; + std::string param = argv[3]; + if (subcmd == "count") { + int index; + if (!(std::istringstream(param) >> index)) { + result = "bin_count: error parsing bin index"; + return COLVARSCRIPT_ERROR; + } + result = cvm::to_str(b->bin_count(index)); + return COLVARSCRIPT_OK; + } result = "Syntax error"; return COLVARSCRIPT_ERROR; diff --git a/lib/colvars/colvartypes.cpp b/lib/colvars/colvartypes.cpp index b24be512a1..a5bb42ef59 100644 --- a/lib/colvars/colvartypes.cpp +++ b/lib/colvars/colvartypes.cpp @@ -4,6 +4,25 @@ #include "colvartypes.h" #include "colvarparse.h" +std::string cvm::rvector::to_simple_string() const +{ + std::ostringstream os; + os.setf (std::ios::scientific, std::ios::floatfield); + os.precision(cvm::cv_prec); + os << x << " " << y << " " << z; + return os.str(); +} + +int cvm::rvector::from_simple_string(std::string const &s) +{ + std::stringstream stream(s); + if ( !(stream >> x) || + !(stream >> y) || + !(stream >> z) ) { + return COLVARS_ERROR; + } + return COLVARS_OK; +} std::ostream & operator << (std::ostream &os, colvarmodule::rvector const &v) { @@ -38,7 +57,26 @@ std::istream & operator >> (std::istream &is, colvarmodule::rvector &v) return is; } +std::string cvm::quaternion::to_simple_string() const +{ + std::ostringstream os; + os.setf (std::ios::scientific, std::ios::floatfield); + os.precision(cvm::cv_prec); + os << q0 << " " << q1 << " " << q2 << " " << q3; + return os.str(); +} +int cvm::quaternion::from_simple_string(std::string const &s) +{ + std::stringstream stream(s); + if ( !(stream >> q0) || + !(stream >> q1) || + !(stream >> q2) || + !(stream >> q3) ) { + return COLVARS_ERROR; + } + return COLVARS_OK; +} std::ostream & operator << (std::ostream &os, colvarmodule::quaternion const &q) { diff --git a/lib/colvars/colvartypes.h b/lib/colvars/colvartypes.h index 18a6de3cfb..281f03ceac 100644 --- a/lib/colvars/colvartypes.h +++ b/lib/colvars/colvartypes.h @@ -175,7 +175,8 @@ public: return cvm::rvector (v.x/a, v.y/a, v.z/a); } - + std::string to_simple_string() const; + int from_simple_string(std::string const &s); }; @@ -639,6 +640,9 @@ public: return 4*real_width + 13; } + std::string to_simple_string() const; + int from_simple_string(std::string const &s); + /// \brief Formatted output operator friend std::ostream & operator << (std::ostream &os, cvm::quaternion const &q); /// \brief Formatted input operator diff --git a/lib/colvars/colvarvalue.cpp b/lib/colvars/colvarvalue.cpp index fa209ee19d..77326e3a85 100644 --- a/lib/colvars/colvarvalue.cpp +++ b/lib/colvars/colvarvalue.cpp @@ -214,6 +214,51 @@ void colvarvalue::p2leg_opt(colvarvalue const &x, }; } +std::string colvarvalue::to_simple_string() const +{ + switch (type()) { + case colvarvalue::type_scalar: + return cvm::to_str(real_value, 0, cvm::cv_prec); + break; + case colvarvalue::type_vector: + case colvarvalue::type_unitvector: + case colvarvalue::type_unitvectorderiv: + return rvector_value.to_simple_string(); + break; + case colvarvalue::type_quaternion: + case colvarvalue::type_quaternionderiv: + return quaternion_value.to_simple_string(); + break; + case colvarvalue::type_notset: + undef_op(); + break; + } + return std::string(); +} + +int colvarvalue::from_simple_string(std::string const &s) +{ + switch (type()) { + case colvarvalue::type_scalar: + return ((std::istringstream(s) >> real_value) + ? COLVARS_OK : COLVARS_ERROR); + break; + case colvarvalue::type_vector: + case colvarvalue::type_unitvector: + case colvarvalue::type_unitvectorderiv: + return rvector_value.from_simple_string(s); + break; + case colvarvalue::type_quaternion: + case colvarvalue::type_quaternionderiv: + return quaternion_value.from_simple_string(s); + break; + case colvarvalue::type_notset: + break; + default: + undef_op(); + } + return COLVARS_ERROR; +} std::ostream & operator << (std::ostream &os, colvarvalue const &x) { diff --git a/lib/colvars/colvarvalue.h b/lib/colvars/colvarvalue.h index 20c960259c..b5d63e79c9 100644 --- a/lib/colvars/colvarvalue.h +++ b/lib/colvars/colvarvalue.h @@ -287,6 +287,11 @@ public: /// characters for a real number size_t output_width(size_t const &real_width) const; + /// Formats value as a script-friendly string (space separated list) + std::string to_simple_string() const; + + /// Parses value from a script-friendly string (space separated list) + int from_simple_string(std::string const &s); // optimized routines for operations with an array; xv and inner as // vectors are assumed to have the same number of elements (i.e. the