Commit 51ba9bd5 authored by Giacomo Fiorin's avatar Giacomo Fiorin
Browse files

Bugfix for Colvars library (update to version 2019-08-05)

Bugfix for group2CenterOnly (coordNum option):
https://github.com/Colvars/colvars/pull/278
parent 096c2255
Loading
Loading
Loading
Loading
+31 −11
Original line number Diff line number Diff line
@@ -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,19 +494,14 @@ 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 \""+
      parse_error |= cvm::error("Error: no atoms defined for atom group \""+
                                key+"\".\n", INPUT_ERROR);
    }

+6 −0
Original line number Diff line number Diff line
@@ -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.
+6 −4
Original line number Diff line number Diff line
@@ -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);

};


+36 −81
Original line number Diff line number Diff line
@@ -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 compute_flags> int colvar::coordnum::compute_coordnum()
template<int flags> void colvar::coordnum::main_loop(bool **pairlist_elem)
{
  if (group2_center) {
    (*group2_center)[0].pos = group2->center_of_mass();
    group2_center->calc_required_properties();
  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);
      }
    }
  }
}
  cvm::atom_group *group2p = group2_center ? group2_center : group2;


template<int compute_flags> int colvar::coordnum::compute_coordnum()
{
  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);
    }
  }

+1 −1
Original line number Diff line number Diff line
#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