00001
00002
00003
00004
00005 #include "colvarmodule.h"
00006 #include "colvar.h"
00007 #include "colvarbias_abf.h"
00008
00009
00011
00012 colvarbias_abf::colvarbias_abf (std::string const &conf, char const *key)
00013 : colvarbias (conf, key),
00014 gradients (NULL),
00015 samples (NULL)
00016 {
00017
00018
00019 get_keyval (conf, "applybias", apply_bias, true);
00020 if (!apply_bias) cvm::log ("WARNING: ABF biases will *not* be applied!\n");
00021
00022 get_keyval (conf, "hidejacobian", hide_Jacobian, false);
00023 if (hide_Jacobian) {
00024 cvm::log ("Jacobian (geometric) forces will be handled internally.\n");
00025 } else {
00026 cvm::log ("Jacobian (geometric) forces will be included in reported free energy gradients.\n");
00027 }
00028
00029 get_keyval (conf, "fullsamples", full_samples, 200);
00030 if ( full_samples <= 1 ) full_samples = 1;
00031 min_samples = full_samples / 2;
00032
00033
00034 get_keyval (conf, "inputprefix", input_prefix, std::vector<std::string> ());
00035 get_keyval (conf, "outputfreq", output_freq, cvm::restart_out_freq);
00036
00037
00038
00039 if (colvars.size() == 0) {
00040 cvm::fatal_error ("Error: no collective variables specified for the ABF bias.\n");
00041 }
00042
00043 for (size_t i = 0; i < colvars.size(); i++) {
00044
00045 if (colvars[i]->type() != colvarvalue::type_scalar) {
00046 cvm::fatal_error ("Error: ABF bias can only use scalar-type variables.\n");
00047 }
00048
00049
00050 colvars[i]->enable (colvar::task_system_force);
00051
00052
00053 colvars[i]->enable (colvar::task_Jacobian_force);
00054
00055
00056
00057
00058 if (hide_Jacobian) {
00059 if (colvars[i]->n_components() > 1) {
00060 cvm::log ("WARNING: colvar \"" + colvars[i]->name
00061 + "\" has multiple components; reporting its Jacobian forces\n");
00062 colvars[i]->enable (colvar::task_report_Jacobian_force);
00063 }
00064 } else {
00065 colvars[i]->enable (colvar::task_report_Jacobian_force);
00066 }
00067
00068
00069
00070 }
00071
00072 bin.assign (colvars.size(), 0);
00073 prev_bin.assign (colvars.size(), 0);
00074 prev_force = new cvm::real [colvars.size()];
00075
00076
00077 samples = new colvar_grid_count (colvars);
00078 gradients = new colvar_grid_gradient (colvars);
00079 gradients->samples = samples;
00080 samples->has_parent_data = true;
00081
00082
00083 if ( input_prefix.size() > 0 ) {
00084 read_gradients_samples ();
00085 }
00086
00087 cvm::log ("Finished ABF setup.\n");
00088 }
00089
00091 colvarbias_abf::~colvarbias_abf()
00092 {
00093 if (gradients_os.good()) gradients_os.close();
00094 if (samples_os.good()) samples_os.close();
00095
00096 if (samples) {
00097 delete samples;
00098 samples = NULL;
00099 }
00100
00101 if (gradients) {
00102 delete gradients;
00103 gradients = NULL;
00104 }
00105
00106 delete [] prev_force;
00107 }
00108
00109
00112
00113 void colvarbias_abf::update()
00114 {
00115 if (cvm::debug()) cvm::log ("Updating ABF bias " + this->name);
00116
00117 if (cvm::step_relative() == 0) {
00118
00119
00120
00121
00122
00123 if ( cvm::n_abf_biases == 1 && cvm::n_meta_biases == 0 ) {
00124
00125 samples_out_name = cvm::output_prefix + ".count";
00126 gradients_out_name = cvm::output_prefix + ".grad";
00127 if ( colvars.size() == 1 ) {
00128 pmf_out_name = cvm::output_prefix + ".pmf";
00129 }
00130 } else {
00131 samples_out_name = cvm::output_prefix + "." + this->name + ".count";
00132 gradients_out_name = cvm::output_prefix + "." + this->name + ".grad";
00133 if ( colvars.size() == 1 ) {
00134 pmf_out_name = cvm::output_prefix + "." + this->name + ".pmf";
00135 }
00136 }
00137
00138 for (size_t i=0; i<colvars.size(); i++) {
00139 bin[i] = colvars[i]->current_bin_scalar();
00140 }
00141
00142 } else {
00143
00144 for (size_t i=0; i<colvars.size(); i++) {
00145 bin[i] = colvars[i]->current_bin_scalar();
00146 }
00147
00148 if ( samples->index_ok (prev_bin) ) {
00149
00150 for (size_t i=0; i<colvars.size(); i++) {
00151 prev_force[i] = colvars[i]->system_force();
00152 }
00153 gradients->acc_force (prev_bin, prev_force);
00154 }
00155 }
00156
00157
00158 prev_bin = bin;
00159
00160
00161 for (size_t i=0; i<colvars.size(); i++) {
00162 colvar_forces[i].reset();
00163 }
00164
00165
00166 if ( apply_bias && samples->index_ok (bin) ) {
00167
00168 size_t count = samples->value (bin);
00169 cvm::real fact = 1.0;
00170
00171
00172 if ( count < full_samples ) {
00173 fact = ( count < min_samples) ? 0.0 : (cvm::real (count - min_samples)) / (cvm::real (full_samples - min_samples));
00174 }
00175
00176 const cvm::real * grad = &(gradients->value (bin));
00177
00178 if ( fact != 0.0 ) {
00179
00180 if ( (colvars.size() == 1) && colvars[0]->periodic_boundaries() ) {
00181
00182 colvar_forces[0].real_value += fact * (grad[0] / cvm::real (count) - gradients->average ());
00183 } else {
00184 for (size_t i=0; i<colvars.size(); i++) {
00185
00186 colvar_forces[i].real_value += fact * grad[i] / cvm::real (count);
00187
00188 }
00189 }
00190 }
00191 }
00192
00193 if (output_freq && (cvm::step_relative() % output_freq) == 0) {
00194 if (cvm::debug()) cvm::log ("ABF bias trying to write gradients and samples to disk");
00195 write_gradients_samples ();
00196 }
00197 }
00198
00199 void colvarbias_abf::write_gradients_samples ()
00200 {
00201 samples_os.open (samples_out_name.c_str());
00202 if (!samples_os.good()) cvm::fatal_error ("Error opening ABF samples file " + samples_out_name + " for writing");
00203 samples->write_multicol (samples_os);
00204 samples_os.close ();
00205
00206 gradients_os.open (gradients_out_name.c_str());
00207 if (!gradients_os.good()) cvm::fatal_error ("Error opening ABF gradient file " + gradients_out_name + " for writing");
00208 gradients->write_multicol (gradients_os);
00209 gradients_os.close ();
00210
00211 if ( colvars.size () == 1 ) {
00212
00213 pmf_os.open (pmf_out_name.c_str());
00214 if (!pmf_os.good()) cvm::fatal_error ("Error opening pmf file " + pmf_out_name + " for writing");
00215 gradients->write_1D_integral (pmf_os);
00216 pmf_os.close ();
00217 }
00218 return;
00219 }
00220
00221 void colvarbias_abf::read_gradients_samples ()
00222 {
00223 std::string samples_in_name, gradients_in_name;
00224
00225 for ( size_t i = 0; i < input_prefix.size(); i++ ) {
00226 samples_in_name = input_prefix[i] + ".count";
00227 gradients_in_name = input_prefix[i] + ".grad";
00228
00229
00230 std::ifstream is;
00231
00232 cvm::log ("Reading sample count from " + samples_in_name + " and gradients from " + gradients_in_name);
00233 is.open (samples_in_name.c_str());
00234 if (!is.good()) cvm::fatal_error ("Error opening ABF samples file " + samples_in_name + " for reading");
00235 samples->read_multicol (is, true);
00236 is.close ();
00237 is.clear();
00238
00239 is.open (gradients_in_name.c_str());
00240 if (!is.good()) cvm::fatal_error ("Error opening ABF gradient file " + gradients_in_name + " for reading");
00241 gradients->read_multicol (is, true);
00242 is.close ();
00243 }
00244 return;
00245 }
00246
00247
00248 std::ostream & colvarbias_abf::write_restart (std::ostream& os)
00249 {
00250
00251 std::ios::fmtflags flags (os.flags ());
00252 os.setf(std::ios::fmtflags (0), std::ios::floatfield);
00253
00254 os << "abf {\n"
00255 << " configuration {\n"
00256 << " name " << this->name << "\n";
00257 os << " }\n";
00258
00259 os << "samples\n";
00260 samples->write_raw (os, 8);
00261
00262 os << "\ngradient\n";
00263 gradients->write_raw (os);
00264
00265 os << "}\n\n";
00266
00267 os.flags (flags);
00268 return os;
00269 }
00270
00271
00272 std::istream & colvarbias_abf::read_restart (std::istream& is)
00273 {
00274 if ( input_prefix.size() > 0 ) {
00275 cvm::fatal_error ("ERROR: cannot provide both inputPrefix and restart information (colvarsInput)");
00276 }
00277
00278 size_t const start_pos = is.tellg();
00279
00280 cvm::log ("Restarting ABF bias \""+
00281 this->name+"\".\n");
00282 std::string key, brace, conf;
00283
00284 if ( !(is >> key) || !(key == "abf") ||
00285 !(is >> brace) || !(brace == "{") ||
00286 !(is >> colvarparse::read_block ("configuration", conf)) ) {
00287 cvm::log ("Error: in reading restart configuration for ABF bias \""+
00288 this->name+"\" at position "+
00289 cvm::to_str (is.tellg())+" in stream.\n");
00290 is.clear();
00291 is.seekg (start_pos, std::ios::beg);
00292 is.setstate (std::ios::failbit);
00293 return is;
00294 }
00295
00296 std::string name = "";
00297 if ( (colvarparse::get_keyval (conf, "name", name, std::string (""), colvarparse::parse_silent)) &&
00298 (name != this->name) )
00299 cvm::fatal_error ("Error: in the restart file, the "
00300 "\"abf\" block has wrong name (" + name + ")\n");
00301 if ( name == "" ) {
00302 cvm::fatal_error ("Error: \"abf\" block in the restart file has no name.\n");
00303 }
00304
00305 if ( !(is >> key) || !(key == "samples")) {
00306 cvm::log ("Error: in reading restart configuration for ABF bias \""+
00307 this->name+"\" at position "+
00308 cvm::to_str (is.tellg())+" in stream.\n");
00309 is.clear();
00310 is.seekg (start_pos, std::ios::beg);
00311 is.setstate (std::ios::failbit);
00312 return is;
00313 }
00314 samples->read_raw (is);
00315
00316 if ( !(is >> key) || !(key == "gradient")) {
00317 cvm::log ("Error: in reading restart configuration for ABF bias \""+
00318 this->name+"\" at position "+
00319 cvm::to_str (is.tellg())+" in stream.\n");
00320 is.clear();
00321 is.seekg (start_pos, std::ios::beg);
00322 is.setstate (std::ios::failbit);
00323 return is;
00324 }
00325 gradients->read_raw (is);
00326
00327 is >> brace;
00328 if (brace != "}") {
00329 cvm::fatal_error ("Error: corrupt restart information for ABF bias \""+
00330 this->name+"\": no matching brace at position "+
00331 cvm::to_str (is.tellg())+" in the restart file.\n");
00332 is.setstate (std::ios::failbit);
00333 }
00334 return is;
00335 }
00336
00337
00338
00339
00341
00342 colvarbias_histogram::colvarbias_histogram (std::string const &conf, char const *key)
00343 : colvarbias (conf, key),
00344 grid (NULL)
00345 {
00346 get_keyval (conf, "outputfreq", output_freq, cvm::restart_out_freq);
00347
00348 if ( output_freq == 0 ) {
00349 cvm::fatal_error ("User required histogram with zero output frequency");
00350 }
00351
00352 grid = new colvar_grid_count (colvars);
00353 bin.assign (colvars.size(), 0);
00354
00355 out_name = cvm::output_prefix + "." + this->name + ".dat";
00356 cvm::log ("Histogram will be written to file " + out_name);
00357
00358 cvm::log ("Finished histogram setup.\n");
00359 }
00360
00362 colvarbias_histogram::~colvarbias_histogram()
00363 {
00364 if (grid_os.good()) grid_os.close();
00365
00366 if (grid) {
00367 delete grid;
00368 grid = NULL;
00369 }
00370 }
00371
00373 void colvarbias_histogram::update()
00374 {
00375 if (cvm::debug()) cvm::log ("Updating Grid bias " + this->name);
00376
00377 for (size_t i=0; i<colvars.size(); i++) {
00378 bin[i] = colvars[i]->current_bin_scalar();
00379 }
00380
00381 if ( grid->index_ok (bin) ) {
00382 grid->incr_count (bin);
00383 }
00384
00385 if (output_freq && (cvm::step_relative() % output_freq) == 0) {
00386 if (cvm::debug()) cvm::log ("Histogram bias trying to write grid to disk");
00387
00388 grid_os.open (out_name.c_str());
00389 if (!grid_os.good()) cvm::fatal_error ("Error opening histogram file " + out_name + " for writing");
00390 grid->write_multicol (grid_os);
00391 grid_os.close ();
00392 }
00393 }
00394
00395
00396 std::istream & colvarbias_histogram::read_restart (std::istream& is)
00397 {
00398 size_t const start_pos = is.tellg();
00399
00400 cvm::log ("Restarting collective variable histogram \""+
00401 this->name+"\".\n");
00402 std::string key, brace, conf;
00403
00404 if ( !(is >> key) || !(key == "histogram") ||
00405 !(is >> brace) || !(brace == "{") ||
00406 !(is >> colvarparse::read_block ("configuration", conf)) ) {
00407 cvm::log ("Error: in reading restart configuration for histogram \""+
00408 this->name+"\" at position "+
00409 cvm::to_str (is.tellg())+" in stream.\n");
00410 is.clear();
00411 is.seekg (start_pos, std::ios::beg);
00412 is.setstate (std::ios::failbit);
00413 return is;
00414 }
00415
00416 int id = -1;
00417 std::string name = "";
00418 if ( (colvarparse::get_keyval (conf, "name", name, std::string (""), colvarparse::parse_silent)) &&
00419 (name != this->name) )
00420 cvm::fatal_error ("Error: in the restart file, the "
00421 "\"histogram\" block has a wrong name: different system?\n");
00422 if ( (id == -1) && (name == "") ) {
00423 cvm::fatal_error ("Error: \"histogram\" block in the restart file "
00424 "has no name.\n");
00425 }
00426
00427 if ( !(is >> key) || !(key == "grid")) {
00428 cvm::log ("Error: in reading restart configuration for histogram \""+
00429 this->name+"\" at position "+
00430 cvm::to_str (is.tellg())+" in stream.\n");
00431 is.clear();
00432 is.seekg (start_pos, std::ios::beg);
00433 is.setstate (std::ios::failbit);
00434 return is;
00435 }
00436 grid->read_raw (is);
00437
00438 is >> brace;
00439 if (brace != "}") {
00440 cvm::fatal_error ("Error: corrupt restart information for ABF bias \""+
00441 this->name+"\": no matching brace at position "+
00442 cvm::to_str (is.tellg())+" in the restart file.\n");
00443 is.setstate (std::ios::failbit);
00444 }
00445 return is;
00446 }
00447
00448 std::ostream & colvarbias_histogram::write_restart (std::ostream& os)
00449 {
00450 os << "histogram {\n"
00451 << " configuration {\n"
00452 << " name " << this->name << "\n";
00453 os << " }\n";
00454
00455 os << "grid\n";
00456 grid->write_raw (os, 8);
00457
00458 os << "}\n\n";
00459
00460 return os;
00461 }