00001 // -*- c++ -*- 00002 00003 // This file is part of the Collective Variables module (Colvars). 00004 // The original version of Colvars and its updates are located at: 00005 // https://github.com/Colvars/colvars 00006 // Please update all Colvars source files before making any changes. 00007 // If you wish to distribute your changes, please submit them to the 00008 // Colvars repository at GitHub. 00009 00010 #ifndef COLVARATOMS_H 00011 #define COLVARATOMS_H 00012 00013 #include "colvarmodule.h" 00014 #include "colvarproxy.h" 00015 #include "colvarparse.h" 00016 #include "colvardeps.h" 00017 00018 00027 00028 class colvarmodule::atom { 00029 00030 protected: 00031 00033 int index; 00034 00035 public: 00036 00038 int id; 00039 00041 cvm::real mass; 00042 00044 cvm::real charge; 00045 00048 cvm::atom_pos pos; 00049 00052 cvm::rvector vel; 00053 00056 cvm::rvector total_force; 00057 00068 cvm::rvector grad; 00069 00071 atom(); 00072 00076 atom(int atom_number); 00077 00083 atom(cvm::residue_id const &residue, 00084 std::string const &atom_name, 00085 std::string const &segment_id); 00086 00088 atom(atom const &a); 00089 00091 ~atom(); 00092 00094 atom & operator = (atom const &a); 00095 00097 inline void reset_data() 00098 { 00099 pos = cvm::atom_pos(0.0); 00100 vel = grad = total_force = cvm::rvector(0.0); 00101 } 00102 00104 inline void update_mass() 00105 { 00106 colvarproxy *p = cvm::proxy; 00107 mass = p->get_atom_mass(index); 00108 } 00109 00111 inline void update_charge() 00112 { 00113 colvarproxy *p = cvm::proxy; 00114 charge = p->get_atom_charge(index); 00115 } 00116 00118 inline void read_position() 00119 { 00120 pos = (cvm::proxy)->get_atom_position(index); 00121 } 00122 00124 inline void read_velocity() 00125 { 00126 vel = (cvm::proxy)->get_atom_velocity(index); 00127 } 00128 00130 inline void read_total_force() 00131 { 00132 total_force = (cvm::proxy)->get_atom_total_force(index); 00133 } 00134 00144 inline void apply_force(cvm::rvector const &new_force) const 00145 { 00146 (cvm::proxy)->apply_atom_force(index, new_force); 00147 } 00148 }; 00149 00150 00151 00154 class colvarmodule::atom_group 00155 : public colvarparse, public colvardeps 00156 { 00157 public: 00158 00159 00161 atom_group(); 00162 00164 atom_group(char const *key); 00165 00167 atom_group(std::vector<cvm::atom> const &atoms_in); 00168 00170 ~atom_group(); 00171 00173 std::string name; 00174 00176 // TODO Make this field part of the data structures that link a group to a CVC 00177 std::string key; 00178 00180 int init(); 00181 00183 virtual int init_dependencies(); 00184 00186 int setup(); 00187 00190 int parse(std::string const &conf); 00191 00192 int add_atom_numbers(std::string const &numbers_conf); 00193 int add_atoms_of_group(atom_group const * ag); 00194 int add_index_group(std::string const &index_group_name); 00195 int add_atom_numbers_range(std::string const &range_conf); 00196 int add_atom_name_residue_range(std::string const &psf_segid, 00197 std::string const &range_conf); 00198 int parse_fitting_options(std::string const &group_conf); 00199 00201 int add_atom(cvm::atom const &a); 00202 00204 int add_atom_id(int aid); 00205 00207 int remove_atom(cvm::atom_iter ai); 00208 00210 int set_dummy(); 00211 00213 int set_dummy_pos(cvm::atom_pos const &pos); 00214 00218 void print_properties(std::string const &colvar_name, int i, int j); 00219 00221 static std::vector<feature *> ag_features; 00222 00224 virtual const std::vector<feature *> &features() const 00225 { 00226 return ag_features; 00227 } 00228 virtual std::vector<feature *> &modify_features() 00229 { 00230 return ag_features; 00231 } 00232 static void delete_features() { 00233 for (size_t i=0; i < ag_features.size(); i++) { 00234 delete ag_features[i]; 00235 } 00236 ag_features.clear(); 00237 } 00238 00239 protected: 00240 00242 std::vector<cvm::atom> atoms; 00243 00245 std::vector<int> atoms_ids; 00246 00249 std::vector<int> sorted_atoms_ids; 00250 00252 std::vector<int> sorted_atoms_ids_map; 00253 00255 cvm::atom_pos dummy_atom_pos; 00256 00258 int index; 00259 00260 public: 00261 00262 inline cvm::atom & operator [] (size_t const i) 00263 { 00264 return atoms[i]; 00265 } 00266 00267 inline cvm::atom const & operator [] (size_t const i) const 00268 { 00269 return atoms[i]; 00270 } 00271 00272 inline cvm::atom_iter begin() 00273 { 00274 return atoms.begin(); 00275 } 00276 00277 inline cvm::atom_const_iter begin() const 00278 { 00279 return atoms.begin(); 00280 } 00281 00282 inline cvm::atom_iter end() 00283 { 00284 return atoms.end(); 00285 } 00286 00287 inline cvm::atom_const_iter end() const 00288 { 00289 return atoms.end(); 00290 } 00291 00292 inline size_t size() const 00293 { 00294 return atoms.size(); 00295 } 00296 00300 bool b_dummy; 00301 00303 inline std::vector<int> const &ids() const 00304 { 00305 return atoms_ids; 00306 } 00307 00308 std::string const print_atom_ids() const; 00309 00311 int create_sorted_ids(); 00312 00315 inline std::vector<int> const &sorted_ids() const 00316 { 00317 return sorted_atoms_ids; 00318 } 00319 00321 inline std::vector<int> const &sorted_ids_map() const 00322 { 00323 return sorted_atoms_ids_map; 00324 } 00325 00328 static int overlap(const atom_group &g1, const atom_group &g2); 00329 00331 cvm::rotation rot; 00332 00336 bool b_user_defined_fit; 00337 00339 std::vector<cvm::atom_pos> ref_pos; 00340 00344 cvm::atom_pos ref_pos_cog; 00345 00348 atom_group *fitting_group; 00349 00351 cvm::real total_mass; 00352 00354 void update_total_mass(); 00355 00357 cvm::real total_charge; 00358 00360 void update_total_charge(); 00361 00364 bool noforce; 00365 00367 void read_positions(); 00368 00370 void calc_apply_roto_translation(); 00371 00379 void center_ref_pos(); 00380 00382 void apply_translation(cvm::rvector const &t); 00383 00387 void read_velocities(); 00388 00392 void read_total_forces(); 00393 00395 inline void reset_atoms_data() 00396 { 00397 for (cvm::atom_iter ai = atoms.begin(); ai != atoms.end(); ai++) 00398 ai->reset_data(); 00399 if (fitting_group) 00400 fitting_group->reset_atoms_data(); 00401 } 00402 00404 int calc_required_properties(); 00405 00407 std::vector<cvm::atom_pos> positions() const; 00408 00411 int calc_center_of_geometry(); 00412 00413 private: 00414 00416 cvm::atom_pos cog; 00417 00419 cvm::atom_pos cog_orig; 00420 00421 public: 00422 00424 inline cvm::atom_pos center_of_geometry() const 00425 { 00426 return cog; 00427 } 00428 00431 int calc_center_of_mass(); 00432 00433 private: 00434 00436 cvm::atom_pos com; 00437 00439 // TODO for scalable calculations of more complex variables (e.g. rotation), 00440 // use a colvarvalue of vectors to hold the entire derivative 00441 cvm::rvector scalar_com_gradient; 00442 00443 public: 00444 00446 inline cvm::atom_pos center_of_mass() const 00447 { 00448 return com; 00449 } 00450 00453 inline cvm::rvector center_of_mass_scalar_gradient() const 00454 { 00455 return scalar_com_gradient; 00456 } 00457 00459 std::vector<cvm::atom_pos> positions_shifted(cvm::rvector const &shift) const; 00460 00462 std::vector<cvm::rvector> velocities() const; 00463 00465 int calc_dipole(cvm::atom_pos const &dipole_center); 00466 00467 private: 00468 00470 cvm::rvector dip; 00471 00472 public: 00473 00475 inline cvm::rvector dipole() const 00476 { 00477 return dip; 00478 } 00479 00481 std::vector<cvm::rvector> total_forces() const; 00482 00484 cvm::rvector total_force() const; 00485 00486 00490 void set_weighted_gradient(cvm::rvector const &grad); 00491 00493 void calc_fit_gradients(); 00494 00496 std::vector<cvm::atom_pos> fit_gradients; 00497 00510 void apply_colvar_force(cvm::real const &force); 00511 00523 void apply_force(cvm::rvector const &force); 00524 00528 void do_feature_side_effects(int id); 00529 }; 00530 00531 00532 #endif