Commit 7be00451 authored by Giacomo Fiorin's avatar Giacomo Fiorin
Browse files

Update Colvars to version 2020-02-27

    This update contains several small new features or usability improvements.
    Descriptions and authorship information can be accessed from the pull
    requests listed below.

    Allow setting sigma parameter directly for metadynamics
    https://github.com/Colvars/colvars/pull/325

    Remove default values for lowerWall and upperWall legacy keywords
    https://github.com/Colvars/colvars/pull/324

    biasActualColvar option to bypass extended-Lagragian for a bias
    https://github.com/Colvars/colvars/pull/321

    Flexible restart-reading
    https://github.com/Colvars/colvars/pull/320
parent 6e7e3659
Loading
Loading
Loading
Loading
+11.5 KiB (673 KiB)

File changed.

No diff preview for this file type.

+23 −11
Original line number Diff line number Diff line
@@ -27,46 +27,58 @@ $(COLVARS_OBJ_DIR)colvarbias_restraint.o: colvarbias_restraint.cpp \
$(COLVARS_OBJ_DIR)colvarcomp_angles.o: colvarcomp_angles.cpp \
 colvarmodule.h colvars_version.h colvar.h colvarvalue.h colvartypes.h \
 colvarparse.h colvarparams.h colvardeps.h colvarcomp.h colvaratoms.h \
 colvarproxy.h colvar_arithmeticpath.h
$(COLVARS_OBJ_DIR)colvarcomp_apath.o: colvarcomp_apath.cpp
 colvarproxy.h colvar_arithmeticpath.h colvar_geometricpath.h
$(COLVARS_OBJ_DIR)colvarcomp_apath.o: colvarcomp_apath.cpp colvarmodule.h \
 colvars_version.h colvarvalue.h colvartypes.h colvarparse.h \
 colvarparams.h colvar.h colvardeps.h colvarcomp.h colvaratoms.h \
 colvarproxy.h colvar_arithmeticpath.h colvar_geometricpath.h
$(COLVARS_OBJ_DIR)colvarcomp_coordnums.o: colvarcomp_coordnums.cpp \
 colvarmodule.h colvars_version.h colvarparse.h colvarvalue.h \
 colvartypes.h colvarparams.h colvaratoms.h colvarproxy.h colvardeps.h \
 colvar.h colvarcomp.h colvar_arithmeticpath.h
 colvar.h colvarcomp.h colvar_arithmeticpath.h colvar_geometricpath.h
$(COLVARS_OBJ_DIR)colvarcomp.o: colvarcomp.cpp colvarmodule.h \
 colvars_version.h colvarvalue.h colvartypes.h colvar.h colvarparse.h \
 colvarparams.h colvardeps.h colvarcomp.h colvaratoms.h colvarproxy.h \
 colvar_arithmeticpath.h
 colvar_arithmeticpath.h colvar_geometricpath.h
$(COLVARS_OBJ_DIR)colvarcomp_distances.o: colvarcomp_distances.cpp \
 colvarmodule.h colvars_version.h colvarvalue.h colvartypes.h \
 colvarparse.h colvarparams.h colvar.h colvardeps.h colvarcomp.h \
 colvaratoms.h colvarproxy.h colvar_arithmeticpath.h
$(COLVARS_OBJ_DIR)colvarcomp_gpath.o: colvarcomp_gpath.cpp
 colvaratoms.h colvarproxy.h colvar_arithmeticpath.h \
 colvar_geometricpath.h
$(COLVARS_OBJ_DIR)colvarcomp_gpath.o: colvarcomp_gpath.cpp colvarmodule.h \
 colvars_version.h colvarvalue.h colvartypes.h colvarparse.h \
 colvarparams.h colvar.h colvardeps.h colvarcomp.h colvaratoms.h \
 colvarproxy.h colvar_arithmeticpath.h colvar_geometricpath.h
$(COLVARS_OBJ_DIR)colvarcomp_protein.o: colvarcomp_protein.cpp \
 colvarmodule.h colvars_version.h colvarvalue.h colvartypes.h \
 colvarparse.h colvarparams.h colvar.h colvardeps.h colvarcomp.h \
 colvaratoms.h colvarproxy.h colvar_arithmeticpath.h
 colvaratoms.h colvarproxy.h colvar_arithmeticpath.h \
 colvar_geometricpath.h
$(COLVARS_OBJ_DIR)colvarcomp_rotations.o: colvarcomp_rotations.cpp \
 colvarmodule.h colvars_version.h colvarvalue.h colvartypes.h \
 colvarparse.h colvarparams.h colvar.h colvardeps.h colvarcomp.h \
 colvaratoms.h colvarproxy.h colvar_arithmeticpath.h
 colvaratoms.h colvarproxy.h colvar_arithmeticpath.h \
 colvar_geometricpath.h
