version 1.11 | version 1.12 |
---|
| |
/// -*- c++ -*- | // -*- c++ -*- |
| |
#ifndef COLVARATOMS_H | #ifndef COLVARATOMS_H |
#define COLVARATOMS_H | #define COLVARATOMS_H |
| |
#include "colvarmodule.h" | #include "colvarmodule.h" |
#include "colvarparse.h" | #include "colvarparse.h" |
| #include "colvardeps.h" |
| |
| |
/// \brief Stores numeric id, mass and all mutable data for an atom, | /// \brief Stores numeric id, mass and all mutable data for an atom, |
/// mostly used by a \link cvc \endlink | /// mostly used by a \link cvc \endlink |
/// | /// |
/// This class may be used (although not necessarily) to keep atomic | /// This class may be used to keep atomic data such as id, mass, |
/// data (id, mass, position and collective variable derivatives) | /// position and collective variable derivatives) altogether. |
/// altogether. There may be multiple instances with identical | /// There may be multiple instances with identical |
/// numeric id, all acting independently: forces communicated through | /// numeric id, all acting independently: forces communicated through |
/// these instances will be summed together. | /// these instances will be summed together. |
/// | |
/// Read/write operations depend on the underlying code: hence, some | |
/// member functions are defined in colvarproxy_xxx.h. | |
class colvarmodule::atom { | class colvarmodule::atom { |
| |
protected: | protected: |
| |
/// \brief Index in the list of atoms involved by the colvars (\b | /// Index in the colvarproxy arrays (\b NOT in the global topology!) |
/// NOT in the global topology!) | |
int index; | int index; |
| |
public: | public: |
| |
/// Internal identifier (zero-based) | /// Identifier for the MD program (0-based) |
int id; | int id; |
| |
/// Mass | /// Mass |
cvm::real mass; | cvm::real mass; |
| |
| /// Charge |
| cvm::real charge; |
| |
/// \brief Current position (copied from the program, can be | /// \brief Current position (copied from the program, can be |
/// manipulated) | /// modified if necessary) |
cvm::atom_pos pos; | cvm::atom_pos pos; |
| |
/// \brief Current velocity (copied from the program, can be | /// \brief Current velocity (copied from the program, can be |
/// manipulated) | /// modified if necessary) |
cvm::rvector vel; | cvm::rvector vel; |
| |
/// \brief System force at the previous step (copied from the | /// \brief System force at the previous step (copied from the |
/// program, can be manipulated) | /// program, can be modified if necessary) |
cvm::rvector system_force; | cvm::rvector total_force; |
| |
/// \brief Gradient of a scalar collective variable with respect | /// \brief Gradient of a scalar collective variable with respect |
/// to this atom | /// to this atom |
| |
/// implementation | /// implementation |
cvm::rvector grad; | cvm::rvector grad; |
| |
/// \brief Default constructor, setting index and id to invalid numbers | /// \brief Default constructor (sets index and id both to -1) |
atom() : index(-1), id(-1) { reset_data(); } | atom(); |
| |
/// \brief Initialize an atom for collective variable calculation | /// \brief Initialize an atom for collective variable calculation |
/// and get its internal identifier \param atom_number Atom index in | /// and get its internal identifier \param atom_number Atom index in |
/// the system topology (starting from 1) | /// the system topology (starting from 1) |
atom(int const &atom_number); | atom(int atom_number); |
| |
/// \brief Initialize an atom for collective variable calculation | /// \brief Initialize an atom for collective variable calculation |
/// and get its internal identifier \param residue Residue number | /// and get its internal identifier \param residue Residue number |
| |
/// type of topologies, may not be required | /// type of topologies, may not be required |
atom(cvm::residue_id const &residue, | atom(cvm::residue_id const &residue, |
std::string const &atom_name, | std::string const &atom_name, |
std::string const &segment_id = std::string("")); | std::string const &segment_id); |
| |
/// Copy constructor | /// Copy constructor |
atom(atom const &a); | atom(atom const &a); |
| |
/// Destructor | /// Destructor |
~atom(); | ~atom(); |
| |
/// Set non-constant data (everything except id and mass) to zero | /// Set mutable data (everything except id and mass) to zero; update mass |
inline void reset_data() { | inline void reset_data() |
pos = atom_pos(0.0); | { |
vel = grad = system_force = rvector(0.0); | pos = cvm::atom_pos(0.0); |
| vel = grad = total_force = cvm::rvector(0.0); |
| } |
| |
| /// Get the latest value of the mass |
| inline void update_mass() |
| { |
| mass = (cvm::proxy)->get_atom_mass(index); |
| } |
| |
| /// Get the latest value of the charge |
| inline void update_charge() |
| { |
| charge = (cvm::proxy)->get_atom_charge(index); |
} | } |
| |
/// Get the current position | /// Get the current position |
void read_position(); | inline void read_position() |
| { |
| pos = (cvm::proxy)->get_atom_position(index); |
| } |
| |
/// Get the current velocity | /// Get the current velocity |
void read_velocity(); | inline void read_velocity() |
| { |
| vel = (cvm::proxy)->get_atom_velocity(index); |
| } |
| |
/// Get the system force | /// Get the total force |
void read_system_force(); | inline void read_total_force() |
| { |
| total_force = (cvm::proxy)->get_atom_total_force(index); |
| } |
| |
/// \brief Apply a force to the atom | /// \brief Apply a force to the atom |
/// | /// |
/// The force will be used later by the MD integrator, the | /// Note: the force is not applied instantly, but will be used later |
/// collective variables module does not integrate equations of | /// by the MD integrator (the colvars module does not integrate |
/// motion. Multiple calls to this function by either the same | /// equations of motion. |
| /// |
| /// Multiple calls to this function by either the same |
/// \link atom \endlink object or different objects with identical | /// \link atom \endlink object or different objects with identical |
/// \link id \endlink, will all add to the existing MD force. | /// \link id \endlink will all be added together. |
void apply_force(cvm::rvector const &new_force); | inline void apply_force(cvm::rvector const &new_force) const |
| { |
| (cvm::proxy)->apply_atom_force(index, new_force); |
| } |
}; | }; |
| |
| |
| |
| |
/// \brief Group of \link atom \endlink objects, mostly used by a | /// \brief Group of \link atom \endlink objects, mostly used by a |
/// \link cvc \endlink | /// \link cvc \endlink object to gather all atomic data |
/// | |
/// This class inherits from \link colvarparse \endlink and from | |
/// std::vector<colvarmodule::atom>, and hence all functions and | |
/// operators (including the bracket operator, group[i]) can be used | |
/// on an \link atom_group \endlink object. It can be initialized as | |
/// a vector, or by parsing a keyword in the configuration. | |
class colvarmodule::atom_group | class colvarmodule::atom_group |
: public std::vector<cvm::atom>, | : public colvarparse, public colvardeps |
public colvarparse | |
{ | { |
public: | public: |
// Note: all members here are kept public, to allow any | |
// object accessing and manipulating them | |
| |
| /// \brief Initialize the group by looking up its configuration |
| /// string in conf and parsing it; this is actually done by parse(), |
| /// which is a member function so that a group can be initialized |
| /// also after construction |
| atom_group(std::string const &conf, |
| char const *key); |
| |
| /// \brief Keyword used to define the group |
| // TODO Make this field part of the data structures that link a group to a CVC |
| std::string key; |
| |
| /// \brief Set default values for common flags |
| int init(); |
| |
| /// \brief Update data required to calculate cvc's |
| int setup(); |
| |
| /// \brief Initialize the group by looking up its configuration |
| /// string in conf and parsing it |
| int parse(std::string const &conf); |
| |
| int add_atom_numbers(std::string const &numbers_conf); |
| int add_index_group(std::string const &index_group_name); |
| int add_atom_numbers_range(std::string const &range_conf); |
| int add_atom_name_residue_range(std::string const &psf_segid, |
| std::string const &range_conf); |
| int parse_fitting_options(std::string const &group_conf); |
| |
| /// \brief Initialize the group after a (temporary) vector of atoms |
| atom_group(std::vector<cvm::atom> const &atoms_in); |
| |
| /// \brief Add an atom object to this group |
| int add_atom(cvm::atom const &a); |
| |
| /// \brief Add an atom ID to this group (the actual atomicdata will be not be handled by the group) |
| int add_atom_id(int aid); |
| |
| /// \brief Remove an atom object from this group |
| int remove_atom(cvm::atom_iter ai); |
| |
| /// \brief Re-initialize the total mass of a group. |
| /// This is needed in case the hosting MD code has an option to |
| /// change atom masses after their initialization. |
| void reset_mass(std::string &name, int i, int j); |
| |
| /// \brief Implementation of the feature list for atom group |
| static std::vector<feature *> ag_features; |
| |
| /// \brief Implementation of the feature list accessor for atom group |
| virtual std::vector<feature *> &features() { |
| return ag_features; |
| } |
| |
| /// \brief Default constructor |
| atom_group(); |
| |
| /// \brief Destructor |
| ~atom_group(); |
| |
| protected: |
| |
| /// \brief Array of atom objects |
| std::vector<cvm::atom> atoms; |
| |
| /// \brief Array of atom identifiers for the MD program (0-based) |
| std::vector<int> atoms_ids; |
| |
| /// \brief Dummy atom position |
| cvm::atom_pos dummy_atom_pos; |
| |
| /// \brief Index in the colvarproxy arrays (if the group is scalable) |
| int index; |
| |
| public: |
| |
| inline cvm::atom & operator [] (size_t const i) |
| { |
| return atoms[i]; |
| } |
| |
| inline cvm::atom const & operator [] (size_t const i) const |
| { |
| return atoms[i]; |
| } |
| |
| inline cvm::atom_iter begin() |
| { |
| return atoms.begin(); |
| } |
| |
| inline cvm::atom_const_iter begin() const |
| { |
| return atoms.begin(); |
| } |
| |
| inline cvm::atom_iter end() |
| { |
| return atoms.end(); |
| } |
| |
| inline cvm::atom_const_iter end() const |
| { |
| return atoms.end(); |
| } |
| |
| inline size_t size() const |
| { |
| return atoms.size(); |
| } |
| |
/// \brief If this option is on, this group merely acts as a wrapper | /// \brief If this option is on, this group merely acts as a wrapper |
/// for a fixed position; any calls to atoms within or to | /// for a fixed position; any calls to atoms within or to |
/// functions that return disaggregated data will fail | /// functions that return disaggregated data will fail |
bool b_dummy; | bool b_dummy; |
/// \brief dummy atom position | |
cvm::atom_pos dummy_atom_pos; | |
| |
/// Sorted list of zero-based (internal) atom ids | /// Sorted list of zero-based (internal) atom ids |
/// (populated on-demand by create_sorted_ids) | /// (populated on-demand by create_sorted_ids) |
| |
bool b_user_defined_fit; | bool b_user_defined_fit; |
| |
/// \brief Whether or not the derivatives of the roto-translation | /// \brief Whether or not the derivatives of the roto-translation |
/// should be included when calculating the colvar's gradients (default: no) | /// should be included when calculating the colvar's gradients (default: yes) |
bool b_fit_gradients; | bool b_fit_gradients; |
| |
/// \brief use reference coordinates for b_center or b_rotate | /// \brief use reference coordinates for b_center or b_rotate |
| |
| |
/// \brief If b_center or b_rotate is true, use this group to | /// \brief If b_center or b_rotate is true, use this group to |
/// define the transformation (default: this group itself) | /// define the transformation (default: this group itself) |
atom_group *ref_pos_group; | atom_group *fitting_group; |
| |
/// Total mass of the atom group | /// Total mass of the atom group |
cvm::real total_mass; | cvm::real total_mass; |
| void update_total_mass(); |
| |
| /// Total charge of the atom group |
| cvm::real total_charge; |
| void update_total_charge(); |
| |
/// \brief Don't apply any force on this group (use its coordinates | /// \brief Don't apply any force on this group (use its coordinates |
/// only to calculate a colvar) | /// only to calculate a colvar) |
bool noforce; | bool noforce; |
| |
| /// \brief Get the current positions |
/// \brief Initialize the group by looking up its configuration | |
/// string in conf and parsing it; this is actually done by parse(), | |
/// which is a member function so that a group can be initialized | |
/// also after construction | |
atom_group(std::string const &conf, | |
char const *key); | |
| |
/// \brief Initialize the group by looking up its configuration | |
/// string in conf and parsing it | |
int parse(std::string const &conf, | |
char const *key); | |
| |
/// \brief Initialize the group after a temporary vector of atoms | |
atom_group(std::vector<cvm::atom> const &atoms); | |
| |
/// \brief Add an atom to this group | |
void add_atom(cvm::atom const &a); | |
| |
/// \brief Re-initialize the total mass of a group. | |
/// This is needed in case the hosting MD code has an option to | |
/// change atom masses after their initialization. | |
void reset_mass(std::string &name, int i, int j); | |
| |
/// \brief Default constructor | |
atom_group(); | |
| |
/// \brief Destructor | |
~atom_group(); | |
| |
/// \brief Get the current positions; if b_center or b_rotate are | |
/// true, calc_apply_roto_translation() will be called too | |
void read_positions(); | void read_positions(); |
| |
/// \brief (Re)calculate the optimal roto-translation | /// \brief (Re)calculate the optimal roto-translation |
void calc_apply_roto_translation(); | void calc_apply_roto_translation(); |
| |
/// \brief Save center of geometry fo ref positions, | /// \brief Save aside the center of geometry of the reference positions, |
/// then subtract it | /// then subtract it from them |
| /// |
| /// In this way it will be possible to use ref_pos also for the |
| /// rotational fit. |
| /// This is called either by atom_group::parse or by CVCs that assign |
| /// reference positions (eg. RMSD, eigenvector). |
void center_ref_pos(); | void center_ref_pos(); |
| |
/// \brief Move all positions | /// \brief Move all positions |
void apply_translation(cvm::rvector const &t); | void apply_translation(cvm::rvector const &t); |
| |
/// \brief Rotate all positions | |
void apply_rotation(cvm::rotation const &q); | |
| |
| |
/// \brief Get the current velocities; this must be called always | /// \brief Get the current velocities; this must be called always |
/// *after* read_positions(); if b_rotate is defined, the same | /// *after* read_positions(); if b_rotate is defined, the same |
/// rotation applied to the coordinates will be used | /// rotation applied to the coordinates will be used |
void read_velocities(); | void read_velocities(); |
| |
/// \brief Get the current system_forces; this must be called always | /// \brief Get the current total_forces; this must be called always |
/// *after* read_positions(); if b_rotate is defined, the same | /// *after* read_positions(); if b_rotate is defined, the same |
/// rotation applied to the coordinates will be used | /// rotation applied to the coordinates will be used |
void read_system_forces(); | void read_total_forces(); |
| |
/// Call reset_data() for each atom | /// Call reset_data() for each atom |
inline void reset_atoms_data() | inline void reset_atoms_data() |
{ | { |
for (cvm::atom_iter ai = this->begin(); ai != this->end(); ai++) | for (cvm::atom_iter ai = atoms.begin(); ai != atoms.end(); ai++) |
ai->reset_data(); | ai->reset_data(); |
if (ref_pos_group) | if (fitting_group) |
ref_pos_group->reset_atoms_data(); | fitting_group->reset_atoms_data(); |
} | } |
| |
| /// \brief Recompute all mutable quantities that are required to compute CVCs |
| int calc_required_properties(); |
| |
/// \brief Return a copy of the current atom positions | /// \brief Return a copy of the current atom positions |
std::vector<cvm::atom_pos> positions() const; | std::vector<cvm::atom_pos> positions() const; |
| |
/// \brief Return a copy of the current atom positions, shifted by a constant vector | /// \brief Calculate the center of geometry of the atomic positions, assuming |
std::vector<cvm::atom_pos> positions_shifted(cvm::rvector const &shift) const; | /// that they are already pbc-wrapped |
| int calc_center_of_geometry(); |
| |
| private: |
| |
| /// \brief Center of geometry |
| cvm::atom_pos cog; |
| |
| /// \brief Center of geometry before any fitting |
| cvm::atom_pos cog_orig; |
| |
| public: |
| |
/// \brief Return the center of geometry of the positions, assuming | /// \brief Return the center of geometry of the atomic positions |
/// that coordinates are already pbc-wrapped | inline cvm::atom_pos center_of_geometry() const |
cvm::atom_pos center_of_geometry() const; | { |
| return cog; |
/// \brief Return the center of mass of the positions, assuming that | } |
/// coordinates are already pbc-wrapped | |
cvm::atom_pos center_of_mass() const; | |
| |
/// \brief Atom positions at the previous step | /// \brief Calculate the center of mass of the atomic positions, assuming that |
std::vector<cvm::atom_pos> old_pos; | /// they are already pbc-wrapped |
| int calc_center_of_mass(); |
| private: |
| /// \brief Center of mass |
| cvm::atom_pos com; |
| /// \brief The derivative of a scalar variable with respect to the COM |
| // TODO for scalable calculations of more complex variables (e.g. rotation), |
| // use a colvarvalue of vectors to hold the entire derivative |
| cvm::rvector scalar_com_gradient; |
| public: |
| /// \brief Return the center of mass of the atomic positions |
| inline cvm::atom_pos center_of_mass() const |
| { |
| return com; |
| } |
| |
| /// \brief Return a copy of the current atom positions, shifted by a constant vector |
| std::vector<cvm::atom_pos> positions_shifted(cvm::rvector const &shift) const; |
| |
/// \brief Return a copy of the current atom velocities | /// \brief Return a copy of the current atom velocities |
std::vector<cvm::rvector> velocities() const; | std::vector<cvm::rvector> velocities() const; |
| |
| ///\brief Calculate the dipole of the atom group around the specified center |
| int calc_dipole(cvm::atom_pos const &com); |
| private: |
| cvm::rvector dip; |
| public: |
| ///\brief Return the (previously calculated) dipole of the atom group |
| inline cvm::rvector dipole() const |
| { |
| return dip; |
| } |
| |
| /// \brief Return a copy of the total forces |
| std::vector<cvm::rvector> total_forces() const; |
| |
/// \brief Return a copy of the system forces | |
std::vector<cvm::rvector> system_forces() const; | |
/// \brief Return a copy of the aggregated total force on the group | /// \brief Return a copy of the aggregated total force on the group |
cvm::rvector system_force() const; | cvm::rvector total_force() const; |
| |
| |
/// \brief Shorthand: save the specified gradient on each atom, | /// \brief Shorthand: save the specified gradient on each atom, |
| |
/// micromanage the force. | /// micromanage the force. |
void apply_force(cvm::rvector const &force); | void apply_force(cvm::rvector const &force); |
| |
/// \brief Apply an array of forces directly on the individual | |
/// atoms; the length of the specified vector must be the same of | |
/// this \link atom_group \endlink. | |
/// | |
/// If the group is being rotated to a reference frame (e.g. to | |
/// express the colvar independently from the solute rotation), the | |
/// forces are rotated back to the original frame. Colvar gradients | |
/// are not used, either because they were not defined (e.g because | |
/// the colvar has not a scalar value) or the biases require to | |
/// micromanage the forces. | |
void apply_forces(std::vector<cvm::rvector> const &forces); | |
| |
}; | }; |
| |
| |