version 1.5 | version 1.6 |
---|
| |
} | } |
| |
| |
void colvardeps::provide(int feature_id) { | void colvardeps::provide(int feature_id, bool truefalse) { |
feature_states[feature_id].available = true; | |
} | |
| |
| |
void colvardeps::set_available(int feature_id, bool truefalse) { | |
feature_states[feature_id].available = truefalse; | feature_states[feature_id].available = truefalse; |
} | } |
| |
| |
void colvardeps::set_enabled(int feature_id, bool truefalse) { | void colvardeps::set_enabled(int feature_id, bool truefalse) { |
feature_states[feature_id].enabled = truefalse; | // if (!is_static(feature_id)) { |
| // cvm::error("Cannot set feature " + features()[feature_id]->description + " statically in " + description + ".\n"); |
| // return; |
| // } |
| if (truefalse) { |
| // Resolve dependencies too |
| enable(feature_id); |
| } else { |
| feature_states[feature_id].enabled = false; |
| } |
} | } |
| |
| |
| |
int feature_id, bool const &def_value, | int feature_id, bool const &def_value, |
colvarparse::Parse_Mode const parse_mode) | colvarparse::Parse_Mode const parse_mode) |
{ | { |
| if (!is_user(feature_id)) { |
| cvm::error("Cannot set feature " + features()[feature_id]->description + " from user input in " + description + ".\n"); |
| return false; |
| } |
bool value; | bool value; |
bool const found = cvp->get_keyval(conf, key, value, def_value, parse_mode); | bool const found = cvp->get_keyval(conf, key, value, def_value, parse_mode); |
if (value) enable(feature_id); | if (value) enable(feature_id); |
| |
return COLVARS_ERROR; | return COLVARS_ERROR; |
} | } |
| |
| if (!toplevel && !is_dynamic(feature_id)) { |
| if (!dry_run) { |
| cvm::log("Non-dynamic feature : \"" + f->description |
| + "\" in " + description + " may not be enabled as a dependency.\n"); |
| } |
| return COLVARS_ERROR; |
| } |
| |
// 1) enforce exclusions | // 1) enforce exclusions |
for (i=0; i<f->requires_exclude.size(); i++) { | for (i=0; i<f->requires_exclude.size(); i++) { |
feature *g = features()[f->requires_exclude[i]]; | feature *g = features()[f->requires_exclude[i]]; |
| |
// // we need refs to parents to walk up the deps tree! | // // we need refs to parents to walk up the deps tree! |
// // or refresh | // // or refresh |
// } | // } |
| void colvardeps::init_feature(int feature_id, const char *description, feature_type type) { |
| features()[feature_id]->description = description; |
| features()[feature_id]->type = type; |
| } |
| |
// Shorthand macros for describing dependencies | // Shorthand macros for describing dependencies |
#define f_description(f, d) features()[f]->description = d | |
#define f_req_self(f, g) features()[f]->requires_self.push_back(g) | #define f_req_self(f, g) features()[f]->requires_self.push_back(g) |
// This macro ensures that exclusions are symmetric | // This macro ensures that exclusions are symmetric |
#define f_req_exclude(f, g) features()[f]->requires_exclude.push_back(g); \ | #define f_req_exclude(f, g) features()[f]->requires_exclude.push_back(g); \ |
| |
for (i = 0; i < f_cvb_ntot; i++) { | for (i = 0; i < f_cvb_ntot; i++) { |
features().push_back(new feature); | features().push_back(new feature); |
} | } |
} | |
| |
f_description(f_cvb_active, "active"); | init_feature(f_cvb_active, "active", f_type_dynamic); |
f_req_children(f_cvb_active, f_cv_active); | f_req_children(f_cvb_active, f_cv_active); |
| |
f_description(f_cvb_apply_force, "apply force"); | init_feature(f_cvb_apply_force, "apply force", f_type_user); |
f_req_children(f_cvb_apply_force, f_cv_gradient); | f_req_children(f_cvb_apply_force, f_cv_gradient); |
| |
f_description(f_cvb_get_total_force, "obtain total force"); | init_feature(f_cvb_get_total_force, "obtain total force"); |
f_req_children(f_cvb_get_total_force, f_cv_total_force); | f_req_children(f_cvb_get_total_force, f_cv_total_force); |
| |
f_description(f_cvb_history_dependent, "history-dependent"); | init_feature(f_cvb_history_dependent, "history-dependent", f_type_static); |
| |
f_description(f_cvb_scalar_variables, "require scalar variables"); | init_feature(f_cvb_scalar_variables, "require scalar variables", f_type_static); |
f_req_children(f_cvb_scalar_variables, f_cv_scalar); | f_req_children(f_cvb_scalar_variables, f_cv_scalar); |
| |
f_description(f_cvb_calc_pmf, "calculate a PMF"); | init_feature(f_cvb_calc_pmf, "calculate a PMF", f_type_static); |
// TODO define requirements? | } |
| |
// Initialize feature_states for each instance | // Initialize feature_states for each instance |
feature_states.reserve(f_cvb_ntot); | feature_states.reserve(f_cvb_ntot); |
| |
// Most features are available, so we set them so | // Most features are available, so we set them so |
// and list exceptions below | // and list exceptions below |
} | } |
| |
// some biases are not history-dependent | |
feature_states[f_cvb_history_dependent].available = false; | |
| |
// some biases do not compute a PMF | |
feature_states[f_cvb_calc_pmf].available = false; | |
| |
// by default, biases should work with vector variables, too | |
feature_states[f_cvb_scalar_variables].available = false; | |
} | } |
| |
| |
| |
features().push_back(new feature); | features().push_back(new feature); |
} | } |
| |
f_description(f_cv_active, "active"); | init_feature(f_cv_active, "active", f_type_dynamic); |
f_req_children(f_cv_active, f_cvc_active); | f_req_children(f_cv_active, f_cvc_active); |
// Colvars must be either a linear combination, or scalar (and polynomial) or scripted | // Colvars must be either a linear combination, or scalar (and polynomial) or scripted |
f_req_alt3(f_cv_active, f_cv_scalar, f_cv_linear, f_cv_scripted); | f_req_alt3(f_cv_active, f_cv_scalar, f_cv_linear, f_cv_scripted); |
| |
f_description(f_cv_gradient, "gradient"); | init_feature(f_cv_gradient, "gradient", f_type_dynamic); |
f_req_children(f_cv_gradient, f_cvc_gradient); | f_req_children(f_cv_gradient, f_cvc_gradient); |
| |
f_description(f_cv_collect_gradient, "collect gradient"); | init_feature(f_cv_collect_gradient, "collect gradient", f_type_dynamic); |
f_req_self(f_cv_collect_gradient, f_cv_gradient); | f_req_self(f_cv_collect_gradient, f_cv_gradient); |
f_req_self(f_cv_collect_gradient, f_cv_scalar); | f_req_self(f_cv_collect_gradient, f_cv_scalar); |
| |
f_description(f_cv_fdiff_velocity, "fdiff_velocity"); | init_feature(f_cv_fdiff_velocity, "fdiff_velocity", f_type_dynamic); |
| |
// System force: either trivial (spring force); through extended Lagrangian, or calculated explicitly | // System force: either trivial (spring force); through extended Lagrangian, or calculated explicitly |
f_description(f_cv_total_force, "total force"); | init_feature(f_cv_total_force, "total force", f_type_dynamic); |
f_req_alt2(f_cv_total_force, f_cv_extended_Lagrangian, f_cv_total_force_calc); | f_req_alt2(f_cv_total_force, f_cv_extended_Lagrangian, f_cv_total_force_calc); |
| |
// Deps for explicit total force calculation | // Deps for explicit total force calculation |
f_description(f_cv_total_force_calc, "total force calculation"); | init_feature(f_cv_total_force_calc, "total force calculation", f_type_dynamic); |
f_req_self(f_cv_total_force_calc, f_cv_scalar); | f_req_self(f_cv_total_force_calc, f_cv_scalar); |
f_req_self(f_cv_total_force_calc, f_cv_linear); | f_req_self(f_cv_total_force_calc, f_cv_linear); |
f_req_children(f_cv_total_force_calc, f_cvc_inv_gradient); | f_req_children(f_cv_total_force_calc, f_cvc_inv_gradient); |
f_req_self(f_cv_total_force_calc, f_cv_Jacobian); | f_req_self(f_cv_total_force_calc, f_cv_Jacobian); |
| |
f_description(f_cv_Jacobian, "Jacobian derivative"); | init_feature(f_cv_Jacobian, "Jacobian derivative", f_type_dynamic); |
f_req_self(f_cv_Jacobian, f_cv_scalar); | f_req_self(f_cv_Jacobian, f_cv_scalar); |
f_req_self(f_cv_Jacobian, f_cv_linear); | f_req_self(f_cv_Jacobian, f_cv_linear); |
f_req_children(f_cv_Jacobian, f_cvc_Jacobian); | f_req_children(f_cv_Jacobian, f_cvc_Jacobian); |
| |
f_description(f_cv_hide_Jacobian, "hide Jacobian force"); | init_feature(f_cv_hide_Jacobian, "hide Jacobian force", f_type_user); |
f_req_self(f_cv_hide_Jacobian, f_cv_Jacobian); // can only hide if calculated | f_req_self(f_cv_hide_Jacobian, f_cv_Jacobian); // can only hide if calculated |
| |
f_description(f_cv_extended_Lagrangian, "extended Lagrangian"); | init_feature(f_cv_extended_Lagrangian, "extended Lagrangian", f_type_user); |
| f_req_self(f_cv_extended_Lagrangian, f_cv_scalar); |
| f_req_self(f_cv_extended_Lagrangian, f_cv_gradient); |
| |
f_description(f_cv_Langevin, "Langevin dynamics"); | init_feature(f_cv_Langevin, "Langevin dynamics", f_type_user); |
f_req_self(f_cv_Langevin, f_cv_extended_Lagrangian); | f_req_self(f_cv_Langevin, f_cv_extended_Lagrangian); |
| |
f_description(f_cv_linear, "linear"); | init_feature(f_cv_linear, "linear", f_type_static); |
| |
f_description(f_cv_scalar, "scalar"); | init_feature(f_cv_scalar, "scalar", f_type_static); |
| |
f_description(f_cv_output_energy, "output energy"); | init_feature(f_cv_output_energy, "output energy", f_type_user); |
| |
f_description(f_cv_output_value, "output value"); | init_feature(f_cv_output_value, "output value", f_type_user); |
| |
f_description(f_cv_output_velocity, "output velocity"); | init_feature(f_cv_output_velocity, "output velocity", f_type_user); |
f_req_self(f_cv_output_velocity, f_cv_fdiff_velocity); | f_req_self(f_cv_output_velocity, f_cv_fdiff_velocity); |
| |
f_description(f_cv_output_applied_force, "output applied force"); | init_feature(f_cv_output_applied_force, "output applied force", f_type_user); |
| |
f_description(f_cv_output_total_force, "output total force"); | init_feature(f_cv_output_total_force, "output total force", f_type_user); |
f_req_self(f_cv_output_total_force, f_cv_total_force); | f_req_self(f_cv_output_total_force, f_cv_total_force); |
| |
f_description(f_cv_subtract_applied_force, "subtract applied force from total force"); | init_feature(f_cv_subtract_applied_force, "subtract applied force from total force", f_type_user); |
f_req_self(f_cv_subtract_applied_force, f_cv_total_force); | f_req_self(f_cv_subtract_applied_force, f_cv_total_force); |
| // There is no well-defined way to implement f_cv_subtract_applied_force |
| // in the case of extended-Lagrangian colvars |
| f_req_exclude(f_cv_subtract_applied_force, f_cv_extended_Lagrangian); |
| |
f_description(f_cv_lower_boundary, "lower boundary"); | init_feature(f_cv_lower_boundary, "lower boundary", f_type_user); |
f_req_self(f_cv_lower_boundary, f_cv_scalar); | f_req_self(f_cv_lower_boundary, f_cv_scalar); |
| |
f_description(f_cv_upper_boundary, "upper boundary"); | init_feature(f_cv_upper_boundary, "upper boundary", f_type_user); |
f_req_self(f_cv_upper_boundary, f_cv_scalar); | f_req_self(f_cv_upper_boundary, f_cv_scalar); |
| |
f_description(f_cv_grid, "grid"); | init_feature(f_cv_grid, "grid", f_type_user); |
f_req_self(f_cv_grid, f_cv_lower_boundary); | f_req_self(f_cv_grid, f_cv_lower_boundary); |
f_req_self(f_cv_grid, f_cv_upper_boundary); | f_req_self(f_cv_grid, f_cv_upper_boundary); |
| |
f_description(f_cv_runave, "running average"); | init_feature(f_cv_runave, "running average", f_type_user); |
| |
f_description(f_cv_corrfunc, "correlation function"); | init_feature(f_cv_corrfunc, "correlation function", f_type_user); |
| |
// The features below are set programmatically | init_feature(f_cv_scripted, "scripted", f_type_static); |
f_description(f_cv_scripted, "scripted"); | init_feature(f_cv_periodic, "periodic", f_type_static); |
f_description(f_cv_periodic, "periodic"); | |
f_req_self(f_cv_periodic, f_cv_homogeneous); | f_req_self(f_cv_periodic, f_cv_homogeneous); |
f_description(f_cv_scalar, "scalar"); | init_feature(f_cv_scalar, "scalar", f_type_static); |
f_description(f_cv_linear, "linear"); | init_feature(f_cv_linear, "linear", f_type_static); |
f_description(f_cv_homogeneous, "homogeneous"); | init_feature(f_cv_homogeneous, "homogeneous", f_type_static); |
} | } |
| |
// Initialize feature_states for each instance | // Initialize feature_states for each instance |
| |
// and list exceptions below | // and list exceptions below |
} | } |
| |
// properties that may NOT be enabled as a dependency | // // properties that may NOT be enabled as a dependency |
int unavailable_deps[] = { | // // This will be deprecated by feature types |
f_cv_lower_boundary, | // int unavailable_deps[] = { |
f_cv_upper_boundary, | // f_cv_lower_boundary, |
f_cv_extended_Lagrangian, | // f_cv_upper_boundary, |
f_cv_Langevin, | // f_cv_extended_Lagrangian, |
f_cv_scripted, | // f_cv_Langevin, |
f_cv_periodic, | // f_cv_scripted, |
f_cv_scalar, | // f_cv_periodic, |
f_cv_linear, | // f_cv_scalar, |
f_cv_homogeneous | // f_cv_linear, |
}; | // f_cv_homogeneous |
for (i = 0; i < sizeof(unavailable_deps) / sizeof(unavailable_deps[0]); i++) { | // }; |
feature_states[unavailable_deps[i]].available = false; | // for (i = 0; i < sizeof(unavailable_deps) / sizeof(unavailable_deps[0]); i++) { |
} | // feature_states[unavailable_deps[i]].available = false; |
| // } |
} | } |
| |
| |
| |
features().push_back(new feature); | features().push_back(new feature); |
} | } |
| |
f_description(f_cvc_active, "active"); | init_feature(f_cvc_active, "active", f_type_dynamic); |
// The dependency below may become useful if we use dynamic atom groups | // The dependency below may become useful if we use dynamic atom groups |
// f_req_children(f_cvc_active, f_ag_active); | // f_req_children(f_cvc_active, f_ag_active); |
| |
f_description(f_cvc_scalar, "scalar"); | init_feature(f_cvc_scalar, "scalar", f_type_static); |
| |
f_description(f_cvc_gradient, "gradient"); | init_feature(f_cvc_gradient, "gradient", f_type_dynamic); |
| |
f_description(f_cvc_inv_gradient, "inverse gradient"); | init_feature(f_cvc_inv_gradient, "inverse gradient", f_type_dynamic); |
f_req_self(f_cvc_inv_gradient, f_cvc_gradient); | f_req_self(f_cvc_inv_gradient, f_cvc_gradient); |
| |
f_description(f_cvc_debug_gradient, "debug gradient"); | init_feature(f_cvc_debug_gradient, "debug gradient", f_type_user); |
f_req_self(f_cvc_debug_gradient, f_cvc_gradient); | f_req_self(f_cvc_debug_gradient, f_cvc_gradient); |
| |
f_description(f_cvc_Jacobian, "Jacobian derivative"); | init_feature(f_cvc_Jacobian, "Jacobian derivative", f_type_dynamic); |
f_req_self(f_cvc_Jacobian, f_cvc_inv_gradient); | f_req_self(f_cvc_Jacobian, f_cvc_inv_gradient); |
| |
f_description(f_cvc_com_based, "depends on group centers of mass"); | init_feature(f_cvc_com_based, "depends on group centers of mass", f_type_static); |
| |
// Compute total force on first site only to avoid unwanted | // Compute total force on first site only to avoid unwanted |
// coupling to other colvars (see e.g. Ciccotti et al., 2005) | // coupling to other colvars (see e.g. Ciccotti et al., 2005) |
f_description(f_cvc_one_site_total_force, "compute total collective force only from one group center"); | init_feature(f_cvc_one_site_total_force, "compute total collective force only from one group center", f_type_user); |
f_req_self(f_cvc_one_site_total_force, f_cvc_com_based); | f_req_self(f_cvc_one_site_total_force, f_cvc_com_based); |
| |
f_description(f_cvc_scalable, "scalable calculation"); | init_feature(f_cvc_scalable, "scalable calculation", f_type_static); |
f_req_self(f_cvc_scalable, f_cvc_scalable_com); | f_req_self(f_cvc_scalable, f_cvc_scalable_com); |
| |
f_description(f_cvc_scalable_com, "scalable calculation of centers of mass"); | init_feature(f_cvc_scalable_com, "scalable calculation of centers of mass", f_type_static); |
f_req_self(f_cvc_scalable_com, f_cvc_com_based); | f_req_self(f_cvc_scalable_com, f_cvc_com_based); |
| |
| |
| |
} | } |
| |
// Initialize feature_states for each instance | // Initialize feature_states for each instance |
// default as unavailable, not enabled | // default as available, not enabled |
| // except dynamic features which default as unavailable |
feature_states.reserve(f_cvc_ntot); | feature_states.reserve(f_cvc_ntot); |
for (i = 0; i < colvardeps::f_cvc_ntot; i++) { | for (i = 0; i < colvardeps::f_cvc_ntot; i++) { |
feature_states.push_back(feature_state(false, false)); | bool avail = is_dynamic(i) ? false : true; |
| feature_states.push_back(feature_state(avail, false)); |
} | } |
| |
// Features that are implemented by all cvcs by default | // Features that are implemented by all cvcs by default |
| |
features().push_back(new feature); | features().push_back(new feature); |
} | } |
| |
f_description(f_ag_active, "active"); | init_feature(f_ag_active, "active", f_type_dynamic); |
f_description(f_ag_center, "translational fit"); | init_feature(f_ag_center, "translational fit", f_type_static); |
f_description(f_ag_rotate, "rotational fit"); | init_feature(f_ag_rotate, "rotational fit", f_type_static); |
f_description(f_ag_fitting_group, "reference positions group"); | init_feature(f_ag_fitting_group, "reference positions group", f_type_static); |
f_description(f_ag_fit_gradient_group, "fit gradient for main group"); | init_feature(f_ag_fit_gradient_group, "fit gradient for main group", f_type_static); |
f_description(f_ag_fit_gradient_ref, "fit gradient for reference group"); | init_feature(f_ag_fit_gradient_ref, "fit gradient for reference group", f_type_static); |
f_description(f_ag_atom_forces, "atomic forces"); | init_feature(f_ag_atom_forces, "atomic forces", f_type_dynamic); |
| |
// parallel calculation implies that we have at least a scalable center of mass, | // parallel calculation implies that we have at least a scalable center of mass, |
// but f_ag_scalable is kept as a separate feature to deal with future dependencies | // but f_ag_scalable is kept as a separate feature to deal with future dependencies |
f_description(f_ag_scalable, "scalable group calculation"); | init_feature(f_ag_scalable, "scalable group calculation", f_type_static); |
f_description(f_ag_scalable_com, "scalable group center of mass calculation"); | init_feature(f_ag_scalable_com, "scalable group center of mass calculation", f_type_static); |
f_req_self(f_ag_scalable, f_ag_scalable_com); | f_req_self(f_ag_scalable, f_ag_scalable_com); |
| |
// f_description(f_ag_min_msd_fit, "minimum MSD fit") | // init_feature(f_ag_min_msd_fit, "minimum MSD fit") |
// f_req_self(f_ag_min_msd_fit, f_ag_center) | // f_req_self(f_ag_min_msd_fit, f_ag_center) |
// f_req_self(f_ag_min_msd_fit, f_ag_rotate) | // f_req_self(f_ag_min_msd_fit, f_ag_rotate) |
// f_req_exclude(f_ag_min_msd_fit, f_ag_fitting_group) | // f_req_exclude(f_ag_min_msd_fit, f_ag_fitting_group) |