diff --git a/doc/PDF/colvars-refman-lammps.pdf b/doc/PDF/colvars-refman-lammps.pdf index a2d88481b4..2669b4d16f 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 aafa60e1fb..3ed512692e 100644 --- a/lib/colvars/colvar.cpp +++ b/lib/colvars/colvar.cpp @@ -187,39 +187,19 @@ colvar::colvar (std::string const &conf) for (j = 0; j < cvcs.size(); j++) { sorted_cvc_values.push_back(cvcs[j]->p_value()); } - } - if (!tasks[task_scripted]) { - // this is set false if any of the components has an exponent - // different from 1 in the polynomial - b_linear = true; - // these will be set to false if any of the cvcs has them false - b_inverse_gradients = true; - b_Jacobian_force = true; - } - - // Test whether this is a single-component variable - // Decide whether the colvar is periodic - // Used to wrap extended DOF if extendedLagrangian is on - if (cvcs.size() == 1 && (cvcs[0])->sup_np == 1 - && (cvcs[0])->sup_coeff == 1.0 - && !tasks[task_scripted]) { - - b_single_cvc = true; - b_periodic = (cvcs[0])->b_periodic; - period = (cvcs[0])->period; - // TODO write explicit wrap() function for colvars to allow for - // sup_coeff different from 1 - // this->period = (cvcs[0])->period * (cvcs[0])->sup_coeff; - } else { - b_single_cvc = false; + b_homogeneous = false; + // Scripted functions are deemed non-periodic b_periodic = false; period = 0.0; + b_inverse_gradients = false; + b_Jacobian_force = false; } - // check the available features of each cvc - for (i = 0; i < cvcs.size(); i++) { + // check for linear combinations + b_linear = !tasks[task_scripted]; + for (i = 0; i < cvcs.size(); i++) { if ((cvcs[i])->b_debug_gradients) enable (task_gradients); @@ -237,7 +217,41 @@ colvar::colvar (std::string const &conf) (cvcs[i])->function_type+"\" approaches zero.\n"); } } + } + // Colvar is homogeneous iff: + // - it is not scripted + // - it is linear + // - all cvcs have coefficient 1 or -1 + // i.e. sum or difference of cvcs + + b_homogeneous = !tasks[task_scripted] && b_linear; + for (i = 0; i < cvcs.size(); i++) { + if ((std::fabs(cvcs[i]->sup_coeff) - 1.0) > 1.0e-10) { + b_homogeneous = false; + } + } + + // Colvar is deemed periodic iff: + // - it is homogeneous + // - all cvcs are periodic + // - all cvcs have the same period + + b_periodic = cvcs[0]->b_periodic && b_homogeneous; + period = cvcs[0]->period; + for (i = 1; i < cvcs.size(); i++) { + if (!cvcs[i]->b_periodic || cvcs[i]->period != period) { + b_periodic = false; + period = 0.0; + } + } + + // these will be set to false if any of the cvcs has them false + b_inverse_gradients = !tasks[task_scripted]; + b_Jacobian_force = !tasks[task_scripted]; + + // check the available features of each cvc + for (i = 0; i < cvcs.size(); i++) { if ((cvcs[i])->b_periodic && !b_periodic) { cvm::log ("Warning: although this component is periodic, the colvar will " "not be treated as periodic, either because the exponent is not " @@ -251,22 +265,17 @@ colvar::colvar (std::string const &conf) if (! (cvcs[i])->b_Jacobian_derivative) b_Jacobian_force = false; - if (!tasks[task_scripted]) { - // If the combination of components is a scripted function, - // the components may have different types - for (size_t j = i; j < cvcs.size(); j++) { - if ( (cvcs[i])->type() != (cvcs[j])->type() ) { - cvm::log ("ERROR: you are definining this collective variable " - "by using components of different types, \""+ - colvarvalue::type_desc[(cvcs[i])->type()]+ - "\" and \""+ - colvarvalue::type_desc[(cvcs[j])->type()]+ - "\". " - "You must use the same type in order to " - " sum them together.\n"); - cvm::set_error_bits(INPUT_ERROR); - } - } + // components may have different types only for scripted functions + if (!tasks[task_scripted] && (cvcs[i])->type() != (cvcs[0])->type() ) { + cvm::error("ERROR: you are definining this collective variable " + "by using components of different types, \""+ + colvarvalue::type_desc[(cvcs[0])->type()]+ + "\" and \""+ + colvarvalue::type_desc[(cvcs[i])->type()]+ + "\". " + "You must use the same type in order to " + " sum them together.\n", INPUT_ERROR); + return; } } @@ -1235,7 +1244,7 @@ bool colvar::periodic_boundaries() const cvm::real colvar::dist2 (colvarvalue const &x1, colvarvalue const &x2) const { - if (b_single_cvc) { + if (b_homogeneous) { return (cvcs[0])->dist2(x1, x2); } else { return x1.dist2(x2); @@ -1245,7 +1254,7 @@ cvm::real colvar::dist2 (colvarvalue const &x1, colvarvalue colvar::dist2_lgrad (colvarvalue const &x1, colvarvalue const &x2) const { - if (b_single_cvc) { + if (b_homogeneous) { return (cvcs[0])->dist2_lgrad (x1, x2); } else { return x1.dist2_grad(x2); @@ -1255,7 +1264,7 @@ colvarvalue colvar::dist2_lgrad (colvarvalue const &x1, colvarvalue colvar::dist2_rgrad (colvarvalue const &x1, colvarvalue const &x2) const { - if (b_single_cvc) { + if (b_homogeneous) { return (cvcs[0])->dist2_rgrad (x1, x2); } else { return x2.dist2_grad(x1); @@ -1264,7 +1273,7 @@ colvarvalue colvar::dist2_rgrad (colvarvalue const &x1, void colvar::wrap (colvarvalue &x) const { - if (b_single_cvc) { + if (b_homogeneous) { (cvcs[0])->wrap (x); } return; diff --git a/lib/colvars/colvar.h b/lib/colvars/colvar.h index 3d06cf8df5..a3fde81962 100644 --- a/lib/colvars/colvar.h +++ b/lib/colvars/colvar.h @@ -83,9 +83,9 @@ public: /// combination of \link cvc \endlink elements bool b_linear; - /// \brief True if this \link colvar \endlink is equal to - /// its only constituent cvc - bool b_single_cvc; + /// \brief True if this \link colvar \endlink is a linear + /// combination of cvcs with coefficients 1 or -1 + bool b_homogeneous; /// \brief True if all \link cvc \endlink objects are capable /// of calculating inverse gradients diff --git a/lib/colvars/colvarmodule.cpp b/lib/colvars/colvarmodule.cpp index 03f9ba704c..bdc44ac7aa 100644 --- a/lib/colvars/colvarmodule.cpp +++ b/lib/colvars/colvarmodule.cpp @@ -472,100 +472,73 @@ cvm::real colvarmodule::read_width(std::string const &name) return width; } -size_t colvarmodule::bias_current_bin (std::string const &bias_name) +int colvarmodule::bias_current_bin (std::string const &bias_name) { cvm::increase_depth(); - int found = 0; - size_t ret = 0; // N.B.: size_t is unsigned, so returning -1 would be a problem. + int ret; + colvarbias *b = bias_by_name(bias_name); - for (std::vector::iterator bi = biases.begin(); - bi != biases.end(); - bi++) { - if ( (*bi)->name == bias_name ) { - ++found; - ret = (*bi)->current_bin (); - } - } - if (found < 1) { - cvm::error ("Error: bias not found.\n"); - } else if (found > 1) { - cvm::error ("Error: duplicate bias name.\n"); + if (b != NULL) { + ret = b->current_bin(); } else { - cvm::decrease_depth(); - } - return ret; -} - -size_t colvarmodule::bias_bin_num (std::string const &bias_name) -{ - cvm::increase_depth(); - int found = 0; - size_t ret = 0; // N.B.: size_t is unsigned, so returning -1 would be a problem. - - for (std::vector::iterator bi = biases.begin(); - bi != biases.end(); - bi++) { - if ( (*bi)->name == bias_name ) { - ++found; - ret = (*bi)->bin_num (); - } - } - if (found < 1) { cvm::error ("Error: bias not found.\n"); - } else if (found > 1) { - cvm::error ("Error: duplicate bias name.\n"); - } else { - cvm::decrease_depth(); + ret = COLVARS_ERROR; } - return ret; -} -size_t colvarmodule::bias_bin_count (std::string const &bias_name, size_t bin_index) -{ - cvm::increase_depth(); - int found = 0; - size_t ret = 0; // N.B.: size_t is unsigned, so returning -1 would be a problem. - - for (std::vector::iterator bi = biases.begin(); - bi != biases.end(); - bi++) { - if ( (*bi)->name == bias_name ) { - ++found; - ret = (*bi)->bin_count (bin_index); - } - } - if (found < 1) { - cvm::error ("Error: bias not found.\n"); - } else if (found > 1) { - cvm::error ("Error: duplicate bias name.\n"); - } else { - cvm::decrease_depth(); - } - return ret; -} - -void colvarmodule::bias_share (std::string const &bias_name) -{ - cvm::increase_depth(); - int found = 0; - - for (std::vector::iterator bi = biases.begin(); - bi != biases.end(); - bi++) { - if ( (*bi)->name == bias_name ) { - ++found; - (*bi)->replica_share (); - } - } - if (found < 1) { - cvm::error ("Error: bias not found.\n"); - return; - } - if (found > 1) { - cvm::error ("Error: duplicate bias name.\n"); - return; - } cvm::decrease_depth(); + return ret; +} + +int colvarmodule::bias_bin_num (std::string const &bias_name) +{ + cvm::increase_depth(); + int ret; + colvarbias *b = bias_by_name(bias_name); + + if (b != NULL) { + ret = b->bin_num(); + } else { + cvm::error ("Error: bias not found.\n"); + ret = COLVARS_ERROR; + } + + cvm::decrease_depth(); + return ret; +} + +int colvarmodule::bias_bin_count (std::string const &bias_name, size_t bin_index) +{ + cvm::increase_depth(); + int ret; + colvarbias *b = bias_by_name(bias_name); + + if (b != NULL) { + ret = b->bin_count(bin_index); + } else { + cvm::error ("Error: bias not found.\n"); + ret = COLVARS_ERROR; + } + + cvm::decrease_depth(); + return ret; +} + +int colvarmodule::bias_share (std::string const &bias_name) +{ + cvm::increase_depth(); + int ret; + colvarbias *b = bias_by_name(bias_name); + + if (b != NULL) { + b->replica_share(); + ret = COLVARS_OK; + } else { + cvm::error ("Error: bias not found.\n"); + ret = COLVARS_ERROR; + } + + cvm::decrease_depth(); + return ret; } diff --git a/lib/colvars/colvarmodule.h b/lib/colvars/colvarmodule.h index ba1a4937e9..ad791bc375 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-21" +#define COLVARS_VERSION "2014-10-22" #endif #ifndef COLVARS_DEBUG @@ -21,6 +21,7 @@ /// objects. // Internal method return codes +#define COLVARS_NOT_IMPLEMENTED -2 #define COLVARS_ERROR -1 #define COLVARS_OK 0 @@ -276,13 +277,13 @@ public: /// Give the bin width in the units of the colvar. real read_width(std::string const &name); /// Give the total number of bins for a given bias. - size_t bias_bin_num(std::string const &bias_name); + int bias_bin_num(std::string const &bias_name); /// Calculate the bin index for a given bias. - size_t bias_current_bin(std::string const &bias_name); + int bias_current_bin(std::string const &bias_name); //// Give the count at a given bin index. - size_t bias_bin_count(std::string const &bias_name, size_t bin_index); + int bias_bin_count(std::string const &bias_name, size_t bin_index); //// Share among replicas. - void bias_share(std::string const &bias_name); + int bias_share(std::string const &bias_name); /// Calculate collective variables and biases int calc(); diff --git a/lib/colvars/colvarproxy.h b/lib/colvars/colvarproxy.h index ec458d4867..f3351e74e5 100644 --- a/lib/colvars/colvarproxy.h +++ b/lib/colvars/colvarproxy.h @@ -12,10 +12,8 @@ #include "colvarmodule.h" #include "colvarvalue.h" - // return values for the frame() routine #define COLVARS_NO_SUCH_FRAME -1 -#define COLVARS_NOT_IMPLEMENTED -2 // forward declarations class colvarscript; diff --git a/src/USER-COLVARS/fix_colvars.cpp b/src/USER-COLVARS/fix_colvars.cpp index 118312429c..969337ef64 100644 --- a/src/USER-COLVARS/fix_colvars.cpp +++ b/src/USER-COLVARS/fix_colvars.cpp @@ -408,7 +408,7 @@ void FixColvars::one_time_init() if (me == 0) color = 0; MPI_Comm_split(universe->uworld,color,universe->iworld,&root2root); } - + // create and initialize the colvars proxy if (me == 0) {