$(COLVARS_OBJ_DIR)colvar.o: colvar.cpp colvarmodule.h colvars_version.h \
 colvarvalue.h colvartypes.h colvarparse.h colvarparams.h colvar.h \
 colvardeps.h colvarcomp.h colvaratoms.h colvarproxy.h \
 colvar_arithmeticpath.h colvarscript.h colvarbias.h
 colvar_arithmeticpath.h colvar_geometricpath.h colvarscript.h \
 colvarbias.h
$(COLVARS_OBJ_DIR)colvardeps.o: colvardeps.cpp colvarmodule.h \
 colvars_version.h colvarproxy.h colvartypes.h colvarvalue.h colvardeps.h \
 colvarparse.h colvarparams.h
$(COLVARS_OBJ_DIR)colvargrid.o: colvargrid.cpp colvarmodule.h \
 colvars_version.h colvarvalue.h colvartypes.h colvarparse.h \
 colvarparams.h colvar.h colvardeps.h colvarcomp.h colvaratoms.h \
 colvarproxy.h colvar_arithmeticpath.h colvargrid.h
 colvarproxy.h colvar_arithmeticpath.h colvar_geometricpath.h \
 colvargrid.h
$(COLVARS_OBJ_DIR)colvarmodule.o: colvarmodule.cpp colvarmodule.h \
 colvars_version.h colvarparse.h colvarvalue.h colvartypes.h \
 colvarparams.h colvarproxy.h colvar.h colvardeps.h colvarbias.h \
 colvarbias_abf.h colvargrid.h colvar_UIestimator.h colvarbias_alb.h \
 colvarbias_histogram.h colvarbias_meta.h colvarbias_restraint.h \
 colvarscript.h colvaratoms.h colvarcomp.h colvar_arithmeticpath.h
 colvarscript.h colvaratoms.h colvarcomp.h colvar_arithmeticpath.h \
 colvar_geometricpath.h
$(COLVARS_OBJ_DIR)colvarparams.o: colvarparams.cpp colvarmodule.h \
 colvars_version.h colvarvalue.h colvartypes.h colvarparams.h
$(COLVARS_OBJ_DIR)colvarparse.o: colvarparse.cpp colvarmodule.h \
+55 −43
Original line number Diff line number Diff line
@@ -33,6 +33,8 @@ colvar::colvar()
  dev_null = 0.0;
#endif

  expand_boundaries = false;

  description = "uninitialized colvar";
  init_dependencies();
}
@@ -474,6 +476,8 @@ int colvar::init_custom_function(std::string const &conf)

