Merge pull request #1618 from giacomofiorin/colvars-update

Bugfix for Colvars library (update to version 2019-08-05)
This commit is contained in:
Axel Kohlmeyer 2019-08-05 16:36:16 -04:00 committed by GitHub
commit 0bd5704107
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 80 additions and 97 deletions

View File

@ -178,6 +178,31 @@ int cvm::atom_group::remove_atom(cvm::atom_iter ai)
}
int cvm::atom_group::set_dummy()
{
if (atoms_ids.size() > 0) {
return cvm::error("Error: setting group with keyword \""+key+
"\" and name \""+name+"\" as dummy, but it already "
"contains atoms.\n", INPUT_ERROR);
}
b_dummy = true;
return COLVARS_OK;
}
int cvm::atom_group::set_dummy_pos(cvm::atom_pos const &pos)
{
if (b_dummy) {
dummy_atom_pos = pos;
} else {
return cvm::error("Error: setting dummy position for group with keyword \""+
key+"\" and name \""+name+
"\", but it is not dummy.\n", INPUT_ERROR);
}
return COLVARS_OK;
}
int cvm::atom_group::init()
{
if (!key.size()) key = "unnamed";
@ -469,20 +494,15 @@ int cvm::atom_group::parse(std::string const &group_conf)
// checks of doubly-counted atoms have been handled by add_atom() already
if (get_keyval(group_conf, "dummyAtom", dummy_atom_pos, cvm::atom_pos())) {
b_dummy = true;
// note: atoms_ids.size() is used here in lieu of atoms.size(),
// which can be empty for scalable groups
if (atoms_ids.size()) {
cvm::error("Error: cannot set up group \""+
key+"\" as a dummy atom "
"and provide it with atom definitions.\n", INPUT_ERROR);
}
parse_error |= set_dummy();
parse_error |= set_dummy_pos(dummy_atom_pos);
} else {
b_dummy = false;
if (!(atoms_ids.size())) {
cvm::error("Error: no atoms defined for atom group \""+
key+"\".\n", INPUT_ERROR);
parse_error |= cvm::error("Error: no atoms defined for atom group \""+
key+"\".\n", INPUT_ERROR);
}
// whether these atoms will ever receive forces or not

View File

@ -207,6 +207,12 @@ public:
/// \brief Remove an atom object from this group
int remove_atom(cvm::atom_iter ai);
/// Set this group as a dummy group (no actual atoms)
int set_dummy();
/// If this group is dummy, set the corresponding position
int set_dummy_pos(cvm::atom_pos const &pos);
/// \brief Print the updated the total mass and charge of a group.
/// This is needed in case the hosting MD code has an option to
/// change atom masses after their initialization.

View File

@ -887,9 +887,8 @@ protected:
/// Integer exponent of the function denominator
int ed;
/// \brief If true, group2 will be treated as a single atom, stored in this
/// accessory group
cvm::atom_group *group2_center;
/// If true, group2 will be treated as a single atom
bool b_group2_center_only;
/// Tolerance for the pair list
cvm::real tolerance;
@ -941,9 +940,12 @@ public:
bool **pairlist_elem,
cvm::real tolerance);
/// Main workhorse function
/// Workhorse function
template<int flags> int compute_coordnum();
/// Workhorse function
template<int flags> void main_loop(bool **pairlist_elem);
};

View File

