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

colvaratoms.C

Go to the documentation of this file.
00001 #include "colvarmodule.h"
00002 #include "colvarparse.h"
00003 #include "colvaratoms.h"
00004 
00005 
00006 // atom member functions depend tightly on the MD interface, and are
00007 // thus defined in colvarproxy_xxx.cpp
00008 
00009 
00010 // atom_group member functions
00011 
00012 cvm::atom_group::atom_group (std::string const &conf,
00013                              char const        *key,
00014                              atom_group        *ref_pos_group_in)
00015   : b_center (false), b_rotate (false),
00016     ref_pos_group (NULL), // this is always set within parse(),
00017                           // regardless fo ref_pos_group_in
00018     noforce (false)
00019 {
00020   cvm::log ("Defining atom group \""+
00021             std::string (key)+"\".\n");
00022   parse (conf, key, ref_pos_group_in);
00023 }
00024 
00025 
00026 void cvm::atom_group::parse (std::string const &conf,
00027                              char const        *key,
00028                              atom_group        *ref_pos_group_in)
00029 {
00030   std::string group_conf;
00031 
00032   // save_delimiters is set to false for this call, because "conf" is
00033   // not the config string of this group, but of its parent object
00034   // (which has already taken care of the delimiters)
00035   save_delimiters = false;
00036   key_lookup (conf, key, group_conf, dummy_pos);
00037   // restoring the normal value, because we do want keywords checked
00038   // inside "group_conf"
00039   save_delimiters = true;
00040 
00041   if (group_conf.size() == 0) {
00042     cvm::fatal_error ("Error: atom group \""+
00043                       std::string (key)+"\" is set, but "
00044                       "has no definition.\n");
00045   }
00046 
00047   cvm::increase_depth();
00048 
00049   cvm::log ("Initializing atom group \""+std::string (key)+"\".\n");
00050 
00051   // whether or not to include messages in the log
00052   colvarparse::Parse_Mode mode = parse_silent;
00053   {
00054     bool b_verbose;
00055     get_keyval (group_conf, "verboseOutput", b_verbose, false, parse_silent);
00056     if (b_verbose) mode = parse_normal;
00057   }
00058 
00059   {
00060     // get the atoms by numbers
00061     std::vector<int> atom_indexes;
00062     if (get_keyval (group_conf, "atomNumbers", atom_indexes, atom_indexes, mode)) {
00063       if (atom_indexes.size()) {
00064         this->reserve (this->size()+atom_indexes.size());
00065         for (size_t i = 0; i < atom_indexes.size(); i++) {
00066           this->push_back (cvm::atom (atom_indexes[i]));
00067         }
00068       } else
00069         cvm::fatal_error ("Error: no numbers provided for \""
00070                           "atom_numbers\".\n");
00071     }
00072   }
00073 
00074   {
00075     std::string range_conf = "";
00076     size_t pos = 0;
00077     while (key_lookup (group_conf, "atomNumbersRange",
00078                        range_conf, pos)) {
00079 
00080       if (range_conf.size()) {
00081         std::istringstream is (range_conf);
00082         int initial, final;
00083         char dash;
00084         if ( (is >> initial) && (initial > 0) &&
00085              (is >> dash) && (dash == '-') &&
00086              (is >> final) && (final > 0) ) {
00087           for (int anum = initial; anum <= final; anum++) {
00088             this->push_back (cvm::atom (anum));
00089           }
00090           range_conf = "";
00091           continue;
00092         }
00093       }
00094 
00095       cvm::fatal_error ("Error: no valid definition for \""
00096                         "atom_numbers_range\", \""+
00097                         range_conf+"\".\n");
00098     }
00099   }
00100 
00101   std::vector<std::string> psf_segids;
00102   get_keyval (group_conf, "psfSegID", psf_segids, std::vector<std::string> (1, std::string("MAIN")), mode);
00103   for (std::vector<std::string>::iterator psii = psf_segids.begin();
00104        psii < psf_segids.end(); psii++) {
00105 
00106     if ( (psii->size() == 0) || (psii->size() > 4) ) {
00107       cvm::fatal_error ("Error: invalid segmend identifier provided, \""+
00108                         (*psii)+"\".\n");
00109     }
00110   }
00111 
00112   {
00113     std::string range_conf = "";
00114     size_t pos = 0;
00115     size_t range_count = 0;
00116     std::vector<std::string>::iterator psii = psf_segids.begin();
00117     while (key_lookup (group_conf, "atomNameResidueRange",
00118                        range_conf, pos)) {
00119 
00120       if (psii > psf_segids.end()) {
00121         cvm::fatal_error ("Error: more instances of \"atomNameResidueRange\" than "
00122                           "values of \"psfSegID\".\n");
00123       }
00124 
00125       std::string const &psf_segid = *psii;
00126 
00127       if (range_conf.size()) {
00128         
00129         std::istringstream is (range_conf);
00130         std::string atom_name;
00131         int initial, final;
00132         char dash;
00133         if ( (is >> atom_name) && (atom_name.size())  &&
00134              (is >> initial) && (initial > 0) &&
00135              (is >> dash) && (dash == '-') &&
00136              (is >> final) && (final > 0) ) {
00137           for (int resid = initial; resid <= final; resid++) {
00138             this->push_back (cvm::atom (resid, atom_name, psf_segid));
00139           }
00140           range_conf = "";
00141           continue;
00142         }
00143 
00144       } else {
00145         cvm::fatal_error ("Error: no valid definition for \""
00146                           "atom_name_residue_range\", \""+
00147                           range_conf+"\".\n");
00148       }
00149 
00150       psii++;
00151     }
00152   }
00153 
00154   {
00155     // read the atoms from a file
00156     std::string atoms_file_name;
00157     if (get_keyval (group_conf, "atomsFile", atoms_file_name, std::string (""), mode)) {
00158 
00159       std::string atoms_col;
00160       get_keyval (group_conf, "atomsCol", atoms_col, std::string ("O"), mode);
00161 
00162       double atoms_col_value;
00163       bool const atoms_col_value_defined = get_keyval (group_conf, "atomsColValue", atoms_col_value, 0.0, mode);
00164       if (atoms_col_value_defined && (!atoms_col_value))
00165         cvm::fatal_error ("Error: atomsColValue, "
00166                           "if provided, must be non-zero.\n");
00167 
00168       cvm::load_atoms (atoms_file_name.c_str(), *this, atoms_col, atoms_col_value);
00169     }
00170   }
00171 
00172   for (std::vector<cvm::atom>::iterator a1 = this->begin(); 
00173        a1 != this->end(); a1++) {
00174     std::vector<cvm::atom>::iterator a2 = a1;
00175     ++a2;
00176     for ( ; a2 != this->end(); a2++) {
00177       if (a1->id == a2->id) {
00178         if (cvm::debug())
00179           cvm::log ("Discarding doubly counted atom with number "+
00180                     cvm::to_str (a1->id+1)+".\n");
00181         a2 = this->erase (a2);
00182         if (a2 == this->end())
00183           break;
00184       }
00185     }
00186   }
00187 
00188   if (get_keyval (group_conf, "dummyAtom", dummy_atom_pos, cvm::atom_pos(), mode)) {
00189     b_dummy = true;
00190     this->total_mass = 1.0;
00191   } else 
00192     b_dummy = false;
00193 
00194   if (b_dummy && (this->size())) 
00195     cvm::fatal_error ("Error: cannot set up group \""+
00196                       std::string (key)+"\" as a dummy atom "
00197                       "and provide it with atom definitions.\n");
00198 
00199 #if (! defined (COLVARS_STANDALONE))
00200   if ( (!b_dummy) && (!cvm::b_analysis) && (!(this->size())) ) {
00201     cvm::fatal_error ("Error: no atoms defined for atom group \""+
00202                       std::string (key)+"\".\n");
00203   }
00204 #endif
00205 
00206   if (!b_dummy) {
00207     this->total_mass = 0.0;
00208     for (cvm::atom_iter ai = this->begin();
00209          ai != this->end(); ai++) {
00210       this->total_mass += ai->mass;
00211     }
00212   }
00213 
00214   get_keyval (group_conf, "disableForces",   noforce,  false, mode);
00215 
00216   get_keyval (group_conf, "centerReference", b_center, false, mode);
00217   get_keyval (group_conf, "rotateReference", b_rotate, false, mode);
00218 
00219   if (b_center || b_rotate) {
00220 
00221     if (b_dummy)
00222       cvm::fatal_error ("Error: cannot set \"centerReference\" or "
00223                         "\"rotateReference\" with \"dummyAtom\".\n");
00224 
00225     // use refPositionsGroup instead of this group as the one which is
00226     // used to fit the coordinates
00227     if (key_lookup (group_conf, "refPositionsGroup")) {
00228       if (ref_pos_group) {
00229         cvm::fatal_error ("Error: the atom group \""+
00230                           std::string (key)+"\" has already a reference group "
00231                           "for the rototranslational fit, which was communicated by the "
00232                           "colvar component.  You should not use refPositionsGroup "
00233                           "in this case.\n");
00234       }
00235       cvm::log ("Within atom group \""+std::string (key)+"\":\n");
00236       ref_pos_group = new atom_group (group_conf, "refPositionsGroup");
00237     }
00238 
00239     if (get_keyval (group_conf, "refPositions", ref_pos, ref_pos, mode)) {
00240       cvm::log ("Using reference positions from input file.\n");
00241       atom_group *ag = ref_pos_group ? ref_pos_group : this;
00242       if (ref_pos.size() != ag->size()) {
00243         cvm::fatal_error ("Error: the number of reference positions provided ("+
00244                           cvm::to_str (ref_pos.size())+
00245                           ") does not match the number of atoms within \""+
00246                           std::string (key)+
00247                           "\" ("+cvm::to_str (ag->size())+").\n");
00248       }
00249     }
00250 
00251     std::string ref_pos_file;
00252     if (get_keyval (group_conf, "refPositionsFile", ref_pos_file, std::string (""), mode)) {
00253 
00254       if (ref_pos.size()) {
00255         cvm::fatal_error ("Error: cannot specify \"refPositionsFile\" and "
00256                           "\"refPositions\" at the same time.\n");
00257       }
00258 
00259       std::string ref_pos_col;
00260       get_keyval (group_conf, "refPositionsCol", ref_pos_col, std::string ("O"), mode);
00261 
00262       double ref_pos_col_value;
00263       bool found = get_keyval (group_conf, "refPositionsColValue", ref_pos_col_value, 0.0, mode);
00264       if (found && !ref_pos_col_value)
00265         cvm::fatal_error ("Error: refPositionsColValue, "
00266                           "if provided, must be non-zero.\n");
00267 
00268       cvm::load_coords (ref_pos_file.c_str(), ref_pos,
00269                         ref_pos_col, ref_pos_col_value);
00270     }
00271 
00272     if (ref_pos.size()) {
00273 
00274       if (b_rotate) {
00275         atom_group *ag = ref_pos_group ? ref_pos_group : this;
00276         if (ref_pos.size() != ag->size())
00277           cvm::fatal_error ("Error: the number of reference positions provided ("+
00278                             cvm::to_str (ref_pos.size())+
00279                             ") does not match the number of atoms within \""+
00280                             std::string (key)+
00281                             "\" ("+cvm::to_str (ag->size())+").\n");
00282       }
00283 
00284       // save the center of mass of ref_pos and then subtract it from
00285       // them; in this way it is possible to use the coordinates for
00286       // the rotational fit, if needed
00287       ref_pos_com = cvm::atom_pos (0.0, 0.0, 0.0);
00288 
00289       atom_group *ag = ref_pos_group ? ref_pos_group : this;
00290 
00291       cvm::atom_iter ai = ag->begin();
00292       std::vector<cvm::atom_pos>::iterator pi = ref_pos.begin();
00293       for ( ; ai != ag->end(); pi++, ai++) {
00294         ref_pos_com += ai->mass * (*pi);
00295       }
00296       ref_pos_com /= ag->total_mass;
00297 
00298       for (std::vector<cvm::atom_pos>::iterator pi = ref_pos.begin();
00299            pi != ref_pos.end(); pi++) {
00300         (*pi) -= ref_pos_com;
00301       }
00302     } else {
00303 #if (! defined (COLVARS_STANDALONE))
00304       if (!cvm::b_analysis)
00305         cvm::fatal_error ("Error: no reference positions provided.\n");
00306 #endif
00307     }
00308 
00309     if (b_rotate && !noforce) {
00310       cvm::log ("Warning: atom group \""+std::string (key)+
00311                 "\" is set to be rotated to a reference orientation: "
00312                 "a torque different than zero on this group "
00313                 "could make the simulation unstable.  "
00314                 "If this happens, set \"disableForces\" to yes "
00315                 "for this group.\n");
00316     }
00317 
00318   }
00319 
00320 
00321   if (cvm::debug())
00322     cvm::log ("Done initializing atom group with name \""+
00323               std::string (key)+"\".\n");
00324 
00325   this->check_keywords (group_conf, key);
00326 
00327   cvm::log ("Atom group \""+std::string (key)+"\" defined, "+
00328             cvm::to_str (this->size())+" initialized: total mass = "+
00329             cvm::to_str (this->total_mass)+".\n");
00330 
00331   cvm::decrease_depth();
00332 }
00333 
00334 
00335 cvm::atom_group::atom_group (std::vector<cvm::atom> const &atoms)
00336   : b_dummy (false), b_center (false), b_rotate (false), 
00337     ref_pos_group (NULL), noforce (false)
00338 {
00339   this->reserve (atoms.size());
00340   for (size_t i = 0; i < atoms.size(); i++) {
00341     this->push_back (atoms[i]);
00342   }
00343   total_mass = 0.0;
00344   for (cvm::atom_iter ai = this->begin();
00345        ai != this->end(); ai++) {
00346     total_mass += ai->mass;
00347   }
00348 }
00349 
00350 
00351 cvm::atom_group::atom_group()
00352   : b_center (false), b_rotate (false), 
00353     ref_pos_group (NULL), noforce (false)
00354 {
00355   total_mass = 0.0;
00356 }
00357 
00358 
00359 cvm::atom_group::~atom_group()
00360 {
00361   if (ref_pos_group) {
00362     delete ref_pos_group;
00363     ref_pos_group = NULL;
00364   }
00365 }
00366 
00367 
00368 void cvm::atom_group::add_atom (cvm::atom const &a)
00369 {
00370   if (b_dummy) {
00371     cvm::fatal_error ("Error: cannot add atoms to a dummy group.\n");
00372   } else {
00373     this->push_back (a);
00374     total_mass += a.mass;
00375   }
00376 }
00377 
00378 
00379 void cvm::atom_group::read_positions()
00380 {
00381   if (b_dummy) return;
00382 
00383 #if (! defined (COLVARS_STANDALONE))
00384   if (!this->size())
00385     cvm::fatal_error ("Error: no atoms defined in the requested group.\n");
00386 #endif
00387 
00388   for (cvm::atom_iter ai = this->begin();
00389        ai != this->end(); ai++) {
00390     ai->read_position();
00391   }
00392 
00393   if (ref_pos_group)
00394     ref_pos_group->read_positions();
00395 
00396   atom_group *fit_group = ref_pos_group ? ref_pos_group : this;
00397 
00398   if (b_center) {
00399     // store aside the current center of mass (all positions will be
00400     // set to the closest images to the first one) and then center on
00401     // the origin
00402     cvm::atom_pos const com = fit_group->center_of_mass();
00403     for (cvm::atom_iter ai = this->begin();
00404          ai != this->end(); ai++) {
00405       ai->pos -= com;
00406     }
00407   }
00408 
00409   if (b_rotate) {
00410     // rotate the group (around the center of mass if b_center is
00411     // true, around the origin otherwise); store the rotation, in
00412     // order to bring back the forces to the original frame before
00413     // applying them
00414     rot.calc_optimal_rotation (fit_group->positions(), ref_pos);
00415 
00416     for (cvm::atom_iter ai = this->begin();
00417          ai != this->end(); ai++) {
00418       ai->pos = rot.rotate (ai->pos);
00419     }
00420   }
00421 
00422   if (b_center) {
00423     // use the center of mass of ref_pos
00424     for (cvm::atom_iter ai = this->begin();
00425          ai != this->end(); ai++) {
00426       ai->pos += ref_pos_com;
00427     }
00428   }
00429 }
00430 
00431 
00432 void cvm::atom_group::apply_translation (cvm::rvector const &t) 
00433 {
00434   if (b_dummy) return;
00435 
00436   for (cvm::atom_iter ai = this->begin();
00437        ai != this->end(); ai++) {
00438     ai->pos += t;
00439   }
00440 }
00441 
00442 
00443 void cvm::atom_group::apply_rotation (cvm::rotation const &rot) 
00444 {
00445   if (b_dummy) return;
00446 
00447   for (cvm::atom_iter ai = this->begin();
00448        ai != this->end(); ai++) {
00449     ai->pos = rot.rotate (ai->pos);
00450   }
00451 }
00452 
00453 
00454 void cvm::atom_group::read_velocities()
00455 {
00456   if (b_dummy) return;
00457 
00458   if (b_rotate) {
00459 
00460     for (cvm::atom_iter ai = this->begin();
00461          ai != this->end(); ai++) {
00462       ai->read_velocity();
00463       ai->vel = rot.rotate (ai->vel);
00464     }
00465 
00466   } else {
00467 
00468     for (cvm::atom_iter ai = this->begin();
00469          ai != this->end(); ai++) {
00470       ai->read_velocity();
00471     }
00472   }
00473 }
00474 
00475 void cvm::atom_group::read_system_forces()
00476 {
00477   if (b_dummy) return;
00478 
00479   if (b_rotate) {
00480 
00481     for (cvm::atom_iter ai = this->begin();
00482          ai != this->end(); ai++) {
00483       ai->read_system_force();
00484       ai->system_force = rot.rotate (ai->system_force);
00485     }
00486 
00487   } else {
00488 
00489     for (cvm::atom_iter ai = this->begin();
00490          ai != this->end(); ai++) {
00491       ai->read_system_force();
00492     }
00493   }
00494 }
00495 
00496 cvm::atom_pos cvm::atom_group::center_of_geometry (cvm::atom_pos const &ref_pos)
00497 {
00498   if (b_dummy) {
00499     cvm::select_closest_image (dummy_atom_pos, ref_pos);
00500     return dummy_atom_pos;
00501   }
00502 
00503   cvm::atom_pos cog (0.0, 0.0, 0.0);
00504   for (cvm::atom_iter ai = this->begin();
00505        ai != this->end(); ai++) {
00506     cvm::select_closest_image (ai->pos, ref_pos);
00507     cog += ai->pos;
00508   }
00509   cog /= this->size();
00510   return cog;
00511 }
00512 
00513 cvm::atom_pos cvm::atom_group::center_of_geometry() const
00514 {
00515   if (b_dummy)
00516     return dummy_atom_pos;
00517 
00518   cvm::atom_pos cog (0.0, 0.0, 0.0);
00519   for (cvm::atom_const_iter ai = this->begin();
00520        ai != this->end(); ai++) {
00521     cog += ai->pos;
00522   }
00523   cog /= this->size();
00524   return cog;
00525 }
00526 
00527 cvm::atom_pos cvm::atom_group::center_of_mass (cvm::atom_pos const &ref_pos)
00528 {
00529   if (b_dummy) {
00530     cvm::select_closest_image (dummy_atom_pos, ref_pos);
00531     return dummy_atom_pos;
00532   }
00533 
00534   cvm::atom_pos com (0.0, 0.0, 0.0);
00535   for (cvm::atom_iter ai = this->begin();
00536        ai != this->end(); ai++) {
00537     cvm::select_closest_image (ai->pos, ref_pos);
00538     com += ai->mass * ai->pos;
00539   }
00540   com /= this->total_mass;
00541   return com;
00542 }
00543 
00544 cvm::atom_pos cvm::atom_group::center_of_mass() const
00545 {
00546   if (b_dummy)
00547     return dummy_atom_pos;
00548 
00549   cvm::atom_pos com (0.0, 0.0, 0.0);
00550   for (cvm::atom_const_iter ai = this->begin();
00551        ai != this->end(); ai++) {
00552     com += ai->mass * ai->pos;
00553   }
00554   com /= this->total_mass;
00555   return com;
00556 }
00557 
00558 
00559 void cvm::atom_group::set_weighted_gradient (cvm::rvector const &grad)
00560 {
00561   if (b_dummy) return;
00562 
00563   for (cvm::atom_iter ai = this->begin();
00564        ai != this->end(); ai++) {
00565     ai->grad = (ai->mass/this->total_mass) * grad;
00566   }
00567 }
00568 
00569 
00570 std::vector<cvm::atom_pos> cvm::atom_group::positions() const
00571 {
00572   if (b_dummy)
00573     cvm::fatal_error ("Error: positions are not available "
00574                       "from a dummy atom group.\n");
00575 
00576   std::vector<cvm::atom_pos> x (this->size(), 0.0);
00577   cvm::atom_const_iter ai = this->begin();
00578   std::vector<cvm::atom_pos>::iterator xi = x.begin();
00579   for ( ; ai != this->end(); xi++, ai++) {
00580     *xi = ai->pos;
00581   }
00582   return x;
00583 }
00584 
00585 std::vector<cvm::atom_pos> cvm::atom_group::positions_shifted (cvm::rvector const &shift) const
00586 {
00587   if (b_dummy)
00588     cvm::fatal_error ("Error: positions are not available "
00589                       "from a dummy atom group.\n");
00590 
00591   std::vector<cvm::atom_pos> x (this->size(), 0.0);
00592   cvm::atom_const_iter ai = this->begin();
00593   std::vector<cvm::atom_pos>::iterator xi = x.begin();
00594   for ( ; ai != this->end(); xi++, ai++) {
00595     *xi = (ai->pos + shift);
00596   }
00597   return x;
00598 }
00599 
00600 std::vector<cvm::rvector> cvm::atom_group::velocities() const
00601 {
00602   if (b_dummy)
00603     cvm::fatal_error ("Error: velocities are not available "
00604                       "from a dummy atom group.\n");
00605 
00606   std::vector<cvm::rvector> v (this->size(), 0.0);
00607   cvm::atom_const_iter ai = this->begin();
00608   std::vector<cvm::atom_pos>::iterator vi = v.begin();
00609   for ( ; ai != this->end(); vi++, ai++) {
00610     *vi = ai->vel;
00611   }
00612   return v;
00613 }
00614 
00615 std::vector<cvm::rvector> cvm::atom_group::system_forces() const
00616 {
00617   if (b_dummy)
00618     cvm::fatal_error ("Error: system forces are not available "
00619                       "from a dummy atom group.\n");
00620 
00621   std::vector<cvm::rvector> f (this->size(), 0.0);
00622   cvm::atom_const_iter ai = this->begin();
00623   std::vector<cvm::atom_pos>::iterator fi = f.begin();
00624   for ( ; ai != this->end(); fi++, ai++) {
00625     *fi = ai->system_force;
00626   }
00627   return f;
00628 }
00629 
00630 cvm::rvector cvm::atom_group::system_force() const
00631 {
00632   if (b_dummy)
00633     cvm::fatal_error ("Error: system forces are not available "
00634                       "from a dummy atom group.\n");
00635 
00636   cvm::rvector f (0.0);
00637   for (cvm::atom_const_iter ai = this->begin(); ai != this->end(); ai++) {
00638     f += ai->system_force;
00639   }
00640   return f;
00641 }
00642 
00643 
00644 void cvm::atom_group::apply_colvar_force (cvm::real const &force)
00645 {
00646   if (b_dummy)
00647     return;
00648 
00649   if (noforce)
00650     cvm::fatal_error ("Error: sending a force to a group that has "
00651                       "\"disableForces\" defined.\n");
00652 
00653   if (b_rotate) {
00654 
00655     // get the forces back from the rotated frame
00656     cvm::rotation const rot_inv = rot.inverse();
00657     for (cvm::atom_iter ai = this->begin();
00658          ai != this->end(); ai++) {
00659       ai->apply_force (rot_inv.rotate (force * ai->grad));
00660     }
00661 
00662   } else {
00663 
00664     // no need to manipulate gradients, they are still in the original
00665     // frame
00666     for (cvm::atom_iter ai = this->begin();
00667          ai != this->end(); ai++) {
00668       ai->apply_force (force * ai->grad);
00669     }
00670   }
00671 }
00672 
00673 
00674 void cvm::atom_group::apply_force (cvm::rvector const &force)
00675 {
00676   if (b_dummy)
00677     return;
00678 
00679   if (noforce)
00680     cvm::fatal_error ("Error: sending a force to a group that has "
00681                       "\"disableForces\" defined.\n");
00682 
00683   if (b_rotate) {
00684 
00685     cvm::rotation const rot_inv = rot.inverse();
00686     for (cvm::atom_iter ai = this->begin();
00687          ai != this->end(); ai++) {
00688       ai->apply_force (rot_inv.rotate ((ai->mass/this->total_mass) * force));
00689     }
00690 
00691   } else {
00692 
00693     for (cvm::atom_iter ai = this->begin();
00694          ai != this->end(); ai++) {
00695       ai->apply_force ((ai->mass/this->total_mass) * force);
00696     } 
00697   }
00698 }
00699 
00700 
00701 void cvm::atom_group::apply_forces (std::vector<cvm::rvector> const &forces)
00702 {
00703   if (b_dummy)
00704     return;
00705 
00706   if (noforce)
00707     cvm::fatal_error ("Error: sending a force to a group that has "
00708                       "\"disableForces\" defined.\n");
00709 
00710   if (forces.size() != this->size()) {
00711     cvm::fatal_error ("Error: trying to apply an array of forces to an atom "
00712                       "group which does not have the same length.\n");
00713   }
00714 
00715   if (b_rotate) {
00716 
00717     cvm::rotation const rot_inv = rot.inverse();
00718     cvm::atom_iter ai = this->begin();
00719     std::vector<cvm::rvector>::const_iterator fi = forces.begin();
00720     for ( ; ai != this->end(); fi++, ai++) {
00721       ai->apply_force (rot_inv.rotate (*fi));
00722     }
00723 
00724   } else {
00725 
00726     cvm::atom_iter ai = this->begin();
00727     std::vector<cvm::rvector>::const_iterator fi = forces.begin();
00728     for ( ; ai != this->end(); fi++, ai++) {
00729       ai->apply_force (*fi);
00730     }
00731   }
00732 }
00733 
00734 

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