int colvar::init_grid_parameters(std::string const &conf)
{
  int error_code = COLVARS_OK;

  colvarmodule *cv = cvm::main();

  cvm::real default_width = width;
@@ -527,15 +531,18 @@ int colvar::init_grid_parameters(std::string const &conf)
      disable(f_cv_hard_upper_boundary);
    }

    // Parse legacy wall options and set up a harmonicWalls bias if needed
    cvm::real lower_wall_k = 0.0, upper_wall_k = 0.0;
    cvm::real lower_wall = 0.0, upper_wall = 0.0;
    std::string lw_conf, uw_conf;

    if (get_keyval(conf, "lowerWallConstant", lower_wall_k, 0.0,
                   parse_silent)) {
      cvm::log("Reading legacy options lowerWall and lowerWallConstant: "
               "consider using a harmonicWalls restraint\n(caution: force constant would then be scaled by width^2).\n");
      lower_wall.type(value());
      if (!get_keyval(conf, "lowerWall", lower_wall, lower_boundary)) {
        cvm::log("Warning: lowerWall will need to be "
                 "defined explicitly in the next release.\n");
               "consider using a harmonicWalls restraint (caution: force constant would then be scaled by width^2).\n");
      if (!get_keyval(conf, "lowerWall", lower_wall)) {
        error_code != cvm::error("Error: the value of lowerWall must be set "
                                 "explicitly.\n", INPUT_ERROR);
      }
      lw_conf = std::string("\n\
    lowerWallConstant "+cvm::to_str(lower_wall_k*width*width)+"\n\
@@ -545,11 +552,10 @@ int colvar::init_grid_parameters(std::string const &conf)
    if (get_keyval(conf, "upperWallConstant", upper_wall_k, 0.0,
                   parse_silent)) {
      cvm::log("Reading legacy options upperWall and upperWallConstant: "
               "consider using a harmonicWalls restraint\n(caution: force constant would then be scaled by width^2).\n");
      upper_wall.type(value());
      if (!get_keyval(conf, "upperWall", upper_wall, upper_boundary)) {
        cvm::log("Warning: upperWall will need to be "
                 "defined explicitly in the next release.\n");
               "consider using a harmonicWalls restraint (caution: force constant would then be scaled by width^2).\n");
      if (!get_keyval(conf, "upperWall", upper_wall)) {
        error_code != cvm::error("Error: the value of upperWall must be set "
                                 "explicitly.\n", INPUT_ERROR);
      }
      uw_conf = std::string("\n\
    upperWallConstant "+cvm::to_str(upper_wall_k*width*width)+"\n\
@@ -558,12 +564,11 @@ int colvar::init_grid_parameters(std::string const &conf)

    if (lw_conf.size() && uw_conf.size()) {
      if (lower_wall >= upper_wall) {
        cvm::error("Error: the upper wall, "+
        error_code |= cvm::error("Error: the upper wall, "+
                                 cvm::to_str(upper_wall)+
                                 ", is not higher than the lower wall, "+
                                 cvm::to_str(lower_wall)+".\n",
                                 INPUT_ERROR);
        return INPUT_ERROR;
      }
    }

@@ -575,7 +580,7 @@ harmonicWalls {\n\
    colvars "+this->name+"\n"+lw_conf+uw_conf+"\
    timeStepFactor "+cvm::to_str(time_step_factor)+"\n"+
                             "}\n");
      cv->append_new_config(walls_conf);
      error_code |= cv->append_new_config(walls_conf);
    }
  }

@@ -588,29 +593,27 @@ harmonicWalls {\n\
  // consistency checks for boundaries and walls
  if (is_enabled(f_cv_lower_boundary) && is_enabled(f_cv_upper_boundary)) {
    if (lower_boundary >= upper_boundary) {
      cvm::error("Error: the upper boundary, "+
      error_code |= cvm::error("Error: the upper boundary, "+
                               cvm::to_str(upper_boundary)+
                               ", is not higher than the lower boundary, "+
                               cvm::to_str(lower_boundary)+".\n",
                               INPUT_ERROR);
      return INPUT_ERROR;
    }
  }

  get_keyval(conf, "expandBoundaries", expand_boundaries, false);
  get_keyval(conf, "expandBoundaries", expand_boundaries, expand_boundaries);
  if (expand_boundaries && periodic_boundaries()) {
    cvm::error("Error: trying to expand boundaries that already "
    error_code |= cvm::error("Error: trying to expand boundaries that already "
                             "cover a whole period of a periodic colvar.\n",
                             INPUT_ERROR);
    return INPUT_ERROR;
  }

  if (expand_boundaries && is_enabled(f_cv_hard_lower_boundary) &&
      is_enabled(f_cv_hard_upper_boundary)) {
    cvm::error("Error: inconsistent configuration "
               "(trying to expand boundaries with both "
               "hardLowerBoundary and hardUpperBoundary enabled).\n",
               INPUT_ERROR);
    return INPUT_ERROR;
    error_code |= cvm::error("Error: inconsistent configuration "
                             "(trying to expand boundaries, but both "
                             "hardLowerBoundary and hardUpperBoundary "
                             "are enabled).\n", INPUT_ERROR);
  }

  return COLVARS_OK;
@@ -2077,12 +2080,12 @@ void colvar::wrap(colvarvalue &x_unwrapped) const

// ******************** INPUT FUNCTIONS ********************

std::istream & colvar::read_restart(std::istream &is)
std::istream & colvar::read_state(std::istream &is)
{
  size_t const start_pos = is.tellg();

  std::string conf;
  if ( !(is >> colvarparse::read_block("colvar", conf)) ) {
  if ( !(is >> colvarparse::read_block("colvar", &conf)) ) {
    // this is not a colvar block
    is.clear();
    is.seekg(start_pos, std::ios::beg);
@@ -2092,15 +2095,24 @@ std::istream & colvar::read_restart(std::istream &is)

  {
    std::string check_name = "";
    if ( (get_keyval(conf, "name", check_name,
                     std::string(""), colvarparse::parse_silent)) &&
         (check_name != name) )  {
      cvm::error("Error: the state file does not match the "
                 "configuration file, at colvar \""+name+"\".\n");
    }
    get_keyval(conf, "name", check_name,
               std::string(""), colvarparse::parse_silent);
    if (check_name.size() == 0) {
      cvm::error("Error: Collective variable in the "
                 "restart file without any identifier.\n");
                 "restart file without any identifier.\n", INPUT_ERROR);
      is.clear();
      is.seekg(start_pos, std::ios::beg);
      is.setstate(std::ios::failbit);
      return is;
    }

    if (check_name != name)  {
      if (cvm::debug()) {
        cvm::log("Ignoring state of colvar \""+check_name+
                 "\": this colvar is named \""+name+"\".\n");
      }
      is.seekg(start_pos, std::ios::beg);
      return is;
    }
  }

@@ -2199,7 +2211,7 @@ std::istream & colvar::read_traj(std::istream &is)

// ******************** OUTPUT FUNCTIONS ********************

std::ostream & colvar::write_restart(std::ostream &os) {
std::ostream & colvar::write_state(std::ostream &os) {

  os << "colvar {\n"
     << "  name " << name << "\n"
+2 −10
Original line number Diff line number Diff line
@@ -229,17 +229,9 @@ public:

  /// \brief Location of the lower boundary
  colvarvalue lower_boundary;
  /// \brief Location of the lower wall
  colvarvalue lower_wall;
  /// \brief Force constant for the lower boundary potential (|x-xb|^2)
  cvm::real   lower_wall_k;

  /// \brief Location of the upper boundary
  colvarvalue upper_boundary;
  /// \brief Location of the upper wall
  colvarvalue upper_wall;
  /// \brief Force constant for the upper boundary potential (|x-xb|^2)
  cvm::real   upper_wall_k;

  /// \brief Is the interval defined by the two boundaries periodic?
  bool periodic_boundaries() const;
@@ -453,9 +445,9 @@ public:
  std::ostream & write_traj_label(std::ostream &os);

  /// Read the collective variable from a restart file
  std::istream & read_restart(std::istream &is);
  std::istream & read_state(std::istream &is);
  /// Write the collective variable to a restart file
  std::ostream & write_restart(std::ostream &os);
  std::ostream & write_state(std::ostream &os);

  /// Write output files (if defined, e.g. in analysis mode)
  int write_output_files();
+66 −19
Original line number Diff line number Diff line
@@ -15,8 +15,10 @@


colvarbias::colvarbias(char const *key)
  : bias_type(to_lower_cppstr(key))
{
  bias_type = to_lower_cppstr(key);
  state_keyword = bias_type;

  description = "uninitialized " + cvm::to_str(key) + " bias";
  init_dependencies();
  rank = 1;
@@ -25,6 +27,7 @@ colvarbias::colvarbias(char const *key)
  b_output_energy = false;
  reset();
  state_file_step = 0L;
  matching_state = false;
}


@@ -80,10 +83,21 @@ int colvarbias::init(std::string const &conf)
    cvm::log("Reinitializing bias \""+name+"\".\n");
  }

  colvar_values.resize(num_variables());

  for (i = 0; i < num_variables(); i++) {
    colvar_values[i].type(colvars[i]->value().type());
    colvar_forces[i].type(colvar_values[i].type());
    previous_colvar_forces[i].type(colvar_values[i].type());
  }

  output_prefix = cvm::output_prefix();

  get_keyval(conf, "outputEnergy", b_output_energy, b_output_energy);

  // Disabled by default in base class; default value can be overridden by derived class constructor
  get_keyval_feature(this, conf, "bypassExtendedLagrangian", f_cvb_bypass_ext_lagrangian, is_enabled(f_cvb_bypass_ext_lagrangian), parse_silent);

  get_keyval(conf, "timeStepFactor", time_step_factor, 1);
  if (time_step_factor < 1) {
    cvm::error("Error: timeStepFactor must be 1 or greater.\n");
@@ -114,6 +128,11 @@ int colvarbias::init_dependencies() {
    init_feature(f_cvb_apply_force, "apply force", f_type_user);
    require_feature_children(f_cvb_apply_force, f_cv_gradient);

    init_feature(f_cvb_bypass_ext_lagrangian, "bypass extended-Lagrangian coordinates", f_type_user);
    // The exclusion below prevents the inconsistency where biasing forces are applied onto
    // the actual colvar, while total forces are measured on the extended coordinate
    exclude_feature_self(f_cvb_bypass_ext_lagrangian, f_cvb_get_total_force);

    init_feature(f_cvb_get_total_force, "obtain total force", f_type_dynamic);
    require_feature_children(f_cvb_get_total_force, f_cv_total_force);

@@ -158,6 +177,12 @@ int colvarbias::init_dependencies() {
  // only compute TI samples when deriving from colvarbias_ti
  feature_states[f_cvb_calc_ti_samples].available = false;

  // The feature f_cvb_bypass_ext_lagrangian is only implemented by some derived classes
  // (initially, harmonicWalls)
  feature_states[f_cvb_bypass_ext_lagrangian].available = false;
  // disabled by default; can be changed by derived classes that implement it
  feature_states[f_cvb_bypass_ext_lagrangian].enabled = false;

  return COLVARS_OK;
}

@@ -265,6 +290,11 @@ int colvarbias::update()

  has_data = true;

  // Update the cached colvar values
  for (size_t i = 0; i < num_variables(); i++) {
    colvar_values[i] = colvars[i]->value();
  }

  error_code |= calc_energy(NULL);
  error_code |= calc_forces(NULL);

@@ -304,9 +334,11 @@ void colvarbias::communicate_forces()
    // may send forces to the same colvar
    // which is why rescaling has to happen now: the colvar is not
    // aware of this bias' time_step_factor
    if (is_enabled(f_cvb_bypass_ext_lagrangian)) {
      variables(i)->add_bias_force_actual_value(cvm::real(time_step_factor) * colvar_forces[i]);
    } else {
      variables(i)->add_bias_force(cvm::real(time_step_factor) * colvar_forces[i]);
    }
  for (i = 0; i < num_variables(); i++) {
    previous_colvar_forces[i] = colvar_forces[i];
  }
}
@@ -368,20 +400,27 @@ std::string const colvarbias::get_state_params() const

int colvarbias::set_state_params(std::string const &conf)
{
  std::string new_name = "";
  if (colvarparse::get_keyval(conf, "name", new_name,
                              std::string(""), colvarparse::parse_silent) &&
      (new_name != this->name)) {
    cvm::error("Error: in the state file, the "
               "\""+bias_type+"\" block has a different name, \""+new_name+
               "\": different system?\n", INPUT_ERROR);
  }
  matching_state = false;

  if (name.size() == 0) {
  std::string check_name = "";
  colvarparse::get_keyval(conf, "name", check_name,
                          std::string(""), colvarparse::parse_silent);

  if (check_name.size() == 0) {
    cvm::error("Error: \""+bias_type+"\" block within the restart file "
               "has no identifiers.\n", INPUT_ERROR);
  }

  if (check_name != this->name) {
    if (cvm::debug()) {
      cvm::log("Ignoring state of bias \""+check_name+
               "\": this bias is named \""+name+"\".\n");
    }
    return COLVARS_OK;
  }

  matching_state = true;

  colvarparse::get_keyval(conf, "step", state_file_step,
                          cvm::step_absolute(), colvarparse::parse_silent);

@@ -396,7 +435,7 @@ std::ostream & colvarbias::write_state(std::ostream &os)
  }
  os.setf(std::ios::scientific, std::ios::floatfield);
  os.precision(cvm::cv_prec);
  os << bias_type << " {\n"
  os << state_keyword << " {\n"
     << "  configuration {\n";
  std::istringstream is(get_state_params());
  std::string line;
@@ -415,13 +454,12 @@ std::istream & colvarbias::read_state(std::istream &is)
  size_t const start_pos = is.tellg();

  std::string key, brace, conf;
  if ( !(is >> key)   || !(key == bias_type) ||
  if ( !(is >> key)   || !(key == state_keyword || key == bias_type) ||
       !(is >> brace) || !(brace == "{") ||
       !(is >> colvarparse::read_block("configuration", conf)) ||
       !(is >> colvarparse::read_block("configuration", &conf)) ||
       (set_state_params(conf) != COLVARS_OK) ) {
    if (key != bias_type)
      cvm::log("Found key \"" + key + "\" instead of \"" + bias_type + "\"\n");
    cvm::error("Error: in reading state configuration for \""+bias_type+"\" bias \""+
    cvm::error("Error: in reading state configuration for \""+bias_type+
               "\" bias \""+
               this->name+"\" at position "+
               cvm::to_str(static_cast<size_t>(is.tellg()))+
               " in stream.\n", INPUT_ERROR);
@@ -431,6 +469,15 @@ std::istream & colvarbias::read_state(std::istream &is)
    return is;
  }

  if (matching_state == false) {
    // This state is not for this bias
    is.seekg(start_pos, std::ios::beg);
    return is;
  }

  cvm::log("Restarting "+bias_type+" bias \""+name+"\" from step number "+
           cvm::to_str(state_file_step)+".\n");

  if (!read_state_data(is)) {
    cvm::error("Error: in reading state data for \""+bias_type+"\" bias \""+
               this->name+"\" at position "+
Loading