@ -91,7 +91,7 @@ cvm::real colvar::coordnum::switching_function(cvm::real const &r0,
colvar::coordnum::coordnum(std::string const &conf)
: cvc(conf), b_anisotropic(false), group2_center(NULL), pairlist(NULL)
: cvc(conf), b_anisotropic(false), pairlist(NULL)
{
function_type = "coordnum";
@ -156,14 +156,7 @@ colvar::coordnum::coordnum(std::string const &conf)
cvm::log("Warning: only minimum-image distances are used by this variable.\n");
}
bool b_group2_center_only = false;
get_keyval(conf, "group2CenterOnly", b_group2_center_only, group2->b_dummy);
if (b_group2_center_only) {
if (!group2_center) {
group2_center = new cvm::atom_group();
group2_center->add_atom(cvm::atom());
}
}
get_keyval(conf, "tolerance", tolerance, 0.0);
if (tolerance > 0) {
@ -185,7 +178,7 @@ colvar::coordnum::coordnum(std::string const &conf)
colvar::coordnum::coordnum()
: b_anisotropic(false), group2_center(NULL), pairlist(NULL)
: b_anisotropic(false), pairlist(NULL)
{
function_type = "coordnum";
x.type(colvarvalue::type_scalar);
@ -197,69 +190,60 @@ colvar::coordnum::~coordnum()
if (pairlist != NULL) {
delete [] pairlist;
}
if (group2_center != NULL) {
delete group2_center;
}
template<int flags> void colvar::coordnum::main_loop(bool **pairlist_elem)
{
if (b_group2_center_only) {
cvm::atom group2_com_atom;
group2_com_atom.pos = group2->center_of_mass();
for (cvm::atom_iter ai1 = group1->begin(); ai1 != group1->end(); ai1++) {
x.real_value += switching_function<flags>(r0, r0_vec, en, ed,
*ai1, group2_com_atom,
pairlist_elem,
tolerance);
}
if (b_group2_center_only) {
group2->set_weighted_gradient(group2_com_atom.grad);
}
} else {
for (cvm::atom_iter ai1 = group1->begin(); ai1 != group1->end(); ai1++) {
for (cvm::atom_iter ai2 = group2->begin(); ai2 != group2->end(); ai2++) {
x.real_value += switching_function<flags>(r0, r0_vec, en, ed,
*ai1, *ai2,
pairlist_elem,
tolerance);
}
}
}
}
template<int compute_flags> int colvar::coordnum::compute_coordnum()
{
if (group2_center) {
(*group2_center)[0].pos = group2->center_of_mass();
group2_center->calc_required_properties();
}
cvm::atom_group *group2p = group2_center ? group2_center : group2;
bool const use_pairlist = (pairlist != NULL);
bool const rebuild_pairlist = (pairlist != NULL) &&
(cvm::step_relative() % pairlist_freq == 0);
bool *pairlist_elem = use_pairlist ? pairlist : NULL;
cvm::atom_iter ai1 = group1->begin(), ai2 = group2p->begin();
cvm::atom_iter const ai1_end = group1->end();
cvm::atom_iter const ai2_end = group2p->end();
if (b_anisotropic) {
if (use_pairlist) {
if (rebuild_pairlist) {
int const flags = compute_flags | ef_anisotropic | ef_use_pairlist |
ef_rebuild_pairlist;
for (ai1 = group1->begin(); ai1 != ai1_end; ai1++) {
for (ai2 = group2->begin(); ai2 != ai2_end; ai2++) {
x.real_value += switching_function<flags>(r0, r0_vec, en, ed,
*ai1, *ai2,
&pairlist_elem,
tolerance);
}
}
main_loop<flags>(&pairlist_elem);
} else {
int const flags = compute_flags | ef_anisotropic | ef_use_pairlist;
for (ai1 = group1->begin(); ai1 != ai1_end; ai1++) {
for (ai2 = group2->begin(); ai2 != ai2_end; ai2++) {
x.real_value += switching_function<flags>(r0, r0_vec, en, ed,
*ai1, *ai2,
&pairlist_elem,
tolerance);
}
}
main_loop<flags>(&pairlist_elem);
}
} else { // if (use_pairlist) {
} else {
int const flags = compute_flags | ef_anisotropic;
for (ai1 = group1->begin(); ai1 != ai1_end; ai1++) {
for (ai2 = group2->begin(); ai2 != ai2_end; ai2++) {
x.real_value += switching_function<flags>(r0, r0_vec, en, ed,
*ai1, *ai2,
NULL, 0.0);
}
}
main_loop<flags>(NULL);
}
} else {
@ -267,46 +251,17 @@ template<int compute_flags> int colvar::coordnum::compute_coordnum()
if (use_pairlist) {
if (rebuild_pairlist) {
int const flags = compute_flags | ef_use_pairlist | ef_rebuild_pairlist;
for (ai1 = group1->begin(); ai1 != ai1_end; ai1++) {
for (ai2 = group2->begin(); ai2 != ai2_end; ai2++) {
x.real_value += switching_function<flags>(r0, r0_vec, en, ed,
*ai1, *ai2,
&pairlist_elem,
tolerance);
}
}
main_loop<flags>(&pairlist_elem);
} else {
int const flags = compute_flags | ef_use_pairlist;
for (ai1 = group1->begin(); ai1 != ai1_end; ai1++) {
for (ai2 = group2->begin(); ai2 != ai2_end; ai2++) {
x.real_value += switching_function<flags>(r0, r0_vec, en, ed,
*ai1, *ai2,
&pairlist_elem,
tolerance);
}
}
main_loop<flags>(&pairlist_elem);
}
} else { // if (use_pairlist) {
} else {
int const flags = compute_flags;
for (ai1 = group1->begin(); ai1 != ai1_end; ai1++) {
for (ai2 = group2->begin(); ai2 != ai2_end; ai2++) {
x.real_value += switching_function<flags>(r0, r0_vec, en, ed,
*ai1, *ai2,
NULL, 0.0);
}
}
}
}
if (compute_flags & ef_gradients) {
if (group2_center) {
group2->set_weighted_gradient((*group2_center)[0].grad);
main_loop<flags>(NULL);
}
}

View File

@ -1,5 +1,5 @@
#ifndef COLVARS_VERSION
#define COLVARS_VERSION "2019-08-01"
#define COLVARS_VERSION "2019-08-05"
// This file is part of the Collective Variables module (Colvars).
// The original version of Colvars and its updates are located at:
// https://github.com/colvars/colvars