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