Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Class Members | File Members

colvarbias.C

Go to the documentation of this file.
00001 #include "colvarmodule.h"
00002 #include "colvarvalue.h"
00003 #include "colvarbias.h"
00004 
00005 
00006 colvarbias::colvarbias (std::string const &conf, char const *key)
00007   : colvarparse()
00008 {
00009   cvm::log ("Initializing a new \""+std::string (key)+"\" instance.\n");
00010 
00011   size_t rank = 1;
00012   std::string const key_str (key);
00013 
00014   if (colvarparse::to_lower_cppstr (key_str) == std::string ("abf")) {
00015     rank = cvm::n_abf_biases+1;
00016   }
00017   if (colvarparse::to_lower_cppstr (key_str) == std::string ("harmonic")) {
00018     rank = cvm::n_harm_biases+1;
00019   }
00020   if (colvarparse::to_lower_cppstr (key_str) == std::string ("histogram")) {
00021     rank = cvm::n_histo_biases+1;
00022   }
00023   if (colvarparse::to_lower_cppstr (key_str) == std::string ("metadynamics")) {
00024     rank = cvm::n_meta_biases+1;
00025   }
00026 
00027   get_keyval (conf, "name", name, key_str+cvm::to_str (rank));
00028 
00029   // lookup the associated colvars
00030   std::vector<std::string> colvars_str;
00031   if (get_keyval (conf, "colvars", colvars_str)) {
00032     for (size_t i = 0; i < colvars_str.size(); i++) {
00033       add_colvar (colvars_str[i]);
00034     }
00035   }
00036 
00037   if (!colvars.size()) {
00038     cvm::fatal_error ("Error: no collective variables specified.\n");
00039   }
00040 }
00041 
00042 
00043 void colvarbias::add_colvar (std::string const &cv_name)
00044 {
00045   if (colvar *cvp = cvm::colvar_p (cv_name)) {
00046     cvp->enable (colvar::task_gradients);
00047     if (cvm::debug())
00048       cvm::log ("Applying this bias to collective variable \""+
00049                 cvp->name+"\".\n"); 
00050     colvars.push_back (cvp);
00051     colvar_forces.push_back (colvarvalue (cvp->type()));
00052   } else {
00053     cvm::fatal_error ("Error: cannot find a colvar named \""+
00054                       cv_name+"\".\n");
00055   }
00056 }
00057 
00058 
00059 void colvarbias::communicate_forces()
00060 {
00061   for (size_t i = 0; i < colvars.size(); i++) {
00062     if (cvm::debug()) {
00063       cvm::log ("Communicating a force to colvar \""+
00064                 colvars[i]->name+"\", of type \""+
00065                 colvarvalue::type_desc[colvars[i]->type()]+"\".\n");
00066     }
00067     colvars[i]->add_bias_force (colvar_forces[i]);
00068   }
00069 }    
00070 
00071 
00072 
00073 colvarbias_harmonic::colvarbias_harmonic (std::string const &conf,
00074                                           char const *key)
00075   : colvarbias (conf, key), 
00076     force_k_target_nsteps (0), targets_nsteps (0)
00077 {
00078   get_keyval (conf, "forceConstant", force_k, 1.0);
00079   for (size_t i = 0; i < colvars.size(); i++) {
00080     if (colvars[i]->width != 1.0)
00081       cvm::log ("The force constant for colvar \""+colvars[i]->name+
00082                 "\" will be rescaled to "+
00083                 cvm::to_str (force_k/(colvars[i]->width*colvars[i]->width))+
00084                 " according to the specified width.\n");
00085   }
00086 
00087   // get the initial restraint centers
00088   colvar_centers.resize (colvars.size());
00089   for (size_t i = 0; i < colvars.size(); i++) {
00090     colvar_centers[i].type (colvars[i]->type());
00091   }
00092   if (get_keyval (conf, "centers", colvar_centers, colvar_centers)) {
00093     for (size_t i = 0; i < colvars.size(); i++) {
00094       colvar_centers[i].apply_constraints();
00095     }
00096   } else {
00097     colvar_centers.clear();
00098     cvm::fatal_error ("Error: must define the initial centers of the restraints.\n");
00099   }
00100 
00101   if (colvar_centers.size() != colvars.size())
00102     cvm::fatal_error ("Error: number of harmonic centers does not match "
00103                       "that of collective variables.\n");
00104 
00105   //   colvar_targets.resize (colvars.size());
00106   //   for (size_t i = 0; i < colvars.size(); i++) {
00107   //     colvar_targets[i].type (colvars[i]->type());
00108   //   }
00109   colvar_targets = colvar_centers;
00110   if (get_keyval (conf, "targets", colvar_targets, colvar_targets)) {
00111 
00112     for (size_t i = 0; i < colvar_targets.size(); i++) {
00113       colvar_targets[i].apply_constraints();
00114     }
00115 
00116     get_keyval (conf, "targetsNumSteps", targets_nsteps, 0);
00117     if (!targets_nsteps)
00118       cvm::fatal_error ("Error: the number of steps for moving "
00119                         "the restraint centers must be non-zero.\n");
00120   } else {
00121     colvar_targets.clear();
00122   }
00123 
00124   if (get_keyval (conf, "forceConstantTarget", force_k_target, 0.0)) {
00125     get_keyval (conf, "forceConstantTargetNumSteps", force_k_target_nsteps, 1000);
00126     if (!force_k_target_nsteps)
00127       cvm::fatal_error ("Error: the number of steps for changing "
00128                         "the force constant must be non-zero.\n");
00129   }
00130 
00131   if (cvm::debug())
00132     cvm::log ("Done initializing a new harmonic restraint bias.\n");
00133 }
00134 
00135 
00136 void colvarbias_harmonic::update()
00137 {
00138   if (cvm::debug())
00139     cvm::log ("Updating the harmonic bias \""+this->name+"\".\n");
00140   
00141   for (size_t i = 0; i < colvars.size(); i++) {
00142     colvar_forces[i] =
00143       (-0.5) * force_k /
00144       (colvars[i]->width * colvars[i]->width) *
00145       colvars[i]->dist2_lgrad (colvars[i]->value(),
00146                                colvar_centers[i]);
00147     if (cvm::debug())
00148       cvm::log ("dist_grad["+cvm::to_str (i)+
00149                 "] = "+cvm::to_str (colvars[i]->dist2_lgrad (colvars[i]->value(),
00150                                colvar_centers[i]))+"\n");
00151   }
00152 
00153   if (cvm::debug())
00154     cvm::log ("Current forces for the harmonic bias \""+
00155               this->name+"\": "+cvm::to_str (colvar_forces)+".\n");
00156 
00157   if (targets_nsteps) {
00158 
00159     if (!target_steps.size()) {
00160       // if this is the first calculation, calculate the advancement
00161       // at each simulation step
00162       target_steps.resize (colvars.size());
00163       for (size_t i = 0; i < colvars.size(); i++) {
00164         target_steps[i] = (::sqrt (colvars[i]->dist2 (colvar_centers[i],
00165                                                       colvar_targets[i]))) /
00166           cvm::real (targets_nsteps - cvm::step_absolute());
00167       }
00168       if (cvm::debug())
00169         cvm::log ("Center movements for the harmonic bias \""+
00170                   this->name+"\": "+cvm::to_str (target_steps)+".\n");
00171     }
00172 
00173     if (cvm::debug())
00174       cvm::log ("Current centers for the harmonic bias \""+
00175                 this->name+"\": "+cvm::to_str (colvar_centers)+".\n");
00176 
00177     if (cvm::step_absolute() < targets_nsteps) {
00178       // move the restraint centers in the direction of the targets
00179       for (size_t i = 0; i < colvars.size(); i++) {
00180         colvarvalue const d2grad =
00181           colvars[i]->dist2_lgrad (colvar_centers[i],
00182                                    colvar_targets[i]);
00183         colvar_centers[i] += target_steps[i] * (-1.0/d2grad.norm()) * d2grad;
00184         colvar_centers[i].apply_constraints();
00185       }
00186     }
00187   }
00188 
00189   if (cvm::debug())
00190     cvm::log ("Done updating the harmonic bias \""+this->name+"\".\n");
00191 }
00192 
00193 
00194 std::istream & colvarbias_harmonic::read_restart (std::istream &is)
00195 {
00196   size_t const start_pos = is.tellg();
00197 
00198   cvm::log ("Restarting harmonic bias \""+
00199             this->name+"\".\n");
00200 
00201   std::string key, brace, conf;
00202   if ( !(is >> key)   || !(key == "harmonic") ||
00203        !(is >> brace) || !(brace == "{") ||
00204        !(is >> colvarparse::read_block ("configuration", conf)) ) {
00205 
00206     cvm::log ("Error: in reading restart configuration for harmonic bias \""+
00207               this->name+"\" at position "+
00208               cvm::to_str (is.tellg())+" in stream.\n");
00209     is.clear();
00210     is.seekg (start_pos, std::ios::beg);
00211     is.setstate (std::ios::failbit);
00212     return is;
00213   }
00214 
00215 //   int id = -1; 
00216   std::string name = "";
00217 //   if ( ( (colvarparse::get_keyval (conf, "id", id, -1, colvarparse::parse_silent)) &&
00218 //          (id != this->id) ) ||
00219   if ( (colvarparse::get_keyval (conf, "name", name, std::string (""), colvarparse::parse_silent)) &&
00220        (name != this->name) )
00221     cvm::fatal_error ("Error: in the restart file, the "
00222                       "\"harmonic\" block has a wrong name\n");
00223 //   if ( (id == -1) && (name == "") ) {
00224   if (name.size() == 0) {
00225     cvm::fatal_error ("Error: \"harmonic\" block in the restart file "
00226                       "has no identifiers.\n");
00227   }
00228 
00229   if (targets_nsteps) {
00230     cvm::log ("Reading the updated restraint centers from the restart.\n");
00231     if (!get_keyval (conf, "centers", colvar_centers))
00232       cvm::fatal_error ("Error: restraint centers are missing in the restart.\n");
00233   }
00234 
00235   if (force_k_target_nsteps) {
00236     cvm::log ("Reading the updated force constant from the restart.\n");
00237     if (!get_keyval (conf, "forceConstant", force_k))
00238       cvm::fatal_error ("Error: force cosntant is missing in the restart.\n");
00239   }
00240 
00241   is >> brace;
00242   if (brace != "}") {
00243     cvm::fatal_error ("Error: corrupt restart information for harmonic bias \""+
00244                       this->name+"\": no matching brace at position "+
00245                       cvm::to_str (is.tellg())+" in the restart file.\n");
00246     is.setstate (std::ios::failbit);
00247   }
00248   return is;
00249 }
00250 
00251 
00252 std::ostream & colvarbias_harmonic::write_restart (std::ostream &os)
00253 {
00254   os << "harmonic {\n"
00255      << "  configuration {\n"
00256     //      << "    id " << this->id << "\n"
00257      << "    name " << this->name << "\n";
00258 
00259   if (targets_nsteps) {
00260     os << "    centers ";
00261     for (size_t i = 0; i < colvars.size(); i++) {
00262       os << " " << colvar_centers[i];
00263     }
00264     os << "\n";
00265   }
00266 
00267   if (force_k_target_nsteps) {
00268     os << "    forceConstant "
00269        << std::setprecision (cvm::en_prec)
00270        << std::setw (cvm::en_width) << force_k << "\n";
00271   }
00272 
00273   os << "  }\n"
00274      << "}\n\n";
00275 
00276   return os;
00277 }
00278 

Generated on Mon Nov 23 04:59:18 2009 for NAMD by  doxygen 1.3.9.1