forked from lijiext/lammps
git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@9785 f3b2605a-c512-4ea7-a41b-209d697bcdaa
This commit is contained in:
parent
313bbf774b
commit
f1c64db6a9
|
@ -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;
|
||||
|
|
|
@ -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]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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 \""+
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue