Jason de Joannis
jdejoan at emory.edu
Mon Jan 8 22:32:20 CET 2007
Let me revive an old topic concerning the fshift correction
to the virial. This term is added up in the calc_vir function and
I believe it is equivalent to the second term in Eq(2) of the 2005
Gromacs paper or Eq. B.11 of the manual. Since that term is
rather simple it should be easy to check with the following snippet of code:
for (n=start; n<start+homenr; n++)
for (i=0;i<DIM;i++) for (j=0;j<DIM;j++)
virtest[i][j] -= 0.25*box[i][i]*graph->ishift[n][i]*f[n][j];
Unfortunately I am not getting the same number for the trace of the
virial tensor. Any suggestions would be appreciated.
> Quoting Erik Lindahl <lindahl at cbr.su.se>:
>> Hi Jason,
>>> On Nov 21, 2006, at 9:41 PM, Jason de Joannis wrote:
>>> From the manual and the code, it looks like Gromacs uses the atomic
>>> virial. I think that is besides the point.
>>> Why does Gromacs use f[i] which (I think) contains all bonded and
>>> nonbonded forces? After all the derivative resp. volume scaling
>>> vanishes for some of the bonded forces.
>> Forces are forces are forces, which give rise to pressure. There is
>> no fundamental physical difference between bonded and nonbonded
> Hmm. I generally think from the partition function rather than
> mechanically. Anyways, why do you have Appendix B.1.4 which treats
> the virial for harmonic bonds explicitely?
That could be an old remnant - currently all interactions are treated
the same way.
There is one slight technical difference in how we treat bonded vs.
nonbonded interactions, though, and this is the reason for the fshift
term. For bonded interactions we make the molecule continuous and just
calculate all forces without having to worry about periodicity. For
nonbonded interactions the "shift" depends on the particle we're
interacting with, so that's a bit more complicated. If you look at the
JCC gromacs paper in 2005 we have a small figure there explaning it
better than I can do in words here!
>> Gromos (and some other codes) use whole-molecule-virials to reduce
>> the effect of some numerical errors, but there are other drawbacks
>> with this - primarily performance.
>>> Also, the manual describes the SHAKE virial but what about LINCS?
>> We use "Shake virial" as a generic name for virial contributions
>> from constraints, so it's identical for SHAKE and LINCS.
> Okay, thats true. I can see real numbers when I print out shake_vir. That
> means I will have to go inside LINCS and somehow zero the unwanted
> virial terms.
>>> Also, where can I find a little more info on the fr->fshift contribution.
>>> On the mailing list archive someone explained that this comes from
>>> forces on the 27 unit cells. Is that explained in the manual or
>> It's mentioned in the manual where we derive the expression for
>> single-sum-virial. The performance advantage of the single sum is
>> also the reason why we prefer the atomic virial, btw!
> Well I must need a stronger prescription on my contact lenses because
> I have been looking closely at that section. It seems to me that
> Eq. B.11 is all calculated within the normal virial routine.
The first half of Eq. B11 is the "normal" virial sum, while the second
is the fshift contribution.
Normally, when you calculate nonbonded interactions you have to check
the x/y/z periodicity and select the minimum image every time you
calculate the distance between the two atoms. This is extremely bad to
have in the innermost kernels since modern CPUs just hate conditionals
(it breaks the instruction pipeline).
In Gromacs we take care of this during neighborsearching. Instead of
having one big list with e.g. 100 neighbors of "particle i", we split
the list and essentially store it like:
(i particle translated one box to the left): 10 neighbors
(i particle not translated): 30 neighbors
(i particle translated one box to the right): 0 neighbors
... etc ...
The "translations" here are the shift indices, in this case -1,0,1 in
the x dimension.
Now, in the nonbonded kernel the i particle coordinates are loaded in
the _outer_ loop, where we correct it for the current shift. After
this we know that the periodicity is correct, so we don't have to
include any periodic boundary condition checks in the innermost loop,
which is the time-critical part.
If we combined this with a molecular virial (which would need to be
calculated in the innermost loop) all would be fine.
However, when we want to use the atomic virial and apply the single
sum of Appendix B1 it turns out that we are making an error, since we
modify the particle coordinates due to the shift in the nonbonded
kernel (different for different nlists), but the single sum always use
the coordinate in the central box. This error is the second term of
Fortunately, it turns out to be easy and computationally cheap to
correct for. That term can be calculated by simply summing all
interaction forces for each shift vector (3*3*3=27), which we can do
entirely in the outer nonbonded loop - after we have added the force
to the i particle force array we also increment the fshift array
corresponding to the shift used for this i particle.
It's perhaps not entirely obvious without a figure, but pretty neat:
it completely removes all virial and PBC calculations from them
nonbonded innerloop, and we only do PBC checks on neighborsearching.
PS: Unfortunately we also use the term "molecular shift" in Gromacs,
when we create a graph of all bonded interactions in a molecule to
move it between the states where all atoms are in the central box or
where the molecule is whole. This is really entirely unrelated to the
nonbonded shifts, apart from the fact that both deal with periodic
boundary conditions. Sorry about the confusing naming ;-)
More information about the gromacs.org_gmx-developers