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 COLVARDEPS_H 00011 #define COLVARDEPS_H 00012 00013 #include "colvarmodule.h" 00014 #include "colvarparse.h" 00015 00034 class colvardeps { 00035 public: 00036 00037 colvardeps(); 00038 virtual ~colvardeps(); 00039 00040 // Subclasses should initialize the following members: 00041 00042 std::string description; // reference to object name (cv, cvc etc.) 00043 00045 // since the feature class only contains static properties 00046 struct feature_state { 00047 feature_state(bool a, bool e) 00048 : available(a), enabled(e), ref_count(0) {} 00049 00051 bool available; 00055 bool enabled; // see if this should be private depending on implementation 00056 00057 // bool enabledOnce; // this should trigger an update when object is evaluated 00058 00063 int ref_count; 00068 std::vector<int> alternate_refs; 00069 }; 00070 00071 protected: 00077 int time_step_factor; 00078 00080 std::vector<feature_state> feature_states; 00081 00083 enum feature_type { 00084 f_type_not_set, 00085 f_type_dynamic, 00086 f_type_user, 00087 f_type_static 00088 }; 00089 00090 public: 00092 inline int get_time_step_factor() const {return time_step_factor;} 00093 00095 void init_feature(int feature_id, const char *description, feature_type type); 00096 00099 class feature { 00100 00101 public: 00102 feature() : type(f_type_not_set) {} 00103 ~feature() {} 00104 00105 std::string description; // Set by derived object initializer 00106 00107 // features that this feature requires in the same object 00108 // NOTE: we have no safety mechanism against circular dependencies, however, they would have to be internal to an object (ie. requires_self or requires_alt) 00109 std::vector<int> requires_self; 00110 00111 // Features that are incompatible, ie. required disabled 00112 // if enabled, they will cause a dependency failure (they will not be disabled) 00113 // To enforce these dependencies regardless of the order in which they 00114 // are enabled, they are always set in a symmetric way, so whichever is enabled 00115 // second will cause the dependency to fail 00116 std::vector<int> requires_exclude; 00117 00118 // sets of features that are required in an alternate way 00119 // when parent feature is enabled, if none are enabled, the first one listed that is available will be enabled 00120 std::vector<std::vector<int> > requires_alt; 00121 00122 // features that this feature requires in children 00123 std::vector<int> requires_children; 00124 00125 inline bool is_dynamic() { return type == f_type_dynamic; } 00126 inline bool is_static() { return type == f_type_static; } 00127 inline bool is_user() { return type == f_type_user; } 00129 feature_type type; 00130 }; 00131 00132 inline bool is_not_set(int id) { return features()[id]->type == f_type_not_set; } 00133 inline bool is_dynamic(int id) { return features()[id]->type == f_type_dynamic; } 00134 inline bool is_static(int id) { return features()[id]->type == f_type_static; } 00135 inline bool is_user(int id) { return features()[id]->type == f_type_user; } 00136 00137 // Accessor to array of all features with deps, static in most derived classes 00138 // Subclasses with dynamic dependency trees may override this 00139 // with a non-static array 00140 // Intermediate classes (colvarbias and colvarcomp, which are also base classes) 00141 // implement this as virtual to allow overriding 00142 virtual const std::vector<feature *> &features() const = 0; 00143 virtual std::vector<feature *>&modify_features() = 0; 00144 00145 void add_child(colvardeps *child); 00146 00147 void remove_child(colvardeps *child); 00148 00151 void remove_all_children(); 00152 00153 private: 00154 00158 std::vector<colvardeps *> children; 00159 00162 std::vector<colvardeps *> parents; 00163 00164 public: 00165 // Checks whether given feature is enabled 00166 // Defaults to querying f_*_active 00167 inline bool is_enabled(int f = f_cv_active) const { 00168 return feature_states[f].enabled; 00169 } 00170 00171 // Checks whether given feature is available 00172 // Defaults to querying f_*_active 00173 inline bool is_available(int f = f_cv_active) const { 00174 return feature_states[f].available; 00175 } 00176 00180 void provide(int feature_id, bool truefalse = true); 00181 00183 void set_enabled(int feature_id, bool truefalse = true); 00184 00185 protected: 00186 00188 bool get_keyval_feature(colvarparse *cvp, 00189 std::string const &conf, char const *key, 00190 int feature_id, bool const &def_value, 00191 colvarparse::Parse_Mode const parse_mode = colvarparse::parse_normal); 00192 00193 public: 00194 00201 int enable(int f, bool dry_run = false, bool toplevel = true); 00202 00205 int disable(int f); 00206 00210 void free_children_deps(); 00211 00213 void restore_children_deps(); 00214 00217 int decr_ref_count(int f); 00218 00222 virtual void do_feature_side_effects(int /* id */) {} 00223 00224 // NOTE that all feature enums should start with f_*_active 00225 enum features_biases { 00227 f_cvb_active, 00229 f_cvb_awake, 00231 f_cvb_step_zero_data, 00233 f_cvb_apply_force, 00235 f_cvb_bypass_ext_lagrangian, 00237 f_cvb_get_total_force, 00239 f_cvb_output_acc_work, 00241 f_cvb_history_dependent, 00243 f_cvb_time_dependent, 00245 f_cvb_scalar_variables, 00247 f_cvb_calc_pmf, 00249 f_cvb_calc_ti_samples, 00251 f_cvb_write_ti_samples, 00253 f_cvb_write_ti_pmf, 00255 f_cvb_scale_biasing_force, 00256 f_cvb_ntot 00257 }; 00258 00259 enum features_colvar { 00261 f_cv_active, 00263 f_cv_awake, 00266 f_cv_gradient, 00269 f_cv_collect_gradient, 00271 f_cv_collect_atom_ids, 00273 f_cv_fdiff_velocity, 00276 f_cv_total_force, 00278 f_cv_total_force_calc, 00280 f_cv_subtract_applied_force, 00282 f_cv_Jacobian, 00285 f_cv_hide_Jacobian, 00289 f_cv_extended_Lagrangian, 00293 f_cv_external, 00295 f_cv_Langevin, 00298 f_cv_output_energy, 00300 f_cv_output_value, 00302 f_cv_output_velocity, 00304 f_cv_output_applied_force, 00306 f_cv_output_total_force, 00308 f_cv_lower_boundary, 00310 f_cv_upper_boundary, 00312 f_cv_hard_lower_boundary, 00314 f_cv_hard_upper_boundary, 00316 f_cv_reflecting_lower_boundary, 00318 f_cv_reflecting_upper_boundary, 00322 f_cv_grid, 00324 f_cv_runave, 00326 f_cv_corrfunc, 00328 f_cv_scripted, 00330 f_cv_custom_function, 00332 f_cv_periodic, 00334 f_cv_single_cvc, 00336 f_cv_scalar, 00337 f_cv_linear, 00338 f_cv_homogeneous, 00340 f_cv_multiple_ts, 00342 f_cv_ntot 00343 }; 00344 00345 enum features_cvc { 00347 f_cvc_active, 00349 f_cvc_scalar, 00351 f_cvc_periodic, 00353 f_cvc_width, 00355 f_cvc_lower_boundary, 00357 f_cvc_upper_boundary, 00359 f_cvc_gradient, 00361 f_cvc_explicit_gradient, 00363 f_cvc_inv_gradient, 00365 f_cvc_Jacobian, 00367 f_cvc_one_site_total_force, 00369 f_cvc_debug_gradient, 00372 f_cvc_pbc_minimum_image, 00374 f_cvc_com_based, 00376 f_cvc_scalable, 00378 f_cvc_scalable_com, 00380 f_cvc_collect_atom_ids, 00382 f_cvc_ntot 00383 }; 00384 00385 enum features_atomgroup { 00386 f_ag_active, 00387 f_ag_center, 00388 f_ag_center_origin, 00389 f_ag_rotate, 00390 f_ag_fitting_group, 00393 // f_ag_min_msd_fit, 00395 f_ag_explicit_gradient, 00396 f_ag_fit_gradients, 00397 f_ag_atom_forces, 00398 f_ag_scalable, 00399 f_ag_scalable_com, 00401 f_ag_collect_atom_ids, 00402 f_ag_ntot 00403 }; 00404 00406 virtual int init_dependencies() = 0; 00407 00409 void require_feature_self(int f, int g); 00410 00412 void exclude_feature_self(int f, int g); 00413 00415 void require_feature_children(int f, int g); 00416 00418 void require_feature_alt(int f, int g, int h); 00419 00421 void require_feature_alt(int f, int g, int h, int i); 00422 00424 void require_feature_alt(int f, int g, int h, int i, int j); 00425 00427 void print_state(); 00428 00430 inline void check_enabled(int f, std::string const &reason) const 00431 { 00432 if (! is_enabled(f)) { 00433 cvm::error("Error: "+reason+" requires that the feature \""+ 00434 features()[f]->description+"\" is active.\n", COLVARS_BUG_ERROR); 00435 } 00436 } 00437 00438 }; 00439 00440 #endif 00441 00442