git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@9785 f3b2605a-c512-4ea7-a41b-209d697bcdaa

This commit is contained in:
sjplimp 2013-04-23 19:03:56 +00:00
parent 313bbf774b
commit f1c64db6a9
9 changed files with 165 additions and 265 deletions

View File

@ -1291,7 +1291,7 @@ std::ostream & colvar::write_traj_label (std::ostream & os)
if (tasks[task_output_system_force]) {
os << " fs_"
<< cvm::wrap_string (this->name, this_cv_width-2);
<< cvm::wrap_string (this->name, this_cv_width-3);
if (tasks[task_extended_lagrangian]) {
// restraint center
@ -1302,7 +1302,7 @@ std::ostream & colvar::write_traj_label (std::ostream & os)
if (tasks[task_output_applied_force]) {
os << " fa_"
<< cvm::wrap_string (this->name, this_cv_width-2);
<< cvm::wrap_string (this->name, this_cv_width-3);
}
return os;

View File

@ -105,9 +105,19 @@ void cvm::atom_group::parse (std::string const &conf,
colvarparse::Parse_Mode mode = parse_normal;
{
// get the atoms by numbers
// std::vector<int> atom_indexes;
std::string numbers_conf = "";
size_t pos = 0;
std::vector<int> atom_indexes;
if (get_keyval (group_conf, "atomNumbers", atom_indexes, atom_indexes, mode)) {
while (key_lookup (group_conf, "atomNumbers", numbers_conf, pos)) {
if (numbers_conf.size()) {
std::istringstream is (numbers_conf);
int ia;
while (is >> ia) {
atom_indexes.push_back (ia);
}
}
if (atom_indexes.size()) {
this->reserve (this->size()+atom_indexes.size());
for (size_t i = 0; i < atom_indexes.size(); i++) {
@ -116,6 +126,8 @@ void cvm::atom_group::parse (std::string const &conf,
} else
cvm::fatal_error ("Error: no numbers provided for \""
"atomNumbers\".\n");
atom_indexes.clear();
}
}
@ -264,30 +276,33 @@ void cvm::atom_group::parse (std::string const &conf,
}
}
if (!b_dummy)
get_keyval (group_conf, "disableForces", noforce, false, mode);
if (!b_dummy) {
bool enable_forces = true;
// disableForces is deprecated
if (get_keyval (group_conf, "enableForces", enable_forces, true, mode)) {
noforce = !enable_forces;
} else {
get_keyval (group_conf, "disableForces", noforce, false, mode);
}
}
// FITTING OPTIONS
bool b_defined_center = get_keyval (group_conf, "centerReference", b_center, false, mode);
bool b_defined_rotate = get_keyval (group_conf, "rotateReference", b_rotate, false, mode);
b_fit_gradients = get_keyval (group_conf, "fitGradients", b_fit_gradients, false, mode);
// this cannot be shortened to one statement because lazy evaluation may prevent one
// function from being called!
// is the user setting explicit options?
b_user_defined_fit = b_defined_center || b_defined_rotate;
// if ((b_center || b_rotate) && b_dummy)
// cvm::fatal_error ("Error: cannot set \"centerReference\" or "
// "\"rotateReference\" when \"dummyAtom\" is defined.\n");
get_keyval (group_conf, "enableFitGradients", b_fit_gradients, true, mode);
if (b_center || b_rotate) {
if (b_dummy)
cvm::fatal_error ("Error: centerReference or rotateReference "
"cannot be defined for a dummy atom.\n");
if (key_lookup (group_conf, "refPositionsGroup")) {
// instead of this group, define another group (refPositionsGroup)
// to be the one used to fit the coordinates
// instead of this group, define another group to compute the fit
if (ref_pos_group) {
cvm::fatal_error ("Error: the atom group \""+
std::string (key)+"\" has already a reference group "
@ -323,7 +338,9 @@ void cvm::atom_group::parse (std::string const &conf,
} else {
// if not, rely on existing atom indices for the group
group_for_fit->create_sorted_ids();
ref_pos.resize (group_for_fit->size());
}
cvm::load_coords (ref_pos_file.c_str(), ref_pos, group_for_fit->sorted_ids,
ref_pos_col, ref_pos_col_value);
}
@ -341,7 +358,6 @@ void cvm::atom_group::parse (std::string const &conf,
"these numbers should be equal.\n");
}
// save the center of geometry of ref_pos and subtract it
center_ref_pos();
@ -376,7 +392,7 @@ void cvm::atom_group::parse (std::string const &conf,
this->check_keywords (group_conf, key);
cvm::log ("Atom group \""+std::string (key)+"\" defined, "+
cvm::to_str (this->size())+" initialized: total mass = "+
cvm::to_str (this->size())+" atoms initialized: total mass = "+
cvm::to_str (this->total_mass)+".\n");
cvm::decrease_depth();
@ -577,6 +593,8 @@ void cvm::atom_group::calc_fit_gradients()
{
if (b_dummy) return;
if ((!b_center) && (!b_rotate)) return; // no fit
if (cvm::debug())
cvm::log ("Calculating fit gradients.\n");
@ -705,7 +723,7 @@ void cvm::atom_group::apply_colvar_force (cvm::real const &force)
if (noforce)
cvm::fatal_error ("Error: sending a force to a group that has "
"\"disableForces\" defined.\n");
"\"enableForces\" set to off.\n");
if (b_rotate) {
@ -724,7 +742,7 @@ void cvm::atom_group::apply_colvar_force (cvm::real const &force)
}
}
if (b_fit_gradients) {
if ((b_center || b_rotate) && b_fit_gradients) {
atom_group *group_for_fit = ref_pos_group ? ref_pos_group : this;
@ -733,11 +751,11 @@ void cvm::atom_group::apply_colvar_force (cvm::real const &force)
// rotate forces back to the original frame
cvm::rotation const rot_inv = rot.inverse();
for (size_t j = 0; j < group_for_fit->size(); j++) {
(*group_for_fit)[j].apply_force (rot_inv.rotate (force * fit_gradients[j]));
(*group_for_fit)[j].apply_force (rot_inv.rotate (force * group_for_fit->fit_gradients[j]));
}
} else {
for (size_t j = 0; j < group_for_fit->size(); j++) {
(*group_for_fit)[j].apply_force (force * fit_gradients[j]);
(*group_for_fit)[j].apply_force (force * group_for_fit->fit_gradients[j]);
}
}
}

View File

@ -159,7 +159,7 @@ colvarbias_harmonic::colvarbias_harmonic (std::string const &conf,
if (target_nstages) {
// This means that either numStages of lambdaSchedule has been provided
stage = -1;
stage = 0;
restraint_FE = 0.0;
}
@ -201,7 +201,7 @@ void colvarbias_harmonic::change_configuration(std::string const &conf)
}
cvm::real colvarbias_harmonic::energy_difference(std::string const &conf)
cvm::real colvarbias_harmonic::energy_difference (std::string const &conf)
{
std::vector<colvarvalue> alt_colvar_centers;
cvm::real alt_force_k;
@ -221,7 +221,7 @@ cvm::real colvarbias_harmonic::energy_difference(std::string const &conf)
for (size_t i = 0; i < colvars.size(); i++) {
alt_bias_energy += 0.5 * alt_force_k / (colvars[i]->width * colvars[i]->width) *
colvars[i]->dist2(colvars[i]->value(), alt_colvar_centers[i]);
colvars[i]->dist2 (colvars[i]->value(), alt_colvar_centers[i]);
}
return alt_bias_energy - bias_energy;
@ -236,8 +236,7 @@ cvm::real colvarbias_harmonic::update()
cvm::log ("Updating the harmonic bias \""+this->name+"\".\n");
// Setup first stage of staged variable force constant calculation
if (b_chg_force_k && target_nstages && stage == -1) {
stage = 0;
if (b_chg_force_k && target_nstages && cvm::step_absolute() == 0) {
cvm::real lambda;
if (lambda_schedule.size()) {
lambda = lambda_schedule[0];
@ -250,25 +249,6 @@ cvm::real colvarbias_harmonic::update()
cvm::to_str(stage) + " : lambda = " + cvm::to_str(lambda));
cvm::log ("Setting force constant to " + cvm::to_str (force_k));
}
// Force and energy calculation
for (size_t i = 0; i < colvars.size(); i++) {
colvar_forces[i] =
(-0.5) * force_k /
(colvars[i]->width * colvars[i]->width) *
colvars[i]->dist2_lgrad (colvars[i]->value(),
colvar_centers[i]);
bias_energy += 0.5 * force_k / (colvars[i]->width * colvars[i]->width) *
colvars[i]->dist2(colvars[i]->value(), colvar_centers[i]);
if (cvm::debug())
cvm::log ("dist_grad["+cvm::to_str (i)+
"] = "+cvm::to_str (colvars[i]->dist2_lgrad (colvars[i]->value(),
colvar_centers[i]))+"\n");
}
if (cvm::debug())
cvm::log ("Current forces for the harmonic bias \""+
this->name+"\": "+cvm::to_str (colvar_forces)+".\n");
if (b_chg_centers) {
@ -280,26 +260,21 @@ cvm::real colvarbias_harmonic::update()
centers_incr.resize (colvars.size());
for (size_t i = 0; i < colvars.size(); i++) {
centers_incr[i].type (colvars[i]->type());
centers_incr[i] = (target_centers[i] - colvar_centers[i]) /
centers_incr[i] = (target_centers[i] - colvar_centers_raw[i]) /
cvm::real ( target_nstages ? (target_nstages - stage) :
(target_nsteps - cvm::step_absolute()));
}
if (cvm::debug())
cvm::log ("Center increment for the harmonic bias \""+
this->name+"\": "+cvm::to_str (centers_incr)+".\n");
this->name+"\": "+cvm::to_str (centers_incr)+" at stage "+cvm::to_str (stage)+ ".\n");
}
if (cvm::debug())
cvm::log ("Current centers for the harmonic bias \""+
this->name+"\": "+cvm::to_str (colvar_centers)+".\n");
if (target_nstages) {
if (cvm::step_absolute() > 0
if ((cvm::step_relative() > 0)
&& (cvm::step_absolute() % target_nsteps) == 0
&& stage < target_nstages) {
// any per-stage calculation, e.g. free energy stuff
// should be done here
for (size_t i = 0; i < colvars.size(); i++) {
colvar_centers_raw[i] += centers_incr[i];
colvar_centers[i] = colvar_centers_raw[i];
@ -308,9 +283,10 @@ cvm::real colvarbias_harmonic::update()
}
stage++;
cvm::log ("Moving restraint stage " + cvm::to_str(stage) +
" : setting centers to " + cvm::to_str (colvar_centers));
" : setting centers to " + cvm::to_str (colvar_centers) +
" at step " + cvm::to_str (cvm::step_absolute()));
}
} else if (cvm::step_absolute() < target_nsteps) {
} else if ((cvm::step_relative() > 0) && (cvm::step_absolute() <= target_nsteps)) {
// move the restraint centers in the direction of the targets
// (slow growth)
for (size_t i = 0; i < colvars.size(); i++) {
@ -320,6 +296,10 @@ cvm::real colvarbias_harmonic::update()
colvar_centers[i].apply_constraints();
}
}
if (cvm::debug())
cvm::log ("Current centers for the harmonic bias \""+
this->name+"\": "+cvm::to_str (colvar_centers)+".\n");
}
if (b_chg_force_k) {
@ -383,6 +363,26 @@ cvm::real colvarbias_harmonic::update()
if (cvm::debug())
cvm::log ("Done updating the harmonic bias \""+this->name+"\".\n");
// Force and energy calculation
for (size_t i = 0; i < colvars.size(); i++) {
colvar_forces[i] =
(-0.5) * force_k /
(colvars[i]->width * colvars[i]->width) *
colvars[i]->dist2_lgrad (colvars[i]->value(),
colvar_centers[i]);
bias_energy += 0.5 * force_k / (colvars[i]->width * colvars[i]->width) *
colvars[i]->dist2(colvars[i]->value(), colvar_centers[i]);
if (cvm::debug())
cvm::log ("dist_grad["+cvm::to_str (i)+
"] = "+cvm::to_str (colvars[i]->dist2_lgrad (colvars[i]->value(),
colvar_centers[i]))+"\n");
}
if (cvm::debug())
cvm::log ("Current forces for the harmonic bias \""+
this->name+"\": "+cvm::to_str (colvar_forces)+".\n");
return bias_energy;
}
@ -423,7 +423,7 @@ std::istream & colvarbias_harmonic::read_restart (std::istream &is)
}
if (b_chg_centers) {
cvm::log ("Reading the updated restraint centers from the restart.\n");
// cvm::log ("Reading the updated restraint centers from the restart.\n");
if (!get_keyval (conf, "centers", colvar_centers))
cvm::fatal_error ("Error: restraint centers are missing from the restart.\n");
if (!get_keyval (conf, "centers_raw", colvar_centers_raw))
@ -431,13 +431,13 @@ std::istream & colvarbias_harmonic::read_restart (std::istream &is)
}
if (b_chg_force_k) {
cvm::log ("Reading the updated force constant from the restart.\n");
// cvm::log ("Reading the updated force constant from the restart.\n");
if (!get_keyval (conf, "forceConstant", force_k))
cvm::fatal_error ("Error: force constant is missing from the restart.\n");
}
if (target_nstages) {
cvm::log ("Reading current stage from the restart.\n");
// cvm::log ("Reading current stage from the restart.\n");
if (!get_keyval (conf, "stage", stage))
cvm::fatal_error ("Error: current stage is missing from the restart.\n");
}

View File

@ -93,21 +93,22 @@ void colvar::cvc::debug_gradients (cvm::atom_group &group)
// it only makes sense to debug the fit gradients
// when the fitting group is the same as this group
if (group.b_fit_gradients && (group.ref_pos_group == NULL)) {
group.calc_fit_gradients();
if (group.b_rotate) {
// fit_gradients are in the original frame, we should print them in the rotated frame
for (size_t j = 0; j < group.fit_gradients.size(); j++) {
group.fit_gradients[j] = rot_0.rotate (group.fit_gradients[j]);
if (group.b_rotate || group.b_center)
if (group.b_fit_gradients && (group.ref_pos_group == NULL)) {
group.calc_fit_gradients();
if (group.b_rotate) {
// fit_gradients are in the original frame, we should print them in the rotated frame
for (size_t j = 0; j < group.fit_gradients.size(); j++) {
group.fit_gradients[j] = rot_0.rotate (group.fit_gradients[j]);
}
}
cvm::log ("fit_gradients = "+cvm::to_str (group.fit_gradients)+"\n");
if (group.b_rotate) {
for (size_t j = 0; j < group.fit_gradients.size(); j++) {
group.fit_gradients[j] = rot_inv.rotate (group.fit_gradients[j]);
}
}
}
cvm::log ("fit_gradients = "+cvm::to_str (group.fit_gradients)+"\n");
if (group.b_rotate) {
for (size_t j = 0; j < group.fit_gradients.size(); j++) {
group.fit_gradients[j] = rot_inv.rotate (group.fit_gradients[j]);
}
}
}
for (size_t ia = 0; ia < group.size(); ia++) {
@ -130,7 +131,7 @@ void colvar::cvc::debug_gradients (cvm::atom_group &group)
cvm::log ("Atom "+cvm::to_str (ia)+", component "+cvm::to_str (id)+":\n");
cvm::log ("dx(actual) = "+cvm::to_str (x_1 - x_0,
21, 14)+"\n");
cvm::real const dx_pred = (group.b_fit_gradients && (group.ref_pos_group == NULL)) ?
cvm::real const dx_pred = (group.fit_gradients.size() && (group.ref_pos_group == NULL)) ?
(cvm::debug_gradients_step_size * (atom_grad[id] + group.fit_gradients[ia][id])) :
(cvm::debug_gradients_step_size * atom_grad[id]);
cvm::log ("dx(interp) = "+cvm::to_str (dx_pred,

View File

@ -521,9 +521,6 @@ colvar::gyration::gyration (std::string const &conf)
if (atoms.b_user_defined_fit) {
cvm::log ("WARNING: explicit fitting parameters were provided for atom group \"atoms\".");
} else {
// default: fit everything
cvm::log ("No explicit fitting parameters: enabling centerReference by default to align with the origin\n");
cvm::log (" (rotateReference will not affect results for gyration and inertia, but it will for inertiaZ).\n");
atoms.b_center = true;
atoms.ref_pos.assign (1, cvm::rvector (0.0, 0.0, 0.0));
}
@ -613,7 +610,7 @@ void colvar::inertia::calc_value()
{
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 += (ai->pos).norm2();
}
}
@ -621,7 +618,7 @@ void colvar::inertia::calc_value()
void colvar::inertia::calc_gradients()
{
for (cvm::atom_iter ai = atoms.begin(); ai != atoms.end(); ai++) {
ai->grad = 2.0 * ai->mass * ai->pos;
ai->grad = 2.0 * ai->pos;
}
if (b_debug_gradients) {
@ -666,7 +663,7 @@ void colvar::inertia_z::calc_value()
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 += iprod * iprod;
}
}
@ -674,7 +671,7 @@ void colvar::inertia_z::calc_value()
void colvar::inertia_z::calc_gradients()
{
for (cvm::atom_iter ai = atoms.begin(); ai != atoms.end(); ai++) {
ai->grad = 2.0 * ai->mass * (ai->pos * axis) * axis;
ai->grad = 2.0 * (ai->pos * axis) * axis;
}
if (b_debug_gradients) {
@ -757,7 +754,8 @@ colvar::rmsd::rmsd (std::string const &conf)
cvm::log ("WARNING: explicit fitting parameters were provided for atom group \"atoms\".");
} else {
// Default: fit everything
cvm::log ("No explicit fitting parameters: enabling both centerReference and rotateReference to compute standard minimum RMSD.");
cvm::log ("Enabling \"centerReference\" and \"rotateReference\", to minimize RMSD before calculating it as a variable: "
"if this is not the desired behavior, disable them explicitly within the \"atoms\" block.\n");
atoms.b_center = true;
atoms.b_rotate = true;
// default case: reference positions for calculating the rmsd are also those used
@ -939,7 +937,8 @@ colvar::eigenvector::eigenvector (std::string const &conf)
cvm::log ("WARNING: explicit fitting parameters were provided for atom group \"atoms\".\n");
} else {
// default: fit everything
cvm::log ("Enabling centerReference and rotateReference (minimize RMSD before calculating the projection).\n");
cvm::log ("Enabling \"centerReference\" and \"rotateReference\", to minimize RMSD before calculating the vector projection: "
"if this is not the desired behavior, disable them explicitly within the \"atoms\" block.\n");
atoms.b_center = true;
atoms.b_rotate = true;
atoms.ref_pos = ref_pos;
@ -999,34 +998,32 @@ colvar::eigenvector::eigenvector (std::string const &conf)
eig_center *= 1.0 / atoms.size();
cvm::log ("Geometric center of the provided vector: "+cvm::to_str (eig_center)+"\n");
bool b_vector_difference;
get_keyval (conf, "vectorDifference", b_vector_difference, false);
if (b_vector_difference) {
bool b_difference_vector = false;
get_keyval (conf, "differenceVector", b_difference_vector, false);
cvm::log ("Subtracting the reference positions from the provided vector.\n");
if (b_difference_vector) {
if (atoms.b_center) {
cvm::log ("centerReference is on: recentering the provided vector to the reference positions.\n");
// both sets should be centered on the origin for fitting
for (size_t i = 0; i < atoms.size(); i++) {
eigenvec[i] -= eig_center;
ref_pos[i] -= ref_pos_center;
}
}
if (atoms.b_rotate) {
cvm::log ("rotateReference is on: aligning the provided vector to the reference positions.\n");
atoms.rot.calc_optimal_rotation (eigenvec, ref_pos);
for (size_t i = 0; i < atoms.size(); i++) {
eigenvec[i] = atoms.rot.rotate (eigenvec[i]);
eigenvec[i] -= ref_pos[i];
}
}
cvm::log ("\"differenceVector\" is on: subtracting the reference positions from the provided vector: v = v - x0.\n");
for (size_t i = 0; i < atoms.size(); i++) {
eigenvec[i] -= ref_pos[i];
}
if (atoms.b_center) {
// bring back the ref positions to where they were
for (size_t i = 0; i < atoms.size(); i++) {
ref_pos[i] -= ref_pos_center;
ref_pos[i] += ref_pos_center;
}
}
@ -1037,7 +1034,7 @@ colvar::eigenvector::eigenvector (std::string const &conf)
}
}
cvm::log ("The first three components (v1x, v1y, v1z) of the resulting vector are: "+cvm::to_str (eigenvec[0])+".\n");
// cvm::log ("The first three components (v1x, v1y, v1z) of the resulting vector are: "+cvm::to_str (eigenvec[0])+".\n");
// for inverse gradients
eigenvec_invnorm2 = 0.0;
@ -1045,6 +1042,15 @@ colvar::eigenvector::eigenvector (std::string const &conf)
eigenvec_invnorm2 += eigenvec[i].norm2();
}
eigenvec_invnorm2 = 1.0 / eigenvec_invnorm2;
if (b_difference_vector) {
cvm::log ("\"differenceVector\" is on: normalizing the vector.\n");
for (size_t i = 0; i < atoms.size(); i++) {
eigenvec[i] *= eigenvec_invnorm2;
}
} else {
cvm::log ("The norm of the vector is |v| = "+cvm::to_str (eigenvec_invnorm2)+".\n");
}
}
@ -1059,152 +1065,13 @@ void colvar::eigenvector::calc_value()
void colvar::eigenvector::calc_gradients()
{
// There are two versions of this code
// The simple version is not formally exact, but its
// results are numerically indistinguishable from the
// exact one. The exact one is more expensive and possibly
// less stable in cases where the optimal rotation
// becomes ill-defined.
// Version A: simple, intuitive, cheap, robust. Wrong.
// Works just fine in practice.
for (size_t ia = 0; ia < atoms.size(); ia++) {
atoms[ia].grad = eigenvec[ia];
}
std::vector<cvm::rvector> gradients (atoms.size());
for (size_t i = 0; i < atoms.size(); i++) {
gradients[i] = atoms[i].grad;
}
std::vector<cvm::rvector> gradients_jh_correct (atoms.size());
/*
// Version B: complex, expensive, fragile. Right.
// gradient of the rotation matrix
cvm::matrix2d <cvm::rvector, 3, 3> grad_rot_mat;
cvm::quaternion &quat0 = atoms.rot.q;
// gradients of products of 2 quaternion components
cvm::rvector g11, g22, g33, g01, g02, g03, g12, g13, g23;
// a term that involves the rotation gradients
cvm::rvector rot_grad_term;
cvm::atom_pos x_relative;
cvm::atom_pos atoms_cog = atoms.center_of_geometry();
for (size_t ia = 0; ia < atoms.size(); ia++) {
// Gradient of optimal quaternion wrt current Cartesian position
cvm::vector1d< cvm::rvector, 4 > &dq = atoms.rot.dQ0_1[ia];
g11 = 2.0 * quat0[1]*dq[1];
g22 = 2.0 * quat0[2]*dq[2];
g33 = 2.0 * quat0[3]*dq[3];
g01 = quat0[0]*dq[1] + quat0[1]*dq[0];
g02 = quat0[0]*dq[2] + quat0[2]*dq[0];
g03 = quat0[0]*dq[3] + quat0[3]*dq[0];
g12 = quat0[1]*dq[2] + quat0[2]*dq[1];
g13 = quat0[1]*dq[3] + quat0[3]*dq[1];
g23 = quat0[2]*dq[3] + quat0[3]*dq[2];
// Gradient of the rotation matrix wrt current Cartesian position
grad_rot_mat[0][0] = -2.0 * (g22 + g33);
grad_rot_mat[1][0] = 2.0 * (g12 + g03);
grad_rot_mat[2][0] = 2.0 * (g13 - g02);
grad_rot_mat[0][1] = 2.0 * (g12 - g03);
grad_rot_mat[1][1] = -2.0 * (g11 + g33);
grad_rot_mat[2][1] = 2.0 * (g01 + g23);
grad_rot_mat[0][2] = 2.0 * (g02 + g13);
grad_rot_mat[1][2] = 2.0 * (g23 - g01);
grad_rot_mat[2][2] = -2.0 * (g11 + g22);
// this term needs to be rotated back, so we sum it separately
rot_grad_term.reset();
for (size_t ja = 0; ja < atoms.size(); ja++) {
x_relative = atoms[ja].pos - atoms_cog;
for (size_t i = 0; i < 3; i++) {
for (size_t j = 0; j < 3; j++) {
rot_grad_term += eigenvec[ja][i] * grad_rot_mat[i][j] * x_relative[j];
}
}
}
// Rotate correction term back to reference frame
// atoms[ia].grad = eigenvec[ia] + quat0.rotate (rot_grad_term);
// atoms[ia].grad = eigenvec[ia] + quat0.rotate (rot_grad_term);
gradients_jh_correct[ia] = eigenvec[ia] + quat0.rotate (rot_grad_term);
}
*/
// TODO replace this with a call to debug_gradients()
if (b_debug_gradients) {
// the following code should work for any scalar variable;
// the only difference is the name of the atom group object (here, "atoms")
cvm::rotation const rot_0 = atoms.rot;
cvm::rotation const rot_inv = atoms.rot.inverse();
cvm::real const x_0 = x.real_value;
cvm::log ("gradients = "+cvm::to_str (gradients)+"\n");
/* cvm::log ("gradients(JH-correct) = "+cvm::to_str (gradients_jh_correct)+"\n"); */
if (atoms.b_fit_gradients) {
atoms.calc_fit_gradients();
if (atoms.b_rotate) {
// fit_gradients are in the original frame, output them in the rotated frame
for (size_t j = 0; j < atoms.fit_gradients.size(); j++) {
atoms.fit_gradients[j] = rot_0.rotate (atoms.fit_gradients[j]);
}
}
cvm::log ("fit_gradients = "+cvm::to_str (atoms.fit_gradients)+"\n");
if (atoms.b_rotate) {
for (size_t j = 0; j < atoms.fit_gradients.size(); j++) {
atoms.fit_gradients[j] = rot_inv.rotate (atoms.fit_gradients[j]);
}
}
}
for (size_t ia = 0; ia < atoms.size(); ia++) {
// tests are best conducted in the unrotated (simulation) frame
cvm::rvector const atom_grad = atoms.b_rotate ?
rot_inv.rotate (atoms[ia].grad) :
atoms[ia].grad;
for (size_t id = 0; id < 3; id++) {
// (re)read original positions
atoms.read_positions();
// change one coordinate
atoms[ia].pos[id] += cvm::debug_gradients_step_size;
// (re)do the fit (if defined)
if (atoms.b_center || atoms.b_rotate) {
atoms.calc_apply_roto_translation();
}
calc_value();
cvm::real const x_1 = x.real_value;
cvm::log ("Atom "+cvm::to_str (ia)+", component "+cvm::to_str (id)+":\n");
cvm::log ("dx(real) = "+cvm::to_str (x_1 - x_0)+"\n");
cvm::real const dx_pred = atoms.b_fit_gradients ?
(cvm::debug_gradients_step_size * (atom_grad[id] + atoms.fit_gradients[ia][id])) :
(cvm::debug_gradients_step_size * atom_grad[id]);
cvm::log ("dx(pred) = "+cvm::to_str (dx_pred)+"\n");
cvm::log ("|dx(real) - dx(pred)|/dx(real) = "+
cvm::to_str (std::fabs (x_1 - x_0 - dx_pred) /
std::fabs (x_1 - x_0),
cvm::cv_width, cvm::cv_prec)+
".\n");
}
}
cvm::log ("Debugging gradients:\n");
debug_gradients (atoms);
}
}

View File

@ -85,8 +85,8 @@ colvar::orientation::orientation()
void colvar::orientation::calc_value()
{
atoms.reset_atoms_data();
atoms.read_positions();
// atoms.reset_atoms_data();
// atoms.read_positions();
atoms_cog = atoms.center_of_geometry();
@ -142,8 +142,8 @@ colvar::orientation_angle::orientation_angle()
void colvar::orientation_angle::calc_value()
{
atoms.reset_atoms_data();
atoms.read_positions();
// atoms.reset_atoms_data();
// atoms.read_positions();
atoms_cog = atoms.center_of_geometry();
@ -206,8 +206,8 @@ colvar::tilt::tilt()
void colvar::tilt::calc_value()
{
atoms.reset_atoms_data();
atoms.read_positions();
// atoms.reset_atoms_data();
// atoms.read_positions();
atoms_cog = atoms.center_of_geometry();
@ -227,6 +227,11 @@ void colvar::tilt::calc_gradients()
atoms[ia].grad += (dxdq[iq] * (rot.dQ0_2[ia])[iq]);
}
}
if (b_debug_gradients) {
cvm::log ("Debugging tilt component gradients:\n");
debug_gradients (atoms);
}
}
@ -271,8 +276,8 @@ colvar::spin_angle::spin_angle()
void colvar::spin_angle::calc_value()
{
atoms.reset_atoms_data();
atoms.read_positions();
// atoms.reset_atoms_data();
// atoms.read_positions();
atoms_cog = atoms.center_of_geometry();

View File

@ -297,26 +297,26 @@ void colvarmodule::init_biases (std::string const &conf)
}
void colvarmodule::change_configuration(
std::string const &name, std::string const &conf)
void colvarmodule::change_configuration (std::string const &bias_name,
std::string const &conf)
{
cvm::increase_depth();
int found = 0;
for (std::vector<colvarbias *>::iterator bi = biases.begin();
bi != biases.end();
bi++) {
if ( (*bi)->name == name ) {
if ( (*bi)->name == bias_name ) {
++found;
(*bi)->change_configuration(conf);
(*bi)->change_configuration (conf);
}
}
if ( found < 1 ) cvm::fatal_error ("Error: bias not found");
if ( found > 1 ) cvm::fatal_error ("Error: duplicate bias name");
if (found < 1) cvm::fatal_error ("Error: bias not found.\n");
if (found > 1) cvm::fatal_error ("Error: duplicate bias name.\n");
cvm::decrease_depth();
}
cvm::real colvarmodule::energy_difference(
std::string const &name, std::string const &conf)
cvm::real colvarmodule::energy_difference (std::string const &bias_name,
std::string const &conf)
{
cvm::increase_depth();
cvm::real energy_diff = 0.;
@ -324,13 +324,13 @@ cvm::real colvarmodule::energy_difference(
for (std::vector<colvarbias *>::iterator bi = biases.begin();
bi != biases.end();
bi++) {
if ( (*bi)->name == name ) {
if ( (*bi)->name == bias_name ) {
++found;
energy_diff = (*bi)->energy_difference(conf);
energy_diff = (*bi)->energy_difference (conf);
}
}
if ( found < 1 ) cvm::fatal_error ("Error: bias not found");
if ( found > 1 ) cvm::fatal_error ("Error: duplicate bias name");
if (found < 1) cvm::fatal_error ("Error: bias not found.\n");
if (found > 1) cvm::fatal_error ("Error: duplicate bias name.\n");
cvm::decrease_depth();
return energy_diff;
}
@ -431,7 +431,7 @@ void colvarmodule::calc() {
cvm::decrease_depth();
// write restart file, if needed
if (restart_out_freq && !cvm::b_analysis) {
if (restart_out_freq && restart_out_name.size() && !cvm::b_analysis) {
if ( (cvm::step_relative() > 0) &&
((cvm::step_absolute() % restart_out_freq) == 0) ) {
cvm::log ("Writing the state file \""+

View File

@ -2,7 +2,7 @@
#define COLVARMODULE_H
#ifndef COLVARS_VERSION
#define COLVARS_VERSION "2013-01-23"
#define COLVARS_VERSION "2013-04-17"
#endif
#ifndef COLVARS_DEBUG
@ -168,11 +168,13 @@ public:
/// Initialize collective variable biases
void init_biases (std::string const &conf);
/// Load new configuration - force constant and/or centers only
void change_configuration(std::string const &name, std::string const &conf);
/// Load new configuration for the given bias -
/// currently works for harmonic (force constant and/or centers)
void change_configuration (std::string const &bias_name, std::string const &conf);
/// Calculate change in energy from using alternate configuration
real energy_difference(std::string const &name, std::string const &conf);
/// Calculate change in energy from using alt. config. for the given bias -
/// currently works for harmonic (force constant and/or centers)
real energy_difference (std::string const &bias_name, std::string const &conf);
/// Calculate collective variables and biases
void calc();

View File

@ -102,12 +102,19 @@ size_t colvarparse::dummy_pos = 0;
\
if (data.size()) { \
std::istringstream is (data); \
size_t data_count = 0; \
TYPE x (def_value); \
if (is >> x) \
while (is >> x) { \
value = x; \
else \
data_count++; \
} \
if (data_count == 0) \
cvm::fatal_error ("Error: in parsing \""+ \
std::string (key)+"\".\n"); \
if (data_count > 1) \
cvm::fatal_error ("Error: multiple values " \
"are not allowed for keyword \""+ \
std::string (key)+"\".\n"); \
if (parse_mode != parse_silent) { \
cvm::log ("# "+std::string (key)+" = "+ \
cvm::to_str (value)+"\n"); \
@ -533,7 +540,7 @@ bool colvarparse::key_lookup (std::string const &conf,
if (line[brace] == '}') brace_count--;
}
// set data_begin afterthe opening brace
// set data_begin after the opening brace
data_begin = line.find_first_of ('{', data_begin) + 1;
data_begin = line.find_first_not_of (white_space,
data_begin);