Difference for src/colvarbias_meta.C from version 1.21 to 1.22

version 1.21version 1.22
Line 1
Line 1
 // -*- c++ -*- // -*- c++ -*-
  
  // This file is part of the Collective Variables module (Colvars).
  // The original version of Colvars and its updates are located at:
  // https://github.com/colvars/colvars
  // Please update all Colvars source files before making any changes.
  // If you wish to distribute your changes, please submit them to the
  // Colvars repository at GitHub.
  
 #include <iostream> #include <iostream>
 #include <sstream> #include <sstream>
 #include <fstream> #include <fstream>
Line 26
Line 33
  
  
 colvarbias_meta::colvarbias_meta(char const *key) colvarbias_meta::colvarbias_meta(char const *key)
   : colvarbias(key),   : colvarbias(key)
     new_hills_begin(hills.end()), 
     state_file_step(0) 
 { {
    new_hills_begin = hills.end();
 } }
  
  
Line 39
Line 45
  
   provide(f_cvb_history_dependent);   provide(f_cvb_history_dependent);
  
    provide(f_cvb_calc_pmf);
    enable(f_cvb_calc_pmf);
  
   get_keyval(conf, "hillWeight", hill_weight, 0.0);   get_keyval(conf, "hillWeight", hill_weight, 0.0);
   if (hill_weight > 0.0) {   if (hill_weight > 0.0) {
     enable(f_cvb_apply_force);     enable(f_cvb_apply_force);
Line 53
Line 62
  
   get_keyval(conf, "hillWidth", hill_width, std::sqrt(2.0 * PI) / 2.0);   get_keyval(conf, "hillWidth", hill_width, std::sqrt(2.0 * PI) / 2.0);
   cvm::log("Half-widths of the Gaussian hills (sigma's):\n");   cvm::log("Half-widths of the Gaussian hills (sigma's):\n");
   for (size_t i = 0; i < colvars.size(); i++) {   for (size_t i = 0; i < num_variables(); i++) {
     cvm::log(colvars[i]->name+std::string(": ")+     cvm::log(variables(i)->name+std::string(": ")+
              cvm::to_str(0.5 * colvars[i]->width * hill_width));              cvm::to_str(0.5 * variables(i)->width * hill_width));
   }   }
  
   {   {
Line 67
Line 76
       comm = single_replica;       comm = single_replica;
   }   }
  
   // This implies gradients for all colvars   // in all cases, the first replica is this bias itself
   enable(f_cvb_apply_force);   if (replicas.size() == 0) {
      replicas.push_back(this);
    }
  
   get_keyval(conf, "useGrids", use_grids, true);   get_keyval(conf, "useGrids", use_grids, true);
  
Line 78
Line 89
  
     expand_grids = false;     expand_grids = false;
     size_t i;     size_t i;
     for (i = 0; i < colvars.size(); i++) {     for (i = 0; i < num_variables(); i++) {
       colvars[i]->enable(f_cv_grid);       variables(i)->enable(f_cv_grid);
       if (colvars[i]->expand_boundaries) {       if (variables(i)->expand_boundaries) {
         expand_grids = true;         expand_grids = true;
         cvm::log("Metadynamics bias \""+this->name+"\""+         cvm::log("Metadynamics bias \""+this->name+"\""+
                  ((comm != single_replica) ? ", replica \""+replica_id+"\"" : "")+                  ((comm != single_replica) ? ", replica \""+replica_id+"\"" : "")+
                  ": Will expand grids when the colvar \""+                  ": Will expand grids when the colvar \""+
                  colvars[i]->name+"\" approaches its boundaries.\n");                  variables(i)->name+"\" approaches its boundaries.\n");
       }       }
     }     }
  
Line 94
Line 105
       get_keyval(conf, "dumpFreeEnergyFile", dump_fes, true, colvarparse::parse_silent);       get_keyval(conf, "dumpFreeEnergyFile", dump_fes, true, colvarparse::parse_silent);
     if (get_keyval(conf, "saveFreeEnergyFile", dump_fes_save, false, colvarparse::parse_silent)) {     if (get_keyval(conf, "saveFreeEnergyFile", dump_fes_save, false, colvarparse::parse_silent)) {
       cvm::log("Option \"saveFreeEnergyFile\" is deprecated, "       cvm::log("Option \"saveFreeEnergyFile\" is deprecated, "
                "please use \"keepFreeEnergyFiles\" instead.");                "please use \"keepFreeEnergyFile\" instead.");
     }     }
     get_keyval(conf, "keepFreeEnergyFiles", dump_fes_save, dump_fes_save);     get_keyval(conf, "keepFreeEnergyFiles", dump_fes_save, dump_fes_save);
  
Line 148
Line 159
  
   get_keyval(conf, "writeHillsTrajectory", b_hills_traj, false);   get_keyval(conf, "writeHillsTrajectory", b_hills_traj, false);
  
    init_well_tempered_params(conf);
    init_ebmeta_params(conf);
  
    if (cvm::debug())
      cvm::log("Done initializing the metadynamics bias \""+this->name+"\""+
               ((comm != single_replica) ? ", replica \""+replica_id+"\"" : "")+".\n");
  
    save_delimiters = false;
    return COLVARS_OK;
  }
  
  
  int colvarbias_meta::init_well_tempered_params(std::string const &conf)
  {
   // for well-tempered metadynamics   // for well-tempered metadynamics
   get_keyval(conf, "wellTempered", well_tempered, false);   get_keyval(conf, "wellTempered", well_tempered, false);
   get_keyval(conf, "biasTemperature", bias_temperature, -1.0);   get_keyval(conf, "biasTemperature", bias_temperature, -1.0);
Line 158
Line 183
     cvm::log("Well-tempered metadynamics is used.\n");     cvm::log("Well-tempered metadynamics is used.\n");
     cvm::log("The bias temperature is "+cvm::to_str(bias_temperature)+".\n");     cvm::log("The bias temperature is "+cvm::to_str(bias_temperature)+".\n");
   }   }
    return COLVARS_OK;
  }
  
  
  int colvarbias_meta::init_ebmeta_params(std::string const &conf)
  {
   // for ebmeta   // for ebmeta
   target_dist = NULL;   target_dist = NULL;
   get_keyval(conf, "ebMeta", ebmeta, false);   get_keyval(conf, "ebMeta", ebmeta, false);
Line 197
Line 226
     get_keyval(conf, "ebMetaEquilSteps", ebmeta_equil_steps, 0);     get_keyval(conf, "ebMetaEquilSteps", ebmeta_equil_steps, 0);
   }   }
  
   if (cvm::debug()) 
     cvm::log("Done initializing the metadynamics bias \""+this->name+"\""+ 
              ((comm != single_replica) ? ", replica \""+replica_id+"\"" : "")+".\n"); 
  
   save_delimiters = false; 
   return COLVARS_OK;   return COLVARS_OK;
 } }
  
Line 228
Line 252
     delete target_dist;     delete target_dist;
     target_dist = NULL;     target_dist = NULL;
   }   }
  
   if (cvm::n_meta_biases > 0) 
     cvm::n_meta_biases -= 1; 
 } }
  
  
Line 308
Line 329
  
 int colvarbias_meta::update() int colvarbias_meta::update()
 { {
   if (cvm::debug())   int error_code = COLVARS_OK;
     cvm::log("Updating the metadynamics bias \""+this->name+"\""+ 
              ((comm != single_replica) ? ", replica \""+replica_id+"\"" : "")+".\n"); 
  
   if (use_grids) {   // update base class
    error_code |= colvarbias::update();
  
     std::vector<int> curr_bin = hills_energy->get_colvars_index();   // update grid definition, if needed
    error_code |= update_grid_params();
    // add new biasing energy/forces
    error_code |= update_bias();
    // update grid content to reflect new bias
    error_code |= update_grid_data();
  
     if (expand_grids) {   if (comm != single_replica &&
        (cvm::step_absolute() % replica_update_freq) == 0) {
      // sync with the other replicas (if needed)
      error_code |= replica_share();
    }
  
       // first of all, expand the grids, if specified   error_code |= calc_energy();
       if (cvm::debug())   error_code |= calc_forces();
  
    return error_code;
  }
  
  
  int colvarbias_meta::update_grid_params()
  {
    if (use_grids) {
  
      std::vector<int> curr_bin = hills_energy->get_colvars_index();
      if (cvm::debug()) {
         cvm::log("Metadynamics bias \""+this->name+"\""+         cvm::log("Metadynamics bias \""+this->name+"\""+
                  ((comm != single_replica) ? ", replica \""+replica_id+"\"" : "")+                  ((comm != single_replica) ? ", replica \""+replica_id+"\"" : "")+
                  ": current coordinates on the grid: "+                  ": current coordinates on the grid: "+
                  cvm::to_str(curr_bin)+".\n");                  cvm::to_str(curr_bin)+".\n");
      }
  
      if (expand_grids) {
        // first of all, expand the grids, if specified
       bool changed_grids = false;       bool changed_grids = false;
       int const min_buffer =       int const min_buffer =
         (3 * (size_t) std::floor(hill_width)) + 1;         (3 * (size_t) std::floor(hill_width)) + 1;
Line 333
Line 376
       std::vector<colvarvalue> new_lower_boundaries(hills_energy->lower_boundaries);       std::vector<colvarvalue> new_lower_boundaries(hills_energy->lower_boundaries);
       std::vector<colvarvalue> new_upper_boundaries(hills_energy->upper_boundaries);       std::vector<colvarvalue> new_upper_boundaries(hills_energy->upper_boundaries);
  
       for (size_t i = 0; i < colvars.size(); i++) {       for (size_t i = 0; i < num_variables(); i++) {
  
         if (! colvars[i]->expand_boundaries)         if (! variables(i)->expand_boundaries)
           continue;           continue;
  
         cvm::real &new_lb   = new_lower_boundaries[i].real_value;         cvm::real &new_lb   = new_lower_boundaries[i].real_value;
Line 343
Line 386
         int       &new_size = new_sizes[i];         int       &new_size = new_sizes[i];
         bool changed_lb = false, changed_ub = false;         bool changed_lb = false, changed_ub = false;
  
         if (!colvars[i]->hard_lower_boundary)         if (!variables(i)->hard_lower_boundary)
           if (curr_bin[i] < min_buffer) {           if (curr_bin[i] < min_buffer) {
             int const extra_points = (min_buffer - curr_bin[i]);             int const extra_points = (min_buffer - curr_bin[i]);
             new_lb -= extra_points * colvars[i]->width;             new_lb -= extra_points * variables(i)->width;
             new_size += extra_points;             new_size += extra_points;
             // changed offset in this direction => the pointer needs to             // changed offset in this direction => the pointer needs to
             // be changed, too             // be changed, too
Line 356
Line 399
             cvm::log("Metadynamics bias \""+this->name+"\""+             cvm::log("Metadynamics bias \""+this->name+"\""+
                      ((comm != single_replica) ? ", replica \""+replica_id+"\"" : "")+                      ((comm != single_replica) ? ", replica \""+replica_id+"\"" : "")+
                      ": new lower boundary for colvar \""+                      ": new lower boundary for colvar \""+
                      colvars[i]->name+"\", at "+                      variables(i)->name+"\", at "+
                      cvm::to_str(new_lower_boundaries[i])+".\n");                      cvm::to_str(new_lower_boundaries[i])+".\n");
           }           }
  
         if (!colvars[i]->hard_upper_boundary)         if (!variables(i)->hard_upper_boundary)
           if (curr_bin[i] > new_size - min_buffer - 1) {           if (curr_bin[i] > new_size - min_buffer - 1) {
             int const extra_points = (curr_bin[i] - (new_size - 1) + min_buffer);             int const extra_points = (curr_bin[i] - (new_size - 1) + min_buffer);
             new_ub += extra_points * colvars[i]->width;             new_ub += extra_points * variables(i)->width;
             new_size += extra_points;             new_size += extra_points;
  
             changed_ub = true;             changed_ub = true;
             cvm::log("Metadynamics bias \""+this->name+"\""+             cvm::log("Metadynamics bias \""+this->name+"\""+
                      ((comm != single_replica) ? ", replica \""+replica_id+"\"" : "")+                      ((comm != single_replica) ? ", replica \""+replica_id+"\"" : "")+
                      ": new upper boundary for colvar \""+                      ": new upper boundary for colvar \""+
                      colvars[i]->name+"\", at "+                      variables(i)->name+"\", at "+
                      cvm::to_str(new_upper_boundaries[i])+".\n");                      cvm::to_str(new_upper_boundaries[i])+".\n");
           }           }
  
Line 395
Line 438
  
         new_hills_energy_gradients->lower_boundaries = new_lower_boundaries;         new_hills_energy_gradients->lower_boundaries = new_lower_boundaries;
         new_hills_energy_gradients->upper_boundaries = new_upper_boundaries;         new_hills_energy_gradients->upper_boundaries = new_upper_boundaries;
         new_hills_energy_gradients->setup(new_sizes, 0.0, colvars.size());         new_hills_energy_gradients->setup(new_sizes, 0.0, num_variables());
  
         new_hills_energy->map_grid(*hills_energy);         new_hills_energy->map_grid(*hills_energy);
         new_hills_energy_gradients->map_grid(*hills_energy_gradients);         new_hills_energy_gradients->map_grid(*hills_energy_gradients);
Line 412
Line 455
       }       }
     }     }
   }   }
    return COLVARS_OK;
  }
  
  
  int colvarbias_meta::update_bias()
  {
   // add a new hill if the required time interval has passed   // add a new hill if the required time interval has passed
   if ((cvm::step_absolute() % new_hill_freq) == 0) {   if ((cvm::step_absolute() % new_hill_freq) == 0 &&
        is_enabled(f_cvb_history_dependent)) {
  
     if (cvm::debug())     if (cvm::debug()) {
       cvm::log("Metadynamics bias \""+this->name+"\""+       cvm::log("Metadynamics bias \""+this->name+"\""+
                ((comm != single_replica) ? ", replica \""+replica_id+"\"" : "")+                ((comm != single_replica) ? ", replica \""+replica_id+"\"" : "")+
                ": adding a new hill at step "+cvm::to_str(cvm::step_absolute())+".\n");                ": adding a new hill at step "+cvm::to_str(cvm::step_absolute())+".\n");
      }
  
     cvm::real hills_scale=1.0;     cvm::real hills_scale=1.0;
  
Line 465
Line 515
     }     }
   }   }
  
   // sync with the other replicas (if needed)   return COLVARS_OK;
   if (comm != single_replica) { 
  
     // reread the replicas registry 
     if ((cvm::step_absolute() % replica_update_freq) == 0) { 
       update_replicas_registry(); 
       // empty the output buffer 
       if (replica_hills_os.is_open()) 
         replica_hills_os.flush(); 
  
       read_replica_files(); 
     } 
   } 
  
   // calculate the biasing energy and forces 
   bias_energy = 0.0; 
   for (size_t ir = 0; ir < colvars.size(); ir++) { 
     colvar_forces[ir].reset(); 
   } 
   if (comm == multiple_replicas) 
     for (size_t ir = 0; ir < replicas.size(); ir++) { 
       replicas[ir]->bias_energy = 0.0; 
       for (size_t ic = 0; ic < colvars.size(); ic++) { 
         replicas[ir]->colvar_forces[ic].reset(); 
       } 
     }     }
  
   if (use_grids) { 
  
     // get the forces from the grid 
  
  int colvarbias_meta::update_grid_data()
  {
     if ((cvm::step_absolute() % grids_freq) == 0) {     if ((cvm::step_absolute() % grids_freq) == 0) {
       // map the most recent gaussians to the grids       // map the most recent gaussians to the grids
       project_hills(new_hills_begin, hills.end(),       project_hills(new_hills_begin, hills.end(),
Line 515
Line 540
       }       }
     }     }
  
     std::vector<int> curr_bin = hills_energy->get_colvars_index();   return COLVARS_OK;
     if (cvm::debug()) }
  
  
  int colvarbias_meta::calc_energy(std::vector<colvarvalue> const &values)
  {
    size_t ir = 0;
  
    for (ir = 0; ir < replicas.size(); ir++) {
      replicas[ir]->bias_energy = 0.0;
    }
  
    std::vector<int> const curr_bin = values.size() ?
      hills_energy->get_colvars_index(values) :
      hills_energy->get_colvars_index();
  
    if (hills_energy->index_ok(curr_bin)) {
      // index is within the grid: get the energy from there
      for (ir = 0; ir < replicas.size(); ir++) {
  
        bias_energy += replicas[ir]->hills_energy->value(curr_bin);
        if (cvm::debug()) {
       cvm::log("Metadynamics bias \""+this->name+"\""+       cvm::log("Metadynamics bias \""+this->name+"\""+
                ((comm != single_replica) ? ", replica \""+replica_id+"\"" : "")+                ((comm != single_replica) ? ", replica \""+replica_id+"\"" : "")+
                ": current coordinates on the grid: "+                ": current coordinates on the grid: "+
                cvm::to_str(curr_bin)+".\n");                cvm::to_str(curr_bin)+".\n");
          cvm::log("Grid energy = "+cvm::to_str(bias_energy)+".\n");
        }
      }
    } else {
      // off the grid: compute analytically only the hills at the grid's edges
      for (ir = 0; ir < replicas.size(); ir++) {
        calc_hills(replicas[ir]->hills_off_grid.begin(),
                   replicas[ir]->hills_off_grid.end(),
                   bias_energy,
                   values);
      }
    }
  
     if (hills_energy->index_ok(curr_bin)) {   // now include the hills that have not been binned yet (starting
    // from new_hills_begin)
  
    for (ir = 0; ir < replicas.size(); ir++) {
      calc_hills(replicas[ir]->new_hills_begin,
                 replicas[ir]->hills.end(),
                 bias_energy);
      if (cvm::debug()) {
        cvm::log("Hills energy = "+cvm::to_str(bias_energy)+".\n");
      }
    }
  
       // within the grid: add the energy and the forces from there   return COLVARS_OK;
  }
  
       bias_energy += hills_energy->value(curr_bin); 
       for (size_t ic = 0; ic < colvars.size(); ic++) { int colvarbias_meta::calc_forces(std::vector<colvarvalue> const &values)
         cvm::real const *f = &(hills_energy_gradients->value(curr_bin)); {
         colvar_forces[ic].real_value += -1.0 * f[ic];   size_t ir = 0, ic = 0;
         // the gradients are stored, not the forces   for (ir = 0; ir < replicas.size(); ir++) {
      for (ic = 0; ic < num_variables(); ic++) {
        replicas[ir]->colvar_forces[ic].reset();
       }       }
       if (comm == multiple_replicas)   }
         for (size_t ir = 0; ir < replicas.size(); ir++) { 
           bias_energy += replicas[ir]->hills_energy->value(curr_bin);   std::vector<int> const curr_bin = values.size() ?
      hills_energy->get_colvars_index(values) :
      hills_energy->get_colvars_index();
  
    if (hills_energy->index_ok(curr_bin)) {
      for (ir = 0; ir < replicas.size(); ir++) {
           cvm::real const *f = &(replicas[ir]->hills_energy_gradients->value(curr_bin));           cvm::real const *f = &(replicas[ir]->hills_energy_gradients->value(curr_bin));
           for (size_t ic = 0; ic < colvars.size(); ic++) {       for (ic = 0; ic < num_variables(); ic++) {
          // the gradients are stored, not the forces
             colvar_forces[ic].real_value += -1.0 * f[ic];             colvar_forces[ic].real_value += -1.0 * f[ic];
           }           }
         }         }
  
     } else {     } else {
  
       // off the grid: compute analytically only the hills at the grid's edges       // off the grid: compute analytically only the hills at the grid's edges
      for (ir = 0; ir < replicas.size(); ir++) {
       calc_hills(hills_off_grid.begin(), hills_off_grid.end(), bias_energy);       for (ic = 0; ic < num_variables(); ic++) {
       for (size_t ic = 0; ic < colvars.size(); ic++) { 
         calc_hills_force(ic, hills_off_grid.begin(), hills_off_grid.end(), colvar_forces); 
       } 
  
       if (comm == multiple_replicas) 
         for (size_t ir = 0; ir < replicas.size(); ir++) { 
           calc_hills(replicas[ir]->hills_off_grid.begin(), 
                      replicas[ir]->hills_off_grid.end(), 
                      bias_energy); 
           for (size_t ic = 0; ic < colvars.size(); ic++) { 
             calc_hills_force(ic,             calc_hills_force(ic,
                              replicas[ir]->hills_off_grid.begin(),                              replicas[ir]->hills_off_grid.begin(),
                              replicas[ir]->hills_off_grid.end(),                              replicas[ir]->hills_off_grid.end(),
                              colvar_forces);                          colvar_forces,
           }                          values);
         }         }
     }     }
   }   }
Line 568
Line 632
   // now include the hills that have not been binned yet (starting   // now include the hills that have not been binned yet (starting
   // from new_hills_begin)   // from new_hills_begin)
  
   calc_hills(new_hills_begin, hills.end(), bias_energy);   if (cvm::debug()) {
   for (size_t ic = 0; ic < colvars.size(); ic++) { 
     calc_hills_force(ic, new_hills_begin, hills.end(), colvar_forces); 
   } 
  
   if (cvm::debug()) 
     cvm::log("Hills energy = "+cvm::to_str(bias_energy)+ 
              ", hills forces = "+cvm::to_str(colvar_forces)+".\n"); 
  
   if (cvm::debug()) 
     cvm::log("Metadynamics bias \""+this->name+"\""+     cvm::log("Metadynamics bias \""+this->name+"\""+
              ((comm != single_replica) ? ", replica \""+replica_id+"\"" : "")+              ((comm != single_replica) ? ", replica \""+replica_id+"\"" : "")+
              ": adding the forces from the other replicas.\n");              ": adding the forces from the other replicas.\n");
    }
  
   if (comm == multiple_replicas)   for (ir = 0; ir < replicas.size(); ir++) {
     for (size_t ir = 0; ir < replicas.size(); ir++) {     for (ic = 0; ic < num_variables(); ic++) {
       calc_hills(replicas[ir]->new_hills_begin, 
                  replicas[ir]->hills.end(), 
                  bias_energy); 
       for (size_t ic = 0; ic < colvars.size(); ic++) { 
         calc_hills_force(ic,         calc_hills_force(ic,
                          replicas[ir]->new_hills_begin,                          replicas[ir]->new_hills_begin,
                          replicas[ir]->hills.end(),                          replicas[ir]->hills.end(),
                          colvar_forces);                        colvar_forces,
                         values);
        if (cvm::debug()) {
          cvm::log("Hills forces = "+cvm::to_str(colvar_forces)+".\n");
        }
       }       }
       if (cvm::debug()) 
         cvm::log("Hills energy = "+cvm::to_str(bias_energy)+ 
                  ", hills forces = "+cvm::to_str(colvar_forces)+".\n"); 
     }     }
  
   return COLVARS_OK;   return COLVARS_OK;
 } }
  
  
  
 void colvarbias_meta::calc_hills(colvarbias_meta::hill_iter      h_first, void colvarbias_meta::calc_hills(colvarbias_meta::hill_iter      h_first,
                                  colvarbias_meta::hill_iter      h_last,                                  colvarbias_meta::hill_iter      h_last,
                                  cvm::real                      &energy,                                  cvm::real                      &energy,
                                  std::vector<colvarvalue> const &colvar_values)                                  std::vector<colvarvalue> const &colvar_values)
 { {
   std::vector<colvarvalue> curr_values(colvars.size());   size_t i = 0;
   for (size_t i = 0; i < colvars.size(); i++) {   std::vector<colvarvalue> curr_values(num_variables());
     curr_values[i].type(colvars[i]->value());   for (i = 0; i < num_variables(); i++) {
      curr_values[i].type(variables(i)->value());
   }   }
  
   if (colvar_values.size()) {   if (colvar_values.size()) {
     for (size_t i = 0; i < colvars.size(); i++) {     for (i = 0; i < num_variables(); i++) {
       curr_values[i] = colvar_values[i];       curr_values[i] = colvar_values[i];
     }     }
   } else {   } else {
     for (size_t i = 0; i < colvars.size(); i++) {     for (i = 0; i < num_variables(); i++) {
       curr_values[i] = colvars[i]->value();       curr_values[i] = variables(i)->value();
     }     }
   }   }
  
Line 626
Line 681
  
     // compute the gaussian exponent     // compute the gaussian exponent
     cvm::real cv_sqdev = 0.0;     cvm::real cv_sqdev = 0.0;
     for (size_t i = 0; i < colvars.size(); i++) {     for (i = 0; i < num_variables(); i++) {
       colvarvalue const &x  = curr_values[i];       colvarvalue const &x  = curr_values[i];
       colvarvalue const &center = h->centers[i];       colvarvalue const &center = h->centers[i];
       cvm::real const    half_width = 0.5 * h->widths[i];       cvm::real const    half_width = 0.5 * h->widths[i];
       cv_sqdev += (colvars[i]->dist2(x, center)) / (half_width*half_width);       cv_sqdev += (variables(i)->dist2(x, center)) / (half_width*half_width);
     }     }
  
     // compute the gaussian     // compute the gaussian
Line 652
Line 707
                                        std::vector<colvarvalue> const &values)                                        std::vector<colvarvalue> const &values)
 { {
   // Retrieve the value of the colvar   // Retrieve the value of the colvar
   colvarvalue const x(values.size() ? values[i] : colvars[i]->value());   colvarvalue const x(values.size() ? values[i] : variables(i)->value());
  
   // do the type check only once (all colvarvalues in the hills series   // do the type check only once (all colvarvalues in the hills series
   // were already saved with their types matching those in the   // were already saved with their types matching those in the
   // colvars)   // colvars)
  
   hill_iter h;   hill_iter h;
   switch (colvars[i]->value().type()) {   switch (variables(i)->value().type()) {
  
   case colvarvalue::type_scalar:   case colvarvalue::type_scalar:
     for (h = h_first; h != h_last; h++) {     for (h = h_first; h != h_last; h++) {
Line 668
Line 723
       cvm::real const    half_width = 0.5 * h->widths[i];       cvm::real const    half_width = 0.5 * h->widths[i];
       forces[i].real_value +=       forces[i].real_value +=
         ( h->weight() * h->value() * (0.5 / (half_width*half_width)) *         ( h->weight() * h->value() * (0.5 / (half_width*half_width)) *
           (colvars[i]->dist2_lgrad(x, center)).real_value );           (variables(i)->dist2_lgrad(x, center)).real_value );
     }     }
     break;     break;
  
Line 681
Line 736
       cvm::real const    half_width = 0.5 * h->widths[i];       cvm::real const    half_width = 0.5 * h->widths[i];
       forces[i].rvector_value +=       forces[i].rvector_value +=
         ( h->weight() * h->value() * (0.5 / (half_width*half_width)) *         ( h->weight() * h->value() * (0.5 / (half_width*half_width)) *
           (colvars[i]->dist2_lgrad(x, center)).rvector_value );           (variables(i)->dist2_lgrad(x, center)).rvector_value );
     }     }
     break;     break;
  
Line 693
Line 748
       cvm::real const    half_width = 0.5 * h->widths[i];       cvm::real const    half_width = 0.5 * h->widths[i];
       forces[i].quaternion_value +=       forces[i].quaternion_value +=
         ( h->weight() * h->value() * (0.5 / (half_width*half_width)) *         ( h->weight() * h->value() * (0.5 / (half_width*half_width)) *
           (colvars[i]->dist2_lgrad(x, center)).quaternion_value );           (variables(i)->dist2_lgrad(x, center)).quaternion_value );
     }     }
     break;     break;
  
