diff --git a/lib/colvars/colvar.cpp b/lib/colvars/colvar.cpp index 0aaaab0e09..128762cb06 100644 --- a/lib/colvars/colvar.cpp +++ b/lib/colvars/colvar.cpp @@ -98,8 +98,8 @@ colvar::colvar (std::string const &conf) "on an axis", "distanceZ", distance_z); initialize_components ("distance projection " "on a plane", "distanceXY", distance_xy); - initialize_components ("average distance weighted by inverse sixth power", - "distance6", distance6); + initialize_components ("average distance weighted by inverse power", + "distanceInv", distance_inv); initialize_components ("coordination " "number", "coordNum", coordnum); @@ -132,7 +132,7 @@ colvar::colvar (std::string const &conf) initialize_components ("moment of " "inertia", "inertia", inertia); initialize_components ("moment of inertia around an axis", - "inertia_z", inertia_z); + "inertiaZ", inertia_z); initialize_components ("eigenvector", "eigenvector", eigenvector); if (!cvcs.size()) @@ -318,13 +318,13 @@ colvar::colvar (std::string const &conf) "by enabling a thermostat, or through \"extendedTemp\".\n"); } - get_keyval (conf, "extendedFluctuation", tolerance, 0.2*width); + get_keyval (conf, "extendedFluctuation", tolerance, width); if (tolerance <= 0.0) cvm::fatal_error ("Error: \"extendedFluctuation\" must be positive.\n"); ext_force_k = cvm::boltzmann() * temp / (tolerance * tolerance); cvm::log ("Computed extended system force constant: " + cvm::to_str(ext_force_k) + " kcal/mol/U^2"); - get_keyval (conf, "extendedTimeConstant", period, 40.0 * cvm::dt()); + get_keyval (conf, "extendedTimeConstant", period, 200.0); if (period <= 0.0) cvm::fatal_error ("Error: \"extendedTimeConstant\" must be positive.\n"); ext_mass = (cvm::boltzmann() * temp * period * period) @@ -339,7 +339,7 @@ colvar::colvar (std::string const &conf) } } - get_keyval (conf, "extendedLangevinDamping", ext_gamma, 0.0); + get_keyval (conf, "extendedLangevinDamping", ext_gamma, 1.0); if (ext_gamma < 0.0) cvm::fatal_error ("Error: \"extendedLangevinDamping\" may not be negative.\n"); if (ext_gamma != 0.0) { diff --git a/lib/colvars/colvar.h b/lib/colvars/colvar.h index a9542a606c..396c63dc5a 100644 --- a/lib/colvars/colvar.h +++ b/lib/colvars/colvar.h @@ -471,7 +471,7 @@ public: class distance; class distance_z; class distance_xy; - class distance6; + class distance_inv; class angle; class dihedral; class coordnum; diff --git a/lib/colvars/colvaratoms.cpp b/lib/colvars/colvaratoms.cpp index 17107b40f6..d9a936df61 100644 --- a/lib/colvars/colvaratoms.cpp +++ b/lib/colvars/colvaratoms.cpp @@ -116,8 +116,9 @@ void cvm::atom_group::parse (std::string const &conf, std::vector::iterator psii = psf_segids.begin(); while (key_lookup (group_conf, "atomNameResidueRange", range_conf, pos)) { + range_count++; - if (psii > psf_segids.end()) { + if (range_count > psf_segids.size()) { cvm::fatal_error ("Error: more instances of \"atomNameResidueRange\" than " "values of \"psfSegID\".\n"); } @@ -520,6 +521,7 @@ void cvm::atom_group::read_system_forces() } } +/* This is deprecated. cvm::atom_pos cvm::atom_group::center_of_geometry (cvm::atom_pos const &ref_pos) { if (b_dummy) { @@ -535,7 +537,7 @@ cvm::atom_pos cvm::atom_group::center_of_geometry (cvm::atom_pos const &ref_pos) } cog /= this->size(); return cog; -} +} */ cvm::atom_pos cvm::atom_group::center_of_geometry() const { @@ -551,6 +553,7 @@ cvm::atom_pos cvm::atom_group::center_of_geometry() const return cog; } +/* This is deprecated. cvm::atom_pos cvm::atom_group::center_of_mass (cvm::atom_pos const &ref_pos) { if (b_dummy) { @@ -566,7 +569,7 @@ cvm::atom_pos cvm::atom_group::center_of_mass (cvm::atom_pos const &ref_pos) } com /= this->total_mass; return com; -} +}*/ cvm::atom_pos cvm::atom_group::center_of_mass() const { diff --git a/lib/colvars/colvaratoms.h b/lib/colvars/colvaratoms.h index 481a93a9bd..782ae6b9c8 100644 --- a/lib/colvars/colvaratoms.h +++ b/lib/colvars/colvaratoms.h @@ -1,3 +1,5 @@ +// -*- c++ -*- + #ifndef COLVARATOMS_H #define COLVARATOMS_H @@ -304,15 +306,8 @@ public: /// the colvar has not a scalar value) or the biases require to /// micromanage the forces. void apply_forces (std::vector const &forces); + }; - - #endif - - -// Emacs -// Local Variables: -// mode: C++ -// End: diff --git a/lib/colvars/colvarbias_meta.cpp b/lib/colvars/colvarbias_meta.cpp index 607fd94ab4..a3a483d606 100644 --- a/lib/colvars/colvarbias_meta.cpp +++ b/lib/colvars/colvarbias_meta.cpp @@ -1072,8 +1072,12 @@ void colvarbias_meta::read_replica_files() } } else { - cvm::fatal_error ("Error: cannot read from file \""+ - (replicas[ir])->replica_hills_file+"\".\n"); + cvm::log ("Failed to read the file \""+(replicas[ir])->replica_hills_file+ + "\": will try again in "+ + cvm::to_str (replica_update_freq)+" steps.\n"); + (replicas[ir])->update_status++; + // cvm::fatal_error ("Error: cannot read from file \""+ + // (replicas[ir])->replica_hills_file+"\".\n"); } is.close(); } @@ -1081,12 +1085,12 @@ void colvarbias_meta::read_replica_files() size_t const n_flush = (replica_update_freq/new_hill_freq + 1); if ((replicas[ir])->update_status > 3*n_flush) { // TODO: suspend the calculation? - cvm::log ("Warning: in metadynamics bias \""+this->name+"\""+ - ": failet do read completely output files from replica \""+ + cvm::log ("WARNING: in metadynamics bias \""+this->name+"\""+ + " failed to read completely the output of replica \""+ (replicas[ir])->replica_id+ "\" after more than "+ - cvm::to_str (n_flush*new_hill_freq)+ - " steps. Please check that that simulation is still running.\n"); + cvm::to_str ((replicas[ir])->update_status * replica_update_freq)+ + " steps. Ensure that it is still running.\n"); } } } diff --git a/lib/colvars/colvarcomp.cpp b/lib/colvars/colvarcomp.cpp index 5490f697ae..f1997a6dd9 100644 --- a/lib/colvars/colvarcomp.cpp +++ b/lib/colvars/colvarcomp.cpp @@ -71,21 +71,3 @@ void colvar::cvc::calc_Jacobian_derivative() cvm::fatal_error ("Error: calculation of inverse gradients is not implemented " "for colvar components of type \""+function_type+"\".\n"); } - - -colvarvalue colvar::cvc::fdiff_change (cvm::atom_group &group) -{ - colvarvalue change (x.type()); - - if (group.old_pos.size()) { - for (size_t i = 0; i < group.size(); i++) { - cvm::rvector const &pold = group.old_pos[i]; - cvm::rvector const &p = group[i].pos; - change += group[i].grad * (p - pold); - } - } - - // save for next step - group.old_pos = group.positions(); - return change; -} diff --git a/lib/colvars/colvarcomp.h b/lib/colvars/colvarcomp.h index 2e916c9c29..7954fb5c1d 100644 --- a/lib/colvars/colvarcomp.h +++ b/lib/colvars/colvarcomp.h @@ -111,11 +111,6 @@ public: /// report their differences bool b_debug_gradients; - /// \brief When b_debug_gradients is true, this function can be used - /// to calculate the estimated change in the value using the change - /// in the atomic coordinates times the atomic gradients - colvarvalue fdiff_change (cvm::atom_group &group); - /// \brief If this flag is false (default), inverse gradients /// (derivatives of atom coordinates with respect to x) are /// unavailable; it should be set to true by the constructor of each @@ -475,16 +470,16 @@ public: /// \brief Colvar component: average distance between two groups of atoms, weighted as the sixth power, /// as in NMR refinements (colvarvalue::type_scalar type, range (0:*)) -class colvar::distance6 +class colvar::distance_inv : public colvar::distance { protected: /// Components of the distance vector orthogonal to the axis - cvm::real smoothing; + int exponent; public: - distance6 (std::string const &conf); - distance6(); - virtual inline ~distance6() {} + distance_inv (std::string const &conf); + distance_inv(); + virtual inline ~distance_inv() {} virtual void calc_value(); virtual void calc_gradients(); virtual void apply_force (colvarvalue const &force); @@ -1301,7 +1296,7 @@ inline void colvar::spin_angle::wrap (colvarvalue &x) const simple_scalar_dist_functions (distance) // NOTE: distance_z has explicit functions, see below simple_scalar_dist_functions (distance_xy) - simple_scalar_dist_functions (distance6) + simple_scalar_dist_functions (distance_inv) simple_scalar_dist_functions (angle) simple_scalar_dist_functions (coordnum) simple_scalar_dist_functions (selfcoordnum) diff --git a/lib/colvars/colvarcomp_distances.cpp b/lib/colvars/colvarcomp_distances.cpp index 438929a7a4..35d29efe4b 100644 --- a/lib/colvars/colvarcomp_distances.cpp +++ b/lib/colvars/colvarcomp_distances.cpp @@ -179,7 +179,10 @@ colvar::distance_z::distance_z (std::string const &conf) if (get_keyval (conf, "axis", axis, cvm::rvector (0.0, 0.0, 1.0))) { if (axis.norm2() == 0.0) cvm::fatal_error ("Axis vector is zero!"); - axis = axis.unit(); + if (axis.norm2() != 1.0) { + axis = axis.unit(); + cvm::log ("The normalized axis is: "+cvm::to_str (axis)+".\n"); + } } fixed_axis = true; } @@ -451,25 +454,34 @@ void colvar::distance_dir::apply_force (colvarvalue const &force) -colvar::distance6::distance6 (std::string const &conf) +colvar::distance_inv::distance_inv (std::string const &conf) : distance (conf) { - function_type = "distance6"; + function_type = "distance_inv"; + get_keyval (conf, "exponent", exponent, 6); + if (exponent%2) { + cvm::fatal_error ("Error: odd exponent provided, can only use even ones.\n"); + } + if (exponent <= 0) { + cvm::fatal_error ("Error: negative or zero exponent provided.\n"); + } + b_inverse_gradients = false; b_Jacobian_derivative = false; x.type (colvarvalue::type_scalar); } -colvar::distance6::distance6() +colvar::distance_inv::distance_inv() { - function_type = "distance6"; + function_type = "distance_inv"; + exponent = 6; b_inverse_gradients = false; b_Jacobian_derivative = false; b_1site_force = false; x.type (colvarvalue::type_scalar); } -void colvar::distance6::calc_value() +void colvar::distance_inv::calc_value() { group1.reset_atoms_data(); group2.reset_atoms_data(); @@ -483,8 +495,11 @@ void colvar::distance6::calc_value() for (cvm::atom_iter ai2 = group2.begin(); ai2 != group2.end(); ai2++) { cvm::rvector const dv = ai2->pos - ai1->pos; cvm::real const d2 = dv.norm2(); - x.real_value += 1.0/(d2*d2*d2); - cvm::rvector const dsumddv = -6.0/(d2*d2*d2*d2) * dv; + cvm::real dinv = 1.0; + for (int ne = 0; ne < exponent/2; ne++) + dinv *= 1.0/d2; + x.real_value += dinv; + cvm::rvector const dsumddv = -(cvm::real (exponent)) * dinv/d2 * dv; ai1->grad += -1.0 * dsumddv; ai2->grad += dsumddv; } @@ -494,30 +509,39 @@ void colvar::distance6::calc_value() for (cvm::atom_iter ai2 = group2.begin(); ai2 != group2.end(); ai2++) { cvm::rvector const dv = cvm::position_distance (ai1->pos, ai2->pos); cvm::real const d2 = dv.norm2(); - x.real_value += 1.0/(d2*d2*d2); - cvm::rvector const dsumddv = -6.0/(d2*d2*d2*d2) * dv; + cvm::real dinv = 1.0; + for (int ne = 0; ne < exponent/2; ne++) + dinv *= 1.0/d2; + x.real_value += dinv; + cvm::rvector const dsumddv = -(cvm::real (exponent)) * dinv/d2 * dv; ai1->grad += -1.0 * dsumddv; ai2->grad += dsumddv; } } } - x.real_value = std::pow (x.real_value, -1.0/6.0); + x.real_value *= 1.0 / cvm::real (group1.size() * group2.size()); + x.real_value = std::pow (x.real_value, -1.0/(cvm::real (exponent))); } -void colvar::distance6::calc_gradients() +void colvar::distance_inv::calc_gradients() { + cvm::real const dxdsum = (-1.0/(cvm::real (exponent))) * std::pow (x.real_value, exponent+1) / cvm::real (group1.size() * group2.size()); + for (cvm::atom_iter ai1 = group1.begin(); ai1 != group1.end(); ai1++) { + ai1->grad *= dxdsum; + } + for (cvm::atom_iter ai2 = group2.begin(); ai2 != group2.end(); ai2++) { + ai2->grad *= dxdsum; + } } -void colvar::distance6::apply_force (colvarvalue const &force) +void colvar::distance_inv::apply_force (colvarvalue const &force) { - cvm::real const dxdsum = (-1.0/6.0) * std::pow (x.real_value, -7.0/6.0); - if (!group1.noforce) - group1.apply_colvar_force (dxdsum * force.real_value); + group1.apply_colvar_force (force.real_value); if (!group2.noforce) - group2.apply_colvar_force (dxdsum * force.real_value); + group2.apply_colvar_force (force.real_value); } @@ -614,21 +638,19 @@ void colvar::inertia::calc_value() { atoms.reset_atoms_data(); atoms.read_positions(); - atoms.apply_translation ((-1.0) * atoms.center_of_geometry()); + atoms.apply_translation ((-1.0) * atoms.center_of_mass()); x.real_value = 0.0; for (cvm::atom_iter ai = atoms.begin(); ai != atoms.end(); ai++) { x.real_value += ai->mass * (ai->pos).norm2(); } - x.real_value = std::sqrt (x.real_value / atoms.total_mass); } void colvar::inertia::calc_gradients() { - cvm::real const drdx = 1.0/(atoms.total_mass * x.real_value); for (cvm::atom_iter ai = atoms.begin(); ai != atoms.end(); ai++) { - ai->grad = drdx * ai->mass * ai->pos; + ai->grad = 2.0 * ai->mass * ai->pos; } } @@ -647,7 +669,10 @@ colvar::inertia_z::inertia_z (std::string const &conf) if (get_keyval (conf, "axis", axis, cvm::rvector (0.0, 0.0, 1.0))) { if (axis.norm2() == 0.0) cvm::fatal_error ("Axis vector is zero!"); - axis = axis.unit(); + if (axis.norm2() != 1.0) { + axis = axis.unit(); + cvm::log ("The normalized axis is: "+cvm::to_str (axis)+".\n"); + } } x.type (colvarvalue::type_scalar); } @@ -664,22 +689,20 @@ void colvar::inertia_z::calc_value() { atoms.reset_atoms_data(); atoms.read_positions(); - atoms.apply_translation ((-1.0) * atoms.center_of_geometry()); + atoms.apply_translation ((-1.0) * atoms.center_of_mass()); x.real_value = 0.0; for (cvm::atom_iter ai = atoms.begin(); ai != atoms.end(); ai++) { cvm::real const iprod = ai->pos * axis; x.real_value += ai->mass * iprod * iprod; } - x.real_value = std::sqrt (x.real_value / atoms.total_mass); } void colvar::inertia_z::calc_gradients() { - cvm::real const drdx = 1.0/(atoms.total_mass * x.real_value); for (cvm::atom_iter ai = atoms.begin(); ai != atoms.end(); ai++) { - ai->grad = drdx * ai->mass * (ai->pos * axis) * axis; + ai->grad = 2.0 * ai->mass * (ai->pos * axis) * axis; } } diff --git a/lib/colvars/colvarcomp_rotations.cpp b/lib/colvars/colvarcomp_rotations.cpp index 449613fa30..cae4030a4a 100644 --- a/lib/colvars/colvarcomp_rotations.cpp +++ b/lib/colvars/colvarcomp_rotations.cpp @@ -72,7 +72,6 @@ colvar::orientation::orientation (std::string const &conf) rot.request_group2_gradients (atoms.size()); } - rot.b_debug_gradients = this->b_debug_gradients; } @@ -228,38 +227,6 @@ void colvar::tilt::calc_gradients() atoms[ia].grad += (dxdq[iq] * (rot.dQ0_2[ia])[iq]); } } - - if (cvm::debug()) { - - std::vector pos_test (atoms.positions_shifted (-1.0 * atoms_cog)); - - for (size_t comp = 0; comp < 3; comp++) { - - // correct this cartesian component for the "new" center of geometry - for (size_t ia = 0; ia < atoms.size(); ia++) { - pos_test[ia][comp] -= - cvm::debug_gradients_step_size / cvm::real (atoms.size()); - } - - for (size_t ia = 0; ia < atoms.size(); ia++) { - - pos_test[ia][comp] += cvm::debug_gradients_step_size; - rot.calc_optimal_rotation (ref_pos, pos_test); - pos_test[ia][comp] -= cvm::debug_gradients_step_size; - - cvm::log ("|dx(real) - dx(pred)|/dx(real) = "+ - cvm::to_str (std::fabs (rot.cos_theta (axis) - x.real_value - - cvm::debug_gradients_step_size * atoms[ia].grad[comp]) / - std::fabs (rot.cos_theta (axis) - x.real_value), - cvm::cv_width, cvm::cv_prec)+".\n"); - } - - for (size_t ia = 0; ia < atoms.size(); ia++) { - pos_test[ia][comp] += - cvm::debug_gradients_step_size / cvm::real (atoms.size()); - } - } - } } @@ -326,38 +293,6 @@ void colvar::spin_angle::calc_gradients() atoms[ia].grad += (dxdq[iq] * (rot.dQ0_2[ia])[iq]); } } - - if (cvm::debug()) { - - std::vector pos_test (atoms.positions_shifted (-1.0 * atoms_cog)); - - for (size_t comp = 0; comp < 3; comp++) { - - // correct this cartesian component for the "new" center of geometry - for (size_t ia = 0; ia < atoms.size(); ia++) { - pos_test[ia][comp] -= - cvm::debug_gradients_step_size / cvm::real (atoms.size()); - } - - for (size_t ia = 0; ia < atoms.size(); ia++) { - - pos_test[ia][comp] += cvm::debug_gradients_step_size; - rot.calc_optimal_rotation (ref_pos, pos_test); - pos_test[ia][comp] -= cvm::debug_gradients_step_size; - - cvm::log ("|dx(real) - dx(pred)|/dx(real) = "+ - cvm::to_str (std::fabs (rot.spin_angle (axis) - x.real_value - - cvm::debug_gradients_step_size * atoms[ia].grad[comp]) / - std::fabs (rot.spin_angle (axis) - x.real_value), - cvm::cv_width, cvm::cv_prec)+".\n"); - } - - for (size_t ia = 0; ia < atoms.size(); ia++) { - pos_test[ia][comp] += - cvm::debug_gradients_step_size / cvm::real (atoms.size()); - } - } - } } diff --git a/lib/colvars/colvarmodule.cpp b/lib/colvars/colvarmodule.cpp index 5d1bc92499..d45f0cef2c 100644 --- a/lib/colvars/colvarmodule.cpp +++ b/lib/colvars/colvarmodule.cpp @@ -46,9 +46,8 @@ colvarmodule::colvarmodule (char const *config_filename, parse->get_keyval (conf, "analysis", b_analysis, false); - if (cvm::debug()) - parse->get_keyval (conf, "debugGradientsStepSize", debug_gradients_step_size, 1.0e-03, - colvarparse::parse_silent); + parse->get_keyval (conf, "debugGradientsStepSize", debug_gradients_step_size, 1.0e-03, + colvarparse::parse_silent); parse->get_keyval (conf, "eigenvalueCrossingThreshold", colvarmodule::rotation::crossing_threshold, 1.0e-04, diff --git a/lib/colvars/colvarmodule.h b/lib/colvars/colvarmodule.h index 11bc94905a..2dfc1bd2ac 100644 --- a/lib/colvars/colvarmodule.h +++ b/lib/colvars/colvarmodule.h @@ -2,7 +2,7 @@ #define COLVARMODULE_H #ifndef COLVARS_VERSION -#define COLVARS_VERSION "2012-06-20" +#define COLVARS_VERSION "2012-08-08" #endif #ifndef COLVARS_DEBUG diff --git a/lib/colvars/colvartypes.h b/lib/colvars/colvartypes.h index 090be30d7f..fa18310ac4 100644 --- a/lib/colvars/colvartypes.h +++ b/lib/colvars/colvartypes.h @@ -810,21 +810,8 @@ public: /// associated to this quaternion and another inline cvm::real cosine (cvm::quaternion const &q) const { - if (q0*q0 >= (1.0-1.0E-10)) { - // null quaternion, return the square of the cosine of the other - // quaternion's rotation angle - return (2.0*q.q0*q.q0 - 1.0); - } else if (q.q0*q.q0 >= (1.0-1.0E-10)) { - return (2.0*q0*q0 - 1.0); - } else { - // get a vector orthogonal to both axes of rotation - cvm::rvector const op = (cvm::rvector::outer (this->get_vector(), q.get_vector())); - cvm::real const opl2 = op.norm2(); - // rotate it with both quaternions and get the normalized inner product - return ( (opl2 > 0.0) ? - ((this->rotate (op)) * (q.rotate (op))) / opl2 : - 1.0 ); - } + cvm::real const iprod = this->inner (q); + return 2.0*iprod*iprod - 1.0; } /// \brief Square distance from another quaternion on the