Difference for src/colvarmodule.C from version 1.25 to 1.26

version 1.25version 1.26
Line 1
Line 1
 /// -*- c++ -*- // -*- c++ -*-
  
 #include <sstream> #include <sstream>
 #include <string.h> #include <string.h>
Line 15
Line 15
 #include "colvarbias_restraint.h" #include "colvarbias_restraint.h"
 #include "colvarscript.h" #include "colvarscript.h"
  
  
 colvarmodule::colvarmodule(colvarproxy *proxy_in) colvarmodule::colvarmodule(colvarproxy *proxy_in)
 { {
   // pointer to the proxy object   // pointer to the proxy object
Line 31
Line 32
   cvm::log(cvm::line_marker);   cvm::log(cvm::line_marker);
   cvm::log("Initializing the collective variables module, version "+   cvm::log("Initializing the collective variables module, version "+
            cvm::to_str(COLVARS_VERSION)+".\n");            cvm::to_str(COLVARS_VERSION)+".\n");
    cvm::log("Please cite Fiorin et al, Mol Phys 2013:\n "
             "http://dx.doi.org/10.1080/00268976.2013.813594\n"
             "in any publication based on this calculation.\n");
  
    if (proxy->smp_enabled() == COLVARS_OK) {
      cvm::log("SMP parallelism is available.\n");
    }
  
   // set initial default values   // set initial default values
  
Line 75
Line 83
   std::string conf = "";   std::string conf = "";
   std::string line;   std::string line;
   while (colvarparse::getline_nocomments(config_s, line)) {   while (colvarparse::getline_nocomments(config_s, line)) {
      // Delete lines that contain only white space after removing comments
      if (line.find_first_not_of(colvarparse::white_space) != std::string::npos)
     conf.append(line+"\n");     conf.append(line+"\n");
   }   }
   config_s.close();   config_s.close();
Line 93
Line 103
   std::string conf = "";   std::string conf = "";
   std::string line;   std::string line;
   while (colvarparse::getline_nocomments(config_s, line)) {   while (colvarparse::getline_nocomments(config_s, line)) {
      // Delete lines that contain only white space after removing comments
      if (line.find_first_not_of(colvarparse::white_space) != std::string::npos)
     conf.append(line+"\n");     conf.append(line+"\n");
   }   }
   return parse_config(conf);   return parse_config(conf);
 } }
  
  
 int colvarmodule::parse_config(std::string &conf) int colvarmodule::parse_config(std::string &conf)
 { {
   int error_code = 0; 
  
   // parse global options   // parse global options
   error_code |= parse_global_params(conf);   if (catch_input_errors(parse_global_params(conf))) {
      return get_error();
   if (error_code != COLVARS_OK || cvm::get_error()) { 
     set_error_bits(INPUT_ERROR); 
     return COLVARS_ERROR; 
   }   }
  
   // parse the options for collective variables   // parse the options for collective variables
   error_code |= parse_colvars(conf);   if (catch_input_errors(parse_colvars(conf))) {
      return get_error();
   if (error_code != COLVARS_OK || cvm::get_error()) { 
     set_error_bits(INPUT_ERROR); 
     return COLVARS_ERROR; 
   }   }
  
   // parse the options for biases   // parse the options for biases
   error_code |= parse_biases(conf);   if (catch_input_errors(parse_biases(conf))) {
      return get_error();
   if (error_code != COLVARS_OK || cvm::get_error()) { 
     set_error_bits(INPUT_ERROR); 
     return COLVARS_ERROR; 
   }   }
  
   // done parsing known keywords, check that all keywords found were valid ones   // done parsing known keywords, check that all keywords found were valid ones
   error_code |= parse->check_keywords(conf, "colvarmodule");   if (catch_input_errors(parse->check_keywords(conf, "colvarmodule"))) {
      return get_error();
   if (error_code != COLVARS_OK || cvm::get_error()) { 
     set_error_bits(INPUT_ERROR); 
     return COLVARS_ERROR; 
   }   }
  
   cvm::log(cvm::line_marker);   cvm::log(cvm::line_marker);
   cvm::log("Collective variables module (re)initialized.\n");   cvm::log("Collective variables module (re)initialized.\n");
   cvm::log(cvm::line_marker);   cvm::log(cvm::line_marker);
  
    // update any necessary proxy data
    proxy->setup();
  
   if (cv_traj_os.is_open()) {   if (cv_traj_os.is_open()) {
     // configuration might have changed, better redo the labels     // configuration might have changed, better redo the labels
     write_traj_label(cv_traj_os);     write_traj_label(cv_traj_os);
   }   }
  
   return (cvm::get_error() ? COLVARS_ERROR : COLVARS_OK);   return get_error();
 } }
  
  