Line 704
Line 759
       cvm::real const    half_width = 0.5 * h->widths[i];       cvm::real const    half_width = 0.5 * h->widths[i];
       forces[i].vector1d_value +=       forces[i].vector1d_value +=
         ( h->weight() * h->value() * (0.5 / (half_width*half_width)) *         ( h->weight() * h->value() * (0.5 / (half_width*half_width)) *
           (colvars[i]->dist2_lgrad(x, center)).vector1d_value );           (variables(i)->dist2_lgrad(x, center)).vector1d_value );
     }     }
     break;     break;
  
Line 733
Line 788
  
   // TODO: improve it by looping over a small subgrid instead of the whole grid   // TODO: improve it by looping over a small subgrid instead of the whole grid
  
   std::vector<colvarvalue> colvar_values(colvars.size());   std::vector<colvarvalue> colvar_values(num_variables());
   std::vector<cvm::real> colvar_forces_scalar(colvars.size());   std::vector<cvm::real> colvar_forces_scalar(num_variables());
  
   std::vector<int> he_ix = he->new_index();   std::vector<int> he_ix = he->new_index();
   std::vector<int> hg_ix = (hg != NULL) ? hg->new_index() : std::vector<int> (0);   std::vector<int> hg_ix = (hg != NULL) ? hg->new_index() : std::vector<int> (0);
   cvm::real hills_energy_here = 0.0;   cvm::real hills_energy_here = 0.0;
   std::vector<colvarvalue> hills_forces_here(colvars.size(), 0.0);   std::vector<colvarvalue> hills_forces_here(num_variables(), 0.0);
  
   size_t count = 0;   size_t count = 0;
   size_t const print_frequency = ((hills.size() >= 1000000) ? 1 : (1000000/(hills.size()+1)));   size_t const print_frequency = ((hills.size() >= 1000000) ? 1 : (1000000/(hills.size()+1)));
