From f2ddf828e4855f7626f129a00f30be2191a28f16 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Wed, 10 Aug 2016 09:03:25 -0400 Subject: [PATCH] update colvars to version 2016-08-10 --- doc/src/PDF/colvars-refman-lammps.pdf | Bin 533542 -> 533480 bytes lib/colvars/colvar.cpp | 178 +++++++++----------------- lib/colvars/colvaratoms.cpp | 12 +- lib/colvars/colvarbias.cpp | 2 +- lib/colvars/colvarbias_histogram.cpp | 4 +- lib/colvars/colvarcomp.cpp | 6 +- lib/colvars/colvardeps.cpp | 8 +- lib/colvars/colvardeps.h | 19 ++- lib/colvars/colvarmodule.cpp | 65 ++++------ lib/colvars/colvarmodule.h | 27 ++-- lib/colvars/colvarparse.cpp | 99 ++++++++++---- lib/colvars/colvarparse.h | 6 + lib/colvars/colvarproxy.h | 10 +- lib/colvars/colvarscript.cpp | 27 ++-- 14 files changed, 222 insertions(+), 241 deletions(-) diff --git a/doc/src/PDF/colvars-refman-lammps.pdf b/doc/src/PDF/colvars-refman-lammps.pdf index 657f24c43696bcf2f8466b39697f927fd97bb50b..0dd82d47947628d5c55c0481499dcc8b79a4598d 100644 GIT binary patch delta 13661 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 diff --git a/lib/colvars/colvar.cpp b/lib/colvars/colvar.cpp index 344a9a1301..49f0285091 100644 --- a/lib/colvars/colvar.cpp +++ b/lib/colvars/colvar.cpp @@ -43,7 +43,8 @@ colvar::colvar(std::string const &conf) kinetic_energy = 0.0; potential_energy = 0.0; - cvm::combine_errors(error_code, init_components(conf)); + error_code |= init_components(conf); + if (error_code != COLVARS_OK) return; size_t i; @@ -492,110 +493,44 @@ int colvar::init_components(std::string const &conf) { int error_code = COLVARS_OK; - cvm::combine_errors(error_code, - init_components_type(conf, - "distance", "distance")); - cvm::combine_errors(error_code, - init_components_type(conf, - "distance vector", "distanceVec")); - cvm::combine_errors(error_code, - init_components_type(conf, - "Cartesian coordinates", "cartesian")); - cvm::combine_errors(error_code, - init_components_type(conf, - "distance vector " - "direction", "distanceDir")); - cvm::combine_errors(error_code, - init_components_type(conf, - "distance projection " - "on an axis", "distanceZ")); - cvm::combine_errors(error_code, - init_components_type(conf, - "distance projection " - "on a plane", "distanceXY")); - cvm::combine_errors(error_code, - init_components_type(conf, - "average distance " - "weighted by inverse power", - "distanceInv")); - cvm::combine_errors(error_code, - init_components_type(conf, - "N1xN2-long vector " - "of pairwise distances", - "distancePairs")); - - cvm::combine_errors(error_code, - init_components_type(conf, - "coordination " - "number", "coordNum")); - cvm::combine_errors(error_code, - init_components_type(conf, - "self-coordination " - "number", "selfCoordNum")); - - cvm::combine_errors(error_code, - init_components_type(conf, - "angle", "angle")); - cvm::combine_errors(error_code, - init_components_type(conf, - "dipole angle", "dipoleAngle")); - cvm::combine_errors(error_code, - init_components_type(conf, - "dihedral", "dihedral")); - - cvm::combine_errors(error_code, - init_components_type(conf, - "hydrogen bond", "hBond")); - - // cvm::combine_errors(error_code, init_components_type(conf, "alpha helix", "alphaDihedrals")); - cvm::combine_errors(error_code, - init_components_type(conf, - "alpha helix", "alpha")); - - cvm::combine_errors(error_code, - init_components_type(conf, - "dihedral " - "principal component", "dihedralPC")); - - cvm::combine_errors(error_code, - init_components_type(conf, - "orientation", "orientation")); - cvm::combine_errors(error_code, - init_components_type(conf, - "orientation " - "angle", "orientationAngle")); - cvm::combine_errors(error_code, - init_components_type(conf, - "orientation " - "projection", "orientationProj")); - cvm::combine_errors(error_code, - init_components_type(conf, - "tilt", "tilt")); - cvm::combine_errors(error_code, - init_components_type(conf, - "spin angle", "spinAngle")); - - cvm::combine_errors(error_code, - init_components_type(conf, - "RMSD", "rmsd")); - - // cvm::combine_errors(error_code, init_components_type (conf,"logarithm of MSD", "logmsd")); - - cvm::combine_errors(error_code, - init_components_type(conf, - "radius of " - "gyration", "gyration")); - cvm::combine_errors(error_code, - init_components_type(conf, - "moment of " - "inertia", "inertia")); - cvm::combine_errors(error_code, - init_components_type(conf, - "moment of inertia around an axis", - "inertiaZ")); - cvm::combine_errors(error_code, - init_components_type(conf, - "eigenvector", "eigenvector")); + error_code |= init_components_type(conf, "distance", "distance"); + error_code |= init_components_type(conf, "distance vector", "distanceVec"); + error_code |= init_components_type(conf, "Cartesian coordinates", "cartesian"); + error_code |= init_components_type(conf, "distance vector " + "direction", "distanceDir"); + error_code |= init_components_type(conf, "distance projection " + "on an axis", "distanceZ"); + error_code |= init_components_type(conf, "distance projection " + "on a plane", "distanceXY"); + error_code |= init_components_type(conf, "average distance " + "weighted by inverse power", "distanceInv"); + error_code |= init_components_type(conf, "N1xN2-long vector " + "of pairwise distances", "distancePairs"); + error_code |= init_components_type(conf, "coordination " + "number", "coordNum"); + error_code |= init_components_type(conf, "self-coordination " + "number", "selfCoordNum"); + error_code |= init_components_type(conf, "angle", "angle"); + error_code |= init_components_type(conf, "dipole angle", "dipoleAngle"); + error_code |= init_components_type(conf, "dihedral", "dihedral"); + error_code |= init_components_type(conf, "hydrogen bond", "hBond"); + error_code |= init_components_type(conf, "alpha helix", "alpha"); + error_code |= init_components_type(conf, "dihedral " + "principal component", "dihedralPC"); + error_code |= init_components_type(conf, "orientation", "orientation"); + error_code |= init_components_type(conf, "orientation " + "angle", "orientationAngle"); + error_code |= init_components_type(conf, "orientation " + "projection", "orientationProj"); + error_code |= init_components_type(conf, "tilt", "tilt"); + error_code |= init_components_type(conf, "spin angle", "spinAngle"); + error_code |= init_components_type(conf, "RMSD", "rmsd"); + error_code |= init_components_type(conf, "radius of " + "gyration", "gyration"); + error_code |= init_components_type(conf, "moment of " + "inertia", "inertia"); + error_code |= init_components_type(conf, "moment of inertia around an axis", "inertiaZ"); + error_code |= init_components_type(conf, "eigenvector", "eigenvector"); if (!cvcs.size() || (error_code != COLVARS_OK)) { cvm::error("Error: no valid components were provided " @@ -732,7 +667,7 @@ int colvar::parse_analysis(std::string const &conf) } else { cvm::log("Unknown type of correlation function, \""+ acf_type_str+"\".\n"); - cvm::set_error_bit(INPUT_ERROR); + cvm::set_error_bits(INPUT_ERROR); } get_keyval(conf, "corrFuncOffset", acf_offset, 0); @@ -803,9 +738,11 @@ int colvar::calc() // Note: if anything is added here, it should be added also in the SMP block of calc_colvars() int error_code = COLVARS_OK; if (is_enabled(f_cv_active)) { - cvm::combine_errors(error_code, update_cvc_flags()); - cvm::combine_errors(error_code, calc_cvcs()); - cvm::combine_errors(error_code, collect_cvc_data()); + error_code |= update_cvc_flags(); + if (error_code != COLVARS_OK) return error_code; + error_code |= calc_cvcs(); + if (error_code != COLVARS_OK) return error_code; + error_code |= collect_cvc_data(); } return error_code; } @@ -818,15 +755,15 @@ int colvar::calc_cvcs(int first_cvc, size_t num_cvcs) cvm::log("Calculating colvar \""+this->name+"\", components "+ cvm::to_str(first_cvc)+" through "+cvm::to_str(first_cvc+num_cvcs)+".\n"); - cvm::combine_errors(error_code, check_cvc_range(first_cvc, num_cvcs)); + error_code |= check_cvc_range(first_cvc, num_cvcs); if (error_code != COLVARS_OK) { return error_code; } - cvm::combine_errors(error_code, calc_cvc_values(first_cvc, num_cvcs)); - cvm::combine_errors(error_code, calc_cvc_gradients(first_cvc, num_cvcs)); - cvm::combine_errors(error_code, calc_cvc_sys_forces(first_cvc, num_cvcs)); - cvm::combine_errors(error_code, calc_cvc_Jacobians(first_cvc, num_cvcs)); + error_code |= calc_cvc_values(first_cvc, num_cvcs); + error_code |= calc_cvc_gradients(first_cvc, num_cvcs); + error_code |= calc_cvc_sys_forces(first_cvc, num_cvcs); + error_code |= calc_cvc_Jacobians(first_cvc, num_cvcs); if (cvm::debug()) cvm::log("Done calculating colvar \""+this->name+"\".\n"); @@ -842,12 +779,11 @@ int colvar::collect_cvc_data() int error_code = COLVARS_OK; - cvm::combine_errors(error_code, collect_cvc_values()); - cvm::combine_errors(error_code, collect_cvc_gradients()); - cvm::combine_errors(error_code, collect_cvc_sys_forces()); - cvm::combine_errors(error_code, collect_cvc_Jacobians()); - - cvm::combine_errors(error_code, calc_colvar_properties()); + error_code |= collect_cvc_values(); + error_code |= collect_cvc_gradients(); + error_code |= collect_cvc_sys_forces(); + error_code |= collect_cvc_Jacobians(); + error_code |= calc_colvar_properties(); if (cvm::debug()) cvm::log("Done calculating colvar \""+this->name+"\"'s properties.\n"); @@ -1374,7 +1310,7 @@ bool colvar::periodic_boundaries(colvarvalue const &lb, colvarvalue const &ub) c if ( (!is_enabled(f_cv_lower_boundary)) || (!is_enabled(f_cv_upper_boundary)) ) { cvm::log("Error: checking periodicity for collective variable \""+this->name+"\" " "requires lower and upper boundaries to be defined.\n"); - cvm::set_error_bit(INPUT_ERROR); + cvm::set_error_bits(INPUT_ERROR); } if (period > 0.0) { diff --git a/lib/colvars/colvaratoms.cpp b/lib/colvars/colvaratoms.cpp index b77576e896..786a72821f 100644 --- a/lib/colvars/colvaratoms.cpp +++ b/lib/colvars/colvaratoms.cpp @@ -297,7 +297,7 @@ int cvm::atom_group::parse(std::string const &conf) std::string numbers_conf = ""; size_t pos = 0; while (key_lookup(group_conf, "atomNumbers", numbers_conf, pos)) { - cvm::combine_errors(parse_error, add_atom_numbers(numbers_conf)); + parse_error |= add_atom_numbers(numbers_conf); numbers_conf = ""; } } @@ -306,7 +306,7 @@ int cvm::atom_group::parse(std::string const &conf) std::string index_group_name; if (get_keyval(group_conf, "indexGroup", index_group_name)) { // use an index group from the index file read globally - cvm::combine_errors(parse_error, add_index_group(index_group_name)); + parse_error |= add_index_group(index_group_name); } } @@ -315,7 +315,7 @@ int cvm::atom_group::parse(std::string const &conf) size_t pos = 0; while (key_lookup(group_conf, "atomNumbersRange", range_conf, pos)) { - cvm::combine_errors(parse_error, add_atom_numbers_range(range_conf)); + parse_error |= add_atom_numbers_range(range_conf); range_conf = ""; } } @@ -342,8 +342,8 @@ int cvm::atom_group::parse(std::string const &conf) cvm::error("Error: more instances of \"atomNameResidueRange\" than " "values of \"psfSegID\".\n", INPUT_ERROR); } else { - cvm::combine_errors(parse_error, add_atom_name_residue_range(psf_segids.size() ? - *psii : std::string(""), range_conf)); + parse_error |= add_atom_name_residue_range(psf_segids.size() ? + *psii : std::string(""), range_conf); if (psf_segids.size()) psii++; } range_conf = ""; @@ -407,7 +407,7 @@ int cvm::atom_group::parse(std::string const &conf) index = (cvm::proxy)->init_atom_group(atoms_ids); } - cvm::combine_errors(parse_error, parse_fitting_options(group_conf)); + parse_error |= parse_fitting_options(group_conf); // TODO move this to colvarparse object check_keywords(group_conf, key.c_str()); diff --git a/lib/colvars/colvarbias.cpp b/lib/colvars/colvarbias.cpp index 90c552ac0b..073cfc3965 100644 --- a/lib/colvars/colvarbias.cpp +++ b/lib/colvars/colvarbias.cpp @@ -203,7 +203,7 @@ cvm::real colvarbias::energy_difference(std::string const &conf) } -// So far, these are only implemented in colvarsbias_abf +// So far, these are only implemented in colvarbias_abf int colvarbias::bin_num() { cvm::error("Error: bin_num() not implemented.\n"); diff --git a/lib/colvars/colvarbias_histogram.cpp b/lib/colvars/colvarbias_histogram.cpp index 542dde2017..15ad5936aa 100644 --- a/lib/colvars/colvarbias_histogram.cpp +++ b/lib/colvars/colvarbias_histogram.cpp @@ -104,7 +104,7 @@ int colvarbias_histogram::update() { int error_code = COLVARS_OK; // update base class - cvm::combine_errors(error_code, colvarbias::update()); + error_code |= colvarbias::update(); if (cvm::debug()) { cvm::log("Updating histogram bias " + this->name); @@ -157,7 +157,7 @@ int colvarbias_histogram::update() write_output_files(); } - cvm::combine_errors(error_code, cvm::get_error()); + error_code |= cvm::get_error(); return error_code; } diff --git a/lib/colvars/colvarcomp.cpp b/lib/colvars/colvarcomp.cpp index eec43d0963..89973516be 100644 --- a/lib/colvars/colvarcomp.cpp +++ b/lib/colvars/colvarcomp.cpp @@ -43,11 +43,7 @@ colvar::cvc::cvc(std::string const &conf) // All cvcs implement this provide(f_cvc_debug_gradient); - { - bool b_debug_gradient; - get_keyval(conf, "debugGradients", b_debug_gradient, false, parse_silent); - if (b_debug_gradient) enable(f_cvc_debug_gradient); - } + get_keyval(conf, "debugGradients", set_feature(f_cvc_debug_gradient), false, parse_silent); // Attempt scalable calculations when in parallel? (By default yes, if available) get_keyval(conf, "scalable", b_try_scalable, true); diff --git a/lib/colvars/colvardeps.cpp b/lib/colvars/colvardeps.cpp index eabb67de4c..2801abb191 100644 --- a/lib/colvars/colvardeps.cpp +++ b/lib/colvars/colvardeps.cpp @@ -215,7 +215,7 @@ void cvm::deps::init_cvb_requires() { // Initialize feature_states for each instance feature_states.reserve(f_cvb_ntot); for (i = 0; i < f_cvb_ntot; i++) { - feature_states.push_back(new feature_state(true, false)); + feature_states.push_back(new feature_state(this, feature_states.size(), true, false)); // Most features are available, so we set them so // and list exceptions below } @@ -319,7 +319,7 @@ void cvm::deps::init_cv_requires() { // Initialize feature_states for each instance feature_states.reserve(f_cv_ntot); for (i = 0; i < f_cv_ntot; i++) { - feature_states.push_back(new feature_state(true, false)); + feature_states.push_back(new feature_state(this, feature_states.size(), true, false)); // Most features are available, so we set them so // and list exceptions below } @@ -385,7 +385,7 @@ void cvm::deps::init_cvc_requires() { // default as unavailable, not enabled feature_states.reserve(f_cvc_ntot); for (i = 0; i < cvm::deps::f_cvc_ntot; i++) { - feature_states.push_back(new feature_state(false, false)); + feature_states.push_back(new feature_state(this, feature_states.size(), false, false)); } // Features that are implemented by all cvcs by default @@ -429,7 +429,7 @@ void cvm::deps::init_ag_requires() { // default as unavailable, not enabled feature_states.reserve(f_ag_ntot); for (i = 0; i < cvm::deps::f_ag_ntot; i++) { - feature_states.push_back(new feature_state(false, false)); + feature_states.push_back(new feature_state(this, feature_states.size(), false, false)); } // Features that are implemented (or not) by all atom groups diff --git a/lib/colvars/colvardeps.h b/lib/colvars/colvardeps.h index 8787819b45..2aed77be50 100644 --- a/lib/colvars/colvardeps.h +++ b/lib/colvars/colvardeps.h @@ -27,9 +27,16 @@ public: std::string description; // reference to object name (cv, cvc etc.) /// This contains the current state of each feature for each object - struct feature_state { - feature_state(bool a, bool e) - : available(a), enabled(e) {} + class feature_state { + private: + cvm::deps *const deps_object; + int const id; + operator int() {} // never cast as int + public: + inline cvm::deps *object() const { return deps_object; } + inline int feature_id() const { return id; } + feature_state(cvm::deps *o, int i, bool a, bool e) + : deps_object(o), id(i), available(a), enabled(e) {} /// Available means: supported, subject to dependencies as listed, /// MAY BE ENABLED AS A RESULT OF DEPENDENCY SOLVING @@ -48,6 +55,12 @@ public: /// List of the state of all features std::vector feature_states; + /// Allow setting a feature state while parsing its kewyord + inline feature_state * set_feature(int id) + { + return feature_states[id]; + } + /// Describes a feature and its dependecies /// used in a static array within each subclass class feature { diff --git a/lib/colvars/colvarmodule.cpp b/lib/colvars/colvarmodule.cpp index 9317c421ed..4537c09509 100644 --- a/lib/colvars/colvarmodule.cpp +++ b/lib/colvars/colvarmodule.cpp @@ -340,8 +340,8 @@ int colvarmodule::parse_biases(std::string const &conf) int colvarmodule::catch_input_errors(int result) { if (result != COLVARS_OK || get_error()) { - set_error_bit(result); - set_error_bit(INPUT_ERROR); + set_error_bits(result); + set_error_bits(INPUT_ERROR); parse->init(); return get_error(); } @@ -493,27 +493,27 @@ int colvarmodule::calc() cvm::to_str(cvm::step_absolute())+"\n"); } - combine_errors(error_code, calc_colvars()); + error_code |= calc_colvars(); // set biasing forces to zero before biases are calculated and summed over for (std::vector::iterator cvi = colvars.begin(); cvi != colvars.end(); cvi++) { (*cvi)->reset_bias_force(); } - combine_errors(error_code, calc_biases()); - combine_errors(error_code, update_colvar_forces()); + error_code |= calc_biases(); + error_code |= update_colvar_forces(); if (cvm::b_analysis) { - combine_errors(error_code, analyze()); + error_code |= analyze(); } // write trajectory files, if needed if (cv_traj_freq && cv_traj_name.size()) { - combine_errors(error_code, write_traj_files()); + error_code |= write_traj_files(); } // write restart files, if needed if (restart_out_freq && restart_out_name.size()) { - combine_errors(error_code, write_restart_files()); + error_code |= write_restart_files(); } return error_code; @@ -551,7 +551,7 @@ int colvarmodule::calc_colvars() for (cvi = colvars.begin(); cvi != colvars.end(); cvi++) { if (!(*cvi)->is_enabled()) continue; - combine_errors(error_code, (*cvi)->update_cvc_flags()); + error_code |= (*cvi)->update_cvc_flags(); size_t num_items = (*cvi)->num_active_cvcs(); colvars_smp.reserve(colvars_smp.size() + num_items); @@ -566,12 +566,12 @@ int colvarmodule::calc_colvars() cvm::decrease_depth(); // calculate colvar components in parallel - combine_errors(error_code, proxy->smp_colvars_loop()); + error_code |= proxy->smp_colvars_loop(); cvm::increase_depth(); for (cvi = colvars.begin(); cvi != colvars.end(); cvi++) { if (!(*cvi)->is_enabled()) continue; - combine_errors(error_code, (*cvi)->collect_cvc_data()); + error_code |= (*cvi)->collect_cvc_data(); } cvm::decrease_depth(); @@ -581,7 +581,7 @@ int colvarmodule::calc_colvars() cvm::increase_depth(); for (cvi = colvars.begin(); cvi != colvars.end(); cvi++) { if (!(*cvi)->is_enabled()) continue; - combine_errors(error_code, (*cvi)->calc()); + error_code |= (*cvi)->calc(); if (cvm::get_error()) { return COLVARS_ERROR; } @@ -589,7 +589,7 @@ int colvarmodule::calc_colvars() cvm::decrease_depth(); } - combine_errors(error_code, cvm::get_error()); + error_code |= cvm::get_error(); return error_code; } @@ -609,21 +609,21 @@ int colvarmodule::calc_biases() if (use_scripted_forces && !scripting_after_biases) { // calculate biases and scripted forces in parallel - combine_errors(error_code, proxy->smp_biases_script_loop()); + error_code |= proxy->smp_biases_script_loop(); } else { // calculate biases in parallel - combine_errors(error_code, proxy->smp_biases_loop()); + error_code |= proxy->smp_biases_loop(); } } else { if (use_scripted_forces && !scripting_after_biases) { - combine_errors(error_code, calc_scripted_forces()); + error_code |= calc_scripted_forces(); } cvm::increase_depth(); for (bi = biases.begin(); bi != biases.end(); bi++) { - combine_errors(error_code, (*bi)->update()); + error_code |= (*bi)->update(); if (cvm::get_error()) { return COLVARS_ERROR; } @@ -661,7 +661,7 @@ int colvarmodule::update_colvar_forces() cvm::decrease_depth(); if (use_scripted_forces && scripting_after_biases) { - combine_errors(error_code, calc_scripted_forces()); + error_code |= calc_scripted_forces(); } cvm::real total_colvar_energy = 0.0; @@ -913,17 +913,17 @@ int colvarmodule::setup_output() std::string("")); if (cv_traj_freq && cv_traj_name.size()) { - combine_errors(error_code, open_traj_file(cv_traj_name)); + error_code |= open_traj_file(cv_traj_name); } for (std::vector::iterator bi = biases.begin(); bi != biases.end(); bi++) { - combine_errors(error_code, (*bi)->setup_output()); + error_code |= (*bi)->setup_output(); } if (error_code != COLVARS_OK || cvm::get_error()) { - set_error_bit(FILE_ERROR); + set_error_bits(FILE_ERROR); } return (cvm::get_error() ? COLVARS_ERROR : COLVARS_OK); @@ -1259,29 +1259,20 @@ size_t & cvm::depth() } -void colvarmodule::set_error_bit(int code) +void colvarmodule::set_error_bits(int code) { - if (code > 0) { - cvm::fatal_error("Error: set_error_bit() received positive error code.\n"); + if (code < 0) { + cvm::fatal_error("Error: set_error_bits() received negative error code.\n"); return; } proxy->smp_lock(); - errorCode = -1 * ((-1 * errorCode) | (-1 * code) | (-1 * COLVARS_ERROR)); + errorCode |= code | COLVARS_ERROR; proxy->smp_unlock(); } bool colvarmodule::get_error_bit(int code) { - return bool((-1 * errorCode) & (-1 * code)); -} - -void colvarmodule::combine_errors(int &target, int const code) -{ - if (code > 0 || target > 0) { - cvm::fatal_error("Error: combine_errors() received positive error code.\n"); - return; - } - target = -1 * ((-1 * target) | (-1 * code)); + return bool(errorCode & code); } void colvarmodule::clear_error() @@ -1294,7 +1285,7 @@ void colvarmodule::clear_error() void cvm::error(std::string const &message, int code) { - set_error_bit(code); + set_error_bits(code); proxy->error(message); } @@ -1303,7 +1294,7 @@ void cvm::fatal_error(std::string const &message) { // TODO once all non-fatal errors have been set to be handled by error(), // set DELETE_COLVARS here for VMD to handle it - set_error_bit(FATAL_ERROR); + set_error_bits(FATAL_ERROR); proxy->fatal_error(message); } diff --git a/lib/colvars/colvarmodule.h b/lib/colvars/colvarmodule.h index b8fc01be9e..516f968769 100644 --- a/lib/colvars/colvarmodule.h +++ b/lib/colvars/colvarmodule.h @@ -4,7 +4,7 @@ #define COLVARMODULE_H #ifndef COLVARS_VERSION -#define COLVARS_VERSION "2016-08-05" +#define COLVARS_VERSION "2016-08-10" #endif #ifndef COLVARS_DEBUG @@ -23,19 +23,16 @@ /// shared between all object instances) to be accessed from other /// objects. -// Error codes are the negative of powers-of-two -// as a result, error codes should NOT be bitwise-ORed but only -// accessed through set_error_bit() and get_error_bit() #define COLVARS_OK 0 -#define COLVARS_ERROR -1 -#define COLVARS_NOT_IMPLEMENTED (-1*(1<<1)) -#define INPUT_ERROR (-1*(1<<2)) // out of bounds or inconsistent input -#define BUG_ERROR (-1*(1<<3)) // Inconsistent state indicating bug -#define FILE_ERROR (-1*(1<<4)) -#define MEMORY_ERROR (-1*(1<<5)) -#define FATAL_ERROR (-1*(1<<6)) // Should be set, or not, together with other bits -#define DELETE_COLVARS (-1*(1<<7)) // Instruct the caller to delete cvm -#define COLVARS_NO_SUCH_FRAME (-1*(1<<8)) // Cannot load the requested frame +#define COLVARS_ERROR 1 +#define COLVARS_NOT_IMPLEMENTED (1<<1) +#define INPUT_ERROR (1<<2) // out of bounds or inconsistent input +#define BUG_ERROR (1<<3) // Inconsistent state indicating bug +#define FILE_ERROR (1<<4) +#define MEMORY_ERROR (1<<5) +#define FATAL_ERROR (1<<6) // Should be set, or not, together with other bits +#define DELETE_COLVARS (1<<7) // Instruct the caller to delete cvm +#define COLVARS_NO_SUCH_FRAME (1<<8) // Cannot load the requested frame #include #include @@ -118,12 +115,10 @@ protected: public: - static void set_error_bit(int code); + static void set_error_bits(int code); static bool get_error_bit(int code); - static void combine_errors(int &target, int const code); - static inline int get_error() { return errorCode; diff --git a/lib/colvars/colvarparse.cpp b/lib/colvars/colvarparse.cpp index f6e904c83a..da39f78356 100644 --- a/lib/colvars/colvarparse.cpp +++ b/lib/colvars/colvarparse.cpp @@ -354,6 +354,21 @@ bool colvarparse::get_keyval(std::string const &conf, } +bool colvarparse::get_keyval(std::string const &conf, + char const *key, + cvm::deps::feature_state *value, + bool const &def_value, + Parse_Mode const parse_mode) +{ + bool feature_flag = def_value; + bool const b_found = get_keyval(conf, key, feature_flag, def_value, parse_mode); + if (feature_flag) { + value->object()->enable(value->feature_id()); + } + return b_found; +} + + // multiple-value keyword parsers bool colvarparse::get_keyval(std::string const &conf, @@ -548,6 +563,10 @@ bool colvarparse::key_lookup(std::string const &conf, std::string &data, size_t &save_pos) { + if (cvm::debug()) { + cvm::log("Looking for the keyword \""+std::string(key_in)+"\" and its value.\n"); + } + // add this keyword to the register (in its camelCase version) add_keyword(key_in); @@ -568,11 +587,14 @@ bool colvarparse::key_lookup(std::string const &conf, // start from the first occurrence of key size_t pos = conf_lower.find(key, save_pos); - // iterate over all instances until it finds the isolated keyword + // iterate over all instances of the substring until it finds it as isolated keyword while (true) { if (pos == std::string::npos) { // no valid instance of the keyword has been found + if (cvm::debug()) { + cvm::log("Keyword \""+std::string(key_in)+"\" not found.\n"); + } return false; } @@ -625,25 +647,46 @@ bool colvarparse::key_lookup(std::string const &conf, size_t data_begin = (to_lower_cppstr(line)).find(key) + key.size(); data_begin = line.find_first_not_of(white_space, data_begin+1); - // size_t data_begin_absolute = data_begin + line_begin; - // size_t data_end_absolute = data_begin; - if (data_begin != std::string::npos) { size_t data_end = line.find_last_not_of(white_space) + 1; data_end = (data_end == std::string::npos) ? line.size() : data_end; - // data_end_absolute = data_end + line_begin; - if (line.find('{', data_begin) != std::string::npos) { + size_t brace = line.find('{', data_begin); // look for an opening brace + size_t brace_last = brace; - size_t brace_count = 1; - size_t brace = line.find('{', data_begin); // start from the first opening brace + if (brace != std::string::npos) { + + // find the matching closing brace + + if (cvm::debug()) { + cvm::log("Multi-line value, config is now \""+line+"\".\n"); + } + + int brace_count = 1; while (brace_count > 0) { - // find the matching closing brace - brace = line.find_first_of("{}", brace+1); - while (brace == std::string::npos) { + brace = line.find_first_of("{}", brace_last+1); + // find all braces within this line + while (brace < std::string::npos) { + brace_last = brace; + if (line[brace] == '{') brace_count++; + if (line[brace] == '}') brace_count--; + if (brace_count == 0) { + data_end = brace+1; + break; + } + brace = line.find_first_of("{}", brace+1); + } + + if (brace_count == 0) { + data_end = brace+1; + break; + } + + if (brace == std::string::npos) { + // add a new line if (line_end >= conf.size()) { cvm::error("Parse error: reached the end while " @@ -653,7 +696,6 @@ bool colvarparse::key_lookup(std::string const &conf, return false; } size_t const old_end = line.size(); - // data_end_absolute += old_end+1; line_begin = line_end; nl = conf.find('\n', line_begin+1); @@ -663,36 +705,37 @@ bool colvarparse::key_lookup(std::string const &conf, line_end = nl; line.append(conf, line_begin, (line_end-line_begin)); - brace = line.find_first_of("{}", old_end); + if (cvm::debug()) { + cvm::log("Added a new line, config is now \""+line+"\".\n"); + } } - if (line[brace] == '{') brace_count++; - if (line[brace] == '}') brace_count--; + if (brace_count < 0) { + cvm::error("Error: found closing brace without opening brace.\n", INPUT_ERROR); + } } - // set data_begin after the opening brace - data_begin = line.find_first_of('{', data_begin) + 1; + cvm::log("Value so far = "+line.substr(data_begin, (data_end-data_begin))+".\n"); + + // strip the leading and trailing braces + data_begin = line.find_first_of('{') + 1; data_begin = line.find_first_not_of(white_space, data_begin); - // set data_end before the closing brace - data_end = brace; - data_end = line.find_last_not_of(white_space+"}", - data_end) + 1; - // data_end_absolute = line_end; - if (data_end > line.size()) - data_end = line.size(); + data_end = line.find_last_of('}', line.size()) - 1; + data_end = line.find_last_not_of(white_space, + data_end) + 1; } data.append(line, data_begin, (data_end-data_begin)); + if (cvm::debug()) { + cvm::log("Keyword value = \""+data+"\".\n"); + } + if (data.size() && save_delimiters) { data_begin_pos.push_back(conf.find(data, pos+key.size())); data_end_pos.push_back(data_begin_pos.back()+data.size()); - // std::cerr << "key = " << key << ", data = \"" - // << data << "\", data_begin, data_end = " - // << data_begin_pos.back() << ", " << data_end_pos.back() - // << "\n"; } } diff --git a/lib/colvars/colvarparse.h b/lib/colvars/colvarparse.h index 9bce5412ed..c091cbc15d 100644 --- a/lib/colvars/colvarparse.h +++ b/lib/colvars/colvarparse.h @@ -8,6 +8,7 @@ #include "colvarmodule.h" #include "colvarvalue.h" +#include "colvardeps.h" /// \file colvarparse.h Parsing functions for collective variables @@ -180,6 +181,11 @@ public: bool &value, bool const &def_value = false, Parse_Mode const parse_mode = parse_normal); + bool get_keyval(std::string const &conf, + char const *key, + cvm::deps::feature_state *value, + bool const &def_value = false, + Parse_Mode const parse_mode = parse_normal); bool get_keyval(std::string const &conf, char const *key, diff --git a/lib/colvars/colvarproxy.h b/lib/colvars/colvarproxy.h index 0d29a7297d..4bba189bb7 100644 --- a/lib/colvars/colvarproxy.h +++ b/lib/colvars/colvarproxy.h @@ -69,12 +69,12 @@ public: virtual cvm::real rand_gaussian(void) = 0; /// \brief Get the current frame number - // Negative return values indicate error - virtual int frame() { return COLVARS_NOT_IMPLEMENTED; } + // Returns error code + virtual int get_frame(long int&) { return COLVARS_NOT_IMPLEMENTED; } - /// \brief Set the current frame number - // return frame number on success, COLVARS_NO_SUCH_FRAME otherwise - virtual int frame(int) { return COLVARS_NOT_IMPLEMENTED; } + /// \brief Set the current frame number (as well as colvarmodule::it) + // Returns error code + virtual int set_frame(long int) { return COLVARS_NOT_IMPLEMENTED; } /// \brief Prefix to be used for input files (restarts, not /// configuration) diff --git a/lib/colvars/colvarscript.cpp b/lib/colvars/colvarscript.cpp index 091162fc18..374359ccef 100644 --- a/lib/colvars/colvarscript.cpp +++ b/lib/colvars/colvarscript.cpp @@ -55,14 +55,14 @@ int colvarscript::run(int argc, char const *argv[]) { if (cmd == "delete") { // Note: the delete bit may be ignored by some backends // it is mostly useful in VMD - colvars->set_error_bit(DELETE_COLVARS); + colvars->set_error_bits(DELETE_COLVARS); return COLVARS_OK; } if (cmd == "update") { - cvm::combine_errors(error_code, proxy->update_input()); - cvm::combine_errors(error_code, colvars->calc()); - cvm::combine_errors(error_code, proxy->update_output()); + error_code |= proxy->update_input(); + error_code |= colvars->calc(); + error_code |= proxy->update_output(); if (error_code) { result += "Error updating the colvars module.\n"; } @@ -142,8 +142,8 @@ int colvarscript::run(int argc, char const *argv[]) { } proxy->output_prefix_str = argv[2]; int error = 0; - cvm::combine_errors(error, colvars->setup_output()); - cvm::combine_errors(error, colvars->write_output_files()); + error |= colvars->setup_output(); + error |= colvars->write_output_files(); return error ? COLVARSCRIPT_ERROR : COLVARS_OK; } @@ -163,8 +163,9 @@ int colvarscript::run(int argc, char const *argv[]) { if (cmd == "frame") { if (argc == 2) { - int f = proxy->frame(); - if (f >= 0) { + long int f; + int error = proxy->get_frame(f); + if (error == COLVARS_OK) { result = cvm::to_str(f); return COLVARS_OK; } else { @@ -173,10 +174,9 @@ int colvarscript::run(int argc, char const *argv[]) { } } else if (argc == 3) { // Failure of this function does not trigger an error, but - // returns the plain result to let scripts detect available frames - long int f = proxy->frame(strtol(argv[2], NULL, 10)); - colvars->it = proxy->frame(); - result = cvm::to_str(f); + // returns nonzero, to let scripts detect available frames + int error = proxy->set_frame(strtol(argv[2], NULL, 10)); + result = cvm::to_str(error == COLVARS_OK ? 0 : -1); return COLVARS_OK; } else { result = "Wrong arguments to command \"frame\"\n" + help_string(); @@ -414,7 +414,8 @@ Input and output:\n\ printframe -- return a summary of the current frame\n\ printframelabels -- return labels to annotate printframe's output\n"; - if (proxy->frame() != COLVARS_NOT_IMPLEMENTED) { + long int tmp; + if (proxy->get_frame(tmp) != COLVARS_NOT_IMPLEMENTED) { buf += "\ frame -- return current frame number\n\ frame -- set frame number\n";