| version 1.18 | version 1.19 |
|---|
| |
| // -*- c++ -*- | // -*- c++ -*- |
| | |
| | // This file is part of the Collective Variables module (Colvars). |
| | // The original version of Colvars and its updates are located at: |
| | // https://github.com/colvars/colvars |
| | // Please update all Colvars source files before making any changes. |
| | // If you wish to distribute your changes, please submit them to the |
| | // Colvars repository at GitHub. |
| | |
| #include "colvarmodule.h" | #include "colvarmodule.h" |
| #include "colvarvalue.h" | #include "colvarvalue.h" |
| #include "colvarbias.h" | #include "colvarbias.h" |
| |
| | |
| rank = 1; | rank = 1; |
| | |
| if (bias_type == std::string("abf")) { | |
| rank = cvm::n_abf_biases+1; | |
| } | |
| if (bias_type == std::string("harmonic") || | |
| bias_type == std::string("linear")) { | |
| rank = cvm::n_rest_biases+1; | |
| } | |
| if (bias_type == std::string("histogram")) { | |
| rank = cvm::n_histo_biases+1; | |
| } | |
| if (bias_type == std::string("metadynamics")) { | |
| rank = cvm::n_meta_biases+1; | |
| } | |
| | |
| has_data = false; | has_data = false; |
| b_output_energy = false; | b_output_energy = false; |
| reset(); | reset(); |
| | state_file_step = 0; |
| | |
| // Start in active state by default | // Start in active state by default |
| enable(f_cvb_active); | enable(f_cvb_active); |
| |
| colvarparse::init(conf); | colvarparse::init(conf); |
| | |
| if (name.size() == 0) { | if (name.size() == 0) { |
| | |
| | // first initialization |
| | |
| cvm::log("Initializing a new \""+bias_type+"\" instance.\n"); | cvm::log("Initializing a new \""+bias_type+"\" instance.\n"); |
| | rank = cvm::num_biases_type(bias_type); |
| get_keyval(conf, "name", name, bias_type+cvm::to_str(rank)); | get_keyval(conf, "name", name, bias_type+cvm::to_str(rank)); |
| | |
| { | { |
| |
| // lookup the associated colvars | // lookup the associated colvars |
| std::vector<std::string> colvar_names; | std::vector<std::string> colvar_names; |
| if (get_keyval(conf, "colvars", colvar_names)) { | if (get_keyval(conf, "colvars", colvar_names)) { |
| if (colvars.size()) { | if (num_variables()) { |
| cvm::error("Error: cannot redefine the colvars that a bias was already defined on.\n", | cvm::error("Error: cannot redefine the colvars that a bias was already defined on.\n", |
| INPUT_ERROR); | INPUT_ERROR); |
| return INPUT_ERROR; | return INPUT_ERROR; |
| |
| } | } |
| } | } |
| | |
| if (!colvars.size()) { | if (!num_variables()) { |
| cvm::error("Error: no collective variables specified.\n", INPUT_ERROR); | cvm::error("Error: no collective variables specified.\n", INPUT_ERROR); |
| return INPUT_ERROR; | return INPUT_ERROR; |
| } | } |
| |
| cvm::log("Reinitializing bias \""+name+"\".\n"); | cvm::log("Reinitializing bias \""+name+"\".\n"); |
| } | } |
| | |
| | output_prefix = cvm::output_prefix(); |
| | |
| get_keyval(conf, "outputEnergy", b_output_energy, b_output_energy); | get_keyval(conf, "outputEnergy", b_output_energy, b_output_energy); |
| | |
| return COLVARS_OK; | return COLVARS_OK; |
| |
| int colvarbias::reset() | int colvarbias::reset() |
| { | { |
| bias_energy = 0.0; | bias_energy = 0.0; |
| for (size_t i = 0; i < colvars.size(); i++) { | for (size_t i = 0; i < num_variables(); i++) { |
| colvar_forces[i].reset(); | colvar_forces[i].reset(); |
| } | } |
| return COLVARS_OK; | return COLVARS_OK; |
| |
| } | } |
| } | } |
| | |
| | colvarmodule *cv = cvm::main(); |
| // ...and from the colvars module | // ...and from the colvars module |
| for (std::vector<colvarbias *>::iterator bi = cvm::biases.begin(); | for (std::vector<colvarbias *>::iterator bi = cv->biases.begin(); |
| bi != cvm::biases.end(); | bi != cv->biases.end(); |
| ++bi) { | ++bi) { |
| if ( *bi == this) { | if ( *bi == this) { |
| cvm::biases.erase(bi); | cv->biases.erase(bi); |
| break; | break; |
| } | } |
| } | } |
| |
| int colvarbias::add_colvar(std::string const &cv_name) | int colvarbias::add_colvar(std::string const &cv_name) |
| { | { |
| if (colvar *cv = cvm::colvar_by_name(cv_name)) { | if (colvar *cv = cvm::colvar_by_name(cv_name)) { |
| // Removed this as nor all biases apply forces eg histogram | |
| // cv->enable(colvar::task_gradients); | |
| if (cvm::debug()) { | if (cvm::debug()) { |
| cvm::log("Applying this bias to collective variable \""+ | cvm::log("Applying this bias to collective variable \""+ |
| cv->name+"\".\n"); | cv->name+"\".\n"); |
| } | } |
| | |
| colvars.push_back(cv); | colvars.push_back(cv); |
| | |
| colvar_forces.push_back(colvarvalue()); | colvar_forces.push_back(colvarvalue()); |
| colvar_forces.back().type(cv->value()); // make sure each force is initialized to zero | colvar_forces.back().type(cv->value()); // make sure each force is initialized to zero |
| | colvar_forces.back().is_derivative(); // colvar constraints are not applied to the force |
| colvar_forces.back().reset(); | colvar_forces.back().reset(); |
| | |
| cv->biases.push_back(this); // add back-reference to this bias to colvar | cv->biases.push_back(this); // add back-reference to this bias to colvar |
| | |
| | if (is_enabled(f_cvb_apply_force)) { |
| | cv->enable(f_cv_gradient); |
| | } |
| | |
| // Add dependency link. | // Add dependency link. |
| // All biases need at least the value of each colvar | // All biases need at least the value of each colvar |
| // although possibly not at all timesteps | // although possibly not at all timesteps |
| |
| cv_name+"\".\n", INPUT_ERROR); | cv_name+"\".\n", INPUT_ERROR); |
| return INPUT_ERROR; | return INPUT_ERROR; |
| } | } |
| | |
| return COLVARS_OK; | return COLVARS_OK; |
| } | } |
| | |
| | |
| int colvarbias::update() | int colvarbias::update() |
| { | { |
| // Note: if anything is added here, it should be added also in the SMP block of calc_biases() | if (cvm::debug()) { |
| // TODO move here debug msg of bias update | cvm::log("Updating the "+bias_type+" bias \""+this->name+"\".\n"); |
| | } |
| | |
| has_data = true; | has_data = true; |
| | |
| | bias_energy = 0.0; |
| | for (size_t ir = 0; ir < num_variables(); ir++) { |
| | colvar_forces[ir].reset(); |
| | } |
| | |
| return COLVARS_OK; | return COLVARS_OK; |
| } | } |
| | |
| | |
| void colvarbias::communicate_forces() | void colvarbias::communicate_forces() |
| { | { |
| for (size_t i = 0; i < colvars.size(); i++) { | for (size_t i = 0; i < num_variables(); i++) { |
| if (cvm::debug()) { | if (cvm::debug()) { |
| cvm::log("Communicating a force to colvar \""+ | cvm::log("Communicating a force to colvar \""+ |
| colvars[i]->name+"\".\n"); | variables(i)->name+"\".\n"); |
| } | } |
| colvars[i]->add_bias_force(colvar_forces[i]); | variables(i)->add_bias_force(colvar_forces[i]); |
| } | } |
| } | } |
| | |
| | |
| void colvarbias::change_configuration(std::string const &conf) | int colvarbias::change_configuration(std::string const &conf) |
| { | { |
| cvm::error("Error: change_configuration() not implemented.\n"); | cvm::error("Error: change_configuration() not implemented.\n", |
| | COLVARS_NOT_IMPLEMENTED); |
| | return COLVARS_NOT_IMPLEMENTED; |
| } | } |
| | |
| | |
| cvm::real colvarbias::energy_difference(std::string const &conf) | cvm::real colvarbias::energy_difference(std::string const &conf) |
| { | { |
| cvm::error("Error: energy_difference() not implemented.\n"); | cvm::error("Error: energy_difference() not implemented.\n", |
| return 0.; | COLVARS_NOT_IMPLEMENTED); |
| | return 0.0; |
| } | } |
| | |
| | |
| |
| return COLVARS_NOT_IMPLEMENTED; | return COLVARS_NOT_IMPLEMENTED; |
| } | } |
| | |
| | |
| | std::string const colvarbias::get_state_params() const |
| | { |
| | std::ostringstream os; |
| | os << "step " << cvm::step_absolute() << "\n" |
| | << "name " << this->name << "\n"; |
| | return os.str(); |
| | } |
| | |
| | |
| | int colvarbias::set_state_params(std::string const &conf) |
| | { |
| | std::string new_name = ""; |
| | if (colvarparse::get_keyval(conf, "name", new_name, |
| | std::string(""), colvarparse::parse_silent) && |
| | (new_name != this->name)) { |
| | cvm::error("Error: in the state file, the " |
| | "\""+bias_type+"\" block has a different name, \""+new_name+ |
| | "\": different system?\n", INPUT_ERROR); |
| | } |
| | |
| | if (name.size() == 0) { |
| | cvm::error("Error: \""+bias_type+"\" block within the restart file " |
| | "has no identifiers.\n", INPUT_ERROR); |
| | } |
| | |
| | colvarparse::get_keyval(conf, "step", state_file_step, |
| | cvm::step_absolute(), colvarparse::parse_silent); |
| | |
| | return COLVARS_OK; |
| | } |
| | |
| | |
| | std::ostream & colvarbias::write_state(std::ostream &os) |
| | { |
| | if (cvm::debug()) { |
| | cvm::log("Writing state file for bias \""+name+"\"\n"); |
| | } |
| | os.setf(std::ios::scientific, std::ios::floatfield); |
| | os.precision(cvm::cv_prec); |
| | os << bias_type << " {\n" |
| | << " configuration {\n"; |
| | std::istringstream is(get_state_params()); |
| | std::string line; |
| | while (std::getline(is, line)) { |
| | os << " " << line << "\n"; |
| | } |
| | os << " }\n"; |
| | write_state_data(os); |
| | os << "}\n\n"; |
| | return os; |
| | } |
| | |
| | |
| | std::istream & colvarbias::read_state(std::istream &is) |
| | { |
| | size_t const start_pos = is.tellg(); |
| | |
| | std::string key, brace, conf; |
| | if ( !(is >> key) || !(key == bias_type) || |
| | !(is >> brace) || !(brace == "{") || |
| | !(is >> colvarparse::read_block("configuration", conf)) || |
| | (set_state_params(conf) != COLVARS_OK) ) { |
| | cvm::error("Error: in reading state configuration for \""+bias_type+"\" bias \""+ |
| | this->name+"\" at position "+ |
| | cvm::to_str(is.tellg())+" in stream.\n", INPUT_ERROR); |
| | is.clear(); |
| | is.seekg(start_pos, std::ios::beg); |
| | is.setstate(std::ios::failbit); |
| | return is; |
| | } |
| | |
| | if (!read_state_data(is)) { |
| | cvm::error("Error: in reading state data for \""+bias_type+"\" bias \""+ |
| | this->name+"\" at position "+ |
| | cvm::to_str(is.tellg())+" in stream.\n", INPUT_ERROR); |
| | is.clear(); |
| | is.seekg(start_pos, std::ios::beg); |
| | is.setstate(std::ios::failbit); |
| | } |
| | |
| | is >> brace; |
| | if (brace != "}") { |
| | cvm::error("Error: corrupt restart information for \""+bias_type+"\" bias \""+ |
| | this->name+"\": no matching brace at position "+ |
| | cvm::to_str(is.tellg())+" in stream.\n"); |
| | is.setstate(std::ios::failbit); |
| | } |
| | |
| | return is; |
| | } |
| | |
| | |
| | std::istream & colvarbias::read_state_data_key(std::istream &is, char const *key) |
| | { |
| | size_t const start_pos = is.tellg(); |
| | std::string key_in; |
| | if ( !(is >> key_in) || |
| | !(key_in == to_lower_cppstr(std::string(key))) ) { |
| | cvm::error("Error: in reading restart configuration for "+ |
| | bias_type+" bias \""+this->name+"\" at position "+ |
| | cvm::to_str(is.tellg())+" in stream.\n", INPUT_ERROR); |
| | is.clear(); |
| | is.seekg(start_pos, std::ios::beg); |
| | is.setstate(std::ios::failbit); |
| | return is; |
| | } |
| | return is; |
| | } |
| | |
| | |
| | |
| std::ostream & colvarbias::write_traj_label(std::ostream &os) | std::ostream & colvarbias::write_traj_label(std::ostream &os) |
| { | { |
| os << " "; | os << " "; |