Line 751
Line 806
           (he->index_ok(he_ix)) && (hg->index_ok(hg_ix));           (he->index_ok(he_ix)) && (hg->index_ok(hg_ix));
           count++) {           count++) {
       size_t i;       size_t i;
       for (i = 0; i < colvars.size(); i++) {       for (i = 0; i < num_variables(); i++) {
         colvar_values[i] = hills_energy->bin_to_value_scalar(he_ix[i], i);         colvar_values[i] = hills_energy->bin_to_value_scalar(he_ix[i], i);
       }       }
  
Line 760
Line 815
       calc_hills(h_first, h_last, hills_energy_here, colvar_values);       calc_hills(h_first, h_last, hills_energy_here, colvar_values);
       he->acc_value(he_ix, hills_energy_here);       he->acc_value(he_ix, hills_energy_here);
  
       for (i = 0; i < colvars.size(); i++) {       for (i = 0; i < num_variables(); i++) {
         hills_forces_here[i].reset();         hills_forces_here[i].reset();
         calc_hills_force(i, h_first, h_last, hills_forces_here, colvar_values);         calc_hills_force(i, h_first, h_last, hills_forces_here, colvar_values);
         colvar_forces_scalar[i] = hills_forces_here[i].real_value;         colvar_forces_scalar[i] = hills_forces_here[i].real_value;
Line 789
Line 844
  
     for ( ; (he->index_ok(he_ix)); ) {     for ( ; (he->index_ok(he_ix)); ) {
  
       for (size_t i = 0; i < colvars.size(); i++) {       for (size_t i = 0; i < num_variables(); i++) {
         colvar_values[i] = hills_energy->bin_to_value_scalar(he_ix[i], i);         colvar_values[i] = hills_energy->bin_to_value_scalar(he_ix[i], i);
       }       }
  
Line 845
Line 900
 // ********************************************************************** // **********************************************************************
  
  
  int colvarbias_meta::replica_share()
  {
    // sync with the other replicas (if needed)
    if (comm == multiple_replicas) {
      // reread the replicas registry
      update_replicas_registry();
      // empty the output buffer
      if (replica_hills_os.is_open())
        replica_hills_os.flush();
      read_replica_files();
    }
    return COLVARS_OK;
  }
  
  
 void colvarbias_meta::update_replicas_registry() void colvarbias_meta::update_replicas_registry()
 { {
   if (cvm::debug())   if (cvm::debug())
Line 969
Line 1039
     }     }
   }   }
  
  
   if (cvm::debug())   if (cvm::debug())
     cvm::log("Metadynamics bias \""+this->name+"\": the list of replicas contains "+     cvm::log("Metadynamics bias \""+this->name+"\": the list of replicas contains "+
              cvm::to_str(replicas.size())+" elements.\n");              cvm::to_str(replicas.size())+" elements.\n");
Line 978
Line 1047
  
 void colvarbias_meta::read_replica_files() void colvarbias_meta::read_replica_files()
 { {
   for (size_t ir = 0; ir < replicas.size(); ir++) {   // Note: we start from the 2nd replica.
    for (size_t ir = 1; ir < replicas.size(); ir++) {
  
     if (! (replicas[ir])->replica_state_file_in_sync) {     if (! (replicas[ir])->replica_state_file_in_sync) {
       // if a new state file is being read, the hills file is also new       // if a new state file is being read, the hills file is also new
Line 995
Line 1065
                (replicas[ir])->replica_state_file+"\".\n");                (replicas[ir])->replica_state_file+"\".\n");
  
       std::ifstream is((replicas[ir])->replica_state_file.c_str());       std::ifstream is((replicas[ir])->replica_state_file.c_str());
       if (! (replicas[ir])->read_restart(is)) {       if (! (replicas[ir])->read_state(is)) {
         cvm::log("Reading from file \""+(replicas[ir])->replica_state_file+         cvm::log("Reading from file \""+(replicas[ir])->replica_state_file+
                  "\" failed or incomplete: will try again in "+                  "\" failed or incomplete: will try again in "+
                  cvm::to_str(replica_update_freq)+" steps.\n");                  cvm::to_str(replica_update_freq)+" steps.\n");
Line 1091
Line 1161
 } }
  
  
 // ********************************************************************** int colvarbias_meta::set_state_params(std::string const &state_conf)
 // input functions 
 // ********************************************************************** 
  
  
 std::istream & colvarbias_meta::read_restart(std::istream& is) 
 { {
   size_t const start_pos = is.tellg();   std::string new_replica = "";
    if (colvarparse::get_keyval(state_conf, "replicaID", new_replica,
   if (comm == single_replica) { 
     // if using a multiple replicas scheme, output messages 
     // are printed before and after calling this function 
     cvm::log("Restarting metadynamics bias \""+this->name+"\""+ 
              ".\n"); 
   } 
   std::string key, brace, conf; 
   if ( !(is >> key)   || !(key == "metadynamics") || 
        !(is >> brace) || !(brace == "{") || 
        !(is >> colvarparse::read_block("configuration", conf)) ) { 
  
     if (comm == single_replica) 
       cvm::log("Error: in reading restart configuration for metadynamics bias \""+ 
                this->name+"\""+ 
                ((comm != single_replica) ? ", replica \""+replica_id+"\"" : "")+ 
                (replica_state_file_in_sync ? ("at position "+ 
                                               cvm::to_str(start_pos)+ 
                                               " in the state file") : "")+".\n"); 
     is.clear(); 
     is.seekg(start_pos, std::ios::beg); 
     is.setstate(std::ios::failbit); 
     return is; 
   } 
  
   std::string name = ""; 
   if ( colvarparse::get_keyval(conf, "name", name, 
                                std::string(""), colvarparse::parse_silent) &&                                std::string(""), colvarparse::parse_silent) &&
        (name != this->name) )       (new_replica != this->replica_id)) {
     cvm::fatal_error("Error: in the restart file, the "     cvm::error("Error: in the state file, the "
                      "\"metadynamics\" block has a different name: different system?\n");                "\"metadynamics\" block has a different replicaID: different system?\n",
                 INPUT_ERROR);
   if (name.size() == 0) {     return INPUT_ERROR;
     cvm::fatal_error("Error: \"metadynamics\" block within the restart file " 
                      "has no identifiers.\n"); 
   }   }
  
   if (comm != single_replica) {   return COLVARS_OK;
     std::string replica = ""; 
     if (colvarparse::get_keyval(conf, "replicaID", replica, 
                                 std::string(""), colvarparse::parse_silent) && 
         (replica != this->replica_id)) 
       cvm::fatal_error("Error: in the restart file, the " 
                        "\"metadynamics\" block has a different replicaID: different system?\n"); 
  
     colvarparse::get_keyval(conf, "step", state_file_step, 
                             cvm::step_absolute(), colvarparse::parse_silent); 
   }   }
  
  
  std::istream & colvarbias_meta::read_state_data(std::istream& is)
  {
   bool grids_from_restart_file = use_grids;   bool grids_from_restart_file = use_grids;
  
   if (use_grids) {   if (use_grids) {
Line 1178
Line 1209
     }     }
  
     size_t const hills_energy_pos = is.tellg();     size_t const hills_energy_pos = is.tellg();
      std::string key;
     if (!(is >> key)) {     if (!(is >> key)) {
       if (hills_energy_backup != NULL) {       if (hills_energy_backup != NULL) {
         delete hills_energy;         delete hills_energy;
Line 1339
Line 1371
     }     }
   }   }
  
   is >> brace; 
   if (brace != "}") { 
     cvm::log("Incomplete restart information for metadynamics bias \""+ 
              this->name+"\""+ 
              ((comm != single_replica) ? ", replica \""+replica_id+"\"" : "")+ 
              ": no closing brace at position "+ 
              cvm::to_str(is.tellg())+" in the file.\n"); 
     is.setstate(std::ios::failbit); 
     return is; 
   } 
  
   if (cvm::debug())   if (cvm::debug())
     cvm::log("colvarbias_meta::read_restart() done\n");     cvm::log("colvarbias_meta::read_restart() done\n");
  
Line 1395
Line 1416
   cvm::real h_weight;   cvm::real h_weight;
   get_keyval(data, "weight", h_weight, hill_weight, parse_silent);   get_keyval(data, "weight", h_weight, hill_weight, parse_silent);
  
   std::vector<colvarvalue> h_centers(colvars.size());   std::vector<colvarvalue> h_centers(num_variables());
   for (size_t i = 0; i < colvars.size(); i++) {   for (size_t i = 0; i < num_variables(); i++) {
     h_centers[i].type(colvars[i]->value());     h_centers[i].type(variables(i)->value());
   }   }
   {   {
     // it is safer to read colvarvalue objects one at a time;     // it is safer to read colvarvalue objects one at a time;
Line 1405
Line 1426
     std::string centers_input;     std::string centers_input;
     key_lookup(data, "centers", centers_input);     key_lookup(data, "centers", centers_input);
     std::istringstream centers_is(centers_input);     std::istringstream centers_is(centers_input);
     for (size_t i = 0; i < colvars.size(); i++) {     for (size_t i = 0; i < num_variables(); i++) {
       centers_is >> h_centers[i];       centers_is >> h_centers[i];
     }     }
   }   }
  
   std::vector<cvm::real> h_widths(colvars.size());   std::vector<cvm::real> h_widths(num_variables());
   get_keyval(data, "widths", h_widths,   get_keyval(data, "widths", h_widths,
              std::vector<cvm::real> (colvars.size(), (std::sqrt(2.0 * PI) / 2.0)),              std::vector<cvm::real>(num_variables(), (std::sqrt(2.0 * PI) / 2.0)),
              parse_silent);              parse_silent);
  
   std::string h_replica = "";   std::string h_replica = "";
Line 1447
Line 1468
 } }
  
  
  
  
 // ********************************************************************** 
 // output functions 
 // ********************************************************************** 
  
  
 int colvarbias_meta::setup_output() int colvarbias_meta::setup_output()
 { {
    output_prefix = cvm::output_prefix();
    if (cvm::num_biases_feature(colvardeps::f_cvb_calc_pmf) > 1) {
      // if this is not the only free energy integrator, append
      // this bias's name, to distinguish it from the output of the other
      // biases producing a .pmf file
      output_prefix += ("."+this->name);
    }
  
   if (comm == multiple_replicas) {   if (comm == multiple_replicas) {
  
Line 1471
Line 1492
     // those by another replica     // those by another replica
     replica_hills_file =     replica_hills_file =
       (std::string(pwd)+std::string(PATHSEP)+       (std::string(pwd)+std::string(PATHSEP)+
        cvm::output_prefix+".colvars."+this->name+"."+replica_id+".hills");        cvm::output_prefix()+".colvars."+this->name+"."+replica_id+".hills");
     replica_state_file =     replica_state_file =
       (std::string(pwd)+std::string(PATHSEP)+       (std::string(pwd)+std::string(PATHSEP)+
        cvm::output_prefix+".colvars."+this->name+"."+replica_id+".state");        cvm::output_prefix()+".colvars."+this->name+"."+replica_id+".state");
     delete[] pwd;     delete[] pwd;
  
     // now register this replica     // now register this replica
Line 1542
Line 1563
   }   }
  
   if (b_hills_traj) {   if (b_hills_traj) {
     std::string const traj_file_name(cvm::output_prefix+     std::string const traj_file_name(cvm::output_prefix()+
                                      ".colvars."+this->name+                                      ".colvars."+this->name+
                                      ( (comm != single_replica) ?                                      ( (comm != single_replica) ?
                                        ("."+replica_id) :                                        ("."+replica_id) :
                                        ("") )+                                        ("") )+
                                      ".hills.traj");                                      ".hills.traj");
     if (!hills_traj_os.is_open()) {     if (!hills_traj_os.is_open()) {
        cvm::backup_file(traj_file_name.c_str());
       hills_traj_os.open(traj_file_name.c_str());       hills_traj_os.open(traj_file_name.c_str());
     }     }
     if (!hills_traj_os.is_open())     if (!hills_traj_os.is_open())
Line 1560
Line 1582
 } }
  
  
 std::ostream & colvarbias_meta::write_restart(std::ostream& os) std::string const colvarbias_meta::get_state_params() const
 { {
   os << "metadynamics {\n"   std::ostringstream os;
      << "  configuration {\n" 
      << "    step " << cvm::step_absolute() << "\n" 
      << "    name " << this->name << "\n"; 
   if (this->comm != single_replica)   if (this->comm != single_replica)
     os << "    replicaID " << this->replica_id << "\n";     os << "    replicaID " << this->replica_id << "\n";
   os << "  }\n\n";   return (colvarbias::get_state_params() + os.str());
  }
  
  
  std::ostream & colvarbias_meta::write_state_data(std::ostream& os)
  {
   if (use_grids) {   if (use_grids) {
  
     // this is a very good time to project hills, if you haven't done     // this is a very good time to project hills, if you haven't done
Line 1601
Line 1624
     }     }
   }   }
  
   os << "}\n\n";   return os;
  }
  
  
  int colvarbias_meta::write_state_to_replicas()
  {
   if (comm != single_replica) {   if (comm != single_replica) {
     write_replica_state_file();     write_replica_state_file();
     // schedule to reread the state files of the other replicas (they     // schedule to reread the state files of the other replicas (they
Line 1611
Line 1638
       (replicas[ir])->replica_state_file_in_sync = false;       (replicas[ir])->replica_state_file_in_sync = false;
     }     }
   }   }
    return COLVARS_OK;
  }
  
  
  int colvarbias_meta::write_output_files()
  {
   if (dump_fes) {   if (dump_fes) {
     write_pmf();     write_pmf();
   }   }
    return COLVARS_OK;
   return os; 
 } }
  
  
Line 1626
Line 1657
   colvar_grid_scalar *pmf = new colvar_grid_scalar(*hills_energy);   colvar_grid_scalar *pmf = new colvar_grid_scalar(*hills_energy);
   pmf->setup();   pmf->setup();
  
   std::string fes_file_name_prefix(cvm::output_prefix); 
  
   if ((cvm::n_meta_biases > 1) || (cvm::n_abf_biases > 0)) { 
     // if this is not the only free energy integrator, append 
     // this bias's name, to distinguish it from the output of the other 
     // biases producing a .pmf file 
     // TODO: fix for ABF with updateBias == no 
     fes_file_name_prefix += ("."+this->name); 
   } 
  
   if ((comm == single_replica) || (dump_replica_fes)) {   if ((comm == single_replica) || (dump_replica_fes)) {
     // output the PMF from this instance or replica     // output the PMF from this instance or replica
     pmf->reset();     pmf->reset();
Line 1648
Line 1669
       pmf->multiply_constant(well_temper_scale);       pmf->multiply_constant(well_temper_scale);
     }     }
     {     {
       std::string const fes_file_name(fes_file_name_prefix +       std::string const fes_file_name(this->output_prefix +
                                       ((comm != single_replica) ? ".partial" : "") +                                       ((comm != single_replica) ? ".partial" : "") +
                                       (dump_fes_save ?                                       (dump_fes_save ?
                                        "."+cvm::to_str(cvm::step_absolute()) : "") +                                        "."+cvm::to_str(cvm::step_absolute()) : "") +
Line 1673
Line 1694
       cvm::real const well_temper_scale = (bias_temperature + cvm::temperature()) / bias_temperature;       cvm::real const well_temper_scale = (bias_temperature + cvm::temperature()) / bias_temperature;
       pmf->multiply_constant(well_temper_scale);       pmf->multiply_constant(well_temper_scale);
     }     }
     std::string const fes_file_name(fes_file_name_prefix +     std::string const fes_file_name(this->output_prefix +
                                     (dump_fes_save ?                                     (dump_fes_save ?
                                      "."+cvm::to_str(cvm::step_absolute()) : "") +                                      "."+cvm::to_str(cvm::step_absolute()) : "") +
                                     ".pmf");                                     ".pmf");
Line 1688
Line 1709
  
  
  
 void colvarbias_meta::write_replica_state_file() int colvarbias_meta::write_replica_state_file()
 { {
   // write down also the restart for the other replicas: TODO: this   if (cvm::debug()) {
   // is duplicated code, that could be cleaned up later     cvm::log("Writing replica state file for bias \""+name+"\"\n");
   cvm::backup_file(replica_state_file.c_str()); 
   cvm::ofstream rep_state_os(replica_state_file.c_str()); 
   if (!rep_state_os.is_open()) 
     cvm::fatal_error("Error: in opening file \""+ 
                      replica_state_file+"\" for writing.\n"); 
  
   rep_state_os.setf(std::ios::scientific, std::ios::floatfield); 
   rep_state_os << "\n" 
                << "metadynamics {\n" 
                << "  configuration {\n" 
                << "    name " << this->name << "\n" 
                << "    step " << cvm::step_absolute() << "\n"; 
   if (this->comm != single_replica) { 
     rep_state_os << "    replicaID " << this->replica_id << "\n"; 
   } 
   rep_state_os << "  }\n\n"; 
   rep_state_os << "  hills_energy\n"; 
   rep_state_os << std::setprecision(cvm::cv_prec) 
                << std::setw(cvm::cv_width); 
   hills_energy->write_restart(rep_state_os); 
   rep_state_os << "  hills_energy_gradients\n"; 
   rep_state_os << std::setprecision(cvm::cv_prec) 
                << std::setw(cvm::cv_width); 
   hills_energy_gradients->write_restart(rep_state_os); 
  
   if ( (!use_grids) || keep_hills ) { 
     // write all hills currently in memory 
     for (std::list<hill>::const_iterator h = this->hills.begin(); 
          h != this->hills.end(); 
          h++) { 
       rep_state_os << *h; 
     } 
   } else { 
     // write just those that are near the grid boundaries 
     for (std::list<hill>::const_iterator h = this->hills_off_grid.begin(); 
          h != this->hills_off_grid.end(); 
          h++) { 
       rep_state_os << *h; 
     }     }
    // write down also the restart for the other replicas
    cvm::backup_file(replica_state_file.c_str());
    std::ostream *rep_state_os = cvm::proxy->output_stream(replica_state_file);
    if (rep_state_os == NULL) {
      cvm::error("Error: in opening file \""+
                 replica_state_file+"\" for writing.\n", FILE_ERROR);
      return FILE_ERROR;
   }   }
  
   rep_state_os << "}\n\n";   rep_state_os->setf(std::ios::scientific, std::ios::floatfield);
   rep_state_os.close(); 
    if (!write_state(*rep_state_os)) {
      cvm::error("Error: in writing to file \""+
                 replica_state_file+"\".\n", FILE_ERROR);
      cvm::proxy->close_output_stream(replica_state_file);
      return FILE_ERROR;
    }
  
    cvm::proxy->close_output_stream(replica_state_file);
  
    // rep_state_os.setf(std::ios::scientific, std::ios::floatfield);
    // rep_state_os << "\n"
    //              << "metadynamics {\n"
    //              << "  configuration {\n"
    //              << "    name " << this->name << "\n"
    //              << "    step " << cvm::step_absolute() << "\n";
    // if (this->comm != single_replica) {
    //   rep_state_os << "    replicaID " << this->replica_id << "\n";
    // }
    // rep_state_os << "  }\n\n";
    // rep_state_os << "  hills_energy\n";
    // rep_state_os << std::setprecision(cvm::cv_prec)
    //              << std::setw(cvm::cv_width);
    // hills_energy->write_restart(rep_state_os);
    // rep_state_os << "  hills_energy_gradients\n";
    // rep_state_os << std::setprecision(cvm::cv_prec)
    //              << std::setw(cvm::cv_width);
    // hills_energy_gradients->write_restart(rep_state_os);
  
    // if ( (!use_grids) || keep_hills ) {
    //   // write all hills currently in memory
    //   for (std::list<hill>::const_iterator h = this->hills.begin();
    //        h != this->hills.end();
    //        h++) {
    //     rep_state_os << *h;
    //   }
    // } else {
    //   // write just those that are near the grid boundaries
    //   for (std::list<hill>::const_iterator h = this->hills_off_grid.begin();
    //        h != this->hills_off_grid.end();
    //        h++) {
    //     rep_state_os << *h;
    //   }
    // }
    // rep_state_os << "}\n\n";
    // rep_state_os.close();
  
   // reopen the hills file   // reopen the hills file
   replica_hills_os.close();   replica_hills_os.close();
Line 1744
Line 1779
     cvm::fatal_error("Error: in opening file \""+     cvm::fatal_error("Error: in opening file \""+
                      replica_hills_file+"\" for writing.\n");                      replica_hills_file+"\" for writing.\n");
   replica_hills_os.setf(std::ios::scientific, std::ios::floatfield);   replica_hills_os.setf(std::ios::scientific, std::ios::floatfield);
  
    return COLVARS_OK;
 } }
  
  
 std::string colvarbias_meta::hill::output_traj() std::string colvarbias_meta::hill::output_traj()
 { {
   std::ostringstream os;   std::ostringstream os;


Legend:
Removed in v.1.21 
changed lines
 Added in v.1.22



Made by using version 1.53 of cvs2html