version 1.26 | version 1.27 |
---|
| |
{ | { |
if (!key.size()) key = "unnamed"; | if (!key.size()) key = "unnamed"; |
description = "atom group " + key; | description = "atom group " + key; |
// These will be overwritten by parse(), if initializing from a config string | // These may be overwritten by parse(), if a name is provided |
| |
atoms.clear(); | atoms.clear(); |
| |
| |
b_center = false; | b_center = false; |
b_rotate = false; | b_rotate = false; |
b_user_defined_fit = false; | b_user_defined_fit = false; |
b_fit_gradients = false; | |
fitting_group = NULL; | fitting_group = NULL; |
| |
noforce = false; | noforce = false; |
| |
| |
int parse_error = COLVARS_OK; | int parse_error = COLVARS_OK; |
| |
| // Optional group name will let other groups reuse atom definition |
| if (get_keyval(group_conf, "name", name)) { |
| if ((cvm::atom_group_by_name(this->name) != NULL) && |
| (cvm::atom_group_by_name(this->name) != this)) { |
| cvm::error("Error: this atom group cannot have the same name, \""+this->name+ |
| "\", as another atom group.\n", |
| INPUT_ERROR); |
| return INPUT_ERROR; |
| } |
| cvm::main()->register_named_atom_group(this); |
| description = "atom group " + name; |
| } |
| |
| // We need to know about fitting to decide whether the group is scalable |
| // and we need to know about scalability before adding atoms |
| bool b_defined_center = get_keyval(group_conf, "centerReference", b_center, false); |
| bool b_defined_rotate = get_keyval(group_conf, "rotateReference", b_rotate, false); |
| // is the user setting explicit options? |
| b_user_defined_fit = b_defined_center || b_defined_rotate; |
| |
| if (is_available(f_ag_scalable_com) && !b_rotate && !b_center) { |
| enable(f_ag_scalable_com); |
| enable(f_ag_scalable); |
| } |
| |
| { |
| std::string atoms_of = ""; |
| if (get_keyval(group_conf, "atomsOfGroup", atoms_of)) { |
| atom_group * ag = atom_group_by_name(atoms_of); |
| if (ag == NULL) { |
| cvm::error("Error: cannot find atom group with name " + atoms_of + ".\n"); |
| return COLVARS_ERROR; |
| } |
| parse_error |= add_atoms_of_group(ag); |
| } |
| } |
| |
| // if (get_keyval(group_conf, "copyOfGroup", source)) { |
| // // Goal: Initialize this as a full copy |
| // // for this we'll need an atom_group copy constructor |
| // return COLVARS_OK; |
| // } |
| |
{ | { |
std::string numbers_conf = ""; | std::string numbers_conf = ""; |
size_t pos = 0; | size_t pos = 0; |
| |
} | } |
} | } |
| |
// We need to know the fitting options to decide whether the group is scalable | // Now that atoms are defined we can parse the detailed fitting options |
parse_error |= parse_fitting_options(group_conf); | parse_error |= parse_fitting_options(group_conf); |
| |
if (is_available(f_ag_scalable_com) && !b_rotate && !b_center) { | |
enable(f_ag_scalable_com); | |
enable(f_ag_scalable); | |
} | |
| |
if (is_enabled(f_ag_scalable) && !b_dummy) { | if (is_enabled(f_ag_scalable) && !b_dummy) { |
cvm::log("Enabling scalable calculation for group \""+this->key+"\".\n"); | cvm::log("Enabling scalable calculation for group \""+this->key+"\".\n"); |
index = (cvm::proxy)->init_atom_group(atoms_ids); | index = (cvm::proxy)->init_atom_group(atoms_ids); |
| |
} | } |
| |
| |
| int cvm::atom_group::add_atoms_of_group(atom_group const * ag) |
| { |
| std::vector<int> const &source_ids = ag->atoms_ids; |
| |
| if (source_ids.size()) { |
| atoms_ids.reserve(atoms_ids.size()+source_ids.size()); |
| |
| if (is_enabled(f_ag_scalable)) { |
| for (size_t i = 0; i < source_ids.size(); i++) { |
| add_atom_id(source_ids[i]); |
| } |
| } else { |
| atoms.reserve(atoms.size()+source_ids.size()); |
| for (size_t i = 0; i < source_ids.size(); i++) { |
| // We could use the atom copy constructor, but only if the source |
| // group is not scalable - whereas this works in both cases |
| // atom constructor expects 1-based atom number |
| add_atom(cvm::atom(source_ids[i] + 1)); |
| } |
| } |
| |
| if (cvm::get_error()) return COLVARS_ERROR; |
| } else { |
| cvm::error("Error: source atom group contains no atoms\".\n", INPUT_ERROR); |
| return COLVARS_ERROR; |
| } |
| |
| return COLVARS_OK; |
| } |
| |
| |
int cvm::atom_group::add_atom_numbers(std::string const &numbers_conf) | int cvm::atom_group::add_atom_numbers(std::string const &numbers_conf) |
{ | { |
std::vector<int> atom_indexes; | std::vector<int> atom_indexes; |
| |
| |
int cvm::atom_group::parse_fitting_options(std::string const &group_conf) | int cvm::atom_group::parse_fitting_options(std::string const &group_conf) |
{ | { |
bool b_defined_center = get_keyval(group_conf, "centerReference", b_center, false); | |
bool b_defined_rotate = get_keyval(group_conf, "rotateReference", b_rotate, false); | |
// is the user setting explicit options? | |
b_user_defined_fit = b_defined_center || b_defined_rotate; | |
| |
get_keyval(group_conf, "enableFitGradients", b_fit_gradients, true); | |
| |
if (b_center || b_rotate) { | if (b_center || b_rotate) { |
| |
if (b_dummy) | if (b_dummy) |
| |
} | } |
| |
// regardless of the configuration, fit gradients must be calculated by fittingGroup | // regardless of the configuration, fit gradients must be calculated by fittingGroup |
fitting_group->b_fit_gradients = this->b_fit_gradients; | // fitting_group->b_fit_gradients = this->b_fit_gradients; |
} | } |
| |
atom_group *group_for_fit = fitting_group ? fitting_group : this; | atom_group *group_for_fit = fitting_group ? fitting_group : this; |
| |
return COLVARS_ERROR; | return COLVARS_ERROR; |
} | } |
| |
if (b_fit_gradients) { | |
group_for_fit->fit_gradients.assign(group_for_fit->size(), cvm::atom_pos(0.0, 0.0, 0.0)); | |
rot.request_group1_gradients(group_for_fit->size()); | |
} | |
| |
if (b_rotate && !noforce) { | if (b_rotate && !noforce) { |
cvm::log("Warning: atom group \""+key+ | cvm::log("Warning: atom group \""+key+ |
"\" will be aligned to a fixed orientation given by the reference positions provided. " | "\" will be aligned to a fixed orientation given by the reference positions provided. " |
| |
} | } |
} | } |
| |
| // This must happen after fitting group is defined so that side-effects are performed |
| // properly (ie. allocating fitting group gradients) |
| get_keyval_feature(this, group_conf, "enableFitGradients", f_ag_fit_gradients, true); |
| |
return COLVARS_OK; | return COLVARS_OK; |
} | } |
| |
| |
| void cvm::atom_group::do_feature_side_effects(int id) |
| { |
| // If enabled features are changed upstream, the features below should be refreshed |
| switch (id) { |
| case f_ag_fit_gradients: |
| if (b_center || b_rotate) { |
| atom_group *group_for_fit = fitting_group ? fitting_group : this; |
| group_for_fit->fit_gradients.assign(group_for_fit->size(), cvm::atom_pos(0.0, 0.0, 0.0)); |
| rot.request_group1_gradients(group_for_fit->size()); |
| } |
| break; |
| } |
| } |
| |
| |
int cvm::atom_group::create_sorted_ids(void) | int cvm::atom_group::create_sorted_ids(void) |
{ | { |
// Only do the work if the vector is not yet populated | // Only do the work if the vector is not yet populated |
| |
| |
void cvm::atom_group::calc_fit_gradients() | void cvm::atom_group::calc_fit_gradients() |
{ | { |
if (b_dummy) return; | if (b_dummy || ! is_enabled(f_ag_fit_gradients)) return; |
| |
if (cvm::debug()) | if (cvm::debug()) |
cvm::log("Calculating fit gradients.\n"); | cvm::log("Calculating fit gradients.\n"); |
| |
atom_group *group_for_fit = fitting_group ? fitting_group : this; | cvm::atom_group *group_for_fit = fitting_group ? fitting_group : this; |
| |
if (b_center) { | if (b_center) { |
// add the center of geometry contribution to the gradients | // add the center of geometry contribution to the gradients |
| |
} | } |
} | } |
| |
if ((b_center || b_rotate) && b_fit_gradients) { | if ((b_center || b_rotate) && is_enabled(f_ag_fit_gradients)) { |
| |
atom_group *group_for_fit = fitting_group ? fitting_group : this; | atom_group *group_for_fit = fitting_group ? fitting_group : this; |
| |