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

This commit is contained in:
sjplimp
2016-03-01 20:40:25 +00:00
parent 6e2893c768
commit 20beaccf0f
16 changed files with 1675 additions and 716 deletions

View File

@ -112,22 +112,23 @@ colvar::colvar(std::string const &conf)
initialize_components("distance vector", "distanceVec", distance_vec);
initialize_components("Cartesian coordinates", "cartesian", cartesian);
initialize_components("distance vector "
"direction", "distanceDir", distance_dir);
"direction", "distanceDir", distance_dir);
initialize_components("distance projection "
"on an axis", "distanceZ", distance_z);
"on an axis", "distanceZ", distance_z);
initialize_components("distance projection "
"on a plane", "distanceXY", distance_xy);
"on a plane", "distanceXY", distance_xy);
initialize_components("average distance weighted by inverse power",
"distanceInv", distance_inv);
"distanceInv", distance_inv);
initialize_components("N1xN2-long vector of pairwise distances",
"distancePairs", distance_pairs);
"distancePairs", distance_pairs);
initialize_components("coordination "
"number", "coordNum", coordnum);
"number", "coordNum", coordnum);
initialize_components("self-coordination "
"number", "selfCoordNum", selfcoordnum);
"number", "selfCoordNum", selfcoordnum);
initialize_components("angle", "angle", angle);
initialize_components("dipole angle", "dipoleAngle", dipole_angle);
initialize_components("dihedral", "dihedral", dihedral);
initialize_components("hydrogen bond", "hBond", h_bond);
@ -136,13 +137,13 @@ colvar::colvar(std::string const &conf)
initialize_components("alpha helix", "alpha", alpha_angles);
initialize_components("dihedral principal "
"component", "dihedralPC", dihedPC);
"component", "dihedralPC", dihedPC);
initialize_components("orientation", "orientation", orientation);
initialize_components("orientation "
"angle", "orientationAngle",orientation_angle);
"angle", "orientationAngle",orientation_angle);
initialize_components("orientation "
"projection", "orientationProj",orientation_proj);
"projection", "orientationProj",orientation_proj);
initialize_components("tilt", "tilt", tilt);
initialize_components("spin angle", "spinAngle", spin_angle);
@ -151,17 +152,17 @@ colvar::colvar(std::string const &conf)
// initialize_components ("logarithm of MSD", "logmsd", logmsd);
initialize_components("radius of "
"gyration", "gyration", gyration);
"gyration", "gyration", gyration);
initialize_components("moment of "
"inertia", "inertia", inertia);
"inertia", "inertia", inertia);
initialize_components("moment of inertia around an axis",
"inertiaZ", inertia_z);
"inertiaZ", inertia_z);
initialize_components("eigenvector", "eigenvector", eigenvector);
if (!cvcs.size()) {
cvm::error("Error: no valid components were provided "
"for this collective variable.\n",
INPUT_ERROR);
"for this collective variable.\n",
INPUT_ERROR);
return;
}
@ -520,7 +521,8 @@ void colvar::build_atom_list(void)
for (size_t i = 0; i < cvcs.size(); i++) {
for (size_t j = 0; j < cvcs[i]->atom_groups.size(); j++) {
for (size_t k = 0; k < cvcs[i]->atom_groups[j]->size(); k++) {
temp_id_list.push_back(cvcs[i]->atom_groups[j]->at(k).id);
cvm::atom_group &ag = *(cvcs[i]->atom_groups[j]);
temp_id_list.push_back(ag[k].id);
}
}
}
@ -830,8 +832,9 @@ void colvar::setup() {
for (size_t i = 0; i < cvcs.size(); i++) {
for (size_t ig = 0; ig < cvcs[i]->atom_groups.size(); ig++) {
cvm::atom_group &atoms = *(cvcs[i]->atom_groups[ig]);
atoms.read_positions();
atoms.setup();
atoms.reset_mass(name,i,ig);
atoms.read_positions();
}
}
}
@ -861,37 +864,40 @@ colvar::~colvar()
void colvar::calc()
{
size_t i, ig;
if (cvm::debug())
cvm::log("Calculating colvar \""+this->name+"\".\n");
update_cvc_flags();
calc_cvcs();
calc_colvar_properties();
}
int colvar::calc_cvcs(int first_cvc, size_t num_cvcs)
{
size_t i, ig;
size_t cvc_count;
size_t const cvc_max_count = num_cvcs ? num_cvcs : num_active_cvcs();
// prepare atom groups for calculation
if (cvm::debug())
cvm::log("Collecting data from atom groups.\n");
// Update the enabled/disabled status of cvcs if necessary
if (cvc_flags.size()) {
bool any = false;
for (i = 0; i < cvcs.size(); i++) {
cvcs[i]->b_enabled = cvc_flags[i];
any = any || cvc_flags[i];
}
if (!any) {
cvm::error("ERROR: All CVCs are disabled for colvar " + this->name +"\n");
return;
}
cvc_flags.resize(0);
if (first_cvc >= cvcs.size()) {
cvm::error("Error: trying to address a component outside the "
"range defined for colvar \""+name+"\".\n", BUG_ERROR);
return BUG_ERROR;
}
for (i = 0; i < cvcs.size(); i++) {
for (i = first_cvc, cvc_count = 0;
(i < cvcs.size()) && (cvc_count < cvc_max_count);
i++) {
if (!cvcs[i]->b_enabled) continue;
cvc_count++;
for (ig = 0; ig < cvcs[i]->atom_groups.size(); ig++) {
cvm::atom_group &atoms = *(cvcs[i]->atom_groups[ig]);
atoms.reset_atoms_data();
atoms.read_positions();
if (atoms.b_center || atoms.b_rotate) {
atoms.calc_apply_roto_translation();
}
atoms.calc_required_properties();
// each atom group will take care of its own ref_pos_group, if defined
}
}
@ -906,7 +912,11 @@ void colvar::calc()
// }
if (tasks[task_system_force]) {
for (i = 0; i < cvcs.size(); i++) {
for (i = first_cvc, cvc_count = 0;
(i < cvcs.size()) && (cvc_count < cvc_max_count);
i++) {
if (!cvcs[i]->b_enabled) continue;
cvc_count++;
for (ig = 0; ig < cvcs[i]->atom_groups.size(); ig++) {
cvcs[i]->atom_groups[ig]->read_system_forces();
}
@ -919,9 +929,12 @@ void colvar::calc()
cvm::log("Calculating colvar components.\n");
x.reset();
// First, update component values
for (i = 0; i < cvcs.size(); i++) {
// First, calculate component values
for (i = first_cvc, cvc_count = 0;
(i < cvcs.size()) && (cvc_count < cvc_max_count);
i++) {
if (!cvcs[i]->b_enabled) continue;
cvc_count++;
cvm::increase_depth();
(cvcs[i])->calc_value();
cvm::decrease_depth();
@ -932,22 +945,25 @@ void colvar::calc()
cvm::cv_width, cvm::cv_prec)+".\n");
}
// Then combine them appropriately
// Then combine them appropriately, using either a scripted function or a polynomial
if (tasks[task_scripted]) {
// cvcs combined by user script
int res = cvm::proxy->run_colvar_callback(scripted_function, sorted_cvc_values, x);
if (res == COLVARS_NOT_IMPLEMENTED) {
cvm::error("Scripted colvars are not implemented.");
return;
return COLVARS_NOT_IMPLEMENTED;
}
if (res != COLVARS_OK) {
cvm::error("Error running scripted colvar");
return;
return COLVARS_OK;
}
} else if (x.type() == colvarvalue::type_scalar) {
// polynomial combination allowed
for (i = 0; i < cvcs.size(); i++) {
for (i = first_cvc, cvc_count = 0;
(i < cvcs.size()) && (cvc_count < cvc_max_count);
i++) {
if (!cvcs[i]->b_enabled) continue;
cvc_count++;
x += (cvcs[i])->sup_coeff *
( ((cvcs[i])->sup_np != 1) ?
std::pow((cvcs[i])->value().real_value, (cvcs[i])->sup_np) :
@ -955,8 +971,11 @@ void colvar::calc()
}
} else {
// only linear combination allowed
for (i = 0; i < cvcs.size(); i++) {
for (i = first_cvc, cvc_count = 0;
(i < cvcs.size()) && (cvc_count < cvc_max_count);
i++) {
if (!cvcs[i]->b_enabled) continue;
cvc_count++;
x += (cvcs[i])->sup_coeff * (cvcs[i])->value();
}
}
@ -970,9 +989,12 @@ void colvar::calc()
if (cvm::debug())
cvm::log("Calculating gradients of colvar \""+this->name+"\".\n");
for (i = 0; i < cvcs.size(); i++) {
// calculate the gradients of each component
// calculate the gradients of each component
for (i = first_cvc, cvc_count = 0;
(i < cvcs.size()) && (cvc_count < cvc_max_count);
i++) {
if (!cvcs[i]->b_enabled) continue;
cvc_count++;
cvm::increase_depth();
(cvcs[i])->calc_gradients();
// if requested, propagate (via chain rule) the gradients above
@ -991,40 +1013,44 @@ void colvar::calc()
if (tasks[task_scripted]) {
cvm::error("Collecting atomic gradients is not implemented for "
"scripted colvars.");
return;
"scripted colvars.", COLVARS_NOT_IMPLEMENTED);
return COLVARS_NOT_IMPLEMENTED;
}
// Collect the atomic gradients inside colvar object
for (unsigned int a = 0; a < atomic_gradients.size(); a++) {
atomic_gradients[a].reset();
}
for (i = 0; i < cvcs.size(); i++) {
for (i = first_cvc, cvc_count = 0;
(i < cvcs.size()) && (cvc_count < cvc_max_count);
i++) {
if (!cvcs[i]->b_enabled) continue;
cvc_count++;
// Coefficient: d(a * x^n) = a * n * x^(n-1) * dx
cvm::real coeff = (cvcs[i])->sup_coeff * cvm::real((cvcs[i])->sup_np) *
std::pow((cvcs[i])->value().real_value, (cvcs[i])->sup_np-1);
for (size_t j = 0; j < cvcs[i]->atom_groups.size(); j++) {
cvm::atom_group &ag = *(cvcs[i]->atom_groups[j]);
// If necessary, apply inverse rotation to get atomic
// gradient in the laboratory frame
if (cvcs[i]->atom_groups[j]->b_rotate) {
cvm::rotation const rot_inv = cvcs[i]->atom_groups[j]->rot.inverse();
for (size_t k = 0; k < cvcs[i]->atom_groups[j]->size(); k++) {
int a = std::lower_bound(atom_ids.begin(), atom_ids.end(),
cvcs[i]->atom_groups[j]->at(k).id) - atom_ids.begin();
atomic_gradients[a] += coeff *
rot_inv.rotate(cvcs[i]->atom_groups[j]->at(k).grad);
size_t a = std::lower_bound(atom_ids.begin(), atom_ids.end(),
ag[k].id) - atom_ids.begin();
atomic_gradients[a] += coeff * rot_inv.rotate(ag[k].grad);
}
} else {
for (size_t k = 0; k < cvcs[i]->atom_groups[j]->size(); k++) {
int a = std::lower_bound(atom_ids.begin(), atom_ids.end(),
cvcs[i]->atom_groups[j]->at(k).id) - atom_ids.begin();
atomic_gradients[a] += coeff * cvcs[i]->atom_groups[j]->at(k).grad;
size_t a = std::lower_bound(atom_ids.begin(), atom_ids.end(),
ag[k].id) - atom_ids.begin();
atomic_gradients[a] += coeff * ag[k].grad;
}
}
}
@ -1040,8 +1066,8 @@ void colvar::calc()
// TODO see if this could reasonably be done in a generic way
// from generic inverse gradients
cvm::error("System force is not implemented for "
"scripted colvars.");
return;
"scripted colvars.", COLVARS_NOT_IMPLEMENTED);
return COLVARS_NOT_IMPLEMENTED;
}
if (cvm::debug())
cvm::log("Calculating system force of colvar \""+this->name+"\".\n");
@ -1054,7 +1080,11 @@ void colvar::calc()
if (cvm::step_relative() > 0) {
// get from the cvcs the system forces from the PREVIOUS step
for (i = 0; i < cvcs.size(); i++) {
for (i = first_cvc, cvc_count = 0;
(i < cvcs.size()) && (cvc_count < cvc_max_count);
i++) {
if (!cvcs[i]->b_enabled) continue;
cvc_count++;
(cvcs[i])->calc_force_invgrads();
// linear combination is assumed
cvm::increase_depth();
@ -1072,7 +1102,12 @@ void colvar::calc()
if (cvm::debug())
cvm::log("Done calculating system force of colvar \""+this->name+"\".\n");
}
return COLVARS_OK;
}
int colvar::calc_colvar_properties()
{
if (tasks[task_fdiff_velocity]) {
// calculate the velocity by finite differences
if (cvm::step_relative() == 0)
@ -1109,6 +1144,8 @@ void colvar::calc()
if (cvm::debug())
cvm::log("Done calculating colvar \""+this->name+"\".\n");
return COLVARS_OK;
}
@ -1243,6 +1280,7 @@ void colvar::communicate_forces()
if (tasks[task_scripted]) {
std::vector<cvm::matrix2d<cvm::real> > func_grads;
func_grads.reserve(cvcs.size());
for (i = 0; i < cvcs.size(); i++) {
if (!cvcs[i]->b_enabled) continue;
func_grads.push_back(cvm::matrix2d<cvm::real> (x.size(),
@ -1252,7 +1290,7 @@ void colvar::communicate_forces()
if (res != COLVARS_OK) {
if (res == COLVARS_NOT_IMPLEMENTED) {
cvm::error("Colvar gradient scripts are not implemented.");
cvm::error("Colvar gradient scripts are not implemented.", COLVARS_NOT_IMPLEMENTED);
} else {
cvm::error("Error running colvar gradient script");
}
@ -1296,8 +1334,8 @@ void colvar::communicate_forces()
}
int colvar::set_cvc_flags(std::vector<bool> const &flags) {
int colvar::set_cvc_flags(std::vector<bool> const &flags)
{
if (flags.size() != cvcs.size()) {
cvm::error("ERROR: Wrong number of CVC flags provided.");
return COLVARS_ERROR;
@ -1309,6 +1347,36 @@ int colvar::set_cvc_flags(std::vector<bool> const &flags) {
}
int colvar::update_cvc_flags()
{
size_t i;
// Update the enabled/disabled status of cvcs if necessary
if (cvc_flags.size()) {
bool any = false;
for (i = 0; i < cvcs.size(); i++) {
cvcs[i]->b_enabled = cvc_flags[i];
any = any || cvc_flags[i];
}
if (!any) {
cvm::error("ERROR: All CVCs are disabled for colvar " + this->name +"\n");
return COLVARS_ERROR;
}
cvc_flags.resize(0);
}
return COLVARS_OK;
}
int colvar::num_active_cvcs() const
{
int result = 0;
for (size_t i = 0; i < cvcs.size(); i++) {
if (cvcs[i]->b_enabled) result++;
}
return result;
}
// ******************** METRIC FUNCTIONS ********************
// Use the metrics defined by \link cvc \endlink objects