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

colvar.C

Go to the documentation of this file.
00001 // -*- c++ -*-
00002 
00003 #include "colvarmodule.h"
00004 #include "colvarvalue.h"
00005 #include "colvarparse.h"
00006 #include "colvar.h"
00007 #include "colvarcomp.h"
00008 
00009 
00010 // XX TODO make the acf code handle forces as well as values and velocities
00011 
00012 
00013 colvar::colvar (std::string const &conf)
00014 {
00015   cvm::log ("Initializing a new collective variable.\n");
00016   
00017   get_keyval (conf, "name", this->name,
00018               (std::string ("colvar")+cvm::to_str (cvm::colvars.size()+1)));
00019 
00020   for (std::vector<colvar *>::iterator cvi = cvm::colvars.begin();
00021        cvi < cvm::colvars.end();
00022        cvi++) {
00023     if ((*cvi)->name == this->name)
00024       cvm::fatal_error ("Error: this colvar has the same name, \""+this->name+
00025                         "\", of another colvar.\n");
00026   }
00027 
00028   // all tasks disabled by default 
00029   for (size_t i = 0; i < task_ntot; i++) {
00030     tasks[i] = false;
00031   }
00032 
00033   // read the configuration and set up corresponding instances, for
00034   // each type of forcepar implemented
00035 #define initialize_forcepars(def_desc,def_config_key,def_class_name)    \
00036   {                                                                     \
00037     size_t def_count = 0;                                               \
00038     std::string def_conf = "";                                          \
00039     size_t pos = 0;                                                     \
00040     while ( this->key_lookup (conf,                                     \
00041                               def_config_key,                           \
00042                               def_conf,                                 \
00043                               pos) ) {                                  \
00044       if (!def_conf.size()) continue;                                   \
00045       cvm::log ("Initializing "                                         \
00046                 "a new \""+std::string (def_desc)+"\" component"+       \
00047                 (cvm::debug() ? ", with configuration:\n"+def_conf      \
00048                  : ".\n"));                                             \
00049       cvm::increase_depth();                                            \
00050       cvc *cvdp = new colvar::def_class_name (def_conf);                \
00051       cvdp->check_keywords (def_conf, def_config_key);                  \
00052       cvm::decrease_depth();                                            \
00053       if (cvdp != NULL)                                                 \
00054         cvcs.push_back (cvdp);                                          \
00055       else cvm::fatal_error ("Error: in allocating component \""        \
00056                              def_config_key"\".\n");                    \
00057       if ( ! cvcs.back()->name.size())                                  \
00058         cvcs.back()->name = std::string (def_config_key)+               \
00059           (cvm::to_str (++def_count));                                  \
00060       if (cvm::debug())                                                 \
00061         cvm::log ("Done initializing a component of type \""+           \
00062                   std::string (def_desc)+"\""+                          \
00063                   (cvm::debug() ?                                       \
00064                    ", named \""+cvcs.back()->name+"\""                  \
00065                    : "")+".\n");                                        \
00066       def_conf = "";                                                    \
00067       if (cvm::debug())                                                 \
00068         cvm::log ("Parsed "+cvm::to_str (cvcs.size())+                  \
00069                   " components at this time.\n");                       \
00070     }                                                                   \
00071   }
00072 
00073 
00074   initialize_forcepars ("distance",         "distance",       distance);
00075   //   initialize_forcepars ("distance vector",  "distanceVec",    distance_vec);
00076   initialize_forcepars ("distance vector "
00077                         "direction",        "distanceDir",    distance_dir);
00078   initialize_forcepars ("distance projection "
00079                         "on an axis",       "distanceZ",      distance_z);
00080   initialize_forcepars ("distance projection "
00081                         "on a plane",       "distanceXY",     distance_xy);
00082   initialize_forcepars ("minimum distance", "minDistance",    min_distance);
00083 
00084   initialize_forcepars ("coordination "
00085                         "number",           "coordnum",       coordnum);
00086 
00087   initialize_forcepars ("angle",            "angle",          angle);
00088   initialize_forcepars ("dihedral",         "dihedral",       dihedral);
00089 
00090   initialize_forcepars ("hydrogen bond",    "hBond",          h_bond);
00091 
00092   initialize_forcepars ("alpha helix",      "alphaDihedrals", alpha_dihedrals);
00093   initialize_forcepars ("alpha helix",      "alpha",          alpha_angles);
00094 
00095   initialize_forcepars ("orientation",      "orientation",    orientation);
00096   initialize_forcepars ("orientation "
00097                         "angle",            "orientationAngle",orientation_angle);
00098 
00099   initialize_forcepars ("RMSD",             "rmsd",           rmsd);
00100 
00101   initialize_forcepars ("logarithm of MSD", "logmsd",         logmsd);
00102 
00103   initialize_forcepars ("radius of "
00104                         "gyration",         "gyration",       gyration);
00105   initialize_forcepars ("eigenvector",      "eigenvector",    eigenvector);
00106 
00107   if (!cvcs.size())
00108     cvm::fatal_error ("Error: no valid components were provided "
00109                       "for this collective variable.\n");
00110 
00111   cvm::log ("All components initialized.\n");
00112 
00113 
00114   // this is set false if any of the components has an exponent
00115   // different from 1 in the polynomial
00116   b_linear = true;
00117 
00118   // these will be set to false if any of the cvcs has them false
00119   b_inverse_gradients = true;
00120   b_Jacobian_force    = true;
00121 
00122   this->period = 0.0;
00123   b_periodic = false;
00124 
00125   // check the available features of each cvc
00126   for (size_t i = 0; i < cvcs.size(); i++) {
00127 
00128     if ((cvcs[i])->sup_np != 1) {
00129       if (cvm::debug() && b_linear)
00130         cvm::log ("Warning: You are using a non-linear polynomial "
00131                   "superposition to define this collective variable, "
00132                   "some biasing methods may be unavailable.\n");
00133       b_linear = false;
00134 
00135       if ((cvcs[i])->sup_np < 0) {
00136         cvm::log ("Warning: you chose a negative exponent in the superposition; "
00137                   "if you apply forces, the simulation may become unstable "
00138                   "when the component \""+
00139                   (cvcs[i])->function_type+"\" approaches zero.\n");
00140       }
00141     }
00142 
00143 
00144     this->b_periodic = (cvcs[i])->b_periodic;
00145     this->period = (cvcs[i])->period;
00146 
00147     if (this->b_periodic && (cvcs.size() > 1)) {
00148       cvm::fatal_error ("Error: superposition of periodic "
00149                         "components is unsupported.\n");
00150     }
00151 
00152     if (! (cvcs[i])->b_inverse_gradients)
00153       b_inverse_gradients = false;
00154 
00155     if (! (cvcs[i])->b_Jacobian_derivative)
00156       b_Jacobian_force = false;
00157 
00158     for (size_t j = i; j < cvcs.size(); j++) {
00159       if ( (cvcs[i])->type() != (cvcs[j])->type() ) {
00160         cvm::fatal_error ("ERROR: you are definining this collective variable "
00161                           "by using components of different types, \""+
00162                           colvarvalue::type_desc[(cvcs[i])->type()]+
00163                           "\" and \""+
00164                           colvarvalue::type_desc[(cvcs[j])->type()]+
00165                           "\". "
00166                           "You must use the same type in order to "
00167                           " sum them together.\n");
00168       }
00169     }
00170   }
00171 
00172   {
00173     colvarvalue::Type const value_type = (cvcs[0])->type();
00174     if (cvm::debug())
00175       cvm::log ("This collective variable is a "+
00176                 colvarvalue::type_desc[value_type]+", corresponding to "+
00177                 cvm::to_str (colvarvalue::dof_num[value_type])+
00178                 " internal degrees of freedom.\n");
00179     x.type (value_type);
00180     x_reported.type (value_type);
00181   }
00182 
00183   get_keyval (conf, "width", width, 1.0);
00184   if (width <= 0.0)
00185     cvm::fatal_error ("Error: \"width\" must be positive.\n");
00186 
00187   lower_boundary.type (this->type());
00188   lower_wall.type     (this->type());
00189 
00190   upper_boundary.type (this->type());
00191   upper_wall.type     (this->type());
00192 
00193   if (this->type() == colvarvalue::type_scalar) {
00194 
00195     if (get_keyval (conf, "lowerBoundary", lower_boundary, lower_boundary)) {
00196       enable (task_lower_boundary);
00197     }
00198 
00199     get_keyval (conf, "lowerWallConstant", lower_wall_k, 0.0);
00200     if (lower_wall_k > 0.0) {
00201       get_keyval (conf, "lowerWall", lower_wall, lower_boundary);
00202       enable (task_lower_wall);
00203     }
00204 
00205     if (get_keyval (conf, "upperBoundary", upper_boundary, upper_boundary)) {
00206       enable (task_upper_boundary);
00207     }
00208 
00209     get_keyval (conf, "upperWallConstant", upper_wall_k, 0.0);
00210     if (upper_wall_k > 0.0) {
00211       get_keyval (conf, "upperWall", upper_wall, upper_boundary);
00212       enable (task_upper_wall);
00213     }
00214   }
00215 
00216   // consistency checks for boundaries and walls
00217   if (tasks[task_lower_boundary] && tasks[task_upper_boundary]) {
00218     if (lower_boundary >= upper_boundary) {
00219       cvm::fatal_error ("Error: the upper boundary, "+
00220                         cvm::to_str (upper_boundary)+
00221                         ", is not higher than the lower boundary, "+
00222                         cvm::to_str (lower_boundary)+".\n");
00223     }
00224   }
00225 
00226   if (tasks[task_lower_wall] && tasks[task_upper_wall]) {
00227     if (lower_wall >= upper_wall) {
00228       cvm::fatal_error ("Error: the upper wall, "+
00229                         cvm::to_str (upper_wall)+
00230                         ", is not higher than the lower wall, "+
00231                         cvm::to_str (lower_wall)+".\n");
00232     }
00233 
00234     if (dist2 (lower_wall, upper_wall) < 1.0E-12) {
00235       cvm::log ("Lower wall and upper wall are equal "
00236                 "in the periodic domain of the colvar: disabling walls.\n");
00237       disable (task_lower_wall);
00238       disable (task_upper_wall);
00239     }
00240   }
00241 
00242   get_keyval (conf, "expandBoundaries", expand_boundaries, false);
00243   if (expand_boundaries && periodic_boundaries()) {
00244     cvm::fatal_error ("Error: trying to expand boundaries that already "
00245                       "cover a whole period of a periodic colvar.\n");
00246   }
00247 
00248   {
00249     bool b_extended_lagrangian;
00250     get_keyval (conf, "extendedLagrangian", b_extended_lagrangian, false);
00251 
00252     if (b_extended_lagrangian) {
00253 
00254       cvm::log ("Enabling the extended lagrangian term for colvar \""+
00255                 this->name+"\".\n");
00256     
00257       enable (task_extended_lagrangian);
00258 
00259       xr.type (this->type());
00260       vr.type (this->type());
00261       fr.type (this->type());
00262 
00263       get_keyval (conf, "extendedForceConstant", ext_force_k, 1.0);
00264       if (ext_force_k <= 0.0)
00265         cvm::fatal_error ("Error: \"extended_force_constant\" must be positive.\n");
00266 
00267       get_keyval (conf, "extendedFictitiousMass",   ext_mass, 1.0);
00268       if (ext_mass <= 0.0)
00269         cvm::fatal_error ("Error: \"extended_fictitious_mass\" must be positive.\n");
00270     }
00271   }
00272 
00273   //{
00274   //  bool b_jacobian_force;
00275   //  get_keyval (conf, "JacobianForce", b_jacobian_force, false);
00276   //  if (b_jacobian_force) {
00277   //    enable (task_Jacobian_force);
00278   //  }
00279   //}
00280 
00281   {
00282     bool b_output_value;
00283     get_keyval (conf, "outputValue", b_output_value, true);
00284     if (b_output_value) {
00285       enable (task_output_value);
00286     }
00287   }
00288 
00289   {
00290     bool b_output_velocity;
00291     get_keyval (conf, "outputVelocity", b_output_velocity, false);
00292     if (b_output_velocity) {
00293       enable (task_output_velocity);
00294     }
00295   }
00296 
00297   {
00298     bool b_output_system_force;
00299     get_keyval (conf, "outputSystemForce", b_output_system_force, false);
00300     if (b_output_system_force) {
00301       enable (task_output_system_force);
00302     }
00303   }
00304 
00305   {
00306     bool b_output_applied_force;
00307     get_keyval (conf, "outputAppliedForce", b_output_applied_force, false);
00308     if (b_output_applied_force) {
00309       enable (task_output_applied_force);
00310     }
00311   }
00312 
00313   if (cvm::b_analysis)
00314     parse_analysis (conf);
00315 
00316   if (cvm::debug())
00317     cvm::log ("Done initializing collective variable \""+this->name+"\".\n");
00318 }
00319 
00320 
00321 void colvar::parse_analysis (std::string const &conf)
00322 {
00323 
00324   //   if (cvm::debug())
00325   //     cvm::log ("Parsing analysis flags for collective variable \""+
00326   //               this->name+"\".\n");
00327 
00328   runave_length = 0;
00329   bool b_runave = false;
00330   if (get_keyval (conf, "runAve", b_runave) && b_runave) {
00331 
00332     enable (task_runave);
00333 
00334     get_keyval (conf, "runAveLength", runave_length, 1000);
00335     get_keyval (conf, "runAveStride", runave_stride, 1);
00336 
00337     if ((cvm::restart_out_freq % runave_stride) != 0)
00338       cvm::fatal_error ("Error: runAveStride must be commensurate with the restart frequency.\n");
00339 
00340     std::string runave_outfile;
00341     get_keyval (conf, "runAveOutputFile", runave_outfile,
00342                 std::string (cvm::output_prefix+"."+
00343                              this->name+".runave.traj"));
00344 
00345     size_t const this_cv_width = x.output_width (cvm::cv_width);
00346     runave_os.open (runave_outfile.c_str());
00347     runave_os << "# " << cvm::wrap_string ("step", cvm::it_width-2)
00348               << "  "
00349               << cvm::wrap_string ("running average", this_cv_width)
00350               << " "
00351               << cvm::wrap_string ("running stddev", this_cv_width)
00352               << "\n";
00353   }
00354 
00355   acf_length = 0;
00356   bool b_acf = false;
00357   if (get_keyval (conf, "corrFunc", b_acf) && b_acf) {
00358 
00359     enable (task_corrfunc);
00360 
00361     std::string acf_colvar_name;
00362     get_keyval (conf, "corrFuncWithColvar", acf_colvar_name, this->name);
00363     if (acf_colvar_name == this->name) {
00364       cvm::log ("Calculating auto-correlation function.\n");
00365     } else {
00366       cvm::log ("Calculating correlation function with \""+
00367                 this->name+"\".\n");
00368     }
00369 
00370     std::string acf_type_str;
00371     get_keyval (conf, "corrFuncType", acf_type_str, to_lower_cppstr (std::string ("velocity")));
00372     if (acf_type_str == to_lower_cppstr (std::string ("coordinate"))) {
00373       acf_type = acf_coor;
00374     } else if (acf_type_str == to_lower_cppstr (std::string ("velocity"))) {
00375       acf_type = acf_vel;
00376       enable (task_fdiff_velocity);
00377       if (acf_colvar_name.size())
00378         (cvm::colvar_p (acf_colvar_name))->enable (task_fdiff_velocity);
00379     } else if (acf_type_str == to_lower_cppstr (std::string ("coordinate_p2"))) {
00380       acf_type = acf_p2coor;
00381     } else {
00382       cvm::fatal_error ("Unknown type of correlation function, \""+
00383                         acf_type_str+"\".\n");
00384     }
00385 
00386     get_keyval (conf, "corrFuncOffset", acf_offset, 0);
00387     get_keyval (conf, "corrFuncLength", acf_length, 1000);
00388     get_keyval (conf, "corrFuncStride", acf_stride, 1);
00389 
00390     if ((cvm::restart_out_freq % acf_stride) != 0)
00391       cvm::fatal_error ("Error: corrFuncStride must be commensurate with the restart frequency.\n");
00392 
00393     get_keyval (conf, "corrFuncNormalize", acf_normalize, true);
00394     get_keyval (conf, "corrFuncOutputFile", acf_outfile,
00395                 std::string (cvm::output_prefix+"."+this->name+
00396                              ".corrfunc.dat"));
00397   }
00398 }
00399 
00400 
00401 void colvar::enable (colvar::task const &t)
00402 {
00403   switch (t) {
00404 
00405   case task_output_system_force:
00406     enable (task_system_force);
00407     break;
00408 
00409   case task_report_Jacobian_force:
00410     enable (task_Jacobian_force);
00411     enable (task_system_force);
00412     if (cvm::debug())
00413       cvm::log ("Adding the Jacobian force to the system force, "
00414                 "rather than applying its opposite silently.\n");
00415     break;
00416 
00417   case task_Jacobian_force:
00418     enable (task_gradients);
00419 
00420     if (!b_Jacobian_force) 
00421       cvm::fatal_error ("Error: colvar \""+this->name+
00422                         "\" does not have Jacobian forces implemented.\n");
00423     if (!b_linear) 
00424       cvm::fatal_error ("Error: colvar \""+this->name+
00425                         "\" must be defined as a linear superposition "
00426                         "to calculate the Jacobian force.\n");
00427     if (cvm::debug())
00428       cvm::log ("Enabling calculation of the Jacobian force "
00429                 "on this colvar.\n");
00430     fj.type (this->type());
00431     break;
00432 
00433   case task_system_force:
00434     if (!b_inverse_gradients)
00435       cvm::fatal_error ("Error: one or more of the components of "
00436                         "colvar \""+this->name+
00437                         "\" is unable to calculate system forces.\n");
00438     ft.type (this->type());
00439     ft_reported.type (this->type());
00440     break;
00441 
00442   case task_output_applied_force:
00443   case task_lower_wall:
00444   case task_upper_wall:
00445     // all of the above require gradients
00446     enable (task_gradients);
00447     break;
00448 
00449   case task_fdiff_velocity:
00450     x_old.type (this->type());
00451     v_fdiff.type (this->type());
00452     v_reported.type (this->type());
00453     break;
00454 
00455   case task_output_velocity:
00456     enable (task_fdiff_velocity);
00457     break;
00458 
00459   case task_grid:
00460     if (this->type() != colvarvalue::type_scalar)
00461       cvm::fatal_error ("Cannot calculate a grid for collective variable, \""+
00462                         this->name+"\", because its value is not a scalar number.\n");
00463     break;
00464 
00465   case task_extended_lagrangian:
00466     v_reported.type (this->type());
00467     break;
00468 
00469   case task_lower_boundary:
00470   case task_upper_boundary:
00471     if (this->type() != colvarvalue::type_scalar) {
00472       cvm::fatal_error ("Error: this colvar is not a scalar value "
00473                         "and cannot produce a grid.\n");
00474     }
00475     break;
00476 
00477 
00478   case task_output_value:
00479   case task_runave:
00480   case task_corrfunc:
00481   case task_ntot:
00482     break;
00483 
00484   case task_gradients:
00485     f.type  (this->type());
00486     fb.type (this->type());
00487     break;
00488   }
00489 
00490   tasks[t] = true;
00491 }
00492 
00493 
00494 void colvar::disable (colvar::task const &t)
00495 {
00496   // check dependencies
00497   switch (t) {
00498   case task_gradients:
00499     disable (task_upper_wall);
00500     disable (task_lower_wall);
00501     disable (task_output_applied_force);
00502     disable (task_system_force);
00503     disable (task_Jacobian_force);
00504     break;
00505 
00506   case task_system_force:
00507     disable (task_output_system_force);
00508     break;
00509 
00510   case task_Jacobian_force:
00511     disable (task_report_Jacobian_force);
00512     break;
00513 
00514   case task_fdiff_velocity:
00515     disable (task_output_velocity);
00516     break;
00517 
00518   case task_lower_boundary:
00519   case task_upper_boundary:
00520     disable (task_grid);
00521     break;
00522 
00523   case task_extended_lagrangian:
00524   case task_report_Jacobian_force:
00525   case task_output_value:
00526   case task_output_velocity:
00527   case task_output_applied_force:
00528   case task_output_system_force:
00529   case task_runave:
00530   case task_corrfunc:
00531   case task_grid:
00532   case task_lower_wall:
00533   case task_upper_wall:
00534   case task_ntot:
00535     break;
00536   }
00537 
00538   tasks[t] = false;
00539 }
00540 
00541 
00542 colvar::~colvar()
00543 {
00544   if (cvm::b_analysis) {
00545 
00546     if (acf.size()) {
00547       cvm::log ("Writing acf to file \""+acf_outfile+"\".\n");
00548 
00549       std::ofstream acf_os (acf_outfile.c_str());
00550       if (! acf_os.good())
00551         cvm::fatal_error ("Cannot open file \""+acf_outfile+"\".\n");
00552       write_acf (acf_os);
00553       acf_os.close();
00554     }
00555 
00556     if (runave_os.good()) {
00557       runave_os.close();
00558     }
00559   }
00560 
00561   for (size_t i = 0; i < cvcs.size(); i++) {
00562     delete cvcs[i];
00563   }
00564 }  
00565 
00566 
00567 
00568 // ******************** CALC FUNCTIONS ********************
00569 
00570 
00571 void colvar::calc()
00572 {
00573   if (cvm::debug())
00574     cvm::log ("Calculating colvar \""+this->name+"\".\n");
00575 
00576   // calculate the value of the colvar
00577 
00578   x.reset();
00579   if (x.type() == colvarvalue::type_scalar) {
00580 
00581     // scalar variable, polynomial superposition allowed
00582     for (size_t i = 0; i < cvcs.size(); i++) {
00583       cvm::increase_depth();
00584       (cvcs[i])->calc_value();
00585       cvm::decrease_depth();
00586       if (cvm::debug())
00587         cvm::log ("Colvar component no. "+cvm::to_str (i+1)+
00588                   " within colvar \""+this->name+"\" has value "+
00589                   cvm::to_str ((cvcs[i])->value(),
00590                                cvm::cv_width, cvm::cv_prec)+".\n");
00591       x += (cvcs[i])->sup_coeff *
00592         ( ((cvcs[i])->sup_np != 1) ?
00593           ::pow ((cvcs[i])->value().real_value, (cvcs[i])->sup_np) :
00594           (cvcs[i])->value().real_value );
00595     } 
00596   } else {
00597 
00598     for (size_t i = 0; i < cvcs.size(); i++) {
00599       cvm::increase_depth();
00600       (cvcs[i])->calc_value();
00601       cvm::decrease_depth();
00602       if (cvm::debug())
00603         cvm::log ("Colvar component no. "+cvm::to_str (i+1)+
00604                   " within colvar \""+this->name+"\" has value "+
00605                   cvm::to_str ((cvcs[i])->value(),
00606                                cvm::cv_width, cvm::cv_prec)+".\n");
00607       x += (cvcs[i])->sup_coeff * (cvcs[i])->value();
00608     } 
00609   }
00610 
00611   if (cvm::debug())
00612     cvm::log ("Colvar \""+this->name+"\" has value "+
00613               cvm::to_str (x, cvm::cv_width, cvm::cv_prec)+".\n");
00614 
00615   if (tasks[task_gradients]) {
00616     // calculate the gradients
00617     for (size_t i = 0; i < cvcs.size(); i++) {
00618       cvm::increase_depth();
00619       (cvcs[i])->calc_gradients();
00620       cvm::decrease_depth();
00621     }
00622   }
00623 
00624   if (tasks[task_system_force] && (cvm::step_relative() > 0)) {
00625     // get from the cvcs the system forces from the PREVIOUS step
00626     ft.reset();
00627     for (size_t i = 0; i < cvcs.size(); i++) {
00628       (cvcs[i])->calc_force_invgrads();
00629       // linear superposition is assumed
00630       cvm::increase_depth();
00631       ft += (cvcs[i])->system_force() / ((cvcs[i])->sup_coeff * cvm::real (cvcs.size()));
00632       cvm::decrease_depth();
00633     }
00634   }
00635 
00636   if (tasks[task_report_Jacobian_force]) {
00637     // add the Jacobian force to the system force, and don't apply the
00638     // correction internally: biases such as colvarbias_abf will handle it
00639     ft += fj;
00640   }
00641 
00642   if (tasks[task_fdiff_velocity]) {
00643     // calculate the velocity by finite differences
00644     if (cvm::step_relative() == 0)
00645       x_old = x;
00646     else {
00647       v_fdiff = fdiff_velocity (x_old, x);
00648       v_reported = v_fdiff;
00649     }
00650   }
00651 
00652   if (tasks[task_extended_lagrangian]) {
00653 
00654     // initialize the restraint center in the first step to the value
00655     // just calculated from the cvcs; XX TODO: put it in the
00656     // restart information
00657     if (cvm::step_relative() == 0)
00658       xr = x;
00659 
00660     // report the restraint center as "value"
00661     x_reported = xr;
00662     v_reported = vr;
00663     // the "system force" with the extended lagrangian is just the
00664     // harmonic term
00665     ft_reported = fr;
00666 
00667   } else {
00668 
00669     x_reported = x;
00670     ft_reported = ft;
00671   }
00672 
00673   if (cvm::debug())
00674     cvm::log ("Done calculating colvar \""+this->name+"\".\n");
00675 }
00676 
00677 
00678 void colvar::update()
00679 {
00680   if (cvm::debug())
00681     cvm::log ("Updating colvar \""+this->name+"\".\n");
00682 
00683 
00684   // set to zero the applied force
00685   f.reset();
00686 
00687   // add the biases' force, which at this point should already have
00688   // been summed over each bias using this colvar
00689   f += fb;
00690 
00691 
00692   if (tasks[task_lower_wall] || tasks[task_upper_wall]) {
00693 
00694     // wall force
00695     colvarvalue fw (this->type());
00696 
00697     // if the two walls are applied concurrently, decide which is the
00698     // closer one (on a periodic colvar, both walls may be applicable
00699     // at the same time)
00700     if ( (!tasks[task_upper_wall]) ||
00701          (this->dist2 (x, lower_wall) < this->dist2 (x, upper_wall)) ) {
00702 
00703       cvm::real const grad = this->dist2_lgrad (x, lower_wall);
00704       if (grad < 0.0) {
00705         fw = -0.5 * lower_wall_k * grad;
00706         if (cvm::debug())
00707           cvm::log ("Applying a lower wall force ("+
00708                     cvm::to_str (fw)+") to \""+this->name+"\".\n");
00709         f += fw;
00710 
00711       }
00712 
00713     } else {
00714 
00715       cvm::real const grad = this->dist2_lgrad (x, upper_wall);
00716       if (grad > 0.0) {
00717         fw = -0.5 * upper_wall_k * grad;
00718         if (cvm::debug())
00719           cvm::log ("Applying an upper wall force ("+
00720                     cvm::to_str (fw)+") to \""+this->name+"\".\n");
00721         f += fw;
00722       }
00723     }
00724   }
00725 
00726   if (tasks[task_Jacobian_force]) {
00727     
00728     cvm::increase_depth();
00729     for (size_t i = 0; i < cvcs.size(); i++) {
00730       (cvcs[i])->calc_Jacobian_derivative();
00731     }
00732     cvm::decrease_depth();
00733 
00734     // JH - here we could compute the dot product of the cvc inverse gradient
00735     // with the colvar gradient, and renormalize.
00736 
00737     fj.reset();
00738     for (size_t i = 0; i < cvcs.size(); i++) {
00739       // linear superposition is assumed
00740       fj += 1.0 / ( cvm::real (cvcs.size()) *  cvm::real ((cvcs[i])->sup_coeff) ) *
00741         (cvcs[i])->Jacobian_derivative();
00742     }
00743     fj *= cvm::boltzmann() * cvm::temperature();
00744 
00745     // the Jacobian force has not been added to the system force, so
00746     // it's now subtracted from the applied force
00747     if (! tasks[task_report_Jacobian_force]) 
00748       f -= fj;
00749   }
00750 
00751 
00752   if (tasks[task_extended_lagrangian]) {
00753 
00754     // the total force is applied on the fictitious mass, while the
00755     // atoms only feel the harmonic force
00756     fr   = f;
00757     fr  += (-0.5 * ext_force_k) * this->dist2_lgrad (xr, x);
00758     f    = (-0.5 * ext_force_k) * this->dist2_rgrad (xr, x);
00759 
00760     // leap frog
00761     vr  += (0.5 * cvm::dt) * fr / ext_mass;
00762     xr  += cvm::dt * vr;
00763     // if the colvarvalue is set to a type with constraints, apply
00764     // them
00765     xr.apply_constraints();
00766     vr  += (0.5 * cvm::dt) * fr / ext_mass; 
00767   }
00768 
00769 
00770   if (tasks[task_fdiff_velocity]) {
00771     // set it for the next step
00772     x_old = x;
00773   }
00774 
00775   if (cvm::debug())
00776     cvm::log ("Done updating colvar \""+this->name+"\".\n");
00777 }
00778 
00779 
00780 void colvar::communicate_forces()
00781 {
00782   if (cvm::debug())
00783     cvm::log ("Communicating forces from colvar \""+this->name+"\".\n"); 
00784 
00785   if (x.type() == colvarvalue::type_scalar) {
00786 
00787     for (size_t i = 0; i < cvcs.size(); i++) {
00788       cvm::increase_depth();
00789       (cvcs[i])->apply_force (f * (cvcs[i])->sup_coeff * 
00790                               cvm::real ((cvcs[i])->sup_np) *
00791                               (::pow ((cvcs[i])->value().real_value,
00792                                       (cvcs[i])->sup_np-1)) );
00793       cvm::decrease_depth();
00794     }
00795 
00796   } else {
00797 
00798     for (size_t i = 0; i < cvcs.size(); i++) {
00799       cvm::increase_depth();
00800       (cvcs[i])->apply_force (f * (cvcs[i])->sup_coeff);
00801       cvm::decrease_depth();
00802     }
00803   }
00804 
00805   if (cvm::debug())
00806     cvm::log ("Done communicating forces from colvar \""+this->name+"\".\n"); 
00807 }
00808 
00809 
00810 
00811 // ******************** METRIC FUNCTIONS ********************
00812 // Use the metrics defined by \link cvc \endlink objects
00813 
00814 
00815 bool colvar::periodic_boundaries (colvarvalue const &lb, colvarvalue const &ub) const
00816 {
00817   if ( (!tasks[task_lower_boundary]) || (!tasks[task_upper_boundary]) ) {
00818     cvm::fatal_error ("Error: requesting to histogram the "
00819                       "collective variable \""+this->name+"\", but a "
00820                       "pair of lower and upper boundaries must be "
00821                       "defined.\n");
00822   }
00823 
00824   if (period > 0.0) {
00825     if ( ((::sqrt (this->dist2 (lb, ub))) / this->width)
00826          < 1.0E-10 ) {
00827       return true;
00828     }
00829   }
00830 
00831   return false;
00832 }
00833 
00834 bool colvar::periodic_boundaries() const
00835 {
00836   if ( (!tasks[task_lower_boundary]) || (!tasks[task_upper_boundary]) ) {
00837     cvm::fatal_error ("Error: requesting to histogram the "
00838                       "collective variable \""+this->name+"\", but a "
00839                       "pair of lower and upper boundaries must be "
00840                       "defined.\n");
00841   }
00842 
00843   return periodic_boundaries (lower_boundary, upper_boundary);
00844 }
00845 
00846 
00847 cvm::real colvar::dist2 (colvarvalue const &x1,
00848                          colvarvalue const &x2) const
00849 {
00850   return (cvcs[0])->dist2 (x1, x2);
00851 }
00852 
00853 colvarvalue colvar::dist2_lgrad (colvarvalue const &x1,
00854                                  colvarvalue const &x2) const
00855 {
00856   return (cvcs[0])->dist2_lgrad (x1, x2);
00857 }
00858 
00859 colvarvalue colvar::dist2_rgrad (colvarvalue const &x1,
00860                                  colvarvalue const &x2) const
00861 {
00862   return (cvcs[0])->dist2_rgrad (x1, x2);
00863 }
00864 
00865 cvm::real colvar::compare (colvarvalue const &x1,
00866                            colvarvalue const &x2) const
00867 {
00868   return (cvcs[0])->compare (x1, x2);
00869 }
00870 
00871 
00872 
00873 // ******************** INPUT FUNCTIONS ********************
00874 
00875 std::istream & colvar::read_restart (std::istream &is)
00876 {
00877   size_t const start_pos = is.tellg();
00878 
00879   std::string conf;
00880   if ( !(is >> colvarparse::read_block ("colvar", conf)) ) {
00881     // this is not a colvar block
00882     is.clear();
00883     is.seekg (start_pos, std::ios::beg);
00884     is.setstate (std::ios::failbit);
00885     return is;
00886   }
00887 
00888   {
00889     std::string check_name = "";
00890     if ( (get_keyval (conf, "name", check_name,
00891                       std::string (""), colvarparse::parse_silent)) &&
00892          (check_name != name) )  {
00893       cvm::fatal_error ("Error: the state file does not match the "
00894                         "configuration file, at colvar \""+name+"\".\n");
00895     }
00896     if (check_name.size() == 0) {
00897       cvm::fatal_error ("Error: Collective variable in the "
00898                         "restart file without any identifier.\n");
00899     }
00900   }
00901 
00902   if ( !(get_keyval (conf, "x", x,
00903                      colvarvalue (x.type()), colvarparse::parse_silent)) ) {
00904     cvm::log ("Error: restart file does not contain "
00905               "the value of the colvar \""+
00906               name+"\" .\n");
00907   } else {
00908     cvm::log ("Restarting collective variable \""+name+"\" from value: "+
00909               cvm::to_str (x)+"\n");
00910   }
00911 
00912   if (tasks[colvar::task_extended_lagrangian]) {
00913 
00914     if ( !(get_keyval (conf, "extended_x", xr,
00915                        colvarvalue (x.type()), colvarparse::parse_silent)) &&
00916          !(get_keyval (conf, "extended_v", vr,
00917                        colvarvalue (x.type()), colvarparse::parse_silent)) ) {
00918       cvm::log ("Error: restart file does not contain "
00919                 "\"extended_x\" or \"extended_v\" for the colvar \""+
00920                 name+"\", but you requested \"extendedLagrangian\".\n");
00921     }
00922   }
00923 
00924   if (tasks[task_extended_lagrangian]) {
00925     x_reported = xr;
00926   } else {
00927     x_reported = x;
00928   }
00929 
00930   if (tasks[task_output_velocity]) {
00931 
00932     if ( !(get_keyval (conf, "v", v_fdiff,
00933                        colvarvalue (x.type()), colvarparse::parse_silent)) ) {
00934       cvm::log ("Error: restart file does not contain "
00935                 "the velocity for the colvar \""+
00936                 name+"\", but you requested \"outputVelocity\".\n");
00937     }
00938 
00939     if (tasks[task_extended_lagrangian]) {
00940       v_reported = vr;
00941     } else {
00942       v_reported = v_fdiff;
00943     }
00944   }
00945 
00946   return is;
00947 }
00948 
00949 
00950 std::istream & colvar::read_traj (std::istream &is)
00951 {
00952   size_t const start_pos = is.tellg();
00953 
00954   if (tasks[task_output_value]) {
00955 
00956     if (!(is >> x)) {
00957       cvm::log ("Error: in reading the value of colvar \""+
00958                 this->name+"\" from trajectory.\n");
00959       is.clear();
00960       is.seekg (start_pos, std::ios::beg);
00961       is.setstate (std::ios::failbit);
00962       return is;
00963     }
00964 
00965     if (tasks[task_extended_lagrangian]) {
00966       is >> xr;
00967       x_reported = xr;
00968     } else {
00969       x_reported = x;
00970     }
00971   }
00972 
00973   if (tasks[task_output_velocity]) {
00974 
00975     is >> v_fdiff;
00976 
00977     if (tasks[task_extended_lagrangian]) {
00978       is >> vr;
00979       v_reported = vr;
00980     } else {
00981       v_reported = v_fdiff;
00982     }
00983   }
00984 
00985   if (tasks[task_output_system_force]) {
00986 
00987     is >> ft;
00988 
00989     if (tasks[task_extended_lagrangian]) { 
00990       is >> fr;
00991       ft_reported = fr;
00992     } else {
00993       ft_reported = ft;
00994     }
00995   }
00996 
00997   if (tasks[task_output_applied_force]) {
00998     is >> f;
00999   }
01000 
01001   return is;
01002 }
01003 
01004 
01005 // ******************** OUTPUT FUNCTIONS ********************
01006 
01007 std::ostream & colvar::write_restart (std::ostream &os) {
01008 
01009   os << "colvar {\n"
01010      << "  name " << name << "\n"
01011      << "  x "
01012      << std::setprecision (cvm::cv_prec)
01013      << std::setw (cvm::cv_width)
01014      << x << "\n";
01015 
01016   if (tasks[task_output_velocity]) {
01017     os << "  v "
01018        << std::setprecision (cvm::cv_prec)
01019        << std::setw (cvm::cv_width)
01020        << v_reported << "\n";
01021   }
01022 
01023   if (tasks[task_extended_lagrangian]) {
01024     os << "  extended_x "
01025        << std::setprecision (cvm::cv_prec)
01026        << std::setw (cvm::cv_width)
01027        << xr << "\n"
01028        << "  extended_v "
01029        << std::setprecision (cvm::cv_prec)
01030        << std::setw (cvm::cv_width)
01031        << vr << "\n";
01032   }
01033 
01034   os << "}\n\n";
01035 
01036   return os;
01037 }  
01038 
01039 
01040 std::ostream & colvar::write_traj_label (std::ostream & os)
01041 {
01042   size_t const this_cv_width = x.output_width (cvm::cv_width);
01043 
01044   os << " ";
01045 
01046   if (tasks[task_output_value]) {
01047 
01048     os << " "
01049        << cvm::wrap_string (this->name, this_cv_width);
01050 
01051     if (tasks[task_extended_lagrangian]) {
01052       // restraint center
01053       os << " r_"
01054          << cvm::wrap_string (this->name, this_cv_width-2);
01055     }
01056   }
01057 
01058   if (tasks[task_output_velocity]) {
01059 
01060     os << " v_"
01061        << cvm::wrap_string (this->name, this_cv_width-2);
01062 
01063     if (tasks[task_extended_lagrangian]) {
01064       // restraint center
01065       os << " vr_"
01066          << cvm::wrap_string (this->name, this_cv_width-3);
01067     }
01068   }
01069 
01070   if (tasks[task_output_system_force]) {
01071 
01072     os << " fs_"
01073        << cvm::wrap_string (this->name, this_cv_width-2);
01074 
01075     if (tasks[task_extended_lagrangian]) {
01076       // restraint center
01077       os << " fr_"
01078          << cvm::wrap_string (this->name, this_cv_width-3);
01079     }
01080   }
01081 
01082   if (tasks[task_output_applied_force]) {
01083     os << " fa_"
01084        << cvm::wrap_string (this->name, this_cv_width-2);
01085   }
01086 
01087   return os;
01088 }
01089 
01090 
01091 std::ostream & colvar::write_traj (std::ostream &os)
01092 {
01093   os << " ";
01094 
01095   if (tasks[task_output_value]) {
01096 
01097     if (tasks[task_extended_lagrangian]) {
01098       os << " "
01099          << std::setprecision (cvm::cv_prec) << std::setw (cvm::cv_width)
01100          << x;
01101     }
01102 
01103     os << " "
01104        << std::setprecision (cvm::cv_prec) << std::setw (cvm::cv_width)
01105        << x_reported;
01106   }
01107 
01108   if (tasks[task_output_velocity]) {
01109 
01110     if (tasks[task_extended_lagrangian]) {
01111       os << " "
01112          << std::setprecision (cvm::cv_prec) << std::setw (cvm::cv_width)
01113          << v_fdiff;
01114     }
01115 
01116     os << " "
01117        << std::setprecision (cvm::cv_prec) << std::setw (cvm::cv_width)
01118        << v_reported;
01119   }
01120 
01121   if (tasks[task_output_system_force]) {
01122 
01123     if (tasks[task_extended_lagrangian]) {
01124       os << " "
01125          << std::setprecision (cvm::cv_prec) << std::setw (cvm::cv_width)
01126          << ft;
01127     }
01128 
01129     os << " "
01130        << std::setprecision (cvm::cv_prec) << std::setw (cvm::cv_width)
01131        << ft_reported;
01132   }
01133 
01134   if (tasks[task_output_applied_force]) {
01135     os << " "
01136        << std::setprecision (cvm::cv_prec) << std::setw (cvm::cv_width)
01137        << f;
01138   }
01139 
01140   return os;
01141 }
01142 
01143 
01144 
01145 // ******************** ANALYSIS FUNCTIONS ********************
01146 
01147 void colvar::analyse()
01148 {
01149   if (tasks[task_runave]) {
01150     calc_runave();
01151   }
01152 
01153   if (tasks[task_corrfunc]) {
01154     calc_acf();
01155   }
01156 }
01157 
01158 
01159 inline void history_add_value (size_t const           &history_length,
01160                                std::list<colvarvalue> &history,
01161                                colvarvalue const      &new_value)
01162 {
01163   history.push_front (new_value);
01164   if (history.size() > history_length)
01165     history.pop_back();
01166 }
01167 
01168 inline void history_incr (std::list< std::list<colvarvalue> >           &history,
01169                           std::list< std::list<colvarvalue> >::iterator &history_p)
01170 {
01171   if ((++history_p) == history.end()) 
01172     history_p = history.begin();
01173 }
01174 
01175 
01176 void colvar::calc_acf()
01177 {
01178   // using here an acf_stride-long list of vectors for either
01179   // coordinates (acf_x_history) or velocities (acf_v_history); each vector can
01180   // contain up to acf_length values, which are contiguous in memory
01181   // representation but separated by acf_stride in the time series;
01182   // the pointer to each vector is changed at every step
01183 
01184   if (! (acf_x_history.size() || acf_v_history.size()) ) {
01185 
01186     // first-step operations
01187 
01188     colvar *cfcv = (acf_colvar_name.size() ? 
01189                     cvm::colvar_p (acf_colvar_name) :
01190                     this);
01191     if (cfcv->type() != this->type())
01192       cvm::fatal_error ("Error: correlation function between \""+cfcv->name+
01193                         "\" and \""+this->name+"\" cannot be calculated, "
01194                         "because their value types are different.\n");
01195     acf_nframes = 0;
01196 
01197     cvm::log ("Colvar \""+this->name+"\": initializing ACF calculation.\n");
01198 
01199     if (acf.size() < acf_length+1)
01200       acf.resize (acf_length+1, 0.0);
01201 
01202     switch (acf_type) {
01203 
01204     case acf_vel:
01205       // allocate space for the velocities history
01206       for (size_t i = 0; i < acf_stride; i++) {
01207         acf_v_history.push_back (std::list<colvarvalue>());
01208       }
01209       acf_v_history_p = acf_v_history.begin();
01210       break;
01211 
01212     case acf_coor:
01213     case acf_p2coor:
01214       // allocate space for the coordinates history
01215       for (size_t i = 0; i < acf_stride; i++) {
01216         acf_x_history.push_back (std::list<colvarvalue>());
01217       }
01218       acf_x_history_p = acf_x_history.begin();
01219       break;
01220 
01221     default:
01222       break;
01223     }
01224 
01225   } else {
01226 
01227     colvar *cfcv = (acf_colvar_name.size() ? 
01228                     cvm::colvar_p (acf_colvar_name) :
01229                     this);
01230 
01231     switch (acf_type) {
01232 
01233     case acf_vel:
01234 
01235       if (tasks[task_fdiff_velocity]) {
01236         // calc() should do this already, but this only happens in a
01237         // simulation; better do it again in case a trajectory is
01238         // being read
01239         v_reported = v_fdiff = fdiff_velocity (x_old, cfcv->value());
01240       }
01241 
01242       calc_vel_acf ((*acf_v_history_p), cfcv->velocity());
01243       // store this value in the history
01244       history_add_value (acf_length+acf_offset, *acf_v_history_p, cfcv->velocity());
01245       // if stride is larger than one, cycle among different histories
01246       history_incr (acf_v_history, acf_v_history_p);
01247       break;
01248 
01249     case acf_coor:
01250 
01251       calc_coor_acf ((*acf_x_history_p), cfcv->value());
01252       history_add_value (acf_length+acf_offset, *acf_x_history_p, cfcv->value());
01253       history_incr (acf_x_history, acf_x_history_p);
01254       break;
01255 
01256     case acf_p2coor:
01257 
01258       calc_p2coor_acf ((*acf_x_history_p), cfcv->value());
01259       history_add_value (acf_length+acf_offset, *acf_x_history_p, cfcv->value());
01260       history_incr (acf_x_history, acf_x_history_p);
01261       break;
01262 
01263     default:
01264       break;
01265     }
01266   }
01267 
01268   if (tasks[task_fdiff_velocity]) {
01269     // set it for the next step
01270     x_old = x;
01271   }
01272 }
01273 
01274 
01275 void colvar::calc_vel_acf (std::list<colvarvalue> &v_list,
01276                            colvarvalue const      &v)
01277 {
01278   // loop over stored velocities and add to the ACF, but only the
01279   // length is sufficient to hold an entire row of ACF values
01280   if (v_list.size() >= acf_length+acf_offset) {
01281     std::list<colvarvalue>::iterator  vs_i = v_list.begin();
01282     std::vector<cvm::real>::iterator acf_i = acf.begin();
01283 
01284     for (size_t i = 0; i < acf_offset; i++)
01285       vs_i++;
01286 
01287     // current vel with itself
01288     *(acf_i++) += v.norm2();
01289 
01290     // inner products of previous velocities with current (acf_i and
01291     // vs_i are updated)
01292     colvarvalue::inner_opt (v, vs_i, v_list.end(), acf_i); 
01293 
01294     acf_nframes++;
01295   }
01296 }
01297 
01298 
01299 void colvar::calc_coor_acf (std::list<colvarvalue> &x_list,
01300                             colvarvalue const      &x)
01301 {
01302   // same as above but for coordinates
01303   if (x_list.size() >= acf_length+acf_offset) {
01304     std::list<colvarvalue>::iterator  xs_i = x_list.begin();
01305     std::vector<cvm::real>::iterator acf_i = acf.begin();
01306 
01307     for (size_t i = 0; i < acf_offset; i++)
01308       xs_i++;
01309 
01310     *(acf_i++) += x.norm2();
01311 
01312     colvarvalue::inner_opt (x, xs_i, x_list.end(), acf_i); 
01313 
01314     acf_nframes++;
01315   }
01316 }
01317 
01318 
01319 void colvar::calc_p2coor_acf (std::list<colvarvalue> &x_list,
01320                               colvarvalue const      &x)
01321 {
01322   // same as above but with second order Legendre polynomial instead
01323   // of just the scalar product
01324   if (x_list.size() >= acf_length+acf_offset) {
01325     std::list<colvarvalue>::iterator  xs_i = x_list.begin();
01326     std::vector<cvm::real>::iterator acf_i = acf.begin();
01327 
01328     for (size_t i = 0; i < acf_offset; i++)
01329       xs_i++;
01330 
01331     // value of P2(0) = 1
01332     *(acf_i++) += 1.0;
01333 
01334     colvarvalue::p2leg_opt (x, xs_i, x_list.end(), acf_i); 
01335 
01336     acf_nframes++;
01337   }
01338 }
01339 
01340 
01341 void colvar::write_acf (std::ostream &os)
01342 {
01343   if (!acf_nframes)
01344     cvm::log ("Warning: ACF was not calculated (insufficient frames).\n");
01345   os.setf (std::ios::scientific, std::ios::floatfield);
01346   os << "# Autocorrelation function for collective variable \""
01347      << this->name << "\"\n";
01348   // one frame is used for normalization, the statistical sample is
01349   // hence decreased
01350   os << "# nframes = " << (acf_normalize ?
01351                            acf_nframes - 1 :
01352                            acf_nframes) << "\n";
01353 
01354   cvm::real const acf_norm = acf.front() / cvm::real (acf_nframes);
01355   std::vector<cvm::real>::iterator acf_i;
01356   size_t it = acf_offset;
01357   for (acf_i = acf.begin(); acf_i != acf.end(); acf_i++) {
01358     os << std::setw (cvm::it_width) << acf_stride * (it++) << " "
01359        << std::setprecision (cvm::cv_prec)
01360        << std::setw (cvm::cv_width)
01361        << ( acf_normalize ?
01362             (*acf_i)/(acf_norm * cvm::real (acf_nframes)) :
01363             (*acf_i)/(cvm::real (acf_nframes)) ) << "\n";
01364   }
01365 }
01366 
01367 
01368 void colvar::calc_runave()
01369 {
01370   if (!x_history.size()) {
01371 
01372     runave.type (x.type());
01373     runave.reset();
01374 
01375     // first-step operations
01376 
01377     if (cvm::debug())
01378       cvm::log ("Colvar \""+this->name+
01379                 "\": initializing running average calculation.\n");
01380 
01381     acf_nframes = 0;
01382 
01383     x_history.push_back (std::list<colvarvalue>());
01384     x_history_p = x_history.begin();
01385 
01386   } else {
01387 
01388     if ( (cvm::step_relative() % runave_stride) == 0) {
01389 
01390       if ((*x_history_p).size() >= runave_length-1) {
01391 
01392         runave = x;
01393         for (std::list<colvarvalue>::iterator xs_i = (*x_history_p).begin();
01394              xs_i != (*x_history_p).end(); xs_i++) {
01395           runave += (*xs_i);
01396         }
01397         runave *= 1.0 / cvm::real (runave_length);
01398         runave.apply_constraints();
01399 
01400         runave_variance = 0.0;
01401         runave_variance += this->dist2 (x, runave);
01402         for (std::list<colvarvalue>::iterator xs_i = (*x_history_p).begin();
01403              xs_i != (*x_history_p).end(); xs_i++) {
01404           runave_variance += this->dist2 (x, (*xs_i));
01405         }
01406         runave_variance *= 1.0 / cvm::real (runave_length-1);
01407 
01408         runave_os << std::setw (cvm::it_width) << cvm::step_relative()
01409                   << "  "
01410                   << std::setprecision (cvm::cv_prec) << std::setw (cvm::cv_width)
01411                   << runave << " "
01412                   << std::setprecision (cvm::cv_prec) << std::setw (cvm::cv_width)
01413                   << ::sqrt (runave_variance) << "\n";
01414       }
01415 
01416       history_add_value (runave_length, *x_history_p, x);
01417     }
01418   }
01419 
01420 }
01421 
01422 

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