| 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; |
| | |