Skip to content

Loop over replicas when computing well-tempered metadynamics scaling factor#820

Merged
giacomofiorin merged 2 commits intomasterfrom
mw-wt-mtd_and_no_vowels
Apr 16, 2026
Merged

Loop over replicas when computing well-tempered metadynamics scaling factor#820
giacomofiorin merged 2 commits intomasterfrom
mw-wt-mtd_and_no_vowels

Conversation

@giacomofiorin
Copy link
Copy Markdown
Member

Fixes #819

@giacomofiorin giacomofiorin added the bugfix To be used only in PRs label Jul 10, 2025
@giacomofiorin
Copy link
Copy Markdown
Member Author

Still working on this (including test, documentation update).

When finished, I want to use it as a test for a CI job that cherry-picks bugfixes into release branches (e.g. namd-3.0, gromacs-2025).

Comment thread src/colvarbias_meta.cpp
Comment on lines +581 to +582
// TODO: Is it better to compute the energy from all historic hills
// when keepHills is on?
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@HanatoK I didn't understand this comment before, and forgot to ask you about it

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As I understand, without keepHills, the code only accumulates the hills that are off-grid. However, in theory, those Gaussian hills that have been projected onto the histogram are truncated, which means they do not affect the bias energy of an off-grid position.

With keepHills I think it would be better to compute the bias energy from all hills, no matter whether they are in the histogram.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you're doing that, then you would effectively disable use_grids without the user being able to check.

To be honest, at this point trajectories have become so long that the usefulness of keepHills is put into question.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No. What I suggested should only affect off-grid positions. If you use both use_grids and keepHills, then to calculate the energy of a position out of the grid, you can sum all hills, and to calculate the energy of a position in the grid, you can just use the grid value. This shouldn't disable use_grids.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, thanks. The "off-grid hills", which are kept regardless, should also include hills whose center is inside the grid boundaries, but they are within sufficient range that they would affect configurations just outside the grid. At least that was the original logic, assuming that it didn't break along the way.

Looping over all hills would also include hills that are well within the boundaries.

Copy link
Copy Markdown
Member

@HanatoK HanatoK left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In my opinion, the logic of computing bias energy should be the same as colvarbias_meta::calc_energy without adding the new hills:

  bool index_ok = false;
  std::vector<int> curr_bin;

  if (use_grids) {

    curr_bin = values ?
      hills_energy->get_colvars_index(*values) :
      hills_energy->get_colvars_index();

    index_ok = hills_energy->index_ok(curr_bin);

  }

  if ( index_ok ) {
    // index is within the grid: get the energy from there
    for (ir = 0; ir < replicas.size(); ir++) {

      bias_energy += replicas[ir]->hills_energy->value(curr_bin);
      if (cvm::debug()) {
        cvm::log("Metadynamics bias \""+this->name+"\""+
                 ((comm != single_replica) ? ", replica \""+replica_id+"\"" : "")+
                 ": current coordinates on the grid: "+
                 cvm::to_str(curr_bin)+".\n");
        cvm::log("Grid energy = "+cvm::to_str(bias_energy)+".\n");
      }
    }
  } else {
    // off the grid: compute analytically only the hills at the grid's edges
    for (ir = 0; ir < replicas.size(); ir++) {
      calc_hills(replicas[ir]->hills_off_grid.begin(),
                 replicas[ir]->hills_off_grid.end(),
                 bias_energy,
                 values);
    }
  }

Comment thread src/colvarbias_meta.cpp Outdated
Comment on lines +571 to +572
std::vector<int> curr_bin = hills_energy->get_colvars_index();
const bool index_ok = hills_energy->index_ok(curr_bin);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible to move the checking out of the for loop, just like colvarbias_meta::calc_energy?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I moved the initialization of index_ok outside of the loop. As far as moving the check, I'm not sure whether it's worth it (meaning, I don't have enough bandwidth to do this, but wouldn't oppose you if you did).

Comment thread src/colvarbias_meta.cpp
}
// cvm::log("WARNING: computing bias factor for off-grid hills. Hills energy: " + cvm::to_str(hills_energy_sum_here) + "\n");
} else {
calc_hills(replicas[ir]->hills.begin(), replicas[ir]->hills.end(), hills_energy_sum_here,
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now I feel the old code summing the hills starting from new_hills_begin is incorrect, and this fixes it. Is that right?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure, sorry. This branch corresponds to the grids-off, multiple-walkers, well-tempered use case.

With this change, the branch is more consistent with the other options. As for whether it was previously buggy, I think we should first check if anybody ever ran this case before investigating further.

@giacomofiorin giacomofiorin force-pushed the mw-wt-mtd_and_no_vowels branch from 9011617 to 7595e11 Compare April 16, 2026 20:20
@giacomofiorin giacomofiorin merged commit 8338287 into master Apr 16, 2026
16 checks passed
@giacomofiorin giacomofiorin deleted the mw-wt-mtd_and_no_vowels branch April 16, 2026 21:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bugfix To be used only in PRs

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Combine Gaussians for multiple-walkers metadynamics before applying well-tempered scaling

2 participants