Reduce the use of nbnxn_consts.h
[alexxy/gromacs.git] / src / gromacs / mdlib / calc_verletbuf.c
1 /*
2  * This file is part of the GROMACS molecular simulation package.
3  *
4  * Copyright (c) 2012,2013,2014,2015, by the GROMACS development team, led by
5  * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
6  * and including many others, as listed in the AUTHORS file in the
7  * top-level source directory and at http://www.gromacs.org.
8  *
9  * GROMACS is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public License
11  * as published by the Free Software Foundation; either version 2.1
12  * of the License, or (at your option) any later version.
13  *
14  * GROMACS is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with GROMACS; if not, see
21  * http://www.gnu.org/licenses, or write to the Free Software Foundation,
22  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA.
23  *
24  * If you want to redistribute modifications to GROMACS, please
25  * consider that scientific software is very special. Version
26  * control is crucial - bugs must be traceable. We will be happy to
27  * consider code for inclusion in the official distribution, but
28  * derived work must not be called official GROMACS. Details are found
29  * in the README & COPYING files - if they are missing, get the
30  * official version at http://www.gromacs.org.
31  *
32  * To help us fund GROMACS development, we humbly ask that you cite
33  * the research papers on the package. Check out http://www.gromacs.org.
34  */
35 #include "gmxpre.h"
36
37 #include "calc_verletbuf.h"
38
39 #include <assert.h>
40 #include <math.h>
41 #include <stdlib.h>
42
43 #include <sys/types.h>
44
45 #include "gromacs/legacyheaders/macros.h"
46 #include "gromacs/legacyheaders/typedefs.h"
47 #include "gromacs/math/calculate-ewald-splitting-coefficient.h"
48 #include "gromacs/math/units.h"
49 #include "gromacs/math/vec.h"
50 #include "gromacs/mdlib/nb_verlet.h"
51 #include "gromacs/mdlib/nbnxn_search.h"
52 #include "gromacs/mdlib/nbnxn_simd.h"
53 #include "gromacs/utility/fatalerror.h"
54 #include "gromacs/utility/smalloc.h"
55
56 /* The code in this file estimates a pairlist buffer length
57  * given a target energy drift per atom per picosecond.
58  * This is done by estimating the drift given a buffer length.
59  * Ideally we would like to have a tight overestimate of the drift,
60  * but that can be difficult to achieve.
61  *
62  * Significant approximations used:
63  *
64  * Uniform particle density. UNDERESTIMATES the drift by rho_global/rho_local.
65  *
66  * Interactions don't affect particle motion. OVERESTIMATES the drift on longer
67  * time scales. This approximation probably introduces the largest errors.
68  *
69  * Only take one constraint per particle into account: OVERESTIMATES the drift.
70  *
71  * For rotating constraints assume the same functional shape for time scales
72  * where the constraints rotate significantly as the exact expression for
73  * short time scales. OVERESTIMATES the drift on long time scales.
74  *
75  * For non-linear virtual sites use the mass of the lightest constructing atom
76  * to determine the displacement. OVER/UNDERESTIMATES the drift, depending on
77  * the geometry and masses of constructing atoms.
78  *
79  * Note that the formulas for normal atoms and linear virtual sites are exact,
80  * apart from the first two approximations.
81  *
82  * Note that apart from the effect of the above approximations, the actual
83  * drift of the total energy of a system can be order of magnitude smaller
84  * due to cancellation of positive and negative drift for different pairs.
85  */
86
87
88 /* Struct for unique atom type for calculating the energy drift.
89  * The atom displacement depends on mass and constraints.
90  * The energy jump for given distance depend on LJ type and q.
91  */
92 typedef struct
93 {
94     real     mass;     /* mass */
95     int      type;     /* type (used for LJ parameters) */
96     real     q;        /* charge */
97     gmx_bool bConstr;  /* constrained, if TRUE, use #DOF=2 iso 3 */
98     real     con_mass; /* mass of heaviest atom connected by constraints */
99     real     con_len;  /* constraint length to the heaviest atom */
100 } atom_nonbonded_kinetic_prop_t;
101
102 /* Struct for unique atom type for calculating the energy drift.
103  * The atom displacement depends on mass and constraints.
104  * The energy jump for given distance depend on LJ type and q.
105  */
106 typedef struct
107 {
108     atom_nonbonded_kinetic_prop_t prop; /* non-bonded and kinetic atom prop. */
109     int                           n;    /* #atoms of this type in the system */
110 } verletbuf_atomtype_t;
111
112 void verletbuf_get_list_setup(gmx_bool gmx_unused     bSIMD,
113                               gmx_bool                bGPU,
114                               verletbuf_list_setup_t *list_setup)
115 {
116     /* When calling this function we often don't know which kernel type we
117      * are going to use. W choose the kernel type with the smallest possible
118      * i- and j-cluster sizes, so we potentially overestimate, but never
119      * underestimate, the buffer drift.
120      * Note that the current buffer estimation code only handles clusters
121      * of size 1, 2 or 4, so for 4x8 or 8x8 we use the estimate for 4x4.
122      */
123
124     if (bGPU)
125     {
126         /* The CUDA kernels split the j-clusters in two halves */
127         list_setup->cluster_size_i = nbnxn_kernel_to_ci_size(nbnxnk8x8x8_GPU);
128         list_setup->cluster_size_j = nbnxn_kernel_to_cj_size(nbnxnk8x8x8_GPU)/2;
129     }
130     else
131     {
132         int kernel_type;
133
134         kernel_type = nbnxnk4x4_PlainC;
135
136 #ifdef GMX_NBNXN_SIMD
137         if (bSIMD)
138         {
139 #ifdef GMX_NBNXN_SIMD_2XNN
140             /* We use the smallest cluster size to be on the safe side */
141             kernel_type = nbnxnk4xN_SIMD_2xNN;
142 #else
143             kernel_type = nbnxnk4xN_SIMD_4xN;
144 #endif
145         }
146 #endif
147
148         list_setup->cluster_size_i = nbnxn_kernel_to_ci_size(kernel_type);
149         list_setup->cluster_size_j = nbnxn_kernel_to_cj_size(kernel_type);
150     }
151 }
152
153 static gmx_bool
154 atom_nonbonded_kinetic_prop_equal(const atom_nonbonded_kinetic_prop_t *prop1,
155                                   const atom_nonbonded_kinetic_prop_t *prop2)
156 {
157     return (prop1->mass     == prop2->mass &&
158             prop1->type     == prop2->type &&
159             prop1->q        == prop2->q &&
160             prop1->bConstr  == prop2->bConstr &&
161             prop1->con_mass == prop2->con_mass &&
162             prop1->con_len  == prop2->con_len);
163 }
164
165 static void add_at(verletbuf_atomtype_t **att_p, int *natt_p,
166                    const atom_nonbonded_kinetic_prop_t *prop,
167                    int nmol)
168 {
169     verletbuf_atomtype_t   *att;
170     int                     natt, i;
171
172     if (prop->mass == 0)
173     {
174         /* Ignore massless particles */
175         return;
176     }
177
178     att  = *att_p;
179     natt = *natt_p;
180
181     i = 0;
182     while (i < natt && !atom_nonbonded_kinetic_prop_equal(prop, &att[i].prop))
183     {
184         i++;
185     }
186
187     if (i < natt)
188     {
189         att[i].n += nmol;
190     }
191     else
192     {
193         (*natt_p)++;
194         srenew(*att_p, *natt_p);
195         (*att_p)[i].prop = *prop;
196         (*att_p)[i].n    = nmol;
197     }
198 }
199
200 static void get_vsite_masses(const gmx_moltype_t  *moltype,
201                              const gmx_ffparams_t *ffparams,
202                              real                 *vsite_m,
203                              int                  *n_nonlin_vsite)
204 {
205     int            ft, i;
206     const t_ilist *il;
207
208     *n_nonlin_vsite = 0;
209
210     /* Check for virtual sites, determine mass from constructing atoms */
211     for (ft = 0; ft < F_NRE; ft++)
212     {
213         if (IS_VSITE(ft))
214         {
215             il = &moltype->ilist[ft];
216
217             for (i = 0; i < il->nr; i += 1+NRAL(ft))
218             {
219                 const t_iparams *ip;
220                 real             inv_mass, coeff, m_aj;
221                 int              a1, aj;
222
223                 ip = &ffparams->iparams[il->iatoms[i]];
224
225                 a1 = il->iatoms[i+1];
226
227                 if (ft != F_VSITEN)
228                 {
229                     /* Only vsiten can have more than four
230                        constructing atoms, so NRAL(ft) <= 5 */
231                     int        j;
232                     real      *cam;
233                     const int  maxj = NRAL(ft);
234
235                     snew(cam, maxj);
236                     assert(maxj <= 5);
237                     for (j = 1; j < maxj; j++)
238                     {
239                         cam[j] = moltype->atoms.atom[il->iatoms[i+1+j]].m;
240                         if (cam[j] == 0)
241                         {
242                             cam[j] = vsite_m[il->iatoms[i+1+j]];
243                         }
244                         if (cam[j] == 0)
245                         {
246                             gmx_fatal(FARGS, "In molecule type '%s' %s construction involves atom %d, which is a virtual site of equal or high complexity. This is not supported.",
247                                       *moltype->name,
248                                       interaction_function[ft].longname,
249                                       il->iatoms[i+1+j]+1);
250                         }
251                     }
252
253                     switch (ft)
254                     {
255                         case F_VSITE2:
256                             /* Exact */
257                             vsite_m[a1] = (cam[1]*cam[2])/(cam[2]*sqr(1-ip->vsite.a) + cam[1]*sqr(ip->vsite.a));
258                             break;
259                         case F_VSITE3:
260                             /* Exact */
261                             vsite_m[a1] = (cam[1]*cam[2]*cam[3])/(cam[2]*cam[3]*sqr(1-ip->vsite.a-ip->vsite.b) + cam[1]*cam[3]*sqr(ip->vsite.a) + cam[1]*cam[2]*sqr(ip->vsite.b));
262                             break;
263                         case F_VSITEN:
264                             gmx_incons("Invalid vsite type");
265                             break;
266                         default:
267                             /* Use the mass of the lightest constructing atom.
268                              * This is an approximation.
269                              * If the distance of the virtual site to the
270                              * constructing atom is less than all distances
271                              * between constructing atoms, this is a safe
272                              * over-estimate of the displacement of the vsite.
273                              * This condition holds for all H mass replacement
274                              * vsite constructions, except for SP2/3 groups.
275                              * In SP3 groups one H will have a F_VSITE3
276                              * construction, so even there the total drift
277                              * estimate shouldn't be far off.
278                              */
279                             vsite_m[a1] = cam[1];
280                             for (j = 2; j < maxj; j++)
281                             {
282                                 vsite_m[a1] = min(vsite_m[a1], cam[j]);
283                             }
284                             (*n_nonlin_vsite)++;
285                             break;
286                     }
287                     sfree(cam);
288                 }
289                 else
290                 {
291                     int j;
292
293                     /* Exact */
294                     inv_mass = 0;
295                     for (j = 0; j < 3*ffparams->iparams[il->iatoms[i]].vsiten.n; j += 3)
296                     {
297                         aj    = il->iatoms[i+j+2];
298                         coeff = ffparams->iparams[il->iatoms[i+j]].vsiten.a;
299                         if (moltype->atoms.atom[aj].ptype == eptVSite)
300                         {
301                             m_aj = vsite_m[aj];
302                         }
303                         else
304                         {
305                             m_aj = moltype->atoms.atom[aj].m;
306                         }
307                         if (m_aj <= 0)
308                         {
309                             gmx_incons("The mass of a vsiten constructing atom is <= 0");
310                         }
311                         inv_mass += coeff*coeff/m_aj;
312                     }
313                     vsite_m[a1] = 1/inv_mass;
314                     /* Correct for loop increment of i */
315                     i += j - 1 - NRAL(ft);
316                 }
317                 if (gmx_debug_at)
318                 {
319                     fprintf(debug, "atom %4d %-20s mass %6.3f\n",
320                             a1, interaction_function[ft].longname, vsite_m[a1]);
321                 }
322             }
323         }
324     }
325 }
326
327 static void get_verlet_buffer_atomtypes(const gmx_mtop_t      *mtop,
328                                         verletbuf_atomtype_t **att_p,
329                                         int                   *natt_p,
330                                         int                   *n_nonlin_vsite)
331 {
332     verletbuf_atomtype_t          *att;
333     int                            natt;
334     int                            mb, nmol, ft, i, a1, a2, a3, a;
335     const t_atoms                 *atoms;
336     const t_ilist                 *il;
337     const t_iparams               *ip;
338     atom_nonbonded_kinetic_prop_t *prop;
339     real                          *vsite_m;
340     int                            n_nonlin_vsite_mol;
341
342     att  = NULL;
343     natt = 0;
344
345     if (n_nonlin_vsite != NULL)
346     {
347         *n_nonlin_vsite = 0;
348     }
349
350     for (mb = 0; mb < mtop->nmolblock; mb++)
351     {
352         nmol = mtop->molblock[mb].nmol;
353
354         atoms = &mtop->moltype[mtop->molblock[mb].type].atoms;
355
356         /* Check for constraints, as they affect the kinetic energy.
357          * For virtual sites we need the masses and geometry of
358          * the constructing atoms to determine their velocity distribution.
359          */
360         snew(prop, atoms->nr);
361         snew(vsite_m, atoms->nr);
362
363         for (ft = F_CONSTR; ft <= F_CONSTRNC; ft++)
364         {
365             il = &mtop->moltype[mtop->molblock[mb].type].ilist[ft];
366
367             for (i = 0; i < il->nr; i += 1+NRAL(ft))
368             {
369                 ip         = &mtop->ffparams.iparams[il->iatoms[i]];
370                 a1         = il->iatoms[i+1];
371                 a2         = il->iatoms[i+2];
372                 if (atoms->atom[a2].m > prop[a1].con_mass)
373                 {
374                     prop[a1].con_mass = atoms->atom[a2].m;
375                     prop[a1].con_len  = ip->constr.dA;
376                 }
377                 if (atoms->atom[a1].m > prop[a2].con_mass)
378                 {
379                     prop[a2].con_mass = atoms->atom[a1].m;
380                     prop[a2].con_len  = ip->constr.dA;
381                 }
382             }
383         }
384
385         il = &mtop->moltype[mtop->molblock[mb].type].ilist[F_SETTLE];
386
387         for (i = 0; i < il->nr; i += 1+NRAL(F_SETTLE))
388         {
389             ip         = &mtop->ffparams.iparams[il->iatoms[i]];
390             a1         = il->iatoms[i+1];
391             a2         = il->iatoms[i+2];
392             a3         = il->iatoms[i+3];
393             /* Usually the mass of a1 (usually oxygen) is larger than a2/a3.
394              * If this is not the case, we overestimate the displacement,
395              * which leads to a larger buffer (ok since this is an exotic case).
396              */
397             prop[a1].con_mass = atoms->atom[a2].m;
398             prop[a1].con_len  = ip->settle.doh;
399
400             prop[a2].con_mass = atoms->atom[a1].m;
401             prop[a2].con_len  = ip->settle.doh;
402
403             prop[a3].con_mass = atoms->atom[a1].m;
404             prop[a3].con_len  = ip->settle.doh;
405         }
406
407         get_vsite_masses(&mtop->moltype[mtop->molblock[mb].type],
408                          &mtop->ffparams,
409                          vsite_m,
410                          &n_nonlin_vsite_mol);
411         if (n_nonlin_vsite != NULL)
412         {
413             *n_nonlin_vsite += nmol*n_nonlin_vsite_mol;
414         }
415
416         for (a = 0; a < atoms->nr; a++)
417         {
418             if (atoms->atom[a].ptype == eptVSite)
419             {
420                 prop[a].mass = vsite_m[a];
421             }
422             else
423             {
424                 prop[a].mass = atoms->atom[a].m;
425             }
426             prop[a].type     = atoms->atom[a].type;
427             prop[a].q        = atoms->atom[a].q;
428             /* We consider an atom constrained, #DOF=2, when it is
429              * connected with constraints to (at least one) atom with
430              * a mass of more than 0.4x its own mass. This is not a critical
431              * parameter, since with roughly equal masses the unconstrained
432              * and constrained displacement will not differ much (and both
433              * overestimate the displacement).
434              */
435             prop[a].bConstr = (prop[a].con_mass > 0.4*prop[a].mass);
436
437             add_at(&att, &natt, &prop[a], nmol);
438         }
439
440         sfree(vsite_m);
441         sfree(prop);
442     }
443
444     if (gmx_debug_at)
445     {
446         for (a = 0; a < natt; a++)
447         {
448             fprintf(debug, "type %d: m %5.2f t %d q %6.3f con %d con_m %5.3f con_l %5.3f n %d\n",
449                     a, att[a].prop.mass, att[a].prop.type, att[a].prop.q,
450                     att[a].prop.bConstr, att[a].prop.con_mass, att[a].prop.con_len,
451                     att[a].n);
452         }
453     }
454
455     *att_p  = att;
456     *natt_p = natt;
457 }
458
459 /* This function computes two components of the estimate of the variance
460  * in the displacement of one atom in a system of two constrained atoms.
461  * Returns in sigma2_2d the variance due to rotation of the constrained
462  * atom around the atom to which it constrained.
463  * Returns in sigma2_3d the variance due to displacement of the COM
464  * of the whole system of the two constrained atoms.
465  *
466  * Note that we only take a single constraint (the one to the heaviest atom)
467  * into account. If an atom has multiple constraints, this will result in
468  * an overestimate of the displacement, which gives a larger drift and buffer.
469  */
470 static void constrained_atom_sigma2(real                                 kT_fac,
471                                     const atom_nonbonded_kinetic_prop_t *prop,
472                                     real                                *sigma2_2d,
473                                     real                                *sigma2_3d)
474 {
475     real sigma2_rot;
476     real com_dist;
477     real sigma2_rel;
478     real scale;
479
480     /* Here we decompose the motion of a constrained atom into two
481      * components: rotation around the COM and translation of the COM.
482      */
483
484     /* Determine the variance for the displacement of the rotational mode */
485     sigma2_rot = kT_fac/(prop->mass*(prop->mass + prop->con_mass)/prop->con_mass);
486
487     /* The distance from the atom to the COM, i.e. the rotational arm */
488     com_dist = prop->con_len*prop->con_mass/(prop->mass + prop->con_mass);
489
490     /* The variance relative to the arm */
491     sigma2_rel = sigma2_rot/(com_dist*com_dist);
492     /* At 6 the scaling formula has slope 0,
493      * so we keep sigma2_2d constant after that.
494      */
495     if (sigma2_rel < 6)
496     {
497         /* A constrained atom rotates around the atom it is constrained to.
498          * This results in a smaller linear displacement than for a free atom.
499          * For a perfectly circular displacement, this lowers the displacement
500          * by: 1/arcsin(arc_length)
501          * and arcsin(x) = 1 + x^2/6 + ...
502          * For sigma2_rel<<1 the displacement distribution is erfc
503          * (exact formula is provided below). For larger sigma, it is clear
504          * that the displacement can't be larger than 2*com_dist.
505          * It turns out that the distribution becomes nearly uniform.
506          * For intermediate sigma2_rel, scaling down sigma with the third
507          * order expansion of arcsin with argument sigma_rel turns out
508          * to give a very good approximation of the distribution and variance.
509          * Even for larger values, the variance is only slightly overestimated.
510          * Note that the most relevant displacements are in the long tail.
511          * This rotation approximation always overestimates the tail (which
512          * runs to infinity, whereas it should be <= 2*com_dist).
513          * Thus we always overestimate the drift and the buffer size.
514          */
515         scale      = 1/(1 + sigma2_rel/6);
516         *sigma2_2d = sigma2_rot*scale*scale;
517     }
518     else
519     {
520         /* sigma_2d is set to the maximum given by the scaling above.
521          * For large sigma2 the real displacement distribution is close
522          * to uniform over -2*con_len to 2*com_dist.
523          * Our erfc with sigma_2d=sqrt(1.5)*com_dist (which means the sigma
524          * of the erfc output distribution is con_dist) overestimates
525          * the variance and additionally has a long tail. This means
526          * we have a (safe) overestimation of the drift.
527          */
528         *sigma2_2d = 1.5*com_dist*com_dist;
529     }
530
531     /* The constrained atom also moves (in 3D) with the COM of both atoms */
532     *sigma2_3d = kT_fac/(prop->mass + prop->con_mass);
533 }
534
535 static void get_atom_sigma2(real                                 kT_fac,
536                             const atom_nonbonded_kinetic_prop_t *prop,
537                             real                                *sigma2_2d,
538                             real                                *sigma2_3d)
539 {
540     if (prop->bConstr)
541     {
542         /* Complicated constraint calculation in a separate function */
543         constrained_atom_sigma2(kT_fac, prop, sigma2_2d, sigma2_3d);
544     }
545     else
546     {
547         /* Unconstrained atom: trivial */
548         *sigma2_2d = 0;
549         *sigma2_3d = kT_fac/prop->mass;
550     }
551 }
552
553 static void approx_2dof(real s2, real x, real *shift, real *scale)
554 {
555     /* A particle with 1 DOF constrained has 2 DOFs instead of 3.
556      * This code is also used for particles with multiple constraints,
557      * in which case we overestimate the displacement.
558      * The 2DOF distribution is sqrt(pi/2)*erfc(r/(sqrt(2)*s))/(2*s).
559      * We approximate this with scale*Gaussian(s,r+shift),
560      * by matching the distribution value and derivative at x.
561      * This is a tight overestimate for all r>=0 at any s and x.
562      */
563     real ex, er;
564
565     ex = exp(-x*x/(2*s2));
566     er = gmx_erfc(x/sqrt(2*s2));
567
568     *shift = -x + sqrt(2*s2/M_PI)*ex/er;
569     *scale = 0.5*M_PI*exp(ex*ex/(M_PI*er*er))*er;
570 }
571
572 static real ener_drift(const verletbuf_atomtype_t *att, int natt,
573                        const gmx_ffparams_t *ffp,
574                        real kT_fac,
575                        real md1_ljd, real d2_ljd, real md3_ljd,
576                        real md1_ljr, real d2_ljr, real md3_ljr,
577                        real md1_el,  real d2_el,
578                        real r_buffer,
579                        real rlist, real boxvol)
580 {
581     /* Erfc(8)=1e-29, use this limit so we have some space for arithmetic
582      * on the result when using float precision.
583      */
584     const real erfc_arg_max = 8.0;
585
586     double     drift_tot, pot1, pot2, pot3, pot;
587     int        i, j;
588     real       s2i_2d, s2i_3d, s2j_2d, s2j_3d, s2, s;
589     int        ti, tj;
590     real       md1, d2, md3;
591     real       sc_fac, rsh, rsh2;
592     double     c_exp, c_erfc;
593
594     drift_tot = 0;
595
596     /* Loop over the different atom type pairs */
597     for (i = 0; i < natt; i++)
598     {
599         get_atom_sigma2(kT_fac, &att[i].prop, &s2i_2d, &s2i_3d);
600         ti = att[i].prop.type;
601
602         for (j = i; j < natt; j++)
603         {
604             get_atom_sigma2(kT_fac, &att[j].prop, &s2j_2d, &s2j_3d);
605             tj = att[j].prop.type;
606
607             /* Add up the up to four independent variances */
608             s2 = s2i_2d + s2i_3d + s2j_2d + s2j_3d;
609
610             /* Note that attractive and repulsive potentials for individual
611              * pairs will partially cancel.
612              */
613             /* -dV/dr at the cut-off for LJ + Coulomb */
614             md1 =
615                 md1_ljd*ffp->iparams[ti*ffp->atnr+tj].lj.c6 +
616                 md1_ljr*ffp->iparams[ti*ffp->atnr+tj].lj.c12 +
617                 md1_el*att[i].prop.q*att[j].prop.q;
618
619             /* d2V/dr2 at the cut-off for LJ + Coulomb */
620             d2 =
621                 d2_ljd*ffp->iparams[ti*ffp->atnr+tj].lj.c6 +
622                 d2_ljr*ffp->iparams[ti*ffp->atnr+tj].lj.c12 +
623                 d2_el*att[i].prop.q*att[j].prop.q;
624
625             /* -d3V/dr3 at the cut-off for LJ, we neglect Coulomb */
626             md3 =
627                 md3_ljd*ffp->iparams[ti*ffp->atnr+tj].lj.c6 +
628                 md3_ljr*ffp->iparams[ti*ffp->atnr+tj].lj.c12;
629
630             rsh    = r_buffer;
631             sc_fac = 1.0;
632
633             if (rsh*rsh > 2*s2*erfc_arg_max*erfc_arg_max)
634             {
635                 /* Erfc might run out of float and become 0, somewhat before
636                  * c_exp becomes 0. To avoid this and to avoid NaN in
637                  * approx_2dof, we set both c_expc and c_erfc to zero.
638                  * In any relevant case this has no effect on the results,
639                  * since c_exp < 6e-29, so the displacement is completely
640                  * negligible for such atom pairs (and an overestimate).
641                  * In nearly all use cases, there will be other atom
642                  * pairs that contribute much more to the total, so zeroing
643                  * this particular contribution has no effect at all.
644                  */
645                 c_exp  = 0;
646                 c_erfc = 0;
647             }
648             else
649             {
650                 /* For constraints: adapt r and scaling for the Gaussian */
651                 if (att[i].prop.bConstr)
652                 {
653                     real sh, sc;
654
655                     approx_2dof(s2i_2d, r_buffer*s2i_2d/s2, &sh, &sc);
656                     rsh    += sh;
657                     sc_fac *= sc;
658                 }
659                 if (att[j].prop.bConstr)
660                 {
661                     real sh, sc;
662
663                     approx_2dof(s2j_2d, r_buffer*s2j_2d/s2, &sh, &sc);
664                     rsh    += sh;
665                     sc_fac *= sc;
666                 }
667
668                 /* Exact contribution of an atom pair with Gaussian displacement
669                  * with sigma s to the energy drift for a potential with
670                  * derivative -md and second derivative dd at the cut-off.
671                  * The only catch is that for potentials that change sign
672                  * near the cut-off there could be an unlucky compensation
673                  * of positive and negative energy drift.
674                  * Such potentials are extremely rare though.
675                  *
676                  * Note that pot has unit energy*length, as the linear
677                  * atom density still needs to be put in.
678                  */
679                 c_exp  = exp(-rsh*rsh/(2*s2))/sqrt(2*M_PI);
680                 c_erfc = 0.5*gmx_erfc(rsh/(sqrt(2*s2)));
681             }
682             s      = sqrt(s2);
683             rsh2   = rsh*rsh;
684
685             pot1 = sc_fac*
686                 md1/2*((rsh2 + s2)*c_erfc - rsh*s*c_exp);
687             pot2 = sc_fac*
688                 d2/6*(s*(rsh2 + 2*s2)*c_exp - rsh*(rsh2 + 3*s2)*c_erfc);
689             pot3 = sc_fac*
690                 md3/24*((rsh2*rsh2 + 6*rsh2*s2 + 3*s2*s2)*c_erfc - rsh*s*(rsh2 + 5*s2)*c_exp);
691             pot = pot1 + pot2 + pot3;
692
693             if (gmx_debug_at)
694             {
695                 fprintf(debug, "n %d %d d s %.3f %.3f %.3f %.3f con %d -d1 %8.1e d2 %8.1e -d3 %8.1e pot1 %8.1e pot2 %8.1e pot3 %8.1e pot %8.1e\n",
696                         att[i].n, att[j].n,
697                         sqrt(s2i_2d), sqrt(s2i_3d),
698                         sqrt(s2j_2d), sqrt(s2j_3d),
699                         att[i].prop.bConstr+att[j].prop.bConstr,
700                         md1, d2, md3,
701                         pot1, pot2, pot3, pot);
702             }
703
704             /* Multiply by the number of atom pairs */
705             if (j == i)
706             {
707                 pot *= (double)att[i].n*(att[i].n - 1)/2;
708             }
709             else
710             {
711                 pot *= (double)att[i].n*att[j].n;
712             }
713             /* We need the line density to get the energy drift of the system.
714              * The effective average r^2 is close to (rlist+sigma)^2.
715              */
716             pot *= 4*M_PI*sqr(rlist + s)/boxvol;
717
718             /* Add the unsigned drift to avoid cancellation of errors */
719             drift_tot += fabs(pot);
720         }
721     }
722
723     return drift_tot;
724 }
725
726 static real surface_frac(int cluster_size, real particle_distance, real rlist)
727 {
728     real d, area_rel;
729
730     if (rlist < 0.5*particle_distance)
731     {
732         /* We have non overlapping spheres */
733         return 1.0;
734     }
735
736     /* Half the inter-particle distance relative to rlist */
737     d = 0.5*particle_distance/rlist;
738
739     /* Determine the area of the surface at distance rlist to the closest
740      * particle, relative to surface of a sphere of radius rlist.
741      * The formulas below assume close to cubic cells for the pair search grid,
742      * which the pair search code tries to achieve.
743      * Note that in practice particle distances will not be delta distributed,
744      * but have some spread, often involving shorter distances,
745      * as e.g. O-H bonds in a water molecule. Thus the estimates below will
746      * usually be slightly too high and thus conservative.
747      */
748     switch (cluster_size)
749     {
750         case 1:
751             /* One particle: trivial */
752             area_rel = 1.0;
753             break;
754         case 2:
755             /* Two particles: two spheres at fractional distance 2*a */
756             area_rel = 1.0 + d;
757             break;
758         case 4:
759             /* We assume a perfect, symmetric tetrahedron geometry.
760              * The surface around a tetrahedron is too complex for a full
761              * analytical solution, so we use a Taylor expansion.
762              */
763             area_rel = (1.0 + 1/M_PI*(6*acos(1/sqrt(3))*d +
764                                       sqrt(3)*d*d*(1.0 +
765                                                    5.0/18.0*d*d +
766                                                    7.0/45.0*d*d*d*d +
767                                                    83.0/756.0*d*d*d*d*d*d)));
768             break;
769         default:
770             gmx_incons("surface_frac called with unsupported cluster_size");
771             area_rel = 1.0;
772     }
773
774     return area_rel/cluster_size;
775 }
776
777 /* Returns the negative of the third derivative of a potential r^-p
778  * with a force-switch function, evaluated at the cut-off rc.
779  */
780 static real md3_force_switch(real p, real rswitch, real rc)
781 {
782     /* The switched force function is:
783      * p*r^-(p+1) + a*(r - rswitch)^2 + b*(r - rswitch)^3
784      */
785     real a, b;
786     real md3_pot, md3_sw;
787
788     a = -((p + 4)*rc - (p + 1)*rswitch)/(pow(rc, p+2)*pow(rc-rswitch, 2));
789     b =  ((p + 3)*rc - (p + 1)*rswitch)/(pow(rc, p+2)*pow(rc-rswitch, 3));
790
791     md3_pot = (p + 2)*(p + 1)*p*pow(rc, p+3);
792     md3_sw  = 2*a + 6*b*(rc - rswitch);
793
794     return md3_pot + md3_sw;
795 }
796
797 void calc_verlet_buffer_size(const gmx_mtop_t *mtop, real boxvol,
798                              const t_inputrec *ir,
799                              real reference_temperature,
800                              const verletbuf_list_setup_t *list_setup,
801                              int *n_nonlin_vsite,
802                              real *rlist)
803 {
804     double                resolution;
805     char                 *env;
806
807     real                  particle_distance;
808     real                  nb_clust_frac_pairs_not_in_list_at_cutoff;
809
810     verletbuf_atomtype_t *att  = NULL;
811     int                   natt = -1, i;
812     double                reppow;
813     real                  md1_ljd, d2_ljd, md3_ljd;
814     real                  md1_ljr, d2_ljr, md3_ljr;
815     real                  md1_el,  d2_el;
816     real                  elfac;
817     real                  kT_fac, mass_min;
818     int                   ib0, ib1, ib;
819     real                  rb, rl;
820     real                  drift;
821
822     if (reference_temperature < 0)
823     {
824         if (EI_MD(ir->eI) && ir->etc == etcNO)
825         {
826             /* This case should be handled outside calc_verlet_buffer_size */
827             gmx_incons("calc_verlet_buffer_size called with an NVE ensemble and reference_temperature < 0");
828         }
829
830         /* We use the maximum temperature with multiple T-coupl groups.
831          * We could use a per particle temperature, but since particles
832          * interact, this might underestimate the buffer size.
833          */
834         reference_temperature = 0;
835         for (i = 0; i < ir->opts.ngtc; i++)
836         {
837             if (ir->opts.tau_t[i] >= 0)
838             {
839                 reference_temperature = max(reference_temperature,
840                                             ir->opts.ref_t[i]);
841             }
842         }
843     }
844
845     /* Resolution of the buffer size */
846     resolution = 0.001;
847
848     env = getenv("GMX_VERLET_BUFFER_RES");
849     if (env != NULL)
850     {
851         sscanf(env, "%lf", &resolution);
852     }
853
854     /* In an atom wise pair-list there would be no pairs in the list
855      * beyond the pair-list cut-off.
856      * However, we use a pair-list of groups vs groups of atoms.
857      * For groups of 4 atoms, the parallelism of SSE instructions, only
858      * 10% of the atoms pairs are not in the list just beyond the cut-off.
859      * As this percentage increases slowly compared to the decrease of the
860      * Gaussian displacement distribution over this range, we can simply
861      * reduce the drift by this fraction.
862      * For larger groups, e.g. of 8 atoms, this fraction will be lower,
863      * so then buffer size will be on the conservative (large) side.
864      *
865      * Note that the formulas used here do not take into account
866      * cancellation of errors which could occur by missing both
867      * attractive and repulsive interactions.
868      *
869      * The only major assumption is homogeneous particle distribution.
870      * For an inhomogeneous system, such as a liquid-vapor system,
871      * the buffer will be underestimated. The actual energy drift
872      * will be higher by the factor: local/homogeneous particle density.
873      *
874      * The results of this estimate have been checked againt simulations.
875      * In most cases the real drift differs by less than a factor 2.
876      */
877
878     /* Worst case assumption: HCP packing of particles gives largest distance */
879     particle_distance = pow(boxvol*sqrt(2)/mtop->natoms, 1.0/3.0);
880
881     get_verlet_buffer_atomtypes(mtop, &att, &natt, n_nonlin_vsite);
882     assert(att != NULL && natt >= 0);
883
884     if (debug)
885     {
886         fprintf(debug, "particle distance assuming HCP packing: %f nm\n",
887                 particle_distance);
888         fprintf(debug, "energy drift atom types: %d\n", natt);
889     }
890
891     reppow   = mtop->ffparams.reppow;
892     md1_ljd  = 0;
893     d2_ljd   = 0;
894     md3_ljd  = 0;
895     md1_ljr  = 0;
896     d2_ljr   = 0;
897     md3_ljr  = 0;
898     if (ir->vdwtype == evdwCUT)
899     {
900         real sw_range, md3_pswf;
901
902         switch (ir->vdw_modifier)
903         {
904             case eintmodNONE:
905             case eintmodPOTSHIFT:
906                 /* -dV/dr of -r^-6 and r^-reppow */
907                 md1_ljd =     -6*pow(ir->rvdw, -7.0);
908                 md1_ljr = reppow*pow(ir->rvdw, -(reppow+1));
909                 /* The contribution of the higher derivatives is negligible */
910                 break;
911             case eintmodFORCESWITCH:
912                 /* At the cut-off: V=V'=V''=0, so we use only V''' */
913                 md3_ljd  = -md3_force_switch(6.0,    ir->rvdw_switch, ir->rvdw);
914                 md3_ljr  =  md3_force_switch(reppow, ir->rvdw_switch, ir->rvdw);
915                 break;
916             case eintmodPOTSWITCH:
917                 /* At the cut-off: V=V'=V''=0.
918                  * V''' is given by the original potential times
919                  * the third derivative of the switch function.
920                  */
921                 sw_range  = ir->rvdw - ir->rvdw_switch;
922                 md3_pswf  = 60.0*pow(sw_range, -3.0);
923
924                 md3_ljd   = -pow(ir->rvdw, -6.0   )*md3_pswf;
925                 md3_ljr   =  pow(ir->rvdw, -reppow)*md3_pswf;
926                 break;
927             default:
928                 gmx_incons("Unimplemented VdW modifier");
929         }
930     }
931     else if (EVDW_PME(ir->vdwtype))
932     {
933         real b, r, br, br2, br4, br6;
934         b        = calc_ewaldcoeff_lj(ir->rvdw, ir->ewald_rtol_lj);
935         r        = ir->rvdw;
936         br       = b*r;
937         br2      = br*br;
938         br4      = br2*br2;
939         br6      = br4*br2;
940         /* -dV/dr of g(br)*r^-6 [where g(x) = exp(-x^2)(1+x^2+x^4/2), see LJ-PME equations in manual] and r^-reppow */
941         md1_ljd  = -exp(-br2)*(br6 + 3.0*br4 + 6.0*br2 + 6.0)*pow(r, -7.0);
942         md1_ljr  = reppow*pow(r, -(reppow+1));
943         /* The contribution of the higher derivatives is negligible */
944     }
945     else
946     {
947         gmx_fatal(FARGS, "Energy drift calculation is only implemented for plain cut-off Lennard-Jones interactions");
948     }
949
950     elfac = ONE_4PI_EPS0/ir->epsilon_r;
951
952     /* Determine md=-dV/dr and dd=d^2V/dr^2 */
953     md1_el = 0;
954     d2_el  = 0;
955     if (ir->coulombtype == eelCUT || EEL_RF(ir->coulombtype))
956     {
957         real eps_rf, k_rf;
958
959         if (ir->coulombtype == eelCUT)
960         {
961             eps_rf = 1;
962             k_rf   = 0;
963         }
964         else
965         {
966             eps_rf = ir->epsilon_rf/ir->epsilon_r;
967             if (eps_rf != 0)
968             {
969                 k_rf = pow(ir->rcoulomb, -3.0)*(eps_rf - ir->epsilon_r)/(2*eps_rf + ir->epsilon_r);
970             }
971             else
972             {
973                 /* epsilon_rf = infinity */
974                 k_rf = 0.5*pow(ir->rcoulomb, -3.0);
975             }
976         }
977
978         if (eps_rf > 0)
979         {
980             md1_el = elfac*(pow(ir->rcoulomb, -2.0) - 2*k_rf*ir->rcoulomb);
981         }
982         d2_el      = elfac*(2*pow(ir->rcoulomb, -3.0) + 2*k_rf);
983     }
984     else if (EEL_PME(ir->coulombtype) || ir->coulombtype == eelEWALD)
985     {
986         real b, rc, br;
987
988         b      = calc_ewaldcoeff_q(ir->rcoulomb, ir->ewald_rtol);
989         rc     = ir->rcoulomb;
990         br     = b*rc;
991         md1_el = elfac*(b*exp(-br*br)*M_2_SQRTPI/rc + gmx_erfc(br)/(rc*rc));
992         d2_el  = elfac/(rc*rc)*(2*b*(1 + br*br)*exp(-br*br)*M_2_SQRTPI + 2*gmx_erfc(br)/rc);
993     }
994     else
995     {
996         gmx_fatal(FARGS, "Energy drift calculation is only implemented for Reaction-Field and Ewald electrostatics");
997     }
998
999     /* Determine the variance of the atomic displacement
1000      * over nstlist-1 steps: kT_fac
1001      * For inertial dynamics (not Brownian dynamics) the mass factor
1002      * is not included in kT_fac, it is added later.
1003      */
1004     if (ir->eI == eiBD)
1005     {
1006         /* Get the displacement distribution from the random component only.
1007          * With accurate integration the systematic (force) displacement
1008          * should be negligible (unless nstlist is extremely large, which
1009          * you wouldn't do anyhow).
1010          */
1011         kT_fac = 2*BOLTZ*reference_temperature*(ir->nstlist-1)*ir->delta_t;
1012         if (ir->bd_fric > 0)
1013         {
1014             /* This is directly sigma^2 of the displacement */
1015             kT_fac /= ir->bd_fric;
1016
1017             /* Set the masses to 1 as kT_fac is the full sigma^2,
1018              * but we divide by m in ener_drift().
1019              */
1020             for (i = 0; i < natt; i++)
1021             {
1022                 att[i].prop.mass = 1;
1023             }
1024         }
1025         else
1026         {
1027             real tau_t;
1028
1029             /* Per group tau_t is not implemented yet, use the maximum */
1030             tau_t = ir->opts.tau_t[0];
1031             for (i = 1; i < ir->opts.ngtc; i++)
1032             {
1033                 tau_t = max(tau_t, ir->opts.tau_t[i]);
1034             }
1035
1036             kT_fac *= tau_t;
1037             /* This kT_fac needs to be divided by the mass to get sigma^2 */
1038         }
1039     }
1040     else
1041     {
1042         kT_fac = BOLTZ*reference_temperature*sqr((ir->nstlist-1)*ir->delta_t);
1043     }
1044
1045     mass_min = att[0].prop.mass;
1046     for (i = 1; i < natt; i++)
1047     {
1048         mass_min = min(mass_min, att[i].prop.mass);
1049     }
1050
1051     if (debug)
1052     {
1053         fprintf(debug, "md1_ljd %9.2e d2_ljd %9.2e md3_ljd %9.2e\n", md1_ljd, d2_ljd, md3_ljd);
1054         fprintf(debug, "md1_ljr %9.2e d2_ljr %9.2e md3_ljr %9.2e\n", md1_ljr, d2_ljr, md3_ljr);
1055         fprintf(debug, "md1_el  %9.2e d2_el  %9.2e\n", md1_el, d2_el);
1056         fprintf(debug, "sqrt(kT_fac) %f\n", sqrt(kT_fac));
1057         fprintf(debug, "mass_min %f\n", mass_min);
1058     }
1059
1060     /* Search using bisection */
1061     ib0 = -1;
1062     /* The drift will be neglible at 5 times the max sigma */
1063     ib1 = (int)(5*2*sqrt(kT_fac/mass_min)/resolution) + 1;
1064     while (ib1 - ib0 > 1)
1065     {
1066         ib = (ib0 + ib1)/2;
1067         rb = ib*resolution;
1068         rl = max(ir->rvdw, ir->rcoulomb) + rb;
1069
1070         /* Calculate the average energy drift at the last step
1071          * of the nstlist steps at which the pair-list is used.
1072          */
1073         drift = ener_drift(att, natt, &mtop->ffparams,
1074                            kT_fac,
1075                            md1_ljd, d2_ljd, md3_ljd,
1076                            md1_ljr, d2_ljr, md3_ljr,
1077                            md1_el,  d2_el,
1078                            rb,
1079                            rl, boxvol);
1080
1081         /* Correct for the fact that we are using a Ni x Nj particle pair list
1082          * and not a 1 x 1 particle pair list. This reduces the drift.
1083          */
1084         /* We don't have a formula for 8 (yet), use 4 which is conservative */
1085         nb_clust_frac_pairs_not_in_list_at_cutoff =
1086             surface_frac(min(list_setup->cluster_size_i, 4),
1087                          particle_distance, rl)*
1088             surface_frac(min(list_setup->cluster_size_j, 4),
1089                          particle_distance, rl);
1090         drift *= nb_clust_frac_pairs_not_in_list_at_cutoff;
1091
1092         /* Convert the drift to drift per unit time per atom */
1093         drift /= ir->nstlist*ir->delta_t*mtop->natoms;
1094
1095         if (debug)
1096         {
1097             fprintf(debug, "ib %3d %3d %3d rb %.3f %dx%d fac %.3f drift %.1e\n",
1098                     ib0, ib, ib1, rb,
1099                     list_setup->cluster_size_i, list_setup->cluster_size_j,
1100                     nb_clust_frac_pairs_not_in_list_at_cutoff,
1101                     drift);
1102         }
1103
1104         if (fabs(drift) > ir->verletbuf_tol)
1105         {
1106             ib0 = ib;
1107         }
1108         else
1109         {
1110             ib1 = ib;
1111         }
1112     }
1113
1114     sfree(att);
1115
1116     *rlist = max(ir->rvdw, ir->rcoulomb) + ib1*resolution;
1117 }