version 1.4 | version 1.5 |
---|
| |
/// 3. Static features are static properties of the object, determined | /// 3. Static features are static properties of the object, determined |
/// programatically at initialization time. | /// programatically at initialization time. |
/// | /// |
| /// In all classes, feature 0 is active. When an object is inactivated |
| /// all its children dependencies are dereferenced (free_children_deps) |
| /// While the object is inactive, no dependency solving is done on children |
| /// it is done when the object is activated back (restore_children_deps) |
class colvardeps { | class colvardeps { |
public: | public: |
| |
colvardeps() {} | colvardeps(); |
virtual ~colvardeps(); | virtual ~colvardeps(); |
| |
// Subclasses should initialize the following members: | // Subclasses should initialize the following members: |
| |
std::string description; // reference to object name (cv, cvc etc.) | std::string description; // reference to object name (cv, cvc etc.) |
| |
/// This contains the current state of each feature for each object | /// This contains the current state of each feature for each object |
| // since the feature class only contains static properties |
struct feature_state { | struct feature_state { |
feature_state(bool a, bool e) | feature_state(bool a, bool e) |
: available(a), enabled(e) {} | : available(a), enabled(e), ref_count(0) {} |
| |
/// Feature may be enabled, subject to possible dependencies | /// Feature may be enabled, subject to possible dependencies |
bool available; | bool available; |
| |
/// TODO consider implications for dependency solving: anyone who disables | /// TODO consider implications for dependency solving: anyone who disables |
/// it should trigger a refresh of parent objects | /// it should trigger a refresh of parent objects |
bool enabled; // see if this should be private depending on implementation | bool enabled; // see if this should be private depending on implementation |
| |
// bool enabledOnce; // this should trigger an update when object is evaluated | // bool enabledOnce; // this should trigger an update when object is evaluated |
| |
| /// Number of features requiring this one as a dependency |
| /// When it falls to zero: |
| /// - a dynamic feature is disabled automatically |
| /// - other features may be disabled statically |
| int ref_count; |
| /// List of features that were enabled by this one |
| /// as part of an alternate requirement (for ref counting purposes) |
| /// This is necessary because we don't know which feature in the list |
| /// we enabled, otherwise |
| std::vector<int> alternate_refs; |
}; | }; |
| |
| protected: |
| /// Time step multiplier (for coarse-timestep biases & colvars) |
| /// Biases and colvars will only be calculated at those times |
| /// (f_cvb_awake and f_cv_awake); a |
| /// Biases use this to apply "impulse" biasing forces at the outer timestep |
| /// Unused by lower-level objects (cvcs and atom groups) |
| int time_step_factor; |
| |
private: | private: |
/// List of the states of all features | /// List of the states of all features |
| |
}; | }; |
| |
public: | public: |
| /// \brief returns time_step_factor |
| inline int get_time_step_factor() const {return time_step_factor;} |
| |
/// Pair a numerical feature ID with a description and type | /// Pair a numerical feature ID with a description and type |
void init_feature(int feature_id, const char *description, feature_type type = f_type_not_set); | void init_feature(int feature_id, const char *description, feature_type type = f_type_not_set); |
| |
/// Describes a feature and its dependecies | /// Describes a feature and its dependencies |
/// used in a static array within each subclass | /// used in a static array within each subclass |
class feature { | class feature { |
| |
| |
| |
private: | private: |
| |
// pointers to objects this object depends on | /// pointers to objects this object depends on |
// list should be maintained by any code that modifies the object | /// list should be maintained by any code that modifies the object |
// this could be secured by making lists of colvars / cvcs / atom groups private and modified through accessor functions | /// this could be secured by making lists of colvars / cvcs / atom groups private and modified through accessor functions |
std::vector<colvardeps *> children; | std::vector<colvardeps *> children; |
| |
// pointers to objects that depend on this object | /// pointers to objects that depend on this object |
// the size of this array is in effect a reference counter | /// the size of this array is in effect a reference counter |
std::vector<colvardeps *> parents; | std::vector<colvardeps *> parents; |
| |
public: | public: |
| |
/// dependencies will be checked by enable() | /// dependencies will be checked by enable() |
void provide(int feature_id, bool truefalse = true); | void provide(int feature_id, bool truefalse = true); |
| |
/// Set the feature's enabled flag, without dependency check or resolution | /// Enable or disable, depending on flag value |
/// To be used for static properties only | |
/// Checking for availability is up to the caller | |
void set_enabled(int feature_id, bool truefalse = true); | void set_enabled(int feature_id, bool truefalse = true); |
| |
protected: | protected: |
| |
| |
public: | public: |
| |
int enable(int f, bool dry_run = false, bool toplevel = true); // enable a feature and recursively solve its dependencies | /// enable a feature and recursively solve its dependencies |
// dry_run is set to true to recursively test if a feature is available, without enabling it | /// for proper reference counting, one should not add |
// int disable(int f); | /// spurious calls to enable() |
| /// dry_run is set to true to recursively test if a feature is available, without enabling it |
| int enable(int f, bool dry_run = false, bool toplevel = true); |
/// This function is called whenever feature states are changed outside | |
/// of the object's control, that is, by parents | /// Disable a feature, decrease the reference count of its dependencies |
/// Eventually it may also be used when properties of children change | /// and recursively disable them as applicable |
virtual int refresh_deps() { return COLVARS_OK; } | int disable(int f); |
| |
| /// disable all enabled features to free their dependencies |
| /// to be done when deleting the object |
| /// Cannot be in the base class destructor because it needs the derived class features() |
| void free_children_deps(); |
| |
| /// re-enable children features (to be used when object becomes active) |
| void restore_children_deps(); |
| |
| /// Decrement the reference count of a feature |
| /// disabling it if it's dynamic and count reaches zero |
| int decr_ref_count(int f); |
| |
| /// Implements possible actions to be carried out |
| /// when a given feature is enabled |
| /// Base function does nothing, can be overloaded |
| virtual void do_feature_side_effects(int id) {} |
| |
// NOTE that all feature enums should start with f_*_active | // NOTE that all feature enums should start with f_*_active |
enum features_biases { | enum features_biases { |
/// \brief Bias is active | /// \brief Bias is active |
f_cvb_active, | f_cvb_active, |
f_cvb_apply_force, // will apply forces | /// \brief Bias is awake (active on its own accord) this timestep |
f_cvb_get_total_force, // requires total forces | f_cvb_awake, |
f_cvb_history_dependent, // depends on simulation history | /// \brief will apply forces |
f_cvb_scalar_variables, // requires scalar colvars | f_cvb_apply_force, |
f_cvb_calc_pmf, // whether this bias will compute a PMF | /// \brief requires total forces |
| f_cvb_get_total_force, |
| /// \brief depends on simulation history |
| f_cvb_history_dependent, |
| /// \brief requires scalar colvars |
| f_cvb_scalar_variables, |
| /// \brief whether this bias will compute a PMF |
| f_cvb_calc_pmf, |
f_cvb_ntot | f_cvb_ntot |
}; | }; |
| |
enum features_colvar { | enum features_colvar { |
/// \brief Calculate colvar | /// \brief Calculate colvar |
f_cv_active, | f_cv_active, |
| /// \brief Colvar is awake (active on its own accord) this timestep |
| f_cv_awake, |
/// \brief Gradients are calculated and temporarily stored, so | /// \brief Gradients are calculated and temporarily stored, so |
/// that external forces can be applied | /// that external forces can be applied |
f_cv_gradient, | f_cv_gradient, |
| |
f_cv_scalar, | f_cv_scalar, |
f_cv_linear, | f_cv_linear, |
f_cv_homogeneous, | f_cv_homogeneous, |
| /// \brief multiple timestep through time_step_factor |
| f_cv_multiple_ts, |
/// \brief Number of colvar features | /// \brief Number of colvar features |
f_cv_ntot | f_cv_ntot |
}; | }; |
| |
/// Perform a standard minimum msd fit for given atoms | /// Perform a standard minimum msd fit for given atoms |
/// ie. not using refpositionsgroup | /// ie. not using refpositionsgroup |
// f_ag_min_msd_fit, | // f_ag_min_msd_fit, |
f_ag_fit_gradient_group,// TODO check that these are sometimes needed separately | f_ag_fit_gradients, |
// maybe for minimum RMSD? | |
f_ag_fit_gradient_ref, | |
f_ag_atom_forces, | f_ag_atom_forces, |
f_ag_scalable, | f_ag_scalable, |
f_ag_scalable_com, | f_ag_scalable_com, |