Line 177
Line 179
   // we are continuing after a reset(): default to true   // we are continuing after a reset(): default to true
   parse->get_keyval(conf, "colvarsTrajAppend", cv_traj_append, cv_traj_append);   parse->get_keyval(conf, "colvarsTrajAppend", cv_traj_append, cv_traj_append);
  
   parse->get_keyval(conf, "scriptedColvarForces", use_scripted_forces, false,   parse->get_keyval(conf, "scriptedColvarForces", use_scripted_forces, false);
                     colvarparse::parse_silent); 
    parse->get_keyval(conf, "scriptingAfterBiases", scripting_after_biases, true);
  
   if (use_scripted_forces && !proxy->force_script_defined) {   if (use_scripted_forces && !proxy->force_script_defined) {
     cvm::fatal_error("User script for scripted colvar forces not found.");     cvm::error("User script for scripted colvar forces not found.", INPUT_ERROR);
   }   }
  
   return (cvm::get_error() ? COLVARS_ERROR : COLVARS_OK);   return (cvm::get_error() ? COLVARS_ERROR : COLVARS_OK);
Line 230
Line 233
   return (cvm::get_error() ? COLVARS_ERROR : COLVARS_OK);   return (cvm::get_error() ? COLVARS_ERROR : COLVARS_OK);
 } }
  
  
 bool colvarmodule::check_new_bias(std::string &conf, char const *key) bool colvarmodule::check_new_bias(std::string &conf, char const *key)
 { {
   if (cvm::get_error() ||   if (cvm::get_error() ||
Line 254
Line 258
     if (bias_conf.size()) {     if (bias_conf.size()) {
       cvm::log(cvm::line_marker);       cvm::log(cvm::line_marker);
       cvm::increase_depth();       cvm::increase_depth();
       biases.push_back(new bias_type(bias_conf, keyword));       biases.push_back(new bias_type(keyword));
       if (cvm::check_new_bias(bias_conf, keyword)) {       biases.back()->init(bias_conf);
        if (cvm::check_new_bias(bias_conf, keyword) != COLVARS_OK) {
         return COLVARS_ERROR;         return COLVARS_ERROR;
       }       }
       cvm::decrease_depth();       cvm::decrease_depth();
Line 288
Line 293
   /// initialize histograms   /// initialize histograms
   parse_biases_type<colvarbias_histogram>(conf, "histogram", n_histo_biases);   parse_biases_type<colvarbias_histogram>(conf, "histogram", n_histo_biases);
  
    /// initialize histogram restraints
    parse_biases_type<colvarbias_restraint_histogram>(conf, "histogramRestraint", n_rest_biases);
  
   /// initialize linear restraints   /// initialize linear restraints
   parse_biases_type<colvarbias_restraint_linear>(conf, "linear", n_rest_biases);   parse_biases_type<colvarbias_restraint_linear>(conf, "linear", n_rest_biases);
  
Line 301
Line 309
     cvm::decrease_depth();     cvm::decrease_depth();
   }   }
  
    size_t i;
  
    for (i = 0; i < biases.size(); i++) {
      biases[i]->enable(colvardeps::f_cvb_active);
      if (cvm::debug())
        biases[i]->print_state();
    }
  
    size_t n_hist_dep_biases = 0;
    std::vector<std::string> hist_dep_biases_names;
    for (i = 0; i < biases.size(); i++) {
      if (biases[i]->is_enabled(colvardeps::f_cvb_apply_force) &&
          biases[i]->is_enabled(colvardeps::f_cvb_history_dependent)) {
        n_hist_dep_biases++;
        hist_dep_biases_names.push_back(biases[i]->name);
      }
    }
    if (n_hist_dep_biases > 1) {
      cvm::log("WARNING: there are "+cvm::to_str(n_hist_dep_biases)+
               " history-dependent biases with non-zero force parameters:\n"+
               cvm::to_str(hist_dep_biases_names)+"\n"+
               "Please make sure that their forces do not counteract each other.\n");
    }
  
   if (biases.size() || use_scripted_forces) {   if (biases.size() || use_scripted_forces) {
     cvm::log(cvm::line_marker);     cvm::log(cvm::line_marker);
     cvm::log("Collective variables biases initialized, "+     cvm::log("Collective variables biases initialized, "+
Line 315
Line 347
 } }
  
  
  int colvarmodule::catch_input_errors(int result)
  {
    if (result != COLVARS_OK || get_error()) {
      set_error_bits(result);
      set_error_bits(INPUT_ERROR);
      parse->init();
      return get_error();
    }
    return COLVARS_OK;
  }
  
  
 colvarbias * colvarmodule::bias_by_name(std::string const &name) { colvarbias * colvarmodule::bias_by_name(std::string const &name) {
   for (std::vector<colvarbias *>::iterator bi = biases.begin();   for (std::vector<colvarbias *>::iterator bi = biases.begin();
        bi != biases.end();        bi != biases.end();
Line 449
Line 493
 } }
  
  
 int colvarmodule::calc() { int colvarmodule::calc()
   cvm::real total_bias_energy = 0.0; {
   cvm::real total_colvar_energy = 0.0;   int error_code = COLVARS_OK;
  
   std::vector<colvar *>::iterator cvi; 
   std::vector<colvarbias *>::iterator bi; 
  
   if (cvm::debug()) {   if (cvm::debug()) {
     cvm::log(cvm::line_marker);     cvm::log(cvm::line_marker);
Line 462
Line 503
              cvm::to_str(cvm::step_absolute())+"\n");              cvm::to_str(cvm::step_absolute())+"\n");
   }   }
  
   // calculate collective variables and their gradients   error_code |= calc_colvars();
    // set biasing forces to zero before biases are calculated and summed over
    for (std::vector<colvar *>::iterator cvi = colvars.begin();
         cvi != colvars.end(); cvi++) {
      (*cvi)->reset_bias_force();
    }
    error_code |= calc_biases();
    error_code |= update_colvar_forces();
  
    if (cvm::b_analysis) {
      error_code |= analyze();
    }
  
    // write trajectory files, if needed
    if (cv_traj_freq && cv_traj_name.size()) {
      error_code |= write_traj_files();
    }
  
    // write restart files, if needed
    if (restart_out_freq && restart_out_name.size()) {
      error_code |= write_restart_files();
    }
  
    return error_code;
  }
  
  
  int colvarmodule::calc_colvars()
  {
   if (cvm::debug())   if (cvm::debug())
     cvm::log("Calculating collective variables.\n");     cvm::log("Calculating collective variables.\n");
    // calculate collective variables and their gradients
  
    int error_code = COLVARS_OK;
    std::vector<colvar *>::iterator cvi;
  
    // Determine which colvars are active at this time step
    for (cvi = colvars.begin(); cvi != colvars.end(); cvi++) {
      (*cvi)->feature_states[colvardeps::f_cv_active]->enabled = (step_absolute() % (*cvi)->get_time_step_factor() == 0);
    }
  
    // if SMP support is available, split up the work
    if (proxy->smp_enabled() == COLVARS_OK) {
  
      // first, calculate how much work (currently, how many active CVCs) each colvar has
  
      colvars_smp.resize(0);
      colvars_smp_items.resize(0);
  
      colvars_smp.reserve(colvars.size());
      colvars_smp_items.reserve(colvars.size());
  
      // set up a vector containing all components
      size_t num_colvar_items = 0;
   cvm::increase_depth();   cvm::increase_depth();
   for (cvi = colvars.begin(); cvi != colvars.end(); cvi++) {   for (cvi = colvars.begin(); cvi != colvars.end(); cvi++) {
     (*cvi)->calc(); 
        if (!(*cvi)->is_enabled()) continue;
        error_code |= (*cvi)->update_cvc_flags();
  
        size_t num_items = (*cvi)->num_active_cvcs();
        colvars_smp.reserve(colvars_smp.size() + num_items);
        colvars_smp_items.reserve(colvars_smp_items.size() + num_items);
        for (size_t icvc = 0; icvc < num_items; icvc++) {
          colvars_smp.push_back(*cvi);
          colvars_smp_items.push_back(icvc);
        }
  
        num_colvar_items += num_items;
      }
      cvm::decrease_depth();
  
      // calculate colvar components in parallel
      error_code |= proxy->smp_colvars_loop();
  
      cvm::increase_depth();
      for (cvi = colvars.begin(); cvi != colvars.end(); cvi++) {
        if (!(*cvi)->is_enabled()) continue;
        error_code |= (*cvi)->collect_cvc_data();
      }
      cvm::decrease_depth();
  
    } else {
  
      // calculate colvars one at a time
      cvm::increase_depth();
      for (cvi = colvars.begin(); cvi != colvars.end(); cvi++) {
        if (!(*cvi)->is_enabled()) continue;
        error_code |= (*cvi)->calc();
     if (cvm::get_error()) {     if (cvm::get_error()) {
       return COLVARS_ERROR;       return COLVARS_ERROR;
     }     }
   }   }
   cvm::decrease_depth();   cvm::decrease_depth();
    }
  
    error_code |= cvm::get_error();
    return error_code;
  }
  
  
  int colvarmodule::calc_biases()
  {
   // update the biases and communicate their forces to the collective   // update the biases and communicate their forces to the collective
   // variables   // variables
   if (cvm::debug() && biases.size())   if (cvm::debug() && biases.size())
     cvm::log("Updating collective variable biases.\n");     cvm::log("Updating collective variable biases.\n");
   cvm::increase_depth(); 
   for (bi = biases.begin(); bi != biases.end(); bi++) {   std::vector<colvarbias *>::iterator bi;
     total_bias_energy += (*bi)->update();   int error_code = COLVARS_OK;
     if (cvm::get_error()) { 
       return COLVARS_ERROR;   // if SMP support is available, split up the work
    if (proxy->smp_enabled() == COLVARS_OK) {
  
      if (use_scripted_forces && !scripting_after_biases) {
        // calculate biases and scripted forces in parallel
        error_code |= proxy->smp_biases_script_loop();
      } else {
        // calculate biases in parallel
        error_code |= proxy->smp_biases_loop();
     }     }
  
    } else {
  
      if (use_scripted_forces && !scripting_after_biases) {
        error_code |= calc_scripted_forces();
   }   }
   cvm::decrease_depth(); 
  
   // sum the forces from all biases for each collective variable 
   if (cvm::debug() && biases.size()) 
     cvm::log("Collecting forces from all biases.\n"); 
   cvm::increase_depth();   cvm::increase_depth();
   for (cvi = colvars.begin(); cvi != colvars.end(); cvi++) { 
     (*cvi)->reset_bias_force(); 
   } 
   for (bi = biases.begin(); bi != biases.end(); bi++) {   for (bi = biases.begin(); bi != biases.end(); bi++) {
     (*bi)->communicate_forces();       error_code |= (*bi)->update();
     if (cvm::get_error()) {     if (cvm::get_error()) {
       return COLVARS_ERROR;       return COLVARS_ERROR;
     }     }
   }   }
      cvm::decrease_depth();
   // Run user force script, if provided, 
   // potentially adding scripted forces to the colvars 
   if (use_scripted_forces) { 
     int res; 
     res = proxy->run_force_callback(); 
     if (res == COLVARS_NOT_IMPLEMENTED) { 
       cvm::error("Colvar forces scripts are not implemented."); 
       return COLVARS_ERROR; 
     }     }
     if (res != COLVARS_OK) { 
       cvm::error("Error running user colvar forces script");   cvm::real total_bias_energy = 0.0;
       return COLVARS_ERROR;   for (bi = biases.begin(); bi != biases.end(); bi++) {
      total_bias_energy += (*bi)->get_energy();
     }     }
  
    proxy->add_energy(total_bias_energy);
    return (cvm::get_error() ? COLVARS_ERROR : COLVARS_OK);
   }   }
  
   cvm::decrease_depth(); 
  
   if (cvm::b_analysis) { int colvarmodule::update_colvar_forces()
     // perform runtime analysis of colvars and biases {
    int error_code = COLVARS_OK;
  
    std::vector<colvar *>::iterator cvi;
    std::vector<colvarbias *>::iterator bi;
  
    // sum the forces from all biases for each collective variable
     if (cvm::debug() && biases.size())     if (cvm::debug() && biases.size())
       cvm::log("Perform runtime analyses.\n");     cvm::log("Collecting forces from all biases.\n");
     cvm::increase_depth();     cvm::increase_depth();
     for (cvi = colvars.begin(); cvi != colvars.end(); cvi++) { 
       (*cvi)->analyze(); 
       if (cvm::get_error()) { 
         return COLVARS_ERROR; 
       } 
     } 
     for (bi = biases.begin(); bi != biases.end(); bi++) {     for (bi = biases.begin(); bi != biases.end(); bi++) {
       (*bi)->analyze();     (*bi)->communicate_forces();
       if (cvm::get_error()) {       if (cvm::get_error()) {
         return COLVARS_ERROR;         return COLVARS_ERROR;
       }       }
     }     }
     cvm::decrease_depth();     cvm::decrease_depth();
  
    if (use_scripted_forces && scripting_after_biases) {
      error_code |= calc_scripted_forces();
   }   }
  
    cvm::real total_colvar_energy = 0.0;
   // sum up the forces for each colvar, including wall forces   // sum up the forces for each colvar, including wall forces
   // and integrate any internal   // and integrate any internal
   // equation of motion (extended system)   // equation of motion (extended system)
Line 546
Line 683
              "of colvars (if they have any).\n");              "of colvars (if they have any).\n");
   cvm::increase_depth();   cvm::increase_depth();
   for (cvi = colvars.begin(); cvi != colvars.end(); cvi++) {   for (cvi = colvars.begin(); cvi != colvars.end(); cvi++) {
     total_colvar_energy += (*cvi)->update();     // Here we call even inactive colvars, so they accumulate biasing forces
      // as well as update their extended-system dynamics
      total_colvar_energy += (*cvi)->update_forces_energy();
     if (cvm::get_error()) {     if (cvm::get_error()) {
       return COLVARS_ERROR;       return COLVARS_ERROR;
     }     }
   }   }
   cvm::decrease_depth();   cvm::decrease_depth();
   proxy->add_energy(total_bias_energy + total_colvar_energy);   proxy->add_energy(total_colvar_energy);
  
   // make collective variables communicate their forces to their   // make collective variables communicate their forces to their
   // coupled degrees of freedom (i.e. atoms)   // coupled degrees of freedom (i.e. atoms)
Line 560
Line 699
     cvm::log("Communicating forces from the colvars to the atoms.\n");     cvm::log("Communicating forces from the colvars to the atoms.\n");
   cvm::increase_depth();   cvm::increase_depth();
   for (cvi = colvars.begin(); cvi != colvars.end(); cvi++) {   for (cvi = colvars.begin(); cvi != colvars.end(); cvi++) {
     if ((*cvi)->tasks[colvar::task_gradients]) {     if ((*cvi)->is_enabled(colvardeps::f_cv_gradient)) {
        if (!(*cvi)->is_enabled()) continue;
       (*cvi)->communicate_forces();       (*cvi)->communicate_forces();
       if (cvm::get_error()) {       if (cvm::get_error()) {
         return COLVARS_ERROR;         return COLVARS_ERROR;
Line 569
Line 709
   }   }
   cvm::decrease_depth();   cvm::decrease_depth();
  
   // write restart file, if needed   return (cvm::get_error() ? COLVARS_ERROR : COLVARS_OK);
   if (restart_out_freq && restart_out_name.size()) { }
  
  
  int colvarmodule::calc_scripted_forces()
  {
    // Run user force script, if provided,
    // potentially adding scripted forces to the colvars
    int res;
    res = proxy->run_force_callback();
    if (res == COLVARS_NOT_IMPLEMENTED) {
      cvm::error("Colvar forces scripts are not implemented.");
      return COLVARS_NOT_IMPLEMENTED;
    }
    if (res != COLVARS_OK) {
      cvm::error("Error running user colvar forces script");
      return COLVARS_ERROR;
    }
    return COLVARS_OK;
  }
  
  
  int colvarmodule::write_restart_files()
  {
     if ( (cvm::step_relative() > 0) &&     if ( (cvm::step_relative() > 0) &&
          ((cvm::step_absolute() % restart_out_freq) == 0) ) {          ((cvm::step_absolute() % restart_out_freq) == 0) ) {
       cvm::log("Writing the state file \""+       cvm::log("Writing the state file \""+
Line 581
Line 743
         cvm::error("Error: in writing restart file.\n");         cvm::error("Error: in writing restart file.\n");
       restart_out_os.close();       restart_out_os.close();
     }     }
  
    return (cvm::get_error() ? COLVARS_ERROR : COLVARS_OK);
   }   }
  
   // write trajectory file, if needed 
   if (cv_traj_freq && cv_traj_name.size()) { 
  
  int colvarmodule::write_traj_files()
  {
     if (!cv_traj_os.is_open()) {     if (!cv_traj_os.is_open()) {
       open_traj_file(cv_traj_name);       open_traj_file(cv_traj_name);
     }     }
Line 608
Line 772
         cv_traj_os.flush();         cv_traj_os.flush();
       }       }
     }     }
   } // end if (cv_traj_freq) 
  
   return (cvm::get_error() ? COLVARS_ERROR : COLVARS_OK);   return (cvm::get_error() ? COLVARS_ERROR : COLVARS_OK);
 } }
Line 644
Line 807
   return (cvm::get_error() ? COLVARS_ERROR : COLVARS_OK);   return (cvm::get_error() ? COLVARS_ERROR : COLVARS_OK);
 } }
  
  
 int colvarmodule::setup() int colvarmodule::setup()
 { {
    if (this->size() == 0) return cvm::get_error();
   // loop over all components of all colvars to reset masses of all groups   // loop over all components of all colvars to reset masses of all groups
   for (std::vector<colvar *>::iterator cvi = colvars.begin();   for (std::vector<colvar *>::iterator cvi = colvars.begin();
        cvi != colvars.end();  cvi++) {        cvi != colvars.end();  cvi++) {
     (*cvi)->setup();     (*cvi)->setup();
   }   }
   return (cvm::get_error() ? COLVARS_ERROR : COLVARS_OK);   return (cvm::get_error() ? COLVARS_ERROR : COLVARS_OK);
  
 } }
  
  
 colvarmodule::~colvarmodule() colvarmodule::~colvarmodule()
 { {
    if ((proxy->smp_thread_id() == COLVARS_NOT_IMPLEMENTED) ||
        (proxy->smp_thread_id() == 0)) {
   reset();   reset();
   delete parse;   delete parse;
      parse = NULL;
   proxy = NULL;   proxy = NULL;
 } }
  }
  
  
 int colvarmodule::reset() int colvarmodule::reset()
 { {
    parse->init();
  
   cvm::log("Resetting the Collective Variables Module.\n");   cvm::log("Resetting the Collective Variables Module.\n");
   // Iterate backwards because we are deleting the elements as we go 
   for (std::vector<colvar *>::reverse_iterator cvi = colvars.rbegin(); 
        cvi != colvars.rend(); 
        cvi++) { 
     delete *cvi; // the colvar destructor updates the colvars array 
   } 
   colvars.clear(); 
  
   // Iterate backwards because we are deleting the elements as we go   // Iterate backwards because we are deleting the elements as we go
   for (std::vector<colvarbias *>::reverse_iterator bi = biases.rbegin();   for (std::vector<colvarbias *>::reverse_iterator bi = biases.rbegin();
Line 681
Line 846
   }   }
   biases.clear();   biases.clear();
  
    // Iterate backwards because we are deleting the elements as we go
    for (std::vector<colvar *>::reverse_iterator cvi = colvars.rbegin();
         cvi != colvars.rend();
         cvi++) {
      delete *cvi; // the colvar destructor updates the colvars array
    }
    colvars.clear();
  
   index_groups.clear();   index_groups.clear();
   index_group_names.clear();   index_group_names.clear();
  
Line 695
Line 868
  
 int colvarmodule::setup_input() int colvarmodule::setup_input()
 { {
   // name of input state file   if (this->size() == 0) return cvm::get_error();
   restart_in_name = proxy->input_prefix().size() ? 
     std::string(proxy->input_prefix()+".colvars.state") :   std::string restart_in_name("");
     std::string("") ; 
  
   // read the restart configuration, if available   // read the restart configuration, if available
   if (restart_in_name.size()) {   if (proxy->input_prefix().size()) {
     // read the restart file     // read the restart file
      restart_in_name = proxy->input_prefix();
     std::ifstream input_is(restart_in_name.c_str());     std::ifstream input_is(restart_in_name.c_str());
     if (!input_is.good()) {     if (!input_is.good()) {
       cvm::error("Error: in opening restart file \""+       // try by adding the suffix
        input_is.clear();
        restart_in_name = restart_in_name+std::string(".colvars.state");
        input_is.open(restart_in_name.c_str());
      }
  
      if (!input_is.good()) {
        cvm::error("Error: in opening input file \""+
                  std::string(restart_in_name)+"\".\n",                  std::string(restart_in_name)+"\".\n",
                  FILE_ERROR);                  FILE_ERROR);
       return COLVARS_ERROR;       return COLVARS_ERROR;
     } else {     } else {
        cvm::log(cvm::line_marker);
       cvm::log("Restarting from file \""+restart_in_name+"\".\n");       cvm::log("Restarting from file \""+restart_in_name+"\".\n");
       read_restart(input_is);       read_restart(input_is);
       if (cvm::get_error() != COLVARS_OK) {       if (cvm::get_error() != COLVARS_OK) {
         return COLVARS_ERROR;         return COLVARS_ERROR;
        } else {
          proxy->input_prefix().clear();
       }       }
       cvm::log(cvm::line_marker);       cvm::log(cvm::line_marker);
     }     }
Line 725
Line 908
  
 int colvarmodule::setup_output() int colvarmodule::setup_output()
 { {
   int error_code = 0;   if (this->size() == 0) return cvm::get_error();
  
    int error_code = COLVARS_OK;
  
   // output state file (restart)   // output state file (restart)
   restart_out_name = proxy->restart_output_prefix().size() ?   restart_out_name = proxy->restart_output_prefix().size() ?
Line 770
Line 955
  
 std::istream & colvarmodule::read_restart(std::istream &is) std::istream & colvarmodule::read_restart(std::istream &is)
 { {
    bool warn_total_forces = false;
  
   {   {
     // read global restart information     // read global restart information
     std::string restart_conf;     std::string restart_conf;
Line 780
Line 967
                           colvarparse::parse_silent);                           colvarparse::parse_silent);
         it = it_restart;         it = it_restart;
       }       }
        std::string restart_version;
        parse->get_keyval(restart_conf, "version",
                          restart_version, std::string(""),
                          colvarparse::parse_silent);
        if (restart_version.size() && (restart_version != std::string(COLVARS_VERSION))) {
          cvm::log("This state file was generated with version "+restart_version+"\n");
        }
        if ((restart_version.size() == 0) || (restart_version.compare(std::string(COLVARS_VERSION)) < 0)) {
          // check for total force change
          if (proxy->total_forces_enabled()) {
            warn_total_forces = true;
          }
        }
     }     }
     is.clear();     is.clear();
     parse->clear_keyword_registry();     parse->clear_keyword_registry();
Line 809
Line 1009
   }   }
   cvm::decrease_depth();   cvm::decrease_depth();
  
    if (warn_total_forces) {
      cvm::log(cvm::line_marker);
      cvm::log("WARNING:\n");
      std::string const warning("### CHANGES IN THE DEFINITION OF SYSTEM FORCES (NOW TOTAL FORCES)\n\
  \n\
  Starting from the version 2016-08-10 of the Colvars module, \n\
  the role of system forces has been replaced by total forces.\n\
  \n\
  These include *all* forces acting on a collective variable, whether they\n\
  come from the force field potential or from external terms\n\
  (e.g. restraints), including forces applied by Colvars itself.\n\
  \n\
  In NAMD, forces applied by Colvars, IMD, SMD, TMD, symmetry\n\
  restraints and tclForces are now all counted in the total force.\n\
  \n\
  In LAMMPS, forces applied by Colvars itself are now counted in the total\n\
  force (all forces from other fixes were being counted already).\n\
  \n\
  \n\
  ### WHEN IS THIS CHANGE RELEVANT\n\
  \n\
  This change affects results *only* when (1) outputSystemForce is\n\
  requested or (2) the ABF bias is used.  All other usage cases are\n\
  *unaffected* (colvar restraints, metadynamics, etc).\n\
  \n\
  When system forces are reported (flag: outputSystemForce), their values\n\
  in the output may change, but the physical trajectory is never affected.\n\
  The physical results of ABF calculations may be affected in some cases.\n\
  \n\
  \n\
  ### CHANGES TO ABF CALCULATIONS\n\
  \n\
  Compared to previous Colvars versions, the ABF method will now attempt\n\
  to cancel external forces (for example, boundary walls) and it may be\n\
  not possible to resume through a state file a simulation that was\n\
  performed with a previous version.\n\
  \n\
  There are three possible scenarios:\n\
  \n\
  1. No external forces are applied to the atoms used by ABF: results are\n\
  unchanged.\n\
  \n\
  2. Some of the atoms used by ABF experience external forces, but these\n\
  forces are not applied directly to the variables used by ABF\n\
  (e.g. another colvar that uses the same atoms, tclForces, etc): in this\n\
  case, we recommend beginning a new simulation.\n\
  \n\
  3. External forces are applied to one or more of the colvars used by\n\
  ABF, but no other forces are applied to their atoms: you may use the\n\
  subtractAppliedForce keyword inside the corresponding colvars to\n\
  continue the previous simulation.\n\n");
      cvm::log(warning);
      cvm::log(cvm::line_marker);
  
      // update this ahead of time in this special case
      output_prefix = proxy->output_prefix();
      cvm::log("All output files will now be saved with the prefix \""+output_prefix+".tmp.*\".\n");
      output_prefix = output_prefix+".tmp";
      write_output_files();
      cvm::log(cvm::line_marker);
      cvm::log("Please review the important warning above. After that, you may rename:\n\
  \""+output_prefix+".tmp.colvars.state\"\n\
  to:\n\
  \""+output_prefix+".colvars.state\"\n");
      cvm::error("Exiting with error until issue is addressed.\n", FATAL_ERROR);
    }
  
   return is;   return is;
 } }
  
Line 936
Line 1203
      << "  step " << std::setw(it_width)      << "  step " << std::setw(it_width)
      << it << "\n"      << it << "\n"
      << "  dt " << dt() << "\n"      << "  dt " << dt() << "\n"
       << "  version " << std::string(COLVARS_VERSION) << "\n"
      << "}\n\n";      << "}\n\n";
  
   cvm::increase_depth();   cvm::increase_depth();
Line 983
Line 1251
  
 int colvarmodule::close_traj_file() int colvarmodule::close_traj_file()
 { {
   if (cv_traj_os.good()) {   if (cv_traj_os.is_open()) {
     cv_traj_os.close();     cv_traj_os.close();
   }   }
   return (cvm::get_error() ? COLVARS_ERROR : COLVARS_OK);   return (cvm::get_error() ? COLVARS_ERROR : COLVARS_OK);
Line 1048
Line 1316
  
 void cvm::log(std::string const &message) void cvm::log(std::string const &message)
 { {
   if (depth > 0)   size_t const d = depth();
     proxy->log((std::string(2*depth, ' '))+message);   if (d > 0)
      proxy->log((std::string(2*d, ' '))+message);
   else   else
     proxy->log(message);     proxy->log(message);
 } }
  
  
 void cvm::increase_depth() void cvm::increase_depth()
 { {
   depth++;   (depth())++;
 } }
  
  
 void cvm::decrease_depth() void cvm::decrease_depth()
 { {
   if (depth) depth--;   if (depth() > 0) {
      (depth())--;
    }
  }
  
  
  size_t & cvm::depth()
  {
    // NOTE: do not call log() or error() here, to avoid recursion
    size_t const nt = proxy->smp_num_threads();
    if (proxy->smp_enabled() == COLVARS_OK) {
      if (depth_v.size() != nt) {
        // update array of depths
        proxy->smp_lock();
        if (depth_v.size() > 0) { depth_s = depth_v[0]; }
        depth_v.clear();
        depth_v.assign(nt, depth_s);
        proxy->smp_unlock();
      }
      return depth_v[proxy->smp_thread_id()];
    }
    return depth_s;
 } }
  
  
  void colvarmodule::set_error_bits(int code)
  {
    if (code < 0) {
      cvm::fatal_error("Error: set_error_bits() received negative error code.\n");
      return;
    }
    proxy->smp_lock();
    errorCode |= code | COLVARS_ERROR;
    proxy->smp_unlock();
  }
  
  bool colvarmodule::get_error_bit(int code)
  {
    return bool(errorCode & code);
  }
  
  void colvarmodule::clear_error()
  {
    proxy->smp_lock();
    errorCode = COLVARS_OK;
    proxy->smp_unlock();
  }
  
  
 void cvm::error(std::string const &message, int code) void cvm::error(std::string const &message, int code)
 { {
   set_error_bits(code);   set_error_bits(code);
   proxy->error(message);   proxy->error(message);
 } }
  
  
 void cvm::fatal_error(std::string const &message) void cvm::fatal_error(std::string const &message)
 { {
    // TODO once all non-fatal errors have been set to be handled by error(),
    // set DELETE_COLVARS here for VMD to handle it
   set_error_bits(FATAL_ERROR);   set_error_bits(FATAL_ERROR);
   proxy->fatal_error(message);   proxy->fatal_error(message);
 } }
  
  
 void cvm::exit(std::string const &message) void cvm::exit(std::string const &message)
 { {
   proxy->exit(message);   proxy->exit(message);
Line 1143
Line 1464
 } }
  
 int cvm::load_atoms(char const *file_name, int cvm::load_atoms(char const *file_name,
                     std::vector<cvm::atom> &atoms,                     cvm::atom_group &atoms,
                     std::string const &pdb_field,                     std::string const &pdb_field,
                     double const pdb_field_value)                     double const pdb_field_value)
 { {
Line 1224
Line 1545
  
  
 // static runtime data // static runtime data
 cvm::real colvarmodule::debug_gradients_step_size = 1.0e-03; cvm::real colvarmodule::debug_gradients_step_size = 1.0e-07;
 int       colvarmodule::errorCode = 0; int       colvarmodule::errorCode = 0;
 long      colvarmodule::it = 0; long      colvarmodule::it = 0;
 long      colvarmodule::it_restart = 0; long      colvarmodule::it_restart = 0;
 size_t    colvarmodule::restart_out_freq = 0; size_t    colvarmodule::restart_out_freq = 0;
 size_t    colvarmodule::cv_traj_freq = 0; size_t    colvarmodule::cv_traj_freq = 0;
 size_t    colvarmodule::depth = 0; size_t    colvarmodule::depth_s = 0;
  std::vector<size_t> colvarmodule::depth_v(0);
 bool      colvarmodule::b_analysis = false; bool      colvarmodule::b_analysis = false;
 std::list<std::string> colvarmodule::index_group_names; std::list<std::string> colvarmodule::index_group_names;
 std::list<std::vector<int> > colvarmodule::index_groups; std::list<std::vector<int> > colvarmodule::index_groups;
 bool     colvarmodule::use_scripted_forces = false; bool     colvarmodule::use_scripted_forces = false;
  bool     colvarmodule::scripting_after_biases = true;
 // file name prefixes 
 std::string colvarmodule::output_prefix = ""; std::string colvarmodule::output_prefix = "";
 std::string colvarmodule::restart_in_name = ""; 
  
  
 // i/o constants // i/o constants
 size_t const colvarmodule::it_width = 12; size_t const colvarmodule::it_width = 12;


Legend:
Removed in v.1.25 
changed lines
 Added in v.1.26



Made by using version 1.53 of cvs2html