From 7f2773233a63c9c75d5bcca26810d8ae55192150 Mon Sep 17 00:00:00 2001 From: Giacomo Fiorin Date: Wed, 29 Nov 2023 16:30:22 -0500 Subject: [PATCH] Separate creation and initialization of colvar components --- src/colvar.cpp | 18 +- src/colvar.h | 7 +- src/colvarcomp.cpp | 14 -- src/colvarcomp.h | 296 ++++++++++--------------- src/colvarcomp_alchlambda.cpp | 6 +- src/colvarcomp_angles.cpp | 125 ++++------- src/colvarcomp_apath.cpp | 44 +++- src/colvarcomp_combination.cpp | 43 +++- src/colvarcomp_coordnums.cpp | 210 ++++++++++-------- src/colvarcomp_distances.cpp | 365 +++++++++++++++---------------- src/colvarcomp_gpath.cpp | 122 ++++++++--- src/colvarcomp_neuralnetwork.cpp | 34 ++- src/colvarcomp_protein.cpp | 96 ++++---- src/colvarcomp_rotations.cpp | 115 +--------- src/colvarcomp_volmaps.cpp | 24 +- 15 files changed, 703 insertions(+), 816 deletions(-) diff --git a/src/colvar.cpp b/src/colvar.cpp index 9daef0b9d..6a850e3ae 100644 --- a/src/colvar.cpp +++ b/src/colvar.cpp @@ -22,10 +22,8 @@ #include "colvars_memstream.h" - -std::map> - colvar::global_cvc_map = - std::map>(); +std::map> colvar::global_cvc_map = + std::map>(); std::map colvar::global_cvc_desc_map = std::map(); @@ -755,8 +753,8 @@ template void colvar::add_component_type(char const *def_description, char const *def_config_key) { if (global_cvc_map.count(def_config_key) == 0) { - global_cvc_map[def_config_key] = [](const std::string &cvc_conf) { - return new def_class_name(cvc_conf); + global_cvc_map[def_config_key] = []() { + return new def_class_name(); }; global_cvc_desc_map[def_config_key] = std::string(def_description); } @@ -776,11 +774,10 @@ int colvar::init_components_type(const std::string& conf, const char* def_config "a new \""+std::string(def_config_key)+"\" component"+ (cvm::debug() ? ", with configuration:\n"+def_conf : ".\n")); - cvc *cvcp = global_cvc_map[def_config_key](def_conf); - cvm::increase_depth(); + cvc *cvcp = global_cvc_map[def_config_key](); if (cvcp) { - int error_code = cvcp->init_code; - cvcs.push_back(cvcp); + cvm::increase_depth(); + int error_code = cvcp->init(def_conf); error_code |= cvcp->set_function_type(def_config_key); if (error_code == COLVARS_OK) { error_code |= cvcp->check_keywords(def_conf, def_config_key); @@ -796,6 +793,7 @@ int colvar::init_components_type(const std::string& conf, const char* def_config return cvm::error("Error: in allocating component \"" + std::string(def_config_key) + "\".\n", COLVARS_MEMORY_ERROR); } + cvcs.push_back(cvcp); if ((cvcp->period != 0.0) || (cvcp->wrap_center != 0.0)) { if (!cvcp->is_enabled(f_cvc_periodic)) { diff --git a/src/colvar.h b/src/colvar.h index 292a87b76..e4cda8a35 100644 --- a/src/colvar.h +++ b/src/colvar.h @@ -616,7 +616,6 @@ class colvar : public colvarparse, public colvardeps { class dihedPC; class alch_lambda; class alch_Flambda; - class componentDisabled; class CartesianBasedPath; class aspath; class azpath; @@ -644,8 +643,7 @@ class colvar : public colvarparse, public colvardeps { class map_total; /// A global mapping of cvc names to the cvc constructors - static const std::map> & - get_global_cvc_map() + static const std::map> &get_global_cvc_map() { return global_cvc_map; } @@ -688,8 +686,7 @@ class colvar : public colvarparse, public colvardeps { #endif /// A global mapping of cvc names to the cvc constructors - static std::map> - global_cvc_map; + static std::map> global_cvc_map; /// A global mapping of cvc names to the corresponding descriptions static std::map global_cvc_desc_map; diff --git a/src/colvarcomp.cpp b/src/colvarcomp.cpp index 0d05e176a..0cccdc729 100644 --- a/src/colvarcomp.cpp +++ b/src/colvarcomp.cpp @@ -29,20 +29,6 @@ colvar::cvc::cvc() } -colvar::cvc::cvc(std::string const &conf) -{ - description = "uninitialized colvar component"; - b_try_scalable = true; - sup_coeff = 1.0; - sup_np = 1; - period = 0.0; - wrap_center = 0.0; - width = 0.0; - init_dependencies(); - colvar::cvc::init(conf); -} - - int colvar::cvc::update_description() { if (name.size() > 0) { diff --git a/src/colvarcomp.h b/src/colvarcomp.h index 8d7b69618..5db90fe46 100644 --- a/src/colvarcomp.h +++ b/src/colvarcomp.h @@ -100,10 +100,11 @@ class colvar::cvc /// \brief If the component is periodic, wrap around this value (default: 0.0) cvm::real wrap_center; - /// \brief Constructor - /// - /// Calls the init() function of the class - cvc(std::string const &conf); + /// Constructor + cvc(); + + /// Destructor + virtual ~cvc(); /// Current initialization state; TODO remove this when using init() after default constructor int init_code = COLVARS_OK; @@ -132,13 +133,6 @@ class colvar::cvc /// \brief After construction, set data related to dependency handling int setup(); - /// \brief Default constructor (used when \link colvar::cvc \endlink - /// objects are declared within other ones) - cvc(); - - /// Destructor - virtual ~cvc(); - /// \brief Implementation of the feature list for colvar static std::vector cvc_features; @@ -358,9 +352,9 @@ class colvar::distance /// Vector distance, cached to be recycled cvm::rvector dist_v; public: - distance(std::string const &conf); distance(); virtual ~distance() {} + virtual int init(std::string const &conf); virtual void calc_value(); virtual void calc_gradients(); virtual void calc_force_invgrads(); @@ -383,7 +377,6 @@ class colvar::distance_vec : public colvar::distance { public: - distance_vec(std::string const &conf); distance_vec(); virtual ~distance_vec() {} virtual void calc_value(); @@ -409,7 +402,6 @@ class colvar::distance_dir : public colvar::distance { public: - distance_dir(std::string const &conf); distance_dir(); virtual ~distance_dir() {} virtual void calc_value(); @@ -449,9 +441,9 @@ class colvar::distance_z /// Flag: using a fixed axis vector? bool fixed_axis; public: - distance_z(std::string const &conf); distance_z(); virtual ~distance_z() {} + virtual int init(std::string const &conf); virtual void calc_value(); virtual void calc_gradients(); virtual void calc_force_invgrads(); @@ -480,7 +472,6 @@ class colvar::distance_xy /// Vector distances cvm::rvector v12, v13; public: - distance_xy(std::string const &conf); distance_xy(); virtual ~distance_xy() {} virtual void calc_value(); @@ -502,14 +493,14 @@ class colvar::distance_xy class colvar::polar_phi : public colvar::cvc { -public: - polar_phi(std::string const &conf); - polar_phi(); - virtual ~polar_phi() {} protected: - cvm::atom_group *atoms; + cvm::atom_group *atoms; cvm::real r, theta, phi; + public: + polar_phi(); + virtual ~polar_phi() {} + virtual int init(std::string const &conf); virtual void calc_value(); virtual void calc_gradients(); virtual void apply_force(colvarvalue const &force); @@ -533,9 +524,9 @@ class colvar::polar_theta : public colvar::cvc { public: - polar_theta(std::string const &conf); polar_theta(); virtual ~polar_theta() {} + virtual int init(std::string const &conf); protected: cvm::atom_group *atoms; cvm::real r, theta, phi; @@ -565,10 +556,11 @@ class colvar::distance_inv /// Second atom group cvm::atom_group *group2; /// Components of the distance vector orthogonal to the axis - int exponent; + int exponent = 6; public: - distance_inv(std::string const &conf); + distance_inv(); virtual ~distance_inv() {} + virtual int init(std::string const &conf); virtual void calc_value(); virtual void calc_gradients(); virtual void apply_force(colvarvalue const &force); @@ -593,9 +585,9 @@ class colvar::distance_pairs /// Second atom group cvm::atom_group *group2; public: - distance_pairs(std::string const &conf); distance_pairs(); virtual ~distance_pairs() {} + virtual int init(std::string const &conf); virtual void calc_value(); virtual void calc_gradients(); virtual void apply_force(colvarvalue const &force); @@ -612,11 +604,9 @@ class colvar::dipole_magnitude cvm::atom_group *atoms; cvm::atom_pos dipoleV; public: - /// Initialize by parsing the configuration - dipole_magnitude (std::string const &conf); - dipole_magnitude (cvm::atom const &a1); dipole_magnitude(); virtual ~dipole_magnitude() {} + virtual int init(std::string const &conf); virtual void calc_value(); virtual void calc_gradients(); //virtual void calc_force_invgrads(); @@ -641,8 +631,9 @@ class colvar::gyration /// Atoms involved cvm::atom_group *atoms; public: - gyration(std::string const &conf); + gyration(); virtual ~gyration() {} + virtual int init(std::string const &conf); virtual void calc_value(); virtual void calc_gradients(); virtual void calc_force_invgrads(); @@ -664,8 +655,6 @@ class colvar::inertia : public colvar::gyration { public: - /// Constructor - inertia(std::string const &conf); inertia(); virtual ~inertia() {} virtual void calc_value(); @@ -690,10 +679,9 @@ class colvar::inertia_z /// Vector on which the inertia tensor is projected cvm::rvector axis; public: - /// Constructor - inertia_z(std::string const &conf); inertia_z(); virtual ~inertia_z() {} + virtual int init(std::string const &conf); virtual void calc_value(); virtual void calc_gradients(); virtual void apply_force(colvarvalue const &force); @@ -728,9 +716,9 @@ class colvar::eigenvector public: - /// Constructor - eigenvector(std::string const &conf); + eigenvector(); virtual ~eigenvector() {} + virtual int init(std::string const &conf); virtual void calc_value(); virtual void calc_gradients(); virtual void calc_force_invgrads(); @@ -773,11 +761,11 @@ class colvar::angle bool b_1site_force; public: - /// Initialize by parsing the configuration - angle(std::string const &conf); + angle(); /// \brief Initialize the three groups after three atoms angle(cvm::atom const &a1, cvm::atom const &a2, cvm::atom const &a3); virtual ~angle() {} + virtual int init(std::string const &conf); virtual void calc_value(); virtual void calc_gradients(); virtual void calc_force_invgrads(); @@ -820,12 +808,9 @@ class colvar::dipole_angle bool b_1site_force; public: - /// Initialize by parsing the configuration - dipole_angle (std::string const &conf); - /// \brief Initialize the three groups after three atoms - dipole_angle (cvm::atom const &a1, cvm::atom const &a2, cvm::atom const &a3); dipole_angle(); virtual ~dipole_angle() {} + virtual int init(std::string const &conf); virtual void calc_value(); virtual void calc_gradients(); virtual void apply_force (colvarvalue const &force); @@ -863,12 +848,11 @@ class colvar::dihedral public: - /// Initialize by parsing the configuration - dihedral(std::string const &conf); /// \brief Initialize the four groups after four atoms dihedral(cvm::atom const &a1, cvm::atom const &a2, cvm::atom const &a3, cvm::atom const &a4); dihedral(); virtual ~dihedral() {} + virtual int init(std::string const &conf); virtual void calc_value(); virtual void calc_gradients(); virtual void calc_force_invgrads(); @@ -905,29 +889,29 @@ class colvar::coordnum /// \brief "Cutoff vector" for anisotropic calculation cvm::rvector r0_vec; /// \brief Whether r/r0 or \vec{r}*\vec{1/r0_vec} should be used - bool b_anisotropic; + bool b_anisotropic = false; /// Integer exponent of the function numerator - int en; + int en = 6; /// Integer exponent of the function denominator - int ed; + int ed = 12; /// If true, group2 will be treated as a single atom - bool b_group2_center_only; + bool b_group2_center_only = false; /// Tolerance for the pair list - cvm::real tolerance; + cvm::real tolerance = 0.0; /// Frequency of update of the pair list - int pairlist_freq; + int pairlist_freq = 100; /// Pair list - bool *pairlist; + bool *pairlist = nullptr; public: - coordnum(std::string const &conf); - ~coordnum(); - + coordnum(); + virtual ~coordnum(); + virtual int init(std::string const &conf); virtual void calc_value(); virtual void calc_gradients(); virtual void apply_force(colvarvalue const &force); @@ -985,17 +969,19 @@ class colvar::selfcoordnum /// \brief "Cutoff" for isotropic calculation (default) cvm::real r0; /// Integer exponent of the function numerator - int en; + int en = 6; /// Integer exponent of the function denominator - int ed; - cvm::real tolerance; - int pairlist_freq; - bool *pairlist; + int ed = 12; + cvm::real tolerance = 0.0; + int pairlist_freq = 100; + + bool *pairlist = nullptr; public: - selfcoordnum(std::string const &conf); + selfcoordnum(); ~selfcoordnum(); + virtual int init(std::string const &conf); virtual void calc_value(); virtual void calc_gradients(); virtual void apply_force(colvarvalue const &force); @@ -1025,15 +1011,15 @@ class colvar::groupcoordnum cvm::rvector r0_vec; /// \brief Wheter dist/r0 or \vec{dist}*\vec{1/r0_vec} should ne be /// used - bool b_anisotropic; + bool b_anisotropic = false; /// Integer exponent of the function numerator - int en; + int en = 6; /// Integer exponent of the function denominator - int ed; + int ed = 12; public: - /// Constructor - groupcoordnum(std::string const &conf); + groupcoordnum(); virtual ~groupcoordnum() {} + virtual int init(std::string const &conf); virtual void calc_value(); virtual void calc_gradients(); virtual void apply_force(colvarvalue const &force); @@ -1058,17 +1044,17 @@ class colvar::h_bond /// \brief "Cutoff" distance between acceptor and donor cvm::real r0; /// Integer exponent of the function numerator - int en; + int en = 6; /// Integer exponent of the function denominator - int ed; + int ed = 8; public: - h_bond(std::string const &conf); /// Constructor for atoms already allocated h_bond(cvm::atom const &acceptor, cvm::atom const &donor, cvm::real r0, int en, int ed); h_bond(); virtual ~h_bond() {} + virtual int init(std::string const &conf); virtual void calc_value(); virtual void calc_gradients(); virtual void apply_force(colvarvalue const &force); @@ -1082,49 +1068,6 @@ class colvar::h_bond }; - -/// \brief Colvar component: alpha helix content of a contiguous -/// segment of 5 or more residues, implemented as a sum of phi/psi -/// dihedral angles and hydrogen bonds (colvarvalue::type_scalar type, -/// range [0:1]) -// class colvar::alpha_dihedrals -// : public colvar::cvc -// { -// protected: - -// /// Alpha-helical reference phi value -// cvm::real phi_ref; - -// /// Alpha-helical reference psi value -// cvm::real psi_ref; - -// /// List of phi dihedral angles -// std::vector phi; - -// /// List of psi dihedral angles -// std::vector psi; - -// /// List of hydrogen bonds -// std::vector hb; - -// public: - -// alpha_dihedrals (std::string const &conf); -// alpha_dihedrals(); -// virtual ~alpha_dihedrals() {} -// virtual void calc_value(); -// virtual void calc_gradients(); -// virtual void apply_force (colvarvalue const &force); -// virtual cvm::real dist2 (colvarvalue const &x1, -// colvarvalue const &x2) const; -// virtual colvarvalue dist2_lgrad (colvarvalue const &x1, -// colvarvalue const &x2) const; -// virtual colvarvalue dist2_rgrad (colvarvalue const &x1, -// colvarvalue const &x2) const; -// }; - - - /// \brief Colvar component: alpha helix content of a contiguous /// segment of 5 or more residues, implemented as a sum of Ca-Ca-Ca /// angles and hydrogen bonds (colvarvalue::type_scalar type, range @@ -1135,10 +1078,10 @@ class colvar::alpha_angles protected: /// Reference Calpha-Calpha angle (default: 88 degrees) - cvm::real theta_ref; + cvm::real theta_ref = 88.0; /// Tolerance on the Calpha-Calpha angle - cvm::real theta_tol; + cvm::real theta_tol = 15.0; /// List of Calpha-Calpha angles std::vector theta; @@ -1146,14 +1089,23 @@ class colvar::alpha_angles /// List of hydrogen bonds std::vector hb; - /// Contribution of the hb terms - cvm::real hb_coeff; + /// Contribution of the HB terms + cvm::real hb_coeff = 0.5; + + /// Cutoff for HB + cvm::real r0; + + /// Integer exponent of the HB numerator + int en = 6; + + /// Integer exponent of the HB denominator + int ed = 8; public: - alpha_angles(std::string const &conf); alpha_angles(); virtual ~alpha_angles(); + virtual int init(std::string const &conf); void calc_value(); void calc_gradients(); /// Re-implementation of cvc::collect_gradients() to carry over atomic gradients of sub-cvcs @@ -1183,14 +1135,14 @@ class colvar::dihedPC public: - dihedPC(std::string const &conf); dihedPC(); - virtual ~dihedPC(); - void calc_value(); - void calc_gradients(); + virtual ~dihedPC(); + virtual int init(std::string const &conf); + virtual void calc_value(); + virtual void calc_gradients(); /// Re-implementation of cvc::collect_gradients() to carry over atomic gradients of sub-cvcs - void collect_gradients(std::vector const &atom_ids, std::vector &atomic_gradients); - void apply_force(colvarvalue const &force); + virtual void collect_gradients(std::vector const &atom_ids, std::vector &atomic_gradients); + virtual void apply_force(colvarvalue const &force); virtual cvm::real dist2(colvarvalue const &x1, colvarvalue const &x2) const; virtual colvarvalue dist2_lgrad(colvarvalue const &x1, @@ -1234,10 +1186,9 @@ class colvar::orientation public: - orientation(std::string const &conf); orientation(); - virtual int init(std::string const &conf); virtual ~orientation(); + virtual int init(std::string const &conf); virtual void calc_value(); virtual void calc_gradients(); virtual void apply_force(colvarvalue const &force); @@ -1259,8 +1210,7 @@ class colvar::orientation_angle { public: - orientation_angle(std::string const &conf); - virtual int init(std::string const &conf); + orientation_angle(); virtual ~orientation_angle() {} virtual void calc_value(); virtual void calc_gradients(); @@ -1283,9 +1233,7 @@ class colvar::orientation_proj { public: - orientation_proj(std::string const &conf); orientation_proj(); - virtual int init(std::string const &conf); virtual ~orientation_proj() {} virtual void calc_value(); virtual void calc_gradients(); @@ -1311,9 +1259,9 @@ class colvar::tilt public: - tilt(std::string const &conf); - virtual int init(std::string const &conf); + tilt(); virtual ~tilt() {} + virtual int init(std::string const &conf); virtual void calc_value(); virtual void calc_gradients(); virtual void apply_force(colvarvalue const &force); @@ -1338,10 +1286,9 @@ class colvar::spin_angle public: - spin_angle(std::string const &conf); spin_angle(); - virtual int init(std::string const &conf); virtual ~spin_angle() {} + virtual int init(std::string const &conf); virtual void calc_value(); virtual void calc_gradients(); virtual void apply_force(colvarvalue const &force); @@ -1363,9 +1310,7 @@ class colvar::euler_phi : public colvar::orientation { public: - euler_phi(std::string const &conf); euler_phi(); - virtual int init(std::string const &conf); virtual ~euler_phi() {} virtual void calc_value(); virtual void calc_gradients(); @@ -1385,9 +1330,7 @@ class colvar::euler_psi : public colvar::orientation { public: - euler_psi(std::string const &conf); euler_psi(); - virtual int init(std::string const &conf); virtual ~euler_psi() {} virtual void calc_value(); virtual void calc_gradients(); @@ -1407,9 +1350,7 @@ class colvar::euler_theta : public colvar::orientation { public: - euler_theta(std::string const &conf); euler_theta(); - virtual int init(std::string const &conf); virtual ~euler_theta() {} virtual void calc_value(); virtual void calc_gradients(); @@ -1442,15 +1383,18 @@ class colvar::rmsd std::vector ref_pos; /// Number of permutations of symmetry-related atoms - size_t n_permutations; + size_t n_permutations = 1; /// Index of the permutation yielding the smallest RMSD (0 for identity) - size_t best_perm_index; -public: + size_t best_perm_index = 0; - /// Constructor - rmsd(std::string const &conf); + /// Permutation RMSD input parsing + int init_permutation(std::string const &conf); + +public: + rmsd(); virtual ~rmsd() {} + virtual int init(std::string const &conf); virtual void calc_value(); virtual void calc_gradients(); virtual void calc_force_invgrads(); @@ -1477,9 +1421,9 @@ class colvar::cartesian /// Which Cartesian coordinates to include std::vector axes; public: - cartesian(std::string const &conf); cartesian(); virtual ~cartesian() {} + virtual int init(std::string const &conf); virtual void calc_value(); virtual void calc_gradients(); virtual void apply_force(colvarvalue const &force); @@ -1494,7 +1438,6 @@ class colvar::alch_lambda protected: // No atom groups needed public: - alch_lambda(std::string const &conf); alch_lambda(); virtual ~alch_lambda() {} virtual void calc_value(); @@ -1517,7 +1460,6 @@ class colvar::alch_Flambda protected: // No atom groups needed public: - alch_Flambda(std::string const &conf); alch_Flambda(); virtual ~alch_Flambda() {} virtual void calc_value(); @@ -1532,20 +1474,6 @@ class colvar::alch_Flambda }; -class colvar::componentDisabled - : public colvar::cvc -{ -public: - componentDisabled(std::string const & /* conf */) { - cvm::error("Error: this component is not enabled in the current build; please see https://colvars.github.io/README-c++11.html"); - } - virtual ~componentDisabled() {} - virtual void calc_value() {} - virtual void calc_gradients() {} - virtual void apply_force(colvarvalue const & /* force */) {} -}; - - class colvar::CartesianBasedPath : public colvar::cvc @@ -1565,8 +1493,9 @@ class colvar::CartesianBasedPath /// Total number of reference frames size_t total_reference_frames; public: - CartesianBasedPath(std::string const &conf); + CartesianBasedPath(); virtual ~CartesianBasedPath(); + virtual int init(std::string const &conf); virtual void calc_value() = 0; virtual void apply_force(colvarvalue const &force) = 0; }; @@ -1584,8 +1513,9 @@ class colvar::gspath virtual void prepareVectors(); virtual void updateDistanceToReferenceFrames(); public: - gspath(std::string const &conf); + gspath(); virtual ~gspath() {} + virtual int init(std::string const &conf); virtual void calc_value(); virtual void calc_gradients(); virtual void apply_force(colvarvalue const &force); @@ -1606,8 +1536,9 @@ class colvar::gzpath virtual void prepareVectors(); virtual void updateDistanceToReferenceFrames(); public: - gzpath(std::string const &conf); + gzpath(); virtual ~gzpath() {} + virtual int init(std::string const &conf); virtual void calc_value(); virtual void calc_gradients(); virtual void apply_force(colvarvalue const &force); @@ -1625,8 +1556,9 @@ class colvar::linearCombination protected: cvm::real getPolynomialFactorOfCVGradient(size_t i_cv) const; public: - linearCombination(std::string const &conf); + linearCombination(); virtual ~linearCombination(); + virtual int init(std::string const &conf); virtual void calc_value(); virtual void calc_gradients(); virtual void apply_force(colvarvalue const &force); @@ -1638,7 +1570,7 @@ class colvar::customColvar : public colvar::linearCombination { protected: - bool use_custom_function; + bool use_custom_function = false; #ifdef LEPTON /// Vector of evaluators for custom functions using Lepton std::vector value_evaluators; @@ -1648,11 +1580,12 @@ class colvar::customColvar std::vector value_eval_var_refs; std::vector grad_eval_var_refs; /// Unused value that is written to when a variable simplifies out of a Lepton expression - double dev_null; + double dev_null = 0.0; #endif public: - customColvar(std::string const &conf); + customColvar(); virtual ~customColvar(); + virtual int init(std::string const &conf); virtual void calc_value(); virtual void calc_gradients(); virtual void apply_force(colvarvalue const &force); @@ -1677,8 +1610,9 @@ class colvar::CVBasedPath virtual void computeDistanceBetweenReferenceFrames(std::vector& result) const; cvm::real getPolynomialFactorOfCVGradient(size_t i_cv) const; public: - CVBasedPath(std::string const &conf); + CVBasedPath(); virtual ~CVBasedPath(); + virtual int init(std::string const &conf); virtual void calc_value() = 0; virtual void apply_force(colvarvalue const &force) = 0; }; @@ -1695,8 +1629,9 @@ class colvar::gspathCV virtual void updateDistanceToReferenceFrames(); virtual void prepareVectors(); public: - gspathCV(std::string const &conf); + gspathCV(); virtual ~gspathCV(); + virtual int init(std::string const &conf); virtual void calc_value(); virtual void calc_gradients(); virtual void apply_force(colvarvalue const &force); @@ -1711,8 +1646,9 @@ class colvar::gzpathCV virtual void updateDistanceToReferenceFrames(); virtual void prepareVectors(); public: - gzpathCV(std::string const &conf); + gzpathCV(); virtual ~gzpathCV(); + virtual int init(std::string const &conf); virtual void calc_value(); virtual void calc_gradients(); virtual void apply_force(colvarvalue const &force); @@ -1727,8 +1663,9 @@ class colvar::aspath std::unique_ptr impl_; friend struct ArithmeticPathImpl; public: - aspath(std::string const &conf); + aspath(); virtual ~aspath(); + virtual int init(std::string const &conf); virtual void calc_value(); virtual void calc_gradients(); virtual void apply_force(colvarvalue const &force); @@ -1741,8 +1678,9 @@ class colvar::azpath std::unique_ptr impl_; friend struct ArithmeticPathImpl; public: - azpath(std::string const &conf); + azpath(); virtual ~azpath(); + virtual int init(std::string const &conf); virtual void calc_value(); virtual void calc_gradients(); virtual void apply_force(colvarvalue const &force); @@ -1755,8 +1693,9 @@ class colvar::aspathCV std::unique_ptr impl_; friend struct ArithmeticPathImpl; public: - aspathCV(std::string const &conf); + aspathCV(); virtual ~aspathCV(); + virtual int init(std::string const &conf); virtual void calc_value(); virtual void calc_gradients(); virtual void apply_force(colvarvalue const &force); @@ -1770,8 +1709,9 @@ class colvar::azpathCV std::unique_ptr impl_; friend struct ArithmeticPathImpl; public: - azpathCV(std::string const &conf); + azpathCV(); virtual ~azpathCV(); + virtual int init(std::string const &conf); virtual void calc_value(); virtual void calc_gradients(); virtual void apply_force(colvarvalue const &force); @@ -1792,8 +1732,9 @@ class colvar::neuralNetwork /// the index of nn output components size_t m_output_index; public: - neuralNetwork(std::string const &conf); + neuralNetwork(); virtual ~neuralNetwork(); + virtual int init(std::string const &conf); virtual void calc_value(); virtual void calc_gradients(); virtual void apply_force(colvarvalue const &force); @@ -1808,7 +1749,6 @@ class colvar::map_total public: map_total(); - map_total(std::string const &conf); virtual ~map_total() {} virtual int init(std::string const &conf); virtual void calc_value(); @@ -1821,13 +1761,13 @@ class colvar::map_total std::string volmap_name; /// Numeric identifier of the map object (as used by the simulation engine) - int volmap_id; + int volmap_id = -1; /// Index of the map objet in the proxy arrays - int volmap_index; + int volmap_index = -1; /// Group of atoms selected internally (optional) - cvm::atom_group *atoms; + cvm::atom_group *atoms = nullptr; /// Weights assigned to each atom (default: uniform weights) std::vector atom_weights; diff --git a/src/colvarcomp_alchlambda.cpp b/src/colvarcomp_alchlambda.cpp index 9f18bec77..adeaf734b 100644 --- a/src/colvarcomp_alchlambda.cpp +++ b/src/colvarcomp_alchlambda.cpp @@ -17,8 +17,7 @@ #include "colvarcomp.h" -colvar::alch_lambda::alch_lambda(std::string const &conf) - : cvc(conf) +colvar::alch_lambda::alch_lambda() { set_function_type("alchLambda"); @@ -60,8 +59,7 @@ simple_scalar_dist_functions(alch_lambda) -colvar::alch_Flambda::alch_Flambda(std::string const &conf) - : cvc(conf) +colvar::alch_Flambda::alch_Flambda() { set_function_type("alch_Flambda"); diff --git a/src/colvarcomp_angles.cpp b/src/colvarcomp_angles.cpp index 6e02f2c9c..f8f6b42a0 100644 --- a/src/colvarcomp_angles.cpp +++ b/src/colvarcomp_angles.cpp @@ -12,8 +12,7 @@ #include "colvarcomp.h" -colvar::angle::angle(std::string const &conf) - : cvc(conf) +colvar::angle::angle() { set_function_type("angle"); init_as_angle(); @@ -21,26 +20,25 @@ colvar::angle::angle(std::string const &conf) provide(f_cvc_inv_gradient); provide(f_cvc_Jacobian); enable(f_cvc_com_based); +} + + +int colvar::angle::init(std::string const &conf) +{ + int error_code = cvc::init(conf); group1 = parse_group(conf, "group1"); group2 = parse_group(conf, "group2"); group3 = parse_group(conf, "group3"); - init_total_force_params(conf); + error_code |= init_total_force_params(conf); + + return error_code; } -colvar::angle::angle(cvm::atom const &a1, - cvm::atom const &a2, - cvm::atom const &a3) +colvar::angle::angle(cvm::atom const &a1, cvm::atom const &a2, cvm::atom const &a3) : angle() { - set_function_type("angle"); - init_as_angle(); - - provide(f_cvc_inv_gradient); - provide(f_cvc_Jacobian); - enable(f_cvc_com_based); - group1 = new cvm::atom_group(std::vector(1, a1)); group2 = new cvm::atom_group(std::vector(1, a2)); group3 = new cvm::atom_group(std::vector(1, a3)); @@ -137,40 +135,23 @@ simple_scalar_dist_functions(angle) -colvar::dipole_angle::dipole_angle(std::string const &conf) - : cvc(conf) +colvar::dipole_angle::dipole_angle() { set_function_type("dipoleAngle"); init_as_angle(); - - group1 = parse_group(conf, "group1"); - group2 = parse_group(conf, "group2"); - group3 = parse_group(conf, "group3"); - - init_total_force_params(conf); } -colvar::dipole_angle::dipole_angle(cvm::atom const &a1, - cvm::atom const &a2, - cvm::atom const &a3) +int colvar::dipole_angle::init(std::string const &conf) { - set_function_type("dipoleAngle"); - init_as_angle(); - - group1 = new cvm::atom_group(std::vector(1, a1)); - group2 = new cvm::atom_group(std::vector(1, a2)); - group3 = new cvm::atom_group(std::vector(1, a3)); - register_atom_group(group1); - register_atom_group(group2); - register_atom_group(group3); -} + int error_code = cvc::init(conf); + group1 = parse_group(conf, "group1"); + group2 = parse_group(conf, "group2"); + group3 = parse_group(conf, "group3"); -colvar::dipole_angle::dipole_angle() -{ - set_function_type("dipoleAngle"); - init_as_angle(); + error_code |= init_total_force_params(conf); + return error_code; } @@ -246,35 +227,34 @@ simple_scalar_dist_functions(dipole_angle) -colvar::dihedral::dihedral(std::string const &conf) - : cvc(conf) +colvar::dihedral::dihedral() { set_function_type("dihedral"); init_as_periodic_angle(); provide(f_cvc_inv_gradient); provide(f_cvc_Jacobian); enable(f_cvc_com_based); +} + + +int colvar::dihedral::init(std::string const &conf) +{ + int error_code = cvc::init(conf); group1 = parse_group(conf, "group1"); group2 = parse_group(conf, "group2"); group3 = parse_group(conf, "group3"); group4 = parse_group(conf, "group4"); - init_total_force_params(conf); + error_code |= init_total_force_params(conf); + return error_code; } -colvar::dihedral::dihedral(cvm::atom const &a1, - cvm::atom const &a2, - cvm::atom const &a3, +colvar::dihedral::dihedral(cvm::atom const &a1, cvm::atom const &a2, cvm::atom const &a3, cvm::atom const &a4) + : dihedral() { - set_function_type("dihedral"); - init_as_periodic_angle(); - provide(f_cvc_inv_gradient); - provide(f_cvc_Jacobian); - enable(f_cvc_com_based); - b_1site_force = false; group1 = new cvm::atom_group(std::vector(1, a1)); @@ -288,16 +268,6 @@ colvar::dihedral::dihedral(cvm::atom const &a1, } -colvar::dihedral::dihedral() -{ - set_function_type("dihedral"); - init_as_periodic_angle(); - enable(f_cvc_periodic); - provide(f_cvc_inv_gradient); - provide(f_cvc_Jacobian); -} - - void colvar::dihedral::calc_value() { cvm::atom_pos const g1_pos = group1->center_of_mass(); @@ -498,22 +468,21 @@ void colvar::dihedral::wrap(colvarvalue &x_unwrapped) const } -colvar::polar_theta::polar_theta(std::string const &conf) - : cvc(conf) +colvar::polar_theta::polar_theta() { + r = theta = phi = 0.0; set_function_type("polarTheta"); enable(f_cvc_com_based); - - atoms = parse_group(conf, "atoms"); - init_total_force_params(conf); - x.type(colvarvalue::type_scalar); + init_as_angle(); } -colvar::polar_theta::polar_theta() +int colvar::polar_theta::init(std::string const &conf) { - set_function_type("polarTheta"); - x.type(colvarvalue::type_scalar); + int error_code = cvc::init(conf); + atoms = parse_group(conf, "atoms"); + error_code |= init_total_force_params(conf); + return error_code; } @@ -550,22 +519,22 @@ void colvar::polar_theta::apply_force(colvarvalue const &force) simple_scalar_dist_functions(polar_theta) -colvar::polar_phi::polar_phi(std::string const &conf) - : cvc(conf) + +colvar::polar_phi::polar_phi() { + r = theta = phi = 0.0; set_function_type("polarPhi"); - init_as_periodic_angle(); enable(f_cvc_com_based); - - atoms = parse_group(conf, "atoms"); - init_total_force_params(conf); + init_as_periodic_angle(); } -colvar::polar_phi::polar_phi() +int colvar::polar_phi::init(std::string const &conf) { - set_function_type("polarPhi"); - init_as_periodic_angle(); + int error_code = cvc::init(conf); + atoms = parse_group(conf, "atoms"); + error_code |= init_total_force_params(conf); + return error_code; } diff --git a/src/colvarcomp_apath.cpp b/src/colvarcomp_apath.cpp index 38c570add..d82c40138 100644 --- a/src/colvarcomp_apath.cpp +++ b/src/colvarcomp_apath.cpp @@ -136,10 +136,17 @@ struct ArithmeticPathImpl: public ArithmeticPathCV::ArithmeticPathBasesize(); @@ -147,6 +154,7 @@ colvar::aspath::aspath(std::string const &conf): CartesianBasedPath(conf) { // ArithmeticPathCV::ArithmeticPathBase::initialize(num_atoms, total_reference_frames, p_lambda, reference_frames[0], p_weights); impl_ = std::unique_ptr(new ArithmeticPathImpl(num_atoms, total_reference_frames, p_lambda, p_weights)); cvm::log(std::string("Lambda is ") + cvm::to_str(impl_->get_lambda()) + std::string("\n")); + return error_code; } colvar::aspath::~aspath() {} @@ -182,8 +190,15 @@ void colvar::aspath::apply_force(colvarvalue const &force) { } } -colvar::azpath::azpath(std::string const &conf): CartesianBasedPath(conf) { +colvar::azpath::azpath() +{ function_type = "azpath"; + x.type(colvarvalue::type_scalar); +} + +int colvar::azpath::init(std::string const &conf) +{ + int error_code = CartesianBasedPath::init(conf); cvm::log(std::string("Total number of frames: ") + cvm::to_str(total_reference_frames) + std::string("\n")); x.type(colvarvalue::type_scalar); cvm::real p_lambda; @@ -192,6 +207,7 @@ colvar::azpath::azpath(std::string const &conf): CartesianBasedPath(conf) { std::vector p_weights(num_atoms, std::sqrt(1.0 / num_atoms)); impl_ = std::unique_ptr(new ArithmeticPathImpl(num_atoms, total_reference_frames, p_lambda, p_weights)); cvm::log(std::string("Lambda is ") + cvm::to_str(impl_->get_lambda()) + std::string("\n")); + return error_code; } colvar::azpath::~azpath() {} @@ -227,12 +243,18 @@ void colvar::azpath::apply_force(colvarvalue const &force) { } } -colvar::aspathCV::aspathCV(std::string const &conf): CVBasedPath(conf) { +colvar::aspathCV::aspathCV() +{ set_function_type("aspathCV"); + x.type(colvarvalue::type_scalar); +} + +int colvar::aspathCV::init(std::string const &conf) +{ + int error_code = CVBasedPath::init(conf); cvm::log(std::string("Total number of frames: ") + cvm::to_str(total_reference_frames) + std::string("\n")); std::vector p_weights(cv.size(), 1.0); get_keyval(conf, "weights", p_weights, std::vector(cv.size(), 1.0)); - x.type(colvarvalue::type_scalar); use_explicit_gradients = true; cvm::real p_lambda; get_keyval(conf, "lambda", p_lambda, -1.0); @@ -244,6 +266,7 @@ colvar::aspathCV::aspathCV(std::string const &conf): CVBasedPath(conf) { } cvm::log(std::string("The weight of CV ") + cvm::to_str(i_cv) + std::string(" is ") + cvm::to_str(p_weights[i_cv]) + std::string("\n")); } + return error_code; } colvar::aspathCV::~aspathCV() {} @@ -323,12 +346,18 @@ void colvar::aspathCV::apply_force(colvarvalue const &force) { } } -colvar::azpathCV::azpathCV(std::string const &conf): CVBasedPath(conf) { +colvar::azpathCV::azpathCV() +{ set_function_type("azpathCV"); + x.type(colvarvalue::type_scalar); +} + +int colvar::azpathCV::init(std::string const &conf) +{ + int error_code = CVBasedPath::init(conf); cvm::log(std::string("Total number of frames: ") + cvm::to_str(total_reference_frames) + std::string("\n")); std::vector p_weights(cv.size(), 1.0); get_keyval(conf, "weights", p_weights, std::vector(cv.size(), 1.0)); - x.type(colvarvalue::type_scalar); use_explicit_gradients = true; cvm::real p_lambda; get_keyval(conf, "lambda", p_lambda, -1.0); @@ -340,6 +369,7 @@ colvar::azpathCV::azpathCV(std::string const &conf): CVBasedPath(conf) { } cvm::log(std::string("The weight of CV ") + cvm::to_str(i_cv) + std::string(" is ") + cvm::to_str(p_weights[i_cv]) + std::string("\n")); } + return error_code; } void colvar::azpathCV::calc_value() { diff --git a/src/colvarcomp_combination.cpp b/src/colvarcomp_combination.cpp index 974cc870c..c7bb3e305 100644 --- a/src/colvarcomp_combination.cpp +++ b/src/colvarcomp_combination.cpp @@ -9,14 +9,25 @@ #include "colvarcomp.h" -colvar::linearCombination::linearCombination(std::string const &conf): cvc(conf) { + +colvar::linearCombination::linearCombination() +{ + set_function_type("linearCombination"); +} + + +int colvar::linearCombination::init(std::string const &conf) +{ + int error_code = cvc::init(conf); + // Lookup all available sub-cvcs for (auto it_cv_map = colvar::get_global_cvc_map().begin(); it_cv_map != colvar::get_global_cvc_map().end(); ++it_cv_map) { if (key_lookup(conf, it_cv_map->first.c_str())) { std::vector sub_cvc_confs; get_key_string_multi_value(conf, it_cv_map->first.c_str(), sub_cvc_confs); for (auto it_sub_cvc_conf = sub_cvc_confs.begin(); it_sub_cvc_conf != sub_cvc_confs.end(); ++it_sub_cvc_conf) { - cv.push_back((it_cv_map->second)(*(it_sub_cvc_conf))); + cv.push_back((it_cv_map->second)()); + cv.back()->init(*(it_sub_cvc_conf)); } } } @@ -29,9 +40,9 @@ colvar::linearCombination::linearCombination(std::string const &conf): cvc(conf) } // Show useful error messages and prevent crashes if no sub CVC is found if (cv.size() == 0) { - cvm::error("Error: the CV " + name + - " expects one or more nesting components.\n"); - return; + error_code |= + cvm::error("Error: the CV " + name + " expects one or more nesting components.\n", + COLVARS_INPUT_ERROR); } else { x.type(cv[0]->value()); x.reset(); @@ -45,6 +56,7 @@ colvar::linearCombination::linearCombination(std::string const &conf): cvc(conf) if (!use_explicit_gradients) { disable(f_cvc_explicit_gradient); } + return error_code; } cvm::real colvar::linearCombination::getPolynomialFactorOfCVGradient(size_t i_cv) const { @@ -124,8 +136,16 @@ void colvar::linearCombination::apply_force(colvarvalue const &force) { } } -colvar::customColvar::customColvar(std::string const &conf): linearCombination(conf) { - use_custom_function = false; + +colvar::customColvar::customColvar() +{ +} + + +int colvar::customColvar::init(std::string const &conf) +{ + int error_code = linearCombination::init(conf); + // code swipe from colvar::init_custom_function std::string expr_in, expr; size_t pos = 0; // current position in config string @@ -197,14 +217,17 @@ colvar::customColvar::customColvar(std::string const &conf): linearCombination(c x.type(colvarvalue::type_scalar); } #else - cvm::error("customFunction requires the Lepton library, but it is not enabled during compilation.\n" - "Please refer to the Compilation Notes section of the Colvars manual for more information.\n", - COLVARS_INPUT_ERROR); + return cvm::error( + "customFunction requires the Lepton library, but it is not enabled during compilation.\n" + "Please refer to the Compilation Notes section of the Colvars manual for more " + "information.\n", + COLVARS_NOT_IMPLEMENTED); #endif } else { cvm::log("Warning: no customFunction specified.\n"); cvm::log("Warning: use linear combination instead.\n"); } + return error_code; } colvar::customColvar::~customColvar() { diff --git a/src/colvarcomp_coordnums.cpp b/src/colvarcomp_coordnums.cpp index 3d618ff80..afd05c4b8 100644 --- a/src/colvarcomp_coordnums.cpp +++ b/src/colvarcomp_coordnums.cpp @@ -90,48 +90,48 @@ cvm::real colvar::coordnum::switching_function(cvm::real const &r0, } -colvar::coordnum::coordnum(std::string const &conf) - : cvc(conf), b_anisotropic(false), pairlist(NULL) - +colvar::coordnum::coordnum() { set_function_type("coordNum"); x.type(colvarvalue::type_scalar); - colvarproxy *proxy = cvm::main()->proxy; + r0 = proxy->angstrom_to_internal(4.0); + r0_vec = cvm::rvector(proxy->angstrom_to_internal(4.0), + proxy->angstrom_to_internal(4.0), + proxy->angstrom_to_internal(4.0)); +} + + +int colvar::coordnum::init(std::string const &conf) + +{ + int error_code = cvc::init(conf); group1 = parse_group(conf, "group1"); group2 = parse_group(conf, "group2"); - if (group1 == NULL || group2 == NULL) { - cvm::error("Error: failed to initialize atom groups.\n", - COLVARS_INPUT_ERROR); - return; + if (!group1 || !group2) { + return cvm::error("Error: failed to initialize atom groups.\n", COLVARS_INPUT_ERROR); } if (int atom_number = cvm::atom_group::overlap(*group1, *group2)) { - cvm::error("Error: group1 and group2 share a common atom (number: " + - cvm::to_str(atom_number) + ")\n", COLVARS_INPUT_ERROR); - return; + error_code |= cvm::error( + "Error: group1 and group2 share a common atom (number: " + cvm::to_str(atom_number) + ")\n", + COLVARS_INPUT_ERROR); } if (group1->b_dummy) { - cvm::error("Error: only group2 is allowed to be a dummy atom\n", - COLVARS_INPUT_ERROR); - return; + error_code |= + cvm::error("Error: only group2 is allowed to be a dummy atom\n", COLVARS_INPUT_ERROR); } - bool const b_isotropic = get_keyval(conf, "cutoff", r0, - cvm::real(proxy->angstrom_to_internal(4.0))); + bool const b_isotropic = get_keyval(conf, "cutoff", r0, r0); - if (get_keyval(conf, "cutoff3", r0_vec, - cvm::rvector(proxy->angstrom_to_internal(4.0), - proxy->angstrom_to_internal(4.0), - proxy->angstrom_to_internal(4.0)))) { + if (get_keyval(conf, "cutoff3", r0_vec, r0_vec)) { if (b_isotropic) { - cvm::error("Error: cannot specify \"cutoff\" and \"cutoff3\" " - "at the same time.\n", - COLVARS_INPUT_ERROR); - return; + error_code |= cvm::error("Error: cannot specify \"cutoff\" and \"cutoff3\" " + "at the same time.\n", + COLVARS_INPUT_ERROR); } b_anisotropic = true; @@ -141,17 +141,17 @@ colvar::coordnum::coordnum(std::string const &conf) if (r0_vec.z < 0.0) r0_vec.z *= -1.0; } - get_keyval(conf, "expNumer", en, 6); - get_keyval(conf, "expDenom", ed, 12); + get_keyval(conf, "expNumer", en, en); + get_keyval(conf, "expDenom", ed, ed); if ( (en%2) || (ed%2) ) { - cvm::error("Error: odd exponent(s) provided, can only use even ones.\n", - COLVARS_INPUT_ERROR); + error_code |= cvm::error("Error: odd exponent(s) provided, can only use even ones.\n", + COLVARS_INPUT_ERROR); } if ( (en <= 0) || (ed <= 0) ) { - cvm::error("Error: negative exponent(s) provided.\n", - COLVARS_INPUT_ERROR); + error_code |= cvm::error("Error: negative exponent(s) provided.\n", + COLVARS_INPUT_ERROR); } if (!is_enabled(f_cvc_pbc_minimum_image)) { @@ -160,14 +160,14 @@ colvar::coordnum::coordnum(std::string const &conf) get_keyval(conf, "group2CenterOnly", b_group2_center_only, group2->b_dummy); - get_keyval(conf, "tolerance", tolerance, 0.0); + get_keyval(conf, "tolerance", tolerance, tolerance); if (tolerance > 0) { cvm::main()->cite_feature("coordNum pairlist"); - get_keyval(conf, "pairListFrequency", pairlist_freq, 100); + get_keyval(conf, "pairListFrequency", pairlist_freq, pairlist_freq); if ( ! (pairlist_freq > 0) ) { - cvm::error("Error: non-positive pairlistfrequency provided.\n", - COLVARS_INPUT_ERROR); - return; // and do not allocate the pairlists below + return cvm::error("Error: non-positive pairlistfrequency provided.\n", + COLVARS_INPUT_ERROR); + // return and do not allocate the pairlists below } if (b_group2_center_only) { pairlist = new bool[group1->size()]; @@ -181,12 +181,14 @@ colvar::coordnum::coordnum(std::string const &conf) static_cast(group1->size()) : static_cast(group1->size() * group2->size())); + + return error_code; } colvar::coordnum::~coordnum() { - if (pairlist != NULL) { + if (pairlist) { delete [] pairlist; } } @@ -301,9 +303,20 @@ simple_scalar_dist_functions(coordnum) // h_bond member functions -colvar::h_bond::h_bond(std::string const &conf) -: cvc(conf) +colvar::h_bond::h_bond() { + colvarproxy *proxy = cvm::main()->proxy; + r0 = proxy->angstrom_to_internal(3.3); + set_function_type("hBond"); + x.type(colvarvalue::type_scalar); + init_scalar_boundaries(0.0, 1.0); +} + + +int colvar::h_bond::init(std::string const &conf) +{ + int error_code = cvc::init(conf); + if (cvm::debug()) cvm::log("Initializing h_bond object.\n"); @@ -311,15 +324,12 @@ colvar::h_bond::h_bond(std::string const &conf) x.type(colvarvalue::type_scalar); init_scalar_boundaries(0.0, 1.0); - colvarproxy *proxy = cvm::main()->proxy; - int a_num = -1, d_num = -1; get_keyval(conf, "acceptor", a_num, a_num); get_keyval(conf, "donor", d_num, a_num); if ( (a_num == -1) || (d_num == -1) ) { - cvm::error("Error: either acceptor or donor undefined.\n"); - return; + error_code |= cvm::error("Error: either acceptor or donor undefined.\n", COLVARS_INPUT_ERROR); } cvm::atom acceptor = cvm::atom(a_num); @@ -328,34 +338,34 @@ colvar::h_bond::h_bond(std::string const &conf) atom_groups[0]->add_atom(acceptor); atom_groups[0]->add_atom(donor); - get_keyval(conf, "cutoff", r0, proxy->angstrom_to_internal(3.3)); - get_keyval(conf, "expNumer", en, 6); - get_keyval(conf, "expDenom", ed, 8); + get_keyval(conf, "cutoff", r0, r0); + get_keyval(conf, "expNumer", en, en); + get_keyval(conf, "expDenom", ed, ed); - if ( (en%2) || (ed%2) ) { - cvm::error("Error: odd exponent(s) provided, can only use even ones.\n", - COLVARS_INPUT_ERROR); + if ((en % 2) || (ed % 2)) { + error_code |= cvm::error("Error: odd exponent(s) provided, can only use even ones.\n", + COLVARS_INPUT_ERROR); } - if ( (en <= 0) || (ed <= 0) ) { - cvm::error("Error: negative exponent(s) provided.\n", - COLVARS_INPUT_ERROR); + if ((en <= 0) || (ed <= 0)) { + error_code |= cvm::error("Error: negative exponent(s) provided.\n", COLVARS_INPUT_ERROR); } if (cvm::debug()) cvm::log("Done initializing h_bond object.\n"); + + return error_code; } colvar::h_bond::h_bond(cvm::atom const &acceptor, cvm::atom const &donor, cvm::real r0_i, int en_i, int ed_i) - : r0(r0_i), en(en_i), ed(ed_i) + : h_bond() { - set_function_type("hBond"); - x.type(colvarvalue::type_scalar); - init_scalar_boundaries(0.0, 1.0); - + r0 = r0_i; + en = en_i; + ed = ed_i; register_atom_group(new cvm::atom_group); atom_groups[0]->add_atom(acceptor); atom_groups[0]->add_atom(donor); @@ -395,54 +405,58 @@ simple_scalar_dist_functions(h_bond) -colvar::selfcoordnum::selfcoordnum(std::string const &conf) - : cvc(conf), pairlist(NULL) +colvar::selfcoordnum::selfcoordnum() { set_function_type("selfCoordNum"); x.type(colvarvalue::type_scalar); + r0 = cvm::main()->proxy->angstrom_to_internal(4.0); +} - colvarproxy *proxy = cvm::main()->proxy; + +int colvar::selfcoordnum::init(std::string const &conf) +{ + int error_code = cvc::init(conf); group1 = parse_group(conf, "group1"); - get_keyval(conf, "cutoff", r0, cvm::real(proxy->angstrom_to_internal(4.0))); - get_keyval(conf, "expNumer", en, 6); - get_keyval(conf, "expDenom", ed, 12); + get_keyval(conf, "cutoff", r0, r0); + get_keyval(conf, "expNumer", en, en); + get_keyval(conf, "expDenom", ed, ed); - if ( (en%2) || (ed%2) ) { - cvm::error("Error: odd exponent(s) provided, can only use even ones.\n", - COLVARS_INPUT_ERROR); + if ((en % 2) || (ed % 2)) { + error_code |= cvm::error("Error: odd exponent(s) provided, can only use even ones.\n", + COLVARS_INPUT_ERROR); } - if ( (en <= 0) || (ed <= 0) ) { - cvm::error("Error: negative exponent(s) provided.\n", - COLVARS_INPUT_ERROR); + if ((en <= 0) || (ed <= 0)) { + error_code |= cvm::error("Error: negative exponent(s) provided.\n", COLVARS_INPUT_ERROR); } if (!is_enabled(f_cvc_pbc_minimum_image)) { cvm::log("Warning: only minimum-image distances are used by this variable.\n"); } - get_keyval(conf, "tolerance", tolerance, 0.0); + get_keyval(conf, "tolerance", tolerance, tolerance); if (tolerance > 0) { - get_keyval(conf, "pairListFrequency", pairlist_freq, 100); + get_keyval(conf, "pairListFrequency", pairlist_freq, pairlist_freq); if ( ! (pairlist_freq > 0) ) { - cvm::error("Error: non-positive pairlistfrequency provided.\n", - COLVARS_INPUT_ERROR); - return; + error_code |= cvm::error("Error: non-positive pairlistfrequency provided.\n", + COLVARS_INPUT_ERROR); } pairlist = new bool[(group1->size()-1) * (group1->size()-1)]; } init_scalar_boundaries(0.0, static_cast((group1->size()-1) * (group1->size()-1))); + + return error_code; } colvar::selfcoordnum::~selfcoordnum() { - if (pairlist != NULL) { + if (pairlist) { delete [] pairlist; } } @@ -538,33 +552,35 @@ void colvar::selfcoordnum::apply_force(colvarvalue const &force) simple_scalar_dist_functions(selfcoordnum) - -// groupcoordnum member functions -colvar::groupcoordnum::groupcoordnum(std::string const &conf) - : distance(conf), b_anisotropic(false) +colvar::groupcoordnum::groupcoordnum() { set_function_type("groupCoord"); x.type(colvarvalue::type_scalar); init_scalar_boundaries(0.0, 1.0); - colvarproxy *proxy = cvm::main()->proxy; + r0 = proxy->angstrom_to_internal(4.0); + r0_vec = cvm::rvector(proxy->angstrom_to_internal(4.0), + proxy->angstrom_to_internal(4.0), + proxy->angstrom_to_internal(4.0)); +} + + +int colvar::groupcoordnum::init(std::string const &conf) +{ + int error_code = distance::init(conf); // group1 and group2 are already initialized by distance() if (group1->b_dummy || group2->b_dummy) { - cvm::error("Error: neither group can be a dummy atom\n"); - return; + return cvm::error("Error: neither group can be a dummy atom\n", COLVARS_INPUT_ERROR); } - bool const b_scale = get_keyval(conf, "cutoff", r0, - cvm::real(proxy->angstrom_to_internal(4.0))); - - if (get_keyval(conf, "cutoff3", r0_vec, - cvm::rvector(4.0, 4.0, 4.0), parse_silent)) { + bool const b_scale = get_keyval(conf, "cutoff", r0, r0); + if (get_keyval(conf, "cutoff3", r0_vec, r0_vec)) { if (b_scale) { - cvm::error("Error: cannot specify \"scale\" and " - "\"scale3\" at the same time.\n"); - return; + error_code |= + cvm::error("Error: cannot specify \"cutoff\" and \"cutoff3\" at the same time.\n", + COLVARS_INPUT_ERROR); } b_anisotropic = true; // remove meaningless negative signs @@ -573,23 +589,23 @@ colvar::groupcoordnum::groupcoordnum(std::string const &conf) if (r0_vec.z < 0.0) r0_vec.z *= -1.0; } - get_keyval(conf, "expNumer", en, 6); - get_keyval(conf, "expDenom", ed, 12); + get_keyval(conf, "expNumer", en, en); + get_keyval(conf, "expDenom", ed, ed); - if ( (en%2) || (ed%2) ) { - cvm::error("Error: odd exponent(s) provided, can only use even ones.\n", - COLVARS_INPUT_ERROR); + if ((en % 2) || (ed % 2)) { + error_code |= cvm::error("Error: odd exponent(s) provided, can only use even ones.\n", + COLVARS_INPUT_ERROR); } - if ( (en <= 0) || (ed <= 0) ) { - cvm::error("Error: negative exponent(s) provided.\n", - COLVARS_INPUT_ERROR); + if ((en <= 0) || (ed <= 0)) { + error_code |= cvm::error("Error: negative exponent(s) provided.\n", COLVARS_INPUT_ERROR); } if (!is_enabled(f_cvc_pbc_minimum_image)) { cvm::log("Warning: only minimum-image distances are used by this variable.\n"); } + return error_code; } diff --git a/src/colvarcomp_distances.cpp b/src/colvarcomp_distances.cpp index 451bd0d3b..1aac68f9b 100644 --- a/src/colvarcomp_distances.cpp +++ b/src/colvarcomp_distances.cpp @@ -17,8 +17,7 @@ #include "colvar_rotation_derivative.h" -colvar::distance::distance(std::string const &conf) - : cvc(conf) +colvar::distance::distance() { set_function_type("distance"); init_as_distance(); @@ -26,23 +25,19 @@ colvar::distance::distance(std::string const &conf) provide(f_cvc_inv_gradient); provide(f_cvc_Jacobian); enable(f_cvc_com_based); - - group1 = parse_group(conf, "group1"); - group2 = parse_group(conf, "group2"); - - init_total_force_params(conf); } -colvar::distance::distance() - : cvc() +int colvar::distance::init(std::string const &conf) { - set_function_type("distance"); - init_as_distance(); + int error_code = cvc::init(conf); - provide(f_cvc_inv_gradient); - provide(f_cvc_Jacobian); - enable(f_cvc_com_based); + group1 = parse_group(conf, "group1"); + group2 = parse_group(conf, "group2"); + + error_code |= init_total_force_params(conf); + + return error_code; } @@ -98,21 +93,9 @@ simple_scalar_dist_functions(distance) -colvar::distance_vec::distance_vec(std::string const &conf) - : distance(conf) -{ - set_function_type("distanceVec"); - enable(f_cvc_com_based); - disable(f_cvc_explicit_gradient); - x.type(colvarvalue::type_3vector); -} - - colvar::distance_vec::distance_vec() - : distance() { set_function_type("distanceVec"); - enable(f_cvc_com_based); disable(f_cvc_explicit_gradient); x.type(colvarvalue::type_3vector); } @@ -168,14 +151,19 @@ colvarvalue colvar::distance_vec::dist2_rgrad(colvarvalue const &x1, -colvar::distance_z::distance_z(std::string const &conf) - : cvc(conf) +colvar::distance_z::distance_z() { set_function_type("distanceZ"); provide(f_cvc_inv_gradient); provide(f_cvc_Jacobian); enable(f_cvc_com_based); x.type(colvarvalue::type_scalar); +} + + +int colvar::distance_z::init(std::string const &conf) +{ + int error_code = cvc::init(conf); // TODO detect PBC from MD engine (in simple cases) // and then update period in real time @@ -184,9 +172,9 @@ colvar::distance_z::distance_z(std::string const &conf) } if ((wrap_center != 0.0) && !is_enabled(f_cvc_periodic)) { - cvm::error("Error: wrapAround was defined in a distanceZ component," - " but its period has not been set.\n"); - return; + error_code |= cvm::error("Error: wrapAround was defined in a distanceZ component," + " but its period has not been set.\n", + COLVARS_INPUT_ERROR); } main = parse_group(conf, "main"); @@ -202,8 +190,7 @@ colvar::distance_z::distance_z(std::string const &conf) } else { if (get_keyval(conf, "axis", axis, cvm::rvector(0.0, 0.0, 1.0))) { if (axis.norm2() == 0.0) { - cvm::error("Axis vector is zero!"); - return; + error_code |= cvm::error("Axis vector is zero!", COLVARS_INPUT_ERROR); } if (axis.norm2() != 1.0) { axis = axis.unit(); @@ -213,18 +200,9 @@ colvar::distance_z::distance_z(std::string const &conf) fixed_axis = true; } - init_total_force_params(conf); + error_code |= init_total_force_params(conf); -} - - -colvar::distance_z::distance_z() -{ - set_function_type("distanceZ"); - provide(f_cvc_inv_gradient); - provide(f_cvc_Jacobian); - enable(f_cvc_com_based); - x.type(colvarvalue::type_scalar); + return error_code; } @@ -366,27 +344,10 @@ void colvar::distance_z::wrap(colvarvalue &x_unwrapped) const -colvar::distance_xy::distance_xy(std::string const &conf) - : distance_z(conf) -{ - set_function_type("distanceXY"); - init_as_distance(); - - provide(f_cvc_inv_gradient); - provide(f_cvc_Jacobian); - enable(f_cvc_com_based); -} - - colvar::distance_xy::distance_xy() - : distance_z() { set_function_type("distanceXY"); init_as_distance(); - - provide(f_cvc_inv_gradient); - provide(f_cvc_Jacobian); - enable(f_cvc_com_based); } @@ -479,18 +440,7 @@ simple_scalar_dist_functions(distance_xy) -colvar::distance_dir::distance_dir(std::string const &conf) - : distance(conf) -{ - set_function_type("distanceDir"); - enable(f_cvc_com_based); - disable(f_cvc_explicit_gradient); - x.type(colvarvalue::type_unit3vector); -} - - colvar::distance_dir::distance_dir() - : distance() { set_function_type("distanceDir"); enable(f_cvc_com_based); @@ -556,31 +506,35 @@ colvarvalue colvar::distance_dir::dist2_rgrad(colvarvalue const &x1, } - -colvar::distance_inv::distance_inv(std::string const &conf) - : cvc(conf) +colvar::distance_inv::distance_inv() { set_function_type("distanceInv"); init_as_distance(); +} + + +int colvar::distance_inv::init(std::string const &conf) +{ + int error_code = cvc::init(conf); group1 = parse_group(conf, "group1"); group2 = parse_group(conf, "group2"); - get_keyval(conf, "exponent", exponent, 6); - if (exponent%2) { - cvm::error("Error: odd exponent provided, can only use even ones.\n"); - return; + get_keyval(conf, "exponent", exponent, exponent); + if (exponent % 2) { + error_code |= + cvm::error("Error: odd exponent provided, can only use even ones.\n", COLVARS_INPUT_ERROR); } if (exponent <= 0) { - cvm::error("Error: negative or zero exponent provided.\n"); - return; + error_code |= cvm::error("Error: negative or zero exponent provided.\n", COLVARS_INPUT_ERROR); } for (cvm::atom_iter ai1 = group1->begin(); ai1 != group1->end(); ai1++) { for (cvm::atom_iter ai2 = group2->begin(); ai2 != group2->end(); ai2++) { if (ai1->id == ai2->id) { - cvm::error("Error: group1 and group2 have some atoms in common: this is not allowed for distanceInv.\n"); - return; + error_code |= cvm::error("Error: group1 and group2 have some atoms in common: this is not " + "allowed for distanceInv.\n", + COLVARS_INPUT_ERROR); } } } @@ -590,6 +544,8 @@ colvar::distance_inv::distance_inv(std::string const &conf) "for distanceInv, because its value and gradients are computed " "simultaneously.\n"); } + + return error_code; } @@ -656,25 +612,23 @@ simple_scalar_dist_functions(distance_inv) -colvar::distance_pairs::distance_pairs(std::string const &conf) - : cvc(conf) +colvar::distance_pairs::distance_pairs() { set_function_type("distancePairs"); - - group1 = parse_group(conf, "group1"); - group2 = parse_group(conf, "group2"); - - x.type(colvarvalue::type_vector); disable(f_cvc_explicit_gradient); - x.vector1d_value.resize(group1->size() * group2->size()); + x.type(colvarvalue::type_vector); } -colvar::distance_pairs::distance_pairs() +int colvar::distance_pairs::init(std::string const &conf) { - set_function_type("distancePairs"); - disable(f_cvc_explicit_gradient); - x.type(colvarvalue::type_vector); + int error_code = cvc::init(conf); + + group1 = parse_group(conf, "group1"); + group2 = parse_group(conf, "group2"); + x.vector1d_value.resize(group1->size() * group2->size()); + + return error_code; } @@ -741,29 +695,19 @@ void colvar::distance_pairs::apply_force(colvarvalue const &force) -colvar::dipole_magnitude::dipole_magnitude(std::string const &conf) - : cvc(conf) -{ - set_function_type("dipoleMagnitude"); - atoms = parse_group(conf, "atoms"); - init_total_force_params(conf); - x.type(colvarvalue::type_scalar); -} - - -colvar::dipole_magnitude::dipole_magnitude(cvm::atom const &a1) +colvar::dipole_magnitude::dipole_magnitude() { set_function_type("dipoleMagnitude"); - atoms = new cvm::atom_group(std::vector(1, a1)); - register_atom_group(atoms); x.type(colvarvalue::type_scalar); } -colvar::dipole_magnitude::dipole_magnitude() +int colvar::dipole_magnitude::init(std::string const &conf) { - set_function_type("dipoleMagnitude"); - x.type(colvarvalue::type_scalar); + int error_code = cvc::init(conf); + atoms = parse_group(conf, "atoms"); + if (!atoms) error_code |= COLVARS_INPUT_ERROR; + return error_code; } @@ -799,14 +743,19 @@ simple_scalar_dist_functions(dipole_magnitude) -colvar::gyration::gyration(std::string const &conf) - : cvc(conf) +colvar::gyration::gyration() { set_function_type("gyration"); - init_as_distance(); - provide(f_cvc_inv_gradient); provide(f_cvc_Jacobian); + init_as_distance(); +} + + +int colvar::gyration::init(std::string const &conf) +{ + int error_code = cvc::init(conf); + atoms = parse_group(conf, "atoms"); if (atoms->b_user_defined_fit) { @@ -816,6 +765,8 @@ colvar::gyration::gyration(std::string const &conf) atoms->ref_pos.assign(1, cvm::atom_pos(0.0, 0.0, 0.0)); atoms->fit_gradients.assign(atoms->size(), cvm::rvector(0.0, 0.0, 0.0)); } + + return error_code; } @@ -868,11 +819,9 @@ simple_scalar_dist_functions(gyration) -colvar::inertia::inertia(std::string const &conf) - : gyration(conf) +colvar::inertia::inertia() { set_function_type("inertia"); - init_as_distance(); } @@ -904,21 +853,25 @@ simple_scalar_dist_functions(inertia_z) -colvar::inertia_z::inertia_z(std::string const &conf) - : inertia(conf) +colvar::inertia_z::inertia_z() { set_function_type("inertiaZ"); - init_as_distance(); +} + + +int colvar::inertia_z::init(std::string const &conf) +{ + int error_code = inertia::init(conf); if (get_keyval(conf, "axis", axis, cvm::rvector(0.0, 0.0, 1.0))) { if (axis.norm2() == 0.0) { - cvm::error("Axis vector is zero!", COLVARS_INPUT_ERROR); - return; + error_code |= cvm::error("Axis vector is zero!", COLVARS_INPUT_ERROR); } if (axis.norm2() != 1.0) { axis = axis.unit(); cvm::log("The normalized axis is: "+cvm::to_str(axis)+".\n"); } } + return error_code; } @@ -951,21 +904,23 @@ simple_scalar_dist_functions(inertia) - -colvar::rmsd::rmsd(std::string const &conf) - : cvc(conf) +colvar::rmsd::rmsd() { set_function_type("rmsd"); init_as_distance(); - provide(f_cvc_inv_gradient); +} + + +int colvar::rmsd::init(std::string const &conf) +{ + int error_code = cvc::init(conf); atoms = parse_group(conf, "atoms"); - if (cvm::get_error()) return; if (!atoms || atoms->size() == 0) { - cvm::error("Error: \"atoms\" must contain at least 1 atom to compute RMSD."); - return; + return cvm::error("Error: \"atoms\" group is not defined or contains no atoms.", + COLVARS_INPUT_ERROR); } bool b_Jacobian_derivative = true; @@ -982,20 +937,20 @@ colvar::rmsd::rmsd(std::string const &conf) if (get_keyval(conf, "refPositions", ref_pos, ref_pos)) { cvm::log("Using reference positions from configuration file to calculate the variable.\n"); if (ref_pos.size() != atoms->size()) { - cvm::error("Error: the number of reference positions provided ("+ - cvm::to_str(ref_pos.size())+ - ") does not match the number of atoms of group \"atoms\" ("+ - cvm::to_str(atoms->size())+").\n"); - return; + error_code |= cvm::error("Error: the number of reference positions provided (" + + cvm::to_str(ref_pos.size()) + + ") does not match the number of atoms of group \"atoms\" (" + + cvm::to_str(atoms->size()) + ").\n", + COLVARS_INPUT_ERROR); } } else { // Only look for ref pos file if ref positions not already provided std::string ref_pos_file; if (get_keyval(conf, "refPositionsFile", ref_pos_file, std::string(""))) { if (ref_pos.size()) { - cvm::error("Error: cannot specify \"refPositionsFile\" and " - "\"refPositions\" at the same time.\n"); - return; + error_code |= cvm::error("Error: cannot specify \"refPositionsFile\" and " + "\"refPositions\" at the same time.\n", + COLVARS_INPUT_ERROR); } std::string ref_pos_col; @@ -1005,9 +960,9 @@ colvar::rmsd::rmsd(std::string const &conf) // if provided, use PDB column to select coordinates bool found = get_keyval(conf, "refPositionsColValue", ref_pos_col_value, 0.0); if (found && ref_pos_col_value==0.0) { - cvm::error("Error: refPositionsColValue, " - "if provided, must be non-zero.\n"); - return; + error_code |= cvm::error("Error: refPositionsColValue, " + "if provided, must be non-zero.\n", + COLVARS_INPUT_ERROR); } } @@ -1016,15 +971,17 @@ colvar::rmsd::rmsd(std::string const &conf) cvm::load_coords(ref_pos_file.c_str(), &ref_pos, atoms, ref_pos_col, ref_pos_col_value); } else { - cvm::error("Error: no reference positions for RMSD; use either refPositions of refPositionsFile."); - return; + error_code |= cvm::error( + "Error: no reference positions for RMSD; use either refPositions of refPositionsFile.", + COLVARS_INPUT_ERROR); } } if (ref_pos.size() != atoms->size()) { - cvm::error("Error: found " + cvm::to_str(ref_pos.size()) + - " reference positions for RMSD; expected " + cvm::to_str(atoms->size())); - return; + error_code |= + cvm::error("Error: found " + cvm::to_str(ref_pos.size()) + + " reference positions for RMSD; expected " + cvm::to_str(atoms->size()), + COLVARS_INPUT_ERROR); } if (atoms->b_user_defined_fit) { @@ -1046,6 +1003,15 @@ colvar::rmsd::rmsd(std::string const &conf) } atoms->setup_rotation_derivative(); + error_code |= init_permutation(conf); + + return error_code; +} + + +int colvar::rmsd::init_permutation(std::string const &conf) +{ + int error_code = COLVARS_OK; std::string perm_conf; size_t pos = 0; // current position in config string n_permutations = 1; @@ -1060,21 +1026,22 @@ colvar::rmsd::rmsd(std::string const &conf) std::vector const &ids = atoms->ids(); size_t const ia = std::find(ids.begin(), ids.end(), index-1) - ids.begin(); if (ia == atoms->size()) { - cvm::error("Error: atom id " + cvm::to_str(index) + - " is not a member of group \"atoms\"."); - return; + error_code |= cvm::error("Error: atom id " + cvm::to_str(index) + + " is not a member of group \"atoms\".", + COLVARS_INPUT_ERROR); } if (std::find(perm.begin(), perm.end(), ia) != perm.end()) { - cvm::error("Error: atom id " + cvm::to_str(index) + - " is mentioned more than once in atomPermutation list."); - return; + error_code |= cvm::error("Error: atom id " + cvm::to_str(index) + + " is mentioned more than once in atomPermutation list.", + COLVARS_INPUT_ERROR); } perm.push_back(ia); } if (perm.size() != atoms->size()) { - cvm::error("Error: symmetry permutation in input contains " + cvm::to_str(perm.size()) + - " indices, but group \"atoms\" contains " + cvm::to_str(atoms->size()) + " atoms."); - return; + error_code |= cvm::error( + "Error: symmetry permutation in input contains " + cvm::to_str(perm.size()) + + " indices, but group \"atoms\" contains " + cvm::to_str(atoms->size()) + " atoms.", + COLVARS_INPUT_ERROR); } cvm::log("atomPermutation = " + cvm::to_str(perm)); n_permutations++; @@ -1084,6 +1051,8 @@ colvar::rmsd::rmsd(std::string const &conf) } } } + + return error_code; } @@ -1215,16 +1184,24 @@ simple_scalar_dist_functions(rmsd) -colvar::eigenvector::eigenvector(std::string const &conf) - : cvc(conf) +colvar::eigenvector::eigenvector() { set_function_type("eigenvector"); provide(f_cvc_inv_gradient); provide(f_cvc_Jacobian); x.type(colvarvalue::type_scalar); +} + + +int colvar::eigenvector::init(std::string const &conf) +{ + int error_code = cvc::init(conf); atoms = parse_group(conf, "atoms"); - if (cvm::get_error()) return; + if (!atoms || atoms->size() == 0) { + return cvm::error("Error: \"atoms\" group is not defined or contains no atoms.", + COLVARS_INPUT_ERROR); + } { bool const b_inline = get_keyval(conf, "refPositions", ref_pos, ref_pos); @@ -1232,9 +1209,9 @@ colvar::eigenvector::eigenvector(std::string const &conf) if (b_inline) { cvm::log("Using reference positions from input file.\n"); if (ref_pos.size() != atoms->size()) { - cvm::error("Error: reference positions do not " - "match the number of requested atoms.\n"); - return; + error_code |= cvm::error("Error: reference positions do not " + "match the number of requested atoms.\n", + COLVARS_INPUT_ERROR); } } @@ -1242,19 +1219,18 @@ colvar::eigenvector::eigenvector(std::string const &conf) if (get_keyval(conf, "refPositionsFile", file_name)) { if (b_inline) { - cvm::error("Error: refPositions and refPositionsFile cannot be specified at the same time.\n"); - return; + error_code |= cvm::error( + "Error: refPositions and refPositionsFile cannot be specified at the same time.\n", + COLVARS_INPUT_ERROR); } - std::string file_col; double file_col_value=0.0; if (get_keyval(conf, "refPositionsCol", file_col, std::string(""))) { // use PDB flags if column is provided bool found = get_keyval(conf, "refPositionsColValue", file_col_value, 0.0); - if (found && file_col_value==0.0) { - cvm::error("Error: refPositionsColValue, " - "if provided, must be non-zero.\n"); - return; + if (found && file_col_value == 0.0) { + error_code |= cvm::error("Error: refPositionsColValue, if provided, must be non-zero.\n", + COLVARS_INPUT_ERROR); } } @@ -1265,14 +1241,14 @@ colvar::eigenvector::eigenvector(std::string const &conf) } if (ref_pos.size() == 0) { - cvm::error("Error: reference positions were not provided.\n", COLVARS_INPUT_ERROR); - return; + error_code |= + cvm::error("Error: reference positions were not provided.\n", COLVARS_INPUT_ERROR); } if (ref_pos.size() != atoms->size()) { - cvm::error("Error: reference positions do not " - "match the number of requested atoms.\n", COLVARS_INPUT_ERROR); - return; + error_code |= cvm::error("Error: reference positions do not " + "match the number of requested atoms.\n", + COLVARS_INPUT_ERROR); } // save for later the geometric center of the provided positions (may not be the origin) @@ -1303,9 +1279,8 @@ colvar::eigenvector::eigenvector(std::string const &conf) if (b_inline) { cvm::log("Using vector components from input file.\n"); if (eigenvec.size() != atoms->size()) { - cvm::error("Error: vector components do not " - "match the number of requested atoms->\n"); - return; + error_code |= cvm::error("Error: vector components do not " + "match the number of requested atoms->\n", COLVARS_INPUT_ERROR); } } @@ -1313,8 +1288,9 @@ colvar::eigenvector::eigenvector(std::string const &conf) if (get_keyval(conf, "vectorFile", file_name)) { if (b_inline) { - cvm::error("Error: vector and vectorFile cannot be specified at the same time.\n"); - return; + error_code |= + cvm::error("Error: vector and vectorFile cannot be specified at the same time.\n", + COLVARS_INPUT_ERROR); } std::string file_col; @@ -1323,8 +1299,8 @@ colvar::eigenvector::eigenvector(std::string const &conf) // use PDB flags if column is provided bool found = get_keyval(conf, "vectorColValue", file_col_value, 0.0); if (found && file_col_value==0.0) { - cvm::error("Error: vectorColValue, if provided, must be non-zero.\n"); - return; + error_code |= cvm::error("Error: vectorColValue, if provided, must be non-zero.\n", + COLVARS_INPUT_ERROR); } } @@ -1335,9 +1311,8 @@ colvar::eigenvector::eigenvector(std::string const &conf) } if (!ref_pos.size() || !eigenvec.size()) { - cvm::error("Error: both reference coordinates" - "and eigenvector must be defined.\n"); - return; + error_code |= cvm::error("Error: both reference coordinates and eigenvector must be defined.\n", + COLVARS_INPUT_ERROR); } cvm::atom_pos eig_center(0.0, 0.0, 0.0); @@ -1411,6 +1386,8 @@ colvar::eigenvector::eigenvector(std::string const &conf) cvm::log("The norm of the vector is |v| = "+ cvm::to_str(1.0/cvm::sqrt(eigenvec_invnorm2))+".\n"); } + + return error_code; } @@ -1507,10 +1484,17 @@ simple_scalar_dist_functions(eigenvector) -colvar::cartesian::cartesian(std::string const &conf) - : cvc(conf) +colvar::cartesian::cartesian() { set_function_type("cartesian"); + x.type(colvarvalue::type_vector); + disable(f_cvc_explicit_gradient); +} + + +int colvar::cartesian::init(std::string const &conf) +{ + int error_code = cvc::init(conf); atoms = parse_group(conf, "atoms"); @@ -1525,14 +1509,15 @@ colvar::cartesian::cartesian(std::string const &conf) if (use_z) axes.push_back(2); if (axes.size() == 0) { - cvm::error("Error: a \"cartesian\" component was defined with all three axes disabled.\n"); - return; + error_code |= + cvm::error("Error: a \"cartesian\" component was defined with all three axes disabled.\n", + COLVARS_INPUT_ERROR); } - x.type(colvarvalue::type_vector); - disable(f_cvc_explicit_gradient); // Don't try to access atoms if creation of the atom group failed - if (atoms != NULL) x.vector1d_value.resize(atoms->size() * axes.size()); + if (atoms) x.vector1d_value.resize(atoms->size() * axes.size()); + + return error_code; } diff --git a/src/colvarcomp_gpath.cpp b/src/colvarcomp_gpath.cpp index ba7b11f92..7ae8aaeb1 100644 --- a/src/colvarcomp_gpath.cpp +++ b/src/colvarcomp_gpath.cpp @@ -20,7 +20,21 @@ #include "colvar.h" #include "colvarcomp.h" -colvar::CartesianBasedPath::CartesianBasedPath(std::string const &conf): cvc(conf), atoms(nullptr), reference_frames(0) { + + +colvar::CartesianBasedPath::CartesianBasedPath() + : cvc(), atoms(nullptr), reference_frames(0) +{ + x.type(colvarvalue::type_scalar); + // Don't use implicit gradient + enable(f_cvc_explicit_gradient); +} + + +int colvar::CartesianBasedPath::init(std::string const &conf) +{ + int error_code = cvc::init(conf); + // Parse selected atoms atoms = parse_group(conf, "atoms"); has_user_defined_fitting = false; @@ -35,9 +49,8 @@ colvar::CartesianBasedPath::CartesianBasedPath(std::string const &conf): cvc(con if (get_keyval(conf, "refPositionsCol", reference_column, std::string(""))) { bool found = get_keyval(conf, "refPositionsColValue", reference_column_value, reference_column_value); if (found && reference_column_value == 0.0) { - cvm::error("Error: refPositionsColValue, " - "if provided, must be non-zero.\n"); - return; + error_code |= cvm::error("Error: refPositionsColValue, " + "if provided, must be non-zero.\n", COLVARS_INPUT_ERROR); } } // Lookup all reference frames @@ -93,9 +106,8 @@ colvar::CartesianBasedPath::CartesianBasedPath(std::string const &conf): cvc(con tmp_atoms->setup_rotation_derivative(); comp_atoms.push_back(tmp_atoms); } - x.type(colvarvalue::type_scalar); - // Don't use implicit gradient - enable(f_cvc_explicit_gradient); + + return error_code; } colvar::CartesianBasedPath::~CartesianBasedPath() { @@ -155,8 +167,17 @@ void colvar::CartesianBasedPath::computeDistanceBetweenReferenceFrames(std::vect } } -colvar::gspath::gspath(std::string const &conf): CartesianBasedPath(conf) { + +colvar::gspath::gspath() +{ set_function_type("gspath"); +} + + +int colvar::gspath::init(std::string const &conf) +{ + int error_code = CartesianBasedPath::init(conf); + get_keyval(conf, "useSecondClosestFrame", use_second_closest_frame, true); if (use_second_closest_frame == true) { cvm::log(std::string("Geometric path s(σ) will use the second closest frame to compute s_(m-1)\n")); @@ -170,12 +191,12 @@ colvar::gspath::gspath(std::string const &conf): CartesianBasedPath(conf) { cvm::log(std::string("Geometric path s(σ) will use the neighbouring frame to compute s_(m+1)\n")); } if (total_reference_frames < 2) { - cvm::error("Error: you have specified " + cvm::to_str(total_reference_frames) + " reference frames, but gspath requires at least 2 frames.\n"); - return; + error_code |= cvm::error("Error: you have specified " + cvm::to_str(total_reference_frames) + " reference frames, but gspath requires at least 2 frames.\n", COLVARS_INPUT_ERROR); } GeometricPathCV::GeometricPathBase::initialize(atoms->size(), cvm::atom_pos(), total_reference_frames, use_second_closest_frame, use_third_closest_frame); cvm::log(std::string("Geometric pathCV(s) is initialized.\n")); cvm::log(std::string("Geometric pathCV(s) loaded ") + cvm::to_str(reference_frames.size()) + std::string(" frames.\n")); + return error_code; } void colvar::gspath::updateDistanceToReferenceFrames() { @@ -299,8 +320,16 @@ void colvar::gspath::apply_force(colvarvalue const &force) { (*(comp_atoms[min_frame_index_2])).apply_colvar_force(F); } -colvar::gzpath::gzpath(std::string const &conf): CartesianBasedPath(conf) { + +colvar::gzpath::gzpath() +{ set_function_type("gzpath"); +} + +int colvar::gzpath::init(std::string const &conf) +{ + int error_code = CartesianBasedPath::init(conf); + get_keyval(conf, "useSecondClosestFrame", use_second_closest_frame, true); if (use_second_closest_frame == true) { cvm::log(std::string("Geometric path z(σ) will use the second closest frame to compute s_(m-1)\n")); @@ -319,13 +348,13 @@ colvar::gzpath::gzpath(std::string const &conf): CartesianBasedPath(conf) { cvm::log(std::string("Geometric path z(σ) will use the square of distance from current frame to path compute z\n")); } if (total_reference_frames < 2) { - cvm::error("Error: you have specified " + cvm::to_str(total_reference_frames) + " reference frames, but gzpath requires at least 2 frames.\n"); - return; + error_code |= cvm::error("Error: you have specified " + cvm::to_str(total_reference_frames) + " reference frames, but gzpath requires at least 2 frames.\n", COLVARS_INPUT_ERROR); } GeometricPathCV::GeometricPathBase::initialize(atoms->size(), cvm::atom_pos(), total_reference_frames, use_second_closest_frame, use_third_closest_frame, b_use_z_square); // Logging cvm::log(std::string("Geometric pathCV(z) is initialized.\n")); cvm::log(std::string("Geometric pathCV(z) loaded ") + cvm::to_str(reference_frames.size()) + std::string(" frames.\n")); + return error_code; } void colvar::gzpath::updateDistanceToReferenceFrames() { @@ -433,14 +462,25 @@ void colvar::gzpath::apply_force(colvarvalue const &force) { } -colvar::CVBasedPath::CVBasedPath(std::string const &conf): cvc(conf) { +colvar::CVBasedPath::CVBasedPath() +{ + set_function_type("gspathCV"); + x.type(colvarvalue::type_scalar); +} + + +int colvar::CVBasedPath::init(std::string const &conf) +{ + int error_code = cvc::init(conf); + // Lookup all available sub-cvcs for (auto it_cv_map = colvar::get_global_cvc_map().begin(); it_cv_map != colvar::get_global_cvc_map().end(); ++it_cv_map) { if (key_lookup(conf, it_cv_map->first.c_str())) { std::vector sub_cvc_confs; get_key_string_multi_value(conf, it_cv_map->first.c_str(), sub_cvc_confs); for (auto it_sub_cvc_conf = sub_cvc_confs.begin(); it_sub_cvc_conf != sub_cvc_confs.end(); ++it_sub_cvc_conf) { - cv.push_back((it_cv_map->second)(*(it_sub_cvc_conf))); + cv.push_back((it_cv_map->second)()); + cv.back()->init(*(it_sub_cvc_conf)); } } } @@ -463,7 +503,7 @@ colvar::CVBasedPath::CVBasedPath(std::string const &conf): cvc(conf) { cvm::log(std::string("Reading path file: ") + path_filename + std::string("\n")); auto &ifs_path = cvm::main()->proxy->input_stream(path_filename); if (!ifs_path) { - return; + return COLVARS_INPUT_ERROR; } std::string line; const std::string token(" "); @@ -484,8 +524,7 @@ colvar::CVBasedPath::CVBasedPath(std::string const &conf): cvc(conf) { cvm::log(cvm::to_str(tmp_cv[i_cv][i - start_index])); } } else { - cvm::error("Error: incorrect format of path file.\n"); - return; + error_code = cvm::error("Error: incorrect format of path file.\n", COLVARS_INPUT_ERROR); } } if (!fields.empty()) { @@ -495,15 +534,16 @@ colvar::CVBasedPath::CVBasedPath(std::string const &conf): cvc(conf) { } cvm::main()->proxy->close_input_stream(path_filename); if (total_reference_frames <= 1) { - cvm::error("Error: there is only 1 or 0 reference frame, which doesn't constitute a path.\n"); - return; + error_code = cvm::error( + "Error: there is only 1 or 0 reference frame, which doesn't constitute a path.\n", + COLVARS_INPUT_ERROR); } if (cv.size() == 0) { - cvm::error("Error: the CV " + name + - " expects one or more nesting components.\n"); - return; + error_code = + cvm::error("Error: the CV " + name + " expects one or more nesting components.\n", + COLVARS_INPUT_ERROR); } - x.type(colvarvalue::type_scalar); + use_explicit_gradients = true; for (size_t i_cv = 0; i_cv < cv.size(); ++i_cv) { if (!cv[i_cv]->is_enabled(f_cvc_explicit_gradient)) { @@ -513,6 +553,8 @@ colvar::CVBasedPath::CVBasedPath(std::string const &conf): cvc(conf) { if (!use_explicit_gradients) { disable(f_cvc_explicit_gradient); } + + return error_code; } void colvar::CVBasedPath::computeDistanceToReferenceFrames(std::vector& result) { @@ -582,8 +624,16 @@ colvar::CVBasedPath::~CVBasedPath() { atom_groups.clear(); } -colvar::gspathCV::gspathCV(std::string const &conf): CVBasedPath(conf) { +colvar::gspathCV::gspathCV() +{ set_function_type("gspathCV"); + x.type(colvarvalue::type_scalar); +} + +int colvar::gspathCV::init(std::string const &conf) +{ + int error_code = CVBasedPath::init(conf); + cvm::log(std::string("Total number of frames: ") + cvm::to_str(total_reference_frames) + std::string("\n")); // Initialize variables for future calculation get_keyval(conf, "useSecondClosestFrame", use_second_closest_frame, true); @@ -599,11 +649,10 @@ colvar::gspathCV::gspathCV(std::string const &conf): CVBasedPath(conf) { cvm::log(std::string("Geometric path s(σ) will use the neighbouring frame to compute s_(m+1)\n")); } if (total_reference_frames < 2) { - cvm::error("Error: you have specified " + cvm::to_str(total_reference_frames) + " reference frames, but gspathCV requires at least 2 frames.\n"); - return; + error_code |= cvm::error("Error: you have specified " + cvm::to_str(total_reference_frames) + " reference frames, but gspathCV requires at least 2 frames.\n", COLVARS_INPUT_ERROR); } GeometricPathCV::GeometricPathBase::initialize(cv.size(), ref_cv[0], total_reference_frames, use_second_closest_frame, use_third_closest_frame); - x.type(colvarvalue::type_scalar); + return error_code; } colvar::gspathCV::~gspathCV() {} @@ -705,8 +754,15 @@ void colvar::gspathCV::apply_force(colvarvalue const &force) { } } -colvar::gzpathCV::gzpathCV(std::string const &conf): CVBasedPath(conf) { +colvar::gzpathCV::gzpathCV() +{ set_function_type("gzpathCV"); +} + +int colvar::gzpathCV::init(std::string const &conf) { + + int error_code = CVBasedPath::init(conf); + cvm::log(std::string("Total number of frames: ") + cvm::to_str(total_reference_frames) + std::string("\n")); // Initialize variables for future calculation M = cvm::real(total_reference_frames - 1); @@ -729,11 +785,13 @@ colvar::gzpathCV::gzpathCV(std::string const &conf): CVBasedPath(conf) { cvm::log(std::string("Geometric path z(σ) will use the square of distance from current frame to path compute z\n")); } if (total_reference_frames < 2) { - cvm::error("Error: you have specified " + cvm::to_str(total_reference_frames) + " reference frames, but gzpathCV requires at least 2 frames.\n"); - return; + error_code |= cvm::error("Error: you have specified " + cvm::to_str(total_reference_frames) + + " reference frames, but gzpathCV requires at least 2 frames.\n", + COLVARS_INPUT_ERROR); } GeometricPathCV::GeometricPathBase::initialize(cv.size(), ref_cv[0], total_reference_frames, use_second_closest_frame, use_third_closest_frame, b_use_z_square); - x.type(colvarvalue::type_scalar); + + return error_code; } colvar::gzpathCV::~gzpathCV() { diff --git a/src/colvarcomp_neuralnetwork.cpp b/src/colvarcomp_neuralnetwork.cpp index e8ad629b1..f79fe18ad 100644 --- a/src/colvarcomp_neuralnetwork.cpp +++ b/src/colvarcomp_neuralnetwork.cpp @@ -16,8 +16,16 @@ using namespace neuralnetworkCV; -colvar::neuralNetwork::neuralNetwork(std::string const &conf): linearCombination(conf) { + +colvar::neuralNetwork::neuralNetwork() +{ set_function_type("neuralNetwork"); +} + + +int colvar::neuralNetwork::init(std::string const &conf) +{ + int error_code = linearCombination::init(conf); // the output of neural network consists of multiple values // read "output_component" key to determine it get_keyval(conf, "output_component", m_output_index); @@ -66,8 +74,9 @@ colvar::neuralNetwork::neuralNetwork(std::string const &conf): linearCombination std::string function_name; get_keyval(conf, lookup_key.c_str(), function_name, std::string("")); if (activation_function_map.find(function_name) == activation_function_map.end()) { - cvm::error("Unknown activation function name: \"" + function_name + "\".\n"); - return; + error_code |= + cvm::error("Unknown activation function name: \"" + function_name + "\".\n", + COLVARS_INPUT_ERROR); } activation_functions.push_back(std::make_pair(false, function_name)); cvm::log(std::string{"The activation function for layer["} + cvm::to_str(num_activation_functions + 1) + std::string{"] is "} + function_name + '\n'); @@ -86,8 +95,9 @@ colvar::neuralNetwork::neuralNetwork(std::string const &conf): linearCombination } // expect the three numbers are equal if ((num_layers_weight != num_layers_bias) || (num_layers_bias != num_activation_functions)) { - cvm::error("Error: the numbers of weights, biases and activation functions do not match.\n"); - return; + error_code |= cvm::error( + "Error: the numbers of weights, biases and activation functions do not match.\n", + COLVARS_INPUT_ERROR); } // nn = std::make_unique(); // std::make_unique is only available in C++14 @@ -100,8 +110,9 @@ colvar::neuralNetwork::neuralNetwork(std::string const &conf): linearCombination try { d = denseLayer(weight_files[i_layer], bias_files[i_layer], activation_functions[i_layer].second); } catch (std::exception &ex) { - cvm::error("Error on initializing layer " + cvm::to_str(i_layer) + " (" + ex.what() + ")\n", COLVARS_INPUT_ERROR); - return; + error_code |= cvm::error("Error on initializing layer " + cvm::to_str(i_layer) + + " (" + ex.what() + ")\n", + COLVARS_INPUT_ERROR); } } else { #endif @@ -111,8 +122,9 @@ colvar::neuralNetwork::neuralNetwork(std::string const &conf): linearCombination try { d = denseLayer(weight_files[i_layer], bias_files[i_layer], f, df); } catch (std::exception &ex) { - cvm::error("Error on initializing layer " + cvm::to_str(i_layer) + " (" + ex.what() + ")\n", COLVARS_INPUT_ERROR); - return; + error_code |= cvm::error("Error on initializing layer " + cvm::to_str(i_layer) + + " (" + ex.what() + ")\n", + COLVARS_INPUT_ERROR); } #ifdef LEPTON } @@ -130,11 +142,11 @@ colvar::neuralNetwork::neuralNetwork(std::string const &conf): linearCombination } } } else { - cvm::error("Error: error on adding a new dense layer.\n"); - return; + error_code |= cvm::error("Error: error on adding a new dense layer.\n", COLVARS_INPUT_ERROR); } } nn->input().resize(cv.size()); + return error_code; } colvar::neuralNetwork::~neuralNetwork() { diff --git a/src/colvarcomp_protein.cpp b/src/colvarcomp_protein.cpp index 80ef9b855..29db55d99 100644 --- a/src/colvarcomp_protein.cpp +++ b/src/colvarcomp_protein.cpp @@ -16,14 +16,19 @@ #include "colvarcomp.h" -colvar::alpha_angles::alpha_angles(std::string const &conf) - : cvc(conf) +colvar::alpha_angles::alpha_angles() { set_function_type("alpha"); enable(f_cvc_explicit_gradient); x.type(colvarvalue::type_scalar); - colvarproxy *proxy = cvm::main()->proxy; + r0 = proxy->angstrom_to_internal(3.3); +} + + +int colvar::alpha_angles::init(std::string const &conf) +{ + int error_code = cvc::init(conf); std::string segment_id; get_keyval(conf, "psfSegID", segment_id, std::string("MAIN")); @@ -44,29 +49,29 @@ colvar::alpha_angles::alpha_angles(std::string const &conf) } } } else { - cvm::error("Error: no residues defined in \"residueRange\".\n"); - return; + error_code |= + cvm::error("Error: no residues defined in \"residueRange\".\n", COLVARS_INPUT_ERROR); } } if (residues.size() < 5) { - cvm::error("Error: not enough residues defined in \"residueRange\".\n"); - return; + error_code |= cvm::error("Error: not enough residues defined in \"residueRange\".\n", + COLVARS_INPUT_ERROR); } std::string const &sid = segment_id; std::vector const &r = residues; - get_keyval(conf, "hBondCoeff", hb_coeff, 0.5); - if ( (hb_coeff < 0.0) || (hb_coeff > 1.0) ) { - cvm::error("Error: hBondCoeff must be defined between 0 and 1.\n"); - return; + get_keyval(conf, "hBondCoeff", hb_coeff, hb_coeff); + if ((hb_coeff < 0.0) || (hb_coeff > 1.0)) { + error_code |= + cvm::error("Error: hBondCoeff must be defined between 0 and 1.\n", COLVARS_INPUT_ERROR); } - get_keyval(conf, "angleRef", theta_ref, 88.0); - get_keyval(conf, "angleTol", theta_tol, 15.0); + get_keyval(conf, "angleRef", theta_ref, theta_ref); + get_keyval(conf, "angleTol", theta_tol, theta_tol); if (hb_coeff < 1.0) { @@ -84,11 +89,9 @@ colvar::alpha_angles::alpha_angles(std::string const &conf) } { - cvm::real r0; - size_t en, ed; - get_keyval(conf, "hBondCutoff", r0, proxy->angstrom_to_internal(3.3)); - get_keyval(conf, "hBondExpNumer", en, 6); - get_keyval(conf, "hBondExpDenom", ed, 8); + get_keyval(conf, "hBondCutoff", r0, r0); + get_keyval(conf, "hBondExpNumer", en, en); + get_keyval(conf, "hBondExpDenom", ed, ed); if (hb_coeff > 0.0) { @@ -103,15 +106,8 @@ colvar::alpha_angles::alpha_angles(std::string const &conf) cvm::log("The hBondCoeff specified will disable the hydrogen bond terms.\n"); } } -} - -colvar::alpha_angles::alpha_angles() - : cvc() -{ - set_function_type("alphaAngles"); - enable(f_cvc_explicit_gradient); - x.type(colvarvalue::type_scalar); + return error_code; } @@ -281,16 +277,21 @@ simple_scalar_dist_functions(alpha_angles) // dihedral principal component ////////////////////////////////////////////////////////////////////// -colvar::dihedPC::dihedPC(std::string const &conf) - : cvc(conf) +colvar::dihedPC::dihedPC() { - if (cvm::debug()) - cvm::log("Initializing dihedral PC object.\n"); - set_function_type("dihedPC"); // Supported through references to atom groups of children cvcs enable(f_cvc_explicit_gradient); x.type(colvarvalue::type_scalar); +} + + +int colvar::dihedPC::init(std::string const &conf) +{ + int error_code = cvc::init(conf); + + if (cvm::debug()) + cvm::log("Initializing dihedral PC object.\n"); std::string segment_id; get_keyval(conf, "psfSegID", segment_id, std::string("MAIN")); @@ -311,14 +312,14 @@ colvar::dihedPC::dihedPC(std::string const &conf) } } } else { - cvm::error("Error: no residues defined in \"residueRange\".\n"); - return; + error_code |= + cvm::error("Error: no residues defined in \"residueRange\".\n", COLVARS_INPUT_ERROR); } } if (residues.size() < 2) { - cvm::error("Error: dihedralPC requires at least two residues.\n"); - return; + error_code |= + cvm::error("Error: dihedralPC requires at least two residues.\n", COLVARS_INPUT_ERROR); } std::string const &sid = segment_id; @@ -329,15 +330,15 @@ colvar::dihedPC::dihedPC(std::string const &conf) if (get_keyval(conf, "vectorFile", vecFileName, vecFileName)) { get_keyval(conf, "vectorNumber", vecNumber, 0); if (vecNumber < 1) { - cvm::error("A positive value of vectorNumber is required."); - return; + error_code |= + cvm::error("A positive value of vectorNumber is required.", COLVARS_INPUT_ERROR); } std::istream &vecFile = cvm::main()->proxy->input_stream(vecFileName, "dihedral PCA vector file"); if (!vecFile) { - return; + return COLVARS_INPUT_ERROR; } // TODO: adapt to different formats by setting this flag @@ -383,11 +384,10 @@ colvar::dihedPC::dihedPC(std::string const &conf) } if ( coeffs.size() != 4 * (residues.size() - 1)) { - cvm::error("Error: wrong number of coefficients: " + - cvm::to_str(coeffs.size()) + ". Expected " + - cvm::to_str(4 * (residues.size() - 1)) + - " (4 coeffs per residue, minus one residue).\n"); - return; + error_code |= cvm::error("Error: wrong number of coefficients: " + cvm::to_str(coeffs.size()) + + ". Expected " + cvm::to_str(4 * (residues.size() - 1)) + + " (4 coeffs per residue, minus one residue).\n", + COLVARS_INPUT_ERROR); } for (size_t i = 0; i < residues.size()-1; i++) { @@ -413,16 +413,8 @@ colvar::dihedPC::dihedPC(std::string const &conf) if (cvm::debug()) cvm::log("Done initializing dihedPC object.\n"); -} - -colvar::dihedPC::dihedPC() - : cvc() -{ - set_function_type("dihedPC"); - // Supported through references to atom groups of children cvcs - enable(f_cvc_explicit_gradient); - x.type(colvarvalue::type_scalar); + return error_code; } diff --git a/src/colvarcomp_rotations.cpp b/src/colvarcomp_rotations.cpp index 3a19d5ca7..3edf9d4f9 100644 --- a/src/colvarcomp_rotations.cpp +++ b/src/colvarcomp_rotations.cpp @@ -23,13 +23,11 @@ struct colvar::orientation::rotation_derivative_impl_: public rotation_derivativ }; -colvar::orientation::orientation(std::string const &conf) - : cvc() +colvar::orientation::orientation() { set_function_type("orientation"); disable(f_cvc_explicit_gradient); x.type(colvarvalue::type_quaternion); - colvar::orientation::init(conf); } @@ -106,15 +104,6 @@ int colvar::orientation::init(std::string const &conf) } -colvar::orientation::orientation() - : cvc() -{ - set_function_type("orientation"); - disable(f_cvc_explicit_gradient); - x.type(colvarvalue::type_quaternion); -} - - void colvar::orientation::calc_value() { atoms_cog = atoms->center_of_geometry(); @@ -178,19 +167,11 @@ colvarvalue colvar::orientation::dist2_rgrad(colvarvalue const &x1, -colvar::orientation_angle::orientation_angle(std::string const &conf) - : orientation() +colvar::orientation_angle::orientation_angle() { set_function_type("orientationAngle"); init_as_angle(); enable(f_cvc_explicit_gradient); - orientation_angle::init(conf); -} - - -int colvar::orientation_angle::init(std::string const &conf) -{ - return orientation::init(conf); } @@ -238,20 +219,12 @@ simple_scalar_dist_functions(orientation_angle) -colvar::orientation_proj::orientation_proj(std::string const &conf) - : orientation() +colvar::orientation_proj::orientation_proj() { set_function_type("orientationProj"); enable(f_cvc_explicit_gradient); x.type(colvarvalue::type_scalar); init_scalar_boundaries(0.0, 1.0); - orientation_proj::init(conf); -} - - -int colvar::orientation_proj::init(std::string const &conf) -{ - return orientation::init(conf); } @@ -290,22 +263,18 @@ simple_scalar_dist_functions(orientation_proj) -colvar::tilt::tilt(std::string const &conf) - : orientation() +colvar::tilt::tilt() { set_function_type("tilt"); x.type(colvarvalue::type_scalar); enable(f_cvc_explicit_gradient); init_scalar_boundaries(-1.0, 1.0); - tilt::init(conf); } int colvar::tilt::init(std::string const &conf) { - int error_code = COLVARS_OK; - - error_code |= orientation::init(conf); + int error_code = orientation::init(conf); get_keyval(conf, "axis", axis, cvm::rvector(0.0, 0.0, 1.0)); if (axis.norm2() != 1.0) { @@ -358,22 +327,18 @@ simple_scalar_dist_functions(tilt) -colvar::spin_angle::spin_angle(std::string const &conf) - : orientation() +colvar::spin_angle::spin_angle() { set_function_type("spinAngle"); init_as_periodic_angle(); enable(f_cvc_periodic); enable(f_cvc_explicit_gradient); - spin_angle::init(conf); } int colvar::spin_angle::init(std::string const &conf) { - int error_code = COLVARS_OK; - - error_code |= orientation::init(conf); + int error_code = orientation::init(conf); get_keyval(conf, "axis", axis, cvm::rvector(0.0, 0.0, 1.0)); if (axis.norm2() != 1.0) { @@ -385,17 +350,6 @@ int colvar::spin_angle::init(std::string const &conf) } -colvar::spin_angle::spin_angle() - : orientation() -{ - set_function_type("spinAngle"); - period = 360.0; - enable(f_cvc_periodic); - enable(f_cvc_explicit_gradient); - x.type(colvarvalue::type_scalar); -} - - void colvar::spin_angle::calc_value() { atoms_cog = atoms->center_of_geometry(); @@ -477,18 +431,7 @@ void colvar::spin_angle::wrap(colvarvalue &x_unwrapped) const } -colvar::euler_phi::euler_phi(std::string const &conf) - : orientation() -{ - set_function_type("eulerPhi"); - init_as_periodic_angle(); - enable(f_cvc_explicit_gradient); - euler_phi::init(conf); -} - - colvar::euler_phi::euler_phi() - : orientation() { set_function_type("eulerPhi"); init_as_periodic_angle(); @@ -496,14 +439,6 @@ colvar::euler_phi::euler_phi() } -int colvar::euler_phi::init(std::string const &conf) -{ - int error_code = COLVARS_OK; - error_code |= orientation::init(conf); - return error_code; -} - - void colvar::euler_phi::calc_value() { atoms_cog = atoms->center_of_geometry(); @@ -596,16 +531,6 @@ void colvar::euler_phi::wrap(colvarvalue &x_unwrapped) const } -colvar::euler_psi::euler_psi(std::string const &conf) - : orientation() -{ - set_function_type("eulerPsi"); - init_as_periodic_angle(); - enable(f_cvc_explicit_gradient); - euler_psi::init(conf); -} - - colvar::euler_psi::euler_psi() : orientation() { @@ -615,14 +540,6 @@ colvar::euler_psi::euler_psi() } -int colvar::euler_psi::init(std::string const &conf) -{ - int error_code = COLVARS_OK; - error_code |= orientation::init(conf); - return error_code; -} - - void colvar::euler_psi::calc_value() { atoms_cog = atoms->center_of_geometry(); @@ -715,16 +632,6 @@ void colvar::euler_psi::wrap(colvarvalue &x_unwrapped) const } -colvar::euler_theta::euler_theta(std::string const &conf) - : orientation() -{ - set_function_type("eulerTheta"); - init_as_angle(); - enable(f_cvc_explicit_gradient); - euler_theta::init(conf); -} - - colvar::euler_theta::euler_theta() : orientation() { @@ -734,14 +641,6 @@ colvar::euler_theta::euler_theta() } -int colvar::euler_theta::init(std::string const &conf) -{ - int error_code = COLVARS_OK; - error_code |= orientation::init(conf); - return error_code; -} - - void colvar::euler_theta::calc_value() { atoms_cog = atoms->center_of_geometry(); diff --git a/src/colvarcomp_volmaps.cpp b/src/colvarcomp_volmaps.cpp index 00c7206bc..0852408b7 100644 --- a/src/colvarcomp_volmaps.cpp +++ b/src/colvarcomp_volmaps.cpp @@ -16,28 +16,12 @@ colvar::map_total::map_total() - : cvc() { set_function_type("mapTotal"); - volmap_id = -1; - volmap_index = -1; - atoms = NULL; x.type(colvarvalue::type_scalar); } -colvar::map_total::map_total(std::string const &conf) - : cvc() // init() will take care of this -{ - set_function_type("mapTotal"); - volmap_id = -1; - volmap_index = -1; - atoms = NULL; - x.type(colvarvalue::type_scalar); - map_total::init(conf); -} - - int colvar::map_total::init(std::string const &conf) { int error_code = cvc::init(conf); @@ -50,12 +34,12 @@ int colvar::map_total::init(std::string const &conf) if ((volmap_name.size() > 0) && (volmap_id >= 0)) { error_code |= - cvm::error("Error: mapName and mapID are mutually exclusive.\n"); + cvm::error("Error: mapName and mapID are mutually exclusive.\n", COLVARS_INPUT_ERROR); } // Parse optional group atoms = parse_group(conf, "atoms", true); - if (atoms != NULL) { + if (atoms) { // Using internal selection if (volmap_name.size()) { @@ -74,11 +58,11 @@ int colvar::map_total::init(std::string const &conf) if (volmap_id >= 0) { volmap_index = proxy->init_volmap_by_id(volmap_id); } - error_code |= volmap_index > 0 ? COLVARS_OK : COLVARS_INPUT_ERROR; + error_code |= (volmap_index >= 0) ? COLVARS_OK : COLVARS_INPUT_ERROR; } if (get_keyval(conf, "atomWeights", atom_weights, atom_weights)) { - if (atoms == NULL) { + if (!atoms) { error_code |= cvm::error("Error: weights can only be assigned when atoms " "are selected explicitly in Colvars.\n", COLVARS_INPUT_ERROR);