Fixes potential bug in neighborsearching.
[alexxy/gromacs.git] / src / gromacs / mdlib / ns.c
1 /*
2  * This file is part of the GROMACS molecular simulation package.
3  *
4  * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
5  * Copyright (c) 2001-2004, The GROMACS development team.
6  * Copyright (c) 2013,2014, by the GROMACS development team, led by
7  * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
8  * and including many others, as listed in the AUTHORS file in the
9  * top-level source directory and at http://www.gromacs.org.
10  *
11  * GROMACS is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU Lesser General Public License
13  * as published by the Free Software Foundation; either version 2.1
14  * of the License, or (at your option) any later version.
15  *
16  * GROMACS is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19  * Lesser General Public License for more details.
20  *
21  * You should have received a copy of the GNU Lesser General Public
22  * License along with GROMACS; if not, see
23  * http://www.gnu.org/licenses, or write to the Free Software Foundation,
24  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA.
25  *
26  * If you want to redistribute modifications to GROMACS, please
27  * consider that scientific software is very special. Version
28  * control is crucial - bugs must be traceable. We will be happy to
29  * consider code for inclusion in the official distribution, but
30  * derived work must not be called official GROMACS. Details are found
31  * in the README & COPYING files - if they are missing, get the
32  * official version at http://www.gromacs.org.
33  *
34  * To help us fund GROMACS development, we humbly ask that you cite
35  * the research papers on the package. Check out http://www.gromacs.org.
36  */
37 #ifdef HAVE_CONFIG_H
38 #include <config.h>
39 #endif
40
41 #include <math.h>
42 #include <string.h>
43 #include "sysstuff.h"
44 #include "gromacs/utility/smalloc.h"
45 #include "macros.h"
46 #include "gromacs/math/utilities.h"
47 #include "vec.h"
48 #include "types/commrec.h"
49 #include "network.h"
50 #include "nsgrid.h"
51 #include "force.h"
52 #include "nonbonded.h"
53 #include "ns.h"
54 #include "pbc.h"
55 #include "names.h"
56 #include "gmx_fatal.h"
57 #include "nrnb.h"
58 #include "txtdump.h"
59 #include "mtop_util.h"
60
61 #include "domdec.h"
62 #include "adress.h"
63
64
65 /*
66  *    E X C L U S I O N   H A N D L I N G
67  */
68
69 #ifdef DEBUG
70 static void SETEXCL_(t_excl e[], atom_id i, atom_id j)
71 {
72     e[j] = e[j] | (1<<i);
73 }
74 static void RMEXCL_(t_excl e[], atom_id i, atom_id j)
75 {
76     e[j] = e[j] & ~(1<<i);
77 }
78 static gmx_bool ISEXCL_(t_excl e[], atom_id i, atom_id j)
79 {
80     return (gmx_bool)(e[j] & (1<<i));
81 }
82 static gmx_bool NOTEXCL_(t_excl e[], atom_id i, atom_id j)
83 {
84     return !(ISEXCL(e, i, j));
85 }
86 #else
87 #define SETEXCL(e, i, j) (e)[((atom_id) (j))] |= (1<<((atom_id) (i)))
88 #define RMEXCL(e, i, j)  (e)[((atom_id) (j))] &= (~(1<<((atom_id) (i))))
89 #define ISEXCL(e, i, j)  (gmx_bool) ((e)[((atom_id) (j))] & (1<<((atom_id) (i))))
90 #define NOTEXCL(e, i, j) !(ISEXCL(e, i, j))
91 #endif
92
93 static int
94 round_up_to_simd_width(int length, int simd_width)
95 {
96     int offset, newlength;
97
98     offset = (simd_width > 0) ? length % simd_width : 0;
99
100     return (offset == 0) ? length : length-offset+simd_width;
101 }
102 /************************************************
103  *
104  *  U T I L I T I E S    F O R    N S
105  *
106  ************************************************/
107
108 void reallocate_nblist(t_nblist *nl)
109 {
110     if (gmx_debug_at)
111     {
112         fprintf(debug, "reallocating neigborlist (ielec=%d, ivdw=%d, igeometry=%d, type=%d), maxnri=%d\n",
113                 nl->ielec, nl->ivdw, nl->igeometry, nl->type, nl->maxnri);
114     }
115     srenew(nl->iinr,   nl->maxnri);
116     if (nl->igeometry == GMX_NBLIST_GEOMETRY_CG_CG)
117     {
118         srenew(nl->iinr_end, nl->maxnri);
119     }
120     srenew(nl->gid,    nl->maxnri);
121     srenew(nl->shift,  nl->maxnri);
122     srenew(nl->jindex, nl->maxnri+1);
123 }
124
125
126 static void init_nblist(FILE *log, t_nblist *nl_sr, t_nblist *nl_lr,
127                         int maxsr, int maxlr,
128                         int ivdw, int ivdwmod,
129                         int ielec, int ielecmod,
130                         int igeometry, int type,
131                         gmx_bool bElecAndVdwSwitchDiffers)
132 {
133     t_nblist *nl;
134     int       homenr;
135     int       i, nn;
136
137     for (i = 0; (i < 2); i++)
138     {
139         nl     = (i == 0) ? nl_sr : nl_lr;
140         homenr = (i == 0) ? maxsr : maxlr;
141
142         if (nl == NULL)
143         {
144             continue;
145         }
146
147
148         /* Set coul/vdw in neighborlist, and for the normal loops we determine
149          * an index of which one to call.
150          */
151         nl->ivdw        = ivdw;
152         nl->ivdwmod     = ivdwmod;
153         nl->ielec       = ielec;
154         nl->ielecmod    = ielecmod;
155         nl->type        = type;
156         nl->igeometry   = igeometry;
157
158         if (nl->type == GMX_NBLIST_INTERACTION_FREE_ENERGY)
159         {
160             nl->igeometry  = GMX_NBLIST_GEOMETRY_PARTICLE_PARTICLE;
161         }
162
163         /* This will also set the simd_padding_width field */
164         gmx_nonbonded_set_kernel_pointers( (i == 0) ? log : NULL, nl, bElecAndVdwSwitchDiffers);
165
166         /* maxnri is influenced by the number of shifts (maximum is 8)
167          * and the number of energy groups.
168          * If it is not enough, nl memory will be reallocated during the run.
169          * 4 seems to be a reasonable factor, which only causes reallocation
170          * during runs with tiny and many energygroups.
171          */
172         nl->maxnri      = homenr*4;
173         nl->maxnrj      = 0;
174         nl->nri         = -1;
175         nl->nrj         = 0;
176         nl->iinr        = NULL;
177         nl->gid         = NULL;
178         nl->shift       = NULL;
179         nl->jindex      = NULL;
180         nl->jjnr        = NULL;
181         nl->excl_fep    = NULL;
182         reallocate_nblist(nl);
183         nl->jindex[0] = 0;
184
185         if (debug)
186         {
187             fprintf(debug, "Initiating neighbourlist (ielec=%d, ivdw=%d, type=%d) for %s interactions,\nwith %d SR, %d LR atoms.\n",
188                     nl->ielec, nl->ivdw, nl->type, gmx_nblist_geometry_names[nl->igeometry], maxsr, maxlr);
189         }
190     }
191 }
192
193 void init_neighbor_list(FILE *log, t_forcerec *fr, int homenr)
194 {
195     /* Make maxlr tunable! (does not seem to be a big difference though)
196      * This parameter determines the number of i particles in a long range
197      * neighbourlist. Too few means many function calls, too many means
198      * cache trashing.
199      */
200     int        maxsr, maxsr_wat, maxlr, maxlr_wat;
201     int        ielec, ivdw, ielecmod, ivdwmod, type;
202     int        solvent;
203     int        igeometry_def, igeometry_w, igeometry_ww;
204     int        i;
205     gmx_bool   bElecAndVdwSwitchDiffers;
206     t_nblists *nbl;
207
208     /* maxsr     = homenr-fr->nWatMol*3; */
209     maxsr     = homenr;
210
211     if (maxsr < 0)
212     {
213         gmx_fatal(FARGS, "%s, %d: Negative number of short range atoms.\n"
214                   "Call your Gromacs dealer for assistance.", __FILE__, __LINE__);
215     }
216     /* This is just for initial allocation, so we do not reallocate
217      * all the nlist arrays many times in a row.
218      * The numbers seem very accurate, but they are uncritical.
219      */
220     maxsr_wat = min(fr->nWatMol, (homenr+2)/3);
221     if (fr->bTwinRange)
222     {
223         maxlr     = 50;
224         maxlr_wat = min(maxsr_wat, maxlr);
225     }
226     else
227     {
228         maxlr = maxlr_wat = 0;
229     }
230
231     /* Determine the values for ielec/ivdw. */
232     ielec                    = fr->nbkernel_elec_interaction;
233     ivdw                     = fr->nbkernel_vdw_interaction;
234     ielecmod                 = fr->nbkernel_elec_modifier;
235     ivdwmod                  = fr->nbkernel_vdw_modifier;
236     type                     = GMX_NBLIST_INTERACTION_STANDARD;
237     bElecAndVdwSwitchDiffers = ( (fr->rcoulomb_switch != fr->rvdw_switch) || (fr->rcoulomb != fr->rvdw));
238
239     fr->ns.bCGlist = (getenv("GMX_NBLISTCG") != 0);
240     if (!fr->ns.bCGlist)
241     {
242         igeometry_def = GMX_NBLIST_GEOMETRY_PARTICLE_PARTICLE;
243     }
244     else
245     {
246         igeometry_def = GMX_NBLIST_GEOMETRY_CG_CG;
247         if (log != NULL)
248         {
249             fprintf(log, "\nUsing charge-group - charge-group neighbor lists and kernels\n\n");
250         }
251     }
252
253     if (fr->solvent_opt == esolTIP4P)
254     {
255         igeometry_w  = GMX_NBLIST_GEOMETRY_WATER4_PARTICLE;
256         igeometry_ww = GMX_NBLIST_GEOMETRY_WATER4_WATER4;
257     }
258     else
259     {
260         igeometry_w  = GMX_NBLIST_GEOMETRY_WATER3_PARTICLE;
261         igeometry_ww = GMX_NBLIST_GEOMETRY_WATER3_WATER3;
262     }
263
264     for (i = 0; i < fr->nnblists; i++)
265     {
266         nbl = &(fr->nblists[i]);
267
268         if ((fr->adress_type != eAdressOff) && (i >= fr->nnblists/2))
269         {
270             type = GMX_NBLIST_INTERACTION_ADRESS;
271         }
272         init_nblist(log, &nbl->nlist_sr[eNL_VDWQQ], &nbl->nlist_lr[eNL_VDWQQ],
273                     maxsr, maxlr, ivdw, ivdwmod, ielec, ielecmod, igeometry_def, type, bElecAndVdwSwitchDiffers);
274         init_nblist(log, &nbl->nlist_sr[eNL_VDW], &nbl->nlist_lr[eNL_VDW],
275                     maxsr, maxlr, ivdw, ivdwmod, GMX_NBKERNEL_ELEC_NONE, eintmodNONE, igeometry_def, type, bElecAndVdwSwitchDiffers);
276         init_nblist(log, &nbl->nlist_sr[eNL_QQ], &nbl->nlist_lr[eNL_QQ],
277                     maxsr, maxlr, GMX_NBKERNEL_VDW_NONE, eintmodNONE, ielec, ielecmod, igeometry_def, type, bElecAndVdwSwitchDiffers);
278         init_nblist(log, &nbl->nlist_sr[eNL_VDWQQ_WATER], &nbl->nlist_lr[eNL_VDWQQ_WATER],
279                     maxsr_wat, maxlr_wat, ivdw, ivdwmod, ielec, ielecmod, igeometry_w, type, bElecAndVdwSwitchDiffers);
280         init_nblist(log, &nbl->nlist_sr[eNL_QQ_WATER], &nbl->nlist_lr[eNL_QQ_WATER],
281                     maxsr_wat, maxlr_wat, GMX_NBKERNEL_VDW_NONE, eintmodNONE, ielec, ielecmod, igeometry_w, type, bElecAndVdwSwitchDiffers);
282         init_nblist(log, &nbl->nlist_sr[eNL_VDWQQ_WATERWATER], &nbl->nlist_lr[eNL_VDWQQ_WATERWATER],
283                     maxsr_wat, maxlr_wat, ivdw, ivdwmod, ielec, ielecmod, igeometry_ww, type, bElecAndVdwSwitchDiffers);
284         init_nblist(log, &nbl->nlist_sr[eNL_QQ_WATERWATER], &nbl->nlist_lr[eNL_QQ_WATERWATER],
285                     maxsr_wat, maxlr_wat, GMX_NBKERNEL_VDW_NONE, eintmodNONE, ielec, ielecmod, igeometry_ww, type, bElecAndVdwSwitchDiffers);
286
287         /* Did we get the solvent loops so we can use optimized water kernels? */
288         if (nbl->nlist_sr[eNL_VDWQQ_WATER].kernelptr_vf == NULL
289             || nbl->nlist_sr[eNL_QQ_WATER].kernelptr_vf == NULL
290 #ifndef DISABLE_WATERWATER_NLIST
291             || nbl->nlist_sr[eNL_VDWQQ_WATERWATER].kernelptr_vf == NULL
292             || nbl->nlist_sr[eNL_QQ_WATERWATER].kernelptr_vf == NULL
293 #endif
294             )
295         {
296             fr->solvent_opt = esolNO;
297             if (log != NULL)
298             {
299                 fprintf(log, "Note: The available nonbonded kernels do not support water optimization - disabling.\n");
300             }
301         }
302
303         if (fr->efep != efepNO)
304         {
305             init_nblist(log, &nbl->nlist_sr[eNL_VDWQQ_FREE], &nbl->nlist_lr[eNL_VDWQQ_FREE],
306                         maxsr, maxlr, ivdw, ivdwmod, ielec, ielecmod, GMX_NBLIST_GEOMETRY_PARTICLE_PARTICLE, GMX_NBLIST_INTERACTION_FREE_ENERGY, bElecAndVdwSwitchDiffers);
307             init_nblist(log, &nbl->nlist_sr[eNL_VDW_FREE], &nbl->nlist_lr[eNL_VDW_FREE],
308                         maxsr, maxlr, ivdw, ivdwmod, GMX_NBKERNEL_ELEC_NONE, eintmodNONE, GMX_NBLIST_GEOMETRY_PARTICLE_PARTICLE, GMX_NBLIST_INTERACTION_FREE_ENERGY, bElecAndVdwSwitchDiffers);
309             init_nblist(log, &nbl->nlist_sr[eNL_QQ_FREE], &nbl->nlist_lr[eNL_QQ_FREE],
310                         maxsr, maxlr, GMX_NBKERNEL_VDW_NONE, eintmodNONE, ielec, ielecmod, GMX_NBLIST_GEOMETRY_PARTICLE_PARTICLE, GMX_NBLIST_INTERACTION_FREE_ENERGY, bElecAndVdwSwitchDiffers);
311         }
312     }
313     /* QMMM MM list */
314     if (fr->bQMMM && fr->qr->QMMMscheme != eQMMMschemeoniom)
315     {
316         init_nblist(log, &fr->QMMMlist, NULL,
317                     maxsr, maxlr, 0, 0, ielec, ielecmod, GMX_NBLIST_GEOMETRY_PARTICLE_PARTICLE, GMX_NBLIST_INTERACTION_STANDARD, bElecAndVdwSwitchDiffers);
318     }
319
320     if (log != NULL)
321     {
322         fprintf(log, "\n");
323     }
324
325     fr->ns.nblist_initialized = TRUE;
326 }
327
328 static void reset_nblist(t_nblist *nl)
329 {
330     nl->nri       = -1;
331     nl->nrj       = 0;
332     if (nl->jindex)
333     {
334         nl->jindex[0] = 0;
335     }
336 }
337
338 static void reset_neighbor_lists(t_forcerec *fr, gmx_bool bResetSR, gmx_bool bResetLR)
339 {
340     int n, i;
341
342     if (fr->bQMMM)
343     {
344         /* only reset the short-range nblist */
345         reset_nblist(&(fr->QMMMlist));
346     }
347
348     for (n = 0; n < fr->nnblists; n++)
349     {
350         for (i = 0; i < eNL_NR; i++)
351         {
352             if (bResetSR)
353             {
354                 reset_nblist( &(fr->nblists[n].nlist_sr[i]) );
355             }
356             if (bResetLR)
357             {
358                 reset_nblist( &(fr->nblists[n].nlist_lr[i]) );
359             }
360         }
361     }
362 }
363
364
365
366
367 static gmx_inline void new_i_nblist(t_nblist *nlist, atom_id i_atom, int shift, int gid)
368 {
369     int    i, k, nri, nshift;
370
371     nri = nlist->nri;
372
373     /* Check whether we have to increase the i counter */
374     if ((nri == -1) ||
375         (nlist->iinr[nri]  != i_atom) ||
376         (nlist->shift[nri] != shift) ||
377         (nlist->gid[nri]   != gid))
378     {
379         /* This is something else. Now see if any entries have
380          * been added in the list of the previous atom.
381          */
382         if ((nri == -1) ||
383             ((nlist->jindex[nri+1] > nlist->jindex[nri]) &&
384              (nlist->gid[nri] != -1)))
385         {
386             /* If so increase the counter */
387             nlist->nri++;
388             nri++;
389             if (nlist->nri >= nlist->maxnri)
390             {
391                 nlist->maxnri += over_alloc_large(nlist->nri);
392                 reallocate_nblist(nlist);
393             }
394         }
395         /* Set the number of neighbours and the atom number */
396         nlist->jindex[nri+1] = nlist->jindex[nri];
397         nlist->iinr[nri]     = i_atom;
398         nlist->gid[nri]      = gid;
399         nlist->shift[nri]    = shift;
400     }
401     else
402     {
403         /* Adding to previous list. First remove possible previous padding */
404         if (nlist->simd_padding_width > 1)
405         {
406             while (nlist->nrj > 0 && nlist->jjnr[nlist->nrj-1] < 0)
407             {
408                 nlist->nrj--;
409             }
410         }
411     }
412 }
413
414 static gmx_inline void close_i_nblist(t_nblist *nlist)
415 {
416     int nri = nlist->nri;
417     int len;
418
419     if (nri >= 0)
420     {
421         /* Add elements up to padding. Since we allocate memory in units
422          * of the simd_padding width, we do not have to check for possible
423          * list reallocation here.
424          */
425         while ((nlist->nrj % nlist->simd_padding_width) != 0)
426         {
427             /* Use -4 here, so we can write forces for 4 atoms before real data */
428             nlist->jjnr[nlist->nrj++] = -4;
429         }
430         nlist->jindex[nri+1] = nlist->nrj;
431
432         len = nlist->nrj -  nlist->jindex[nri];
433         /* If there are no j-particles we have to reduce the
434          * number of i-particles again, to prevent errors in the
435          * kernel functions.
436          */
437         if ((len == 0) && (nlist->nri > 0))
438         {
439             nlist->nri--;
440         }
441     }
442 }
443
444 static gmx_inline void close_nblist(t_nblist *nlist)
445 {
446     /* Only close this nblist when it has been initialized.
447      * Avoid the creation of i-lists with no j-particles.
448      */
449     if (nlist->nrj == 0)
450     {
451         /* Some assembly kernels do not support empty lists,
452          * make sure here that we don't generate any empty lists.
453          * With the current ns code this branch is taken in two cases:
454          * No i-particles at all: nri=-1 here
455          * There are i-particles, but no j-particles; nri=0 here
456          */
457         nlist->nri = 0;
458     }
459     else
460     {
461         /* Close list number nri by incrementing the count */
462         nlist->nri++;
463     }
464 }
465
466 static gmx_inline void close_neighbor_lists(t_forcerec *fr, gmx_bool bMakeQMMMnblist)
467 {
468     int n, i;
469
470     if (bMakeQMMMnblist)
471     {
472         close_nblist(&(fr->QMMMlist));
473     }
474
475     for (n = 0; n < fr->nnblists; n++)
476     {
477         for (i = 0; (i < eNL_NR); i++)
478         {
479             close_nblist(&(fr->nblists[n].nlist_sr[i]));
480             close_nblist(&(fr->nblists[n].nlist_lr[i]));
481         }
482     }
483 }
484
485
486 static gmx_inline void add_j_to_nblist(t_nblist *nlist, atom_id j_atom, gmx_bool bLR)
487 {
488     int nrj = nlist->nrj;
489
490     if (nlist->nrj >= nlist->maxnrj)
491     {
492         nlist->maxnrj = round_up_to_simd_width(over_alloc_small(nlist->nrj + 1), nlist->simd_padding_width);
493
494         if (gmx_debug_at)
495         {
496             fprintf(debug, "Increasing %s nblist (ielec=%d,ivdw=%d,type=%d,igeometry=%d) j size to %d\n",
497                     bLR ? "LR" : "SR", nlist->ielec, nlist->ivdw, nlist->type, nlist->igeometry, nlist->maxnrj);
498         }
499
500         srenew(nlist->jjnr, nlist->maxnrj);
501     }
502
503     nlist->jjnr[nrj] = j_atom;
504     nlist->nrj++;
505 }
506
507 static gmx_inline void add_j_to_nblist_cg(t_nblist *nlist,
508                                           atom_id j_start, int j_end,
509                                           t_excl *bexcl, gmx_bool i_is_j,
510                                           gmx_bool bLR)
511 {
512     int nrj = nlist->nrj;
513     int j;
514
515     if (nlist->nrj >= nlist->maxnrj)
516     {
517         nlist->maxnrj = over_alloc_small(nlist->nrj + 1);
518         if (gmx_debug_at)
519         {
520             fprintf(debug, "Increasing %s nblist (ielec=%d,ivdw=%d,type=%d,igeometry=%d) j size to %d\n",
521                     bLR ? "LR" : "SR", nlist->ielec, nlist->ivdw, nlist->type, nlist->igeometry, nlist->maxnrj);
522         }
523
524         srenew(nlist->jjnr, nlist->maxnrj);
525         srenew(nlist->jjnr_end, nlist->maxnrj);
526         srenew(nlist->excl, nlist->maxnrj*MAX_CGCGSIZE);
527     }
528
529     nlist->jjnr[nrj]     = j_start;
530     nlist->jjnr_end[nrj] = j_end;
531
532     if (j_end - j_start > MAX_CGCGSIZE)
533     {
534         gmx_fatal(FARGS, "The charge-group - charge-group neighborlist do not support charge groups larger than %d, found a charge group of size %d", MAX_CGCGSIZE, j_end-j_start);
535     }
536
537     /* Set the exclusions */
538     for (j = j_start; j < j_end; j++)
539     {
540         nlist->excl[nrj*MAX_CGCGSIZE + j - j_start] = bexcl[j];
541     }
542     if (i_is_j)
543     {
544         /* Avoid double counting of intra-cg interactions */
545         for (j = 1; j < j_end-j_start; j++)
546         {
547             nlist->excl[nrj*MAX_CGCGSIZE + j] |= (1<<j) - 1;
548         }
549     }
550
551     nlist->nrj++;
552 }
553
554 typedef void
555     put_in_list_t (gmx_bool              bHaveVdW[],
556                    int                   ngid,
557                    t_mdatoms     *       md,
558                    int                   icg,
559                    int                   jgid,
560                    int                   nj,
561                    atom_id               jjcg[],
562                    atom_id               index[],
563                    t_excl                bExcl[],
564                    int                   shift,
565                    t_forcerec     *      fr,
566                    gmx_bool              bLR,
567                    gmx_bool              bDoVdW,
568                    gmx_bool              bDoCoul,
569                    int                   solvent_opt);
570
571 static void
572 put_in_list_at(gmx_bool              bHaveVdW[],
573                int                   ngid,
574                t_mdatoms     *       md,
575                int                   icg,
576                int                   jgid,
577                int                   nj,
578                atom_id               jjcg[],
579                atom_id               index[],
580                t_excl                bExcl[],
581                int                   shift,
582                t_forcerec     *      fr,
583                gmx_bool              bLR,
584                gmx_bool              bDoVdW,
585                gmx_bool              bDoCoul,
586                int                   solvent_opt)
587 {
588     /* The a[] index has been removed,
589      * to put it back in i_atom should be a[i0] and jj should be a[jj].
590      */
591     t_nblist  *   vdwc;
592     t_nblist  *   vdw;
593     t_nblist  *   coul;
594     t_nblist  *   vdwc_free  = NULL;
595     t_nblist  *   vdw_free   = NULL;
596     t_nblist  *   coul_free  = NULL;
597     t_nblist  *   vdwc_ww    = NULL;
598     t_nblist  *   coul_ww    = NULL;
599
600     int           i, j, jcg, igid, gid, nbl_ind, ind_ij;
601     atom_id       jj, jj0, jj1, i_atom;
602     int           i0, nicg, len;
603
604     int          *cginfo;
605     int          *type, *typeB;
606     real         *charge, *chargeB;
607     real          qi, qiB, qq, rlj;
608     gmx_bool      bFreeEnergy, bFree, bFreeJ, bNotEx, *bPert;
609     gmx_bool      bDoVdW_i, bDoCoul_i, bDoCoul_i_sol;
610     int           iwater, jwater;
611     t_nblist     *nlist;
612
613     /* Copy some pointers */
614     cginfo  = fr->cginfo;
615     charge  = md->chargeA;
616     chargeB = md->chargeB;
617     type    = md->typeA;
618     typeB   = md->typeB;
619     bPert   = md->bPerturbed;
620
621     /* Get atom range */
622     i0     = index[icg];
623     nicg   = index[icg+1]-i0;
624
625     /* Get the i charge group info */
626     igid   = GET_CGINFO_GID(cginfo[icg]);
627
628     iwater = (solvent_opt != esolNO) ? GET_CGINFO_SOLOPT(cginfo[icg]) : esolNO;
629
630     bFreeEnergy = FALSE;
631     if (md->nPerturbed)
632     {
633         /* Check if any of the particles involved are perturbed.
634          * If not we can do the cheaper normal put_in_list
635          * and use more solvent optimization.
636          */
637         for (i = 0; i < nicg; i++)
638         {
639             bFreeEnergy |= bPert[i0+i];
640         }
641         /* Loop over the j charge groups */
642         for (j = 0; (j < nj && !bFreeEnergy); j++)
643         {
644             jcg = jjcg[j];
645             jj0 = index[jcg];
646             jj1 = index[jcg+1];
647             /* Finally loop over the atoms in the j-charge group */
648             for (jj = jj0; jj < jj1; jj++)
649             {
650                 bFreeEnergy |= bPert[jj];
651             }
652         }
653     }
654
655     /* Unpack pointers to neighbourlist structs */
656     if (fr->nnblists == 1)
657     {
658         nbl_ind = 0;
659     }
660     else
661     {
662         nbl_ind = fr->gid2nblists[GID(igid, jgid, ngid)];
663     }
664     if (bLR)
665     {
666         nlist = fr->nblists[nbl_ind].nlist_lr;
667     }
668     else
669     {
670         nlist = fr->nblists[nbl_ind].nlist_sr;
671     }
672
673     if (iwater != esolNO)
674     {
675         vdwc = &nlist[eNL_VDWQQ_WATER];
676         vdw  = &nlist[eNL_VDW];
677         coul = &nlist[eNL_QQ_WATER];
678 #ifndef DISABLE_WATERWATER_NLIST
679         vdwc_ww = &nlist[eNL_VDWQQ_WATERWATER];
680         coul_ww = &nlist[eNL_QQ_WATERWATER];
681 #endif
682     }
683     else
684     {
685         vdwc = &nlist[eNL_VDWQQ];
686         vdw  = &nlist[eNL_VDW];
687         coul = &nlist[eNL_QQ];
688     }
689
690     if (!bFreeEnergy)
691     {
692         if (iwater != esolNO)
693         {
694             /* Loop over the atoms in the i charge group */
695             i_atom  = i0;
696             gid     = GID(igid, jgid, ngid);
697             /* Create new i_atom for each energy group */
698             if (bDoCoul && bDoVdW)
699             {
700                 new_i_nblist(vdwc, i_atom, shift, gid);
701 #ifndef DISABLE_WATERWATER_NLIST
702                 new_i_nblist(vdwc_ww, i_atom, shift, gid);
703 #endif
704             }
705             if (bDoVdW)
706             {
707                 new_i_nblist(vdw, i_atom, shift, gid);
708             }
709             if (bDoCoul)
710             {
711                 new_i_nblist(coul, i_atom, shift, gid);
712 #ifndef DISABLE_WATERWATER_NLIST
713                 new_i_nblist(coul_ww, i_atom, shift, gid);
714 #endif
715             }
716             /* Loop over the j charge groups */
717             for (j = 0; (j < nj); j++)
718             {
719                 jcg = jjcg[j];
720
721                 if (jcg == icg)
722                 {
723                     continue;
724                 }
725
726                 jj0    = index[jcg];
727                 jwater = GET_CGINFO_SOLOPT(cginfo[jcg]);
728
729                 if (iwater == esolSPC && jwater == esolSPC)
730                 {
731                     /* Interaction between two SPC molecules */
732                     if (!bDoCoul)
733                     {
734                         /* VdW only - only first atoms in each water interact */
735                         add_j_to_nblist(vdw, jj0, bLR);
736                     }
737                     else
738                     {
739 #ifdef DISABLE_WATERWATER_NLIST
740                         /* Add entries for the three atoms - only do VdW if we need to */
741                         if (!bDoVdW)
742                         {
743                             add_j_to_nblist(coul, jj0, bLR);
744                         }
745                         else
746                         {
747                             add_j_to_nblist(vdwc, jj0, bLR);
748                         }
749                         add_j_to_nblist(coul, jj0+1, bLR);
750                         add_j_to_nblist(coul, jj0+2, bLR);
751 #else
752                         /* One entry for the entire water-water interaction */
753                         if (!bDoVdW)
754                         {
755                             add_j_to_nblist(coul_ww, jj0, bLR);
756                         }
757                         else
758                         {
759                             add_j_to_nblist(vdwc_ww, jj0, bLR);
760                         }
761 #endif
762                     }
763                 }
764                 else if (iwater == esolTIP4P && jwater == esolTIP4P)
765                 {
766                     /* Interaction between two TIP4p molecules */
767                     if (!bDoCoul)
768                     {
769                         /* VdW only - only first atoms in each water interact */
770                         add_j_to_nblist(vdw, jj0, bLR);
771                     }
772                     else
773                     {
774 #ifdef DISABLE_WATERWATER_NLIST
775                         /* Add entries for the four atoms - only do VdW if we need to */
776                         if (bDoVdW)
777                         {
778                             add_j_to_nblist(vdw, jj0, bLR);
779                         }
780                         add_j_to_nblist(coul, jj0+1, bLR);
781                         add_j_to_nblist(coul, jj0+2, bLR);
782                         add_j_to_nblist(coul, jj0+3, bLR);
783 #else
784                         /* One entry for the entire water-water interaction */
785                         if (!bDoVdW)
786                         {
787                             add_j_to_nblist(coul_ww, jj0, bLR);
788                         }
789                         else
790                         {
791                             add_j_to_nblist(vdwc_ww, jj0, bLR);
792                         }
793 #endif
794                     }
795                 }
796                 else
797                 {
798                     /* j charge group is not water, but i is.
799                      * Add entries to the water-other_atom lists; the geometry of the water
800                      * molecule doesn't matter - that is taken care of in the nonbonded kernel,
801                      * so we don't care if it is SPC or TIP4P...
802                      */
803
804                     jj1 = index[jcg+1];
805
806                     if (!bDoVdW)
807                     {
808                         for (jj = jj0; (jj < jj1); jj++)
809                         {
810                             if (charge[jj] != 0)
811                             {
812                                 add_j_to_nblist(coul, jj, bLR);
813                             }
814                         }
815                     }
816                     else if (!bDoCoul)
817                     {
818                         for (jj = jj0; (jj < jj1); jj++)
819                         {
820                             if (bHaveVdW[type[jj]])
821                             {
822                                 add_j_to_nblist(vdw, jj, bLR);
823                             }
824                         }
825                     }
826                     else
827                     {
828                         /* _charge_ _groups_ interact with both coulomb and LJ */
829                         /* Check which atoms we should add to the lists!       */
830                         for (jj = jj0; (jj < jj1); jj++)
831                         {
832                             if (bHaveVdW[type[jj]])
833                             {
834                                 if (charge[jj] != 0)
835                                 {
836                                     add_j_to_nblist(vdwc, jj, bLR);
837                                 }
838                                 else
839                                 {
840                                     add_j_to_nblist(vdw, jj, bLR);
841                                 }
842                             }
843                             else if (charge[jj] != 0)
844                             {
845                                 add_j_to_nblist(coul, jj, bLR);
846                             }
847                         }
848                     }
849                 }
850             }
851             close_i_nblist(vdw);
852             close_i_nblist(coul);
853             close_i_nblist(vdwc);
854 #ifndef DISABLE_WATERWATER_NLIST
855             close_i_nblist(coul_ww);
856             close_i_nblist(vdwc_ww);
857 #endif
858         }
859         else
860         {
861             /* no solvent as i charge group */
862             /* Loop over the atoms in the i charge group */
863             for (i = 0; i < nicg; i++)
864             {
865                 i_atom  = i0+i;
866                 gid     = GID(igid, jgid, ngid);
867                 qi      = charge[i_atom];
868
869                 /* Create new i_atom for each energy group */
870                 if (bDoVdW && bDoCoul)
871                 {
872                     new_i_nblist(vdwc, i_atom, shift, gid);
873                 }
874                 if (bDoVdW)
875                 {
876                     new_i_nblist(vdw, i_atom, shift, gid);
877                 }
878                 if (bDoCoul)
879                 {
880                     new_i_nblist(coul, i_atom, shift, gid);
881                 }
882                 bDoVdW_i  = (bDoVdW  && bHaveVdW[type[i_atom]]);
883                 bDoCoul_i = (bDoCoul && qi != 0);
884
885                 if (bDoVdW_i || bDoCoul_i)
886                 {
887                     /* Loop over the j charge groups */
888                     for (j = 0; (j < nj); j++)
889                     {
890                         jcg = jjcg[j];
891
892                         /* Check for large charge groups */
893                         if (jcg == icg)
894                         {
895                             jj0 = i0 + i + 1;
896                         }
897                         else
898                         {
899                             jj0 = index[jcg];
900                         }
901
902                         jj1 = index[jcg+1];
903                         /* Finally loop over the atoms in the j-charge group */
904                         for (jj = jj0; jj < jj1; jj++)
905                         {
906                             bNotEx = NOTEXCL(bExcl, i, jj);
907
908                             if (bNotEx)
909                             {
910                                 if (!bDoVdW_i)
911                                 {
912                                     if (charge[jj] != 0)
913                                     {
914                                         add_j_to_nblist(coul, jj, bLR);
915                                     }
916                                 }
917                                 else if (!bDoCoul_i)
918                                 {
919                                     if (bHaveVdW[type[jj]])
920                                     {
921                                         add_j_to_nblist(vdw, jj, bLR);
922                                     }
923                                 }
924                                 else
925                                 {
926                                     if (bHaveVdW[type[jj]])
927                                     {
928                                         if (charge[jj] != 0)
929                                         {
930                                             add_j_to_nblist(vdwc, jj, bLR);
931                                         }
932                                         else
933                                         {
934                                             add_j_to_nblist(vdw, jj, bLR);
935                                         }
936                                     }
937                                     else if (charge[jj] != 0)
938                                     {
939                                         add_j_to_nblist(coul, jj, bLR);
940                                     }
941                                 }
942                             }
943                         }
944                     }
945                 }
946                 close_i_nblist(vdw);
947                 close_i_nblist(coul);
948                 close_i_nblist(vdwc);
949             }
950         }
951     }
952     else
953     {
954         /* we are doing free energy */
955         vdwc_free = &nlist[eNL_VDWQQ_FREE];
956         vdw_free  = &nlist[eNL_VDW_FREE];
957         coul_free = &nlist[eNL_QQ_FREE];
958         /* Loop over the atoms in the i charge group */
959         for (i = 0; i < nicg; i++)
960         {
961             i_atom  = i0+i;
962             gid     = GID(igid, jgid, ngid);
963             qi      = charge[i_atom];
964             qiB     = chargeB[i_atom];
965
966             /* Create new i_atom for each energy group */
967             if (bDoVdW && bDoCoul)
968             {
969                 new_i_nblist(vdwc, i_atom, shift, gid);
970             }
971             if (bDoVdW)
972             {
973                 new_i_nblist(vdw, i_atom, shift, gid);
974             }
975             if (bDoCoul)
976             {
977                 new_i_nblist(coul, i_atom, shift, gid);
978             }
979
980             new_i_nblist(vdw_free, i_atom, shift, gid);
981             new_i_nblist(coul_free, i_atom, shift, gid);
982             new_i_nblist(vdwc_free, i_atom, shift, gid);
983
984             bDoVdW_i  = (bDoVdW  &&
985                          (bHaveVdW[type[i_atom]] || bHaveVdW[typeB[i_atom]]));
986             bDoCoul_i = (bDoCoul && (qi != 0 || qiB != 0));
987             /* For TIP4P the first atom does not have a charge,
988              * but the last three do. So we should still put an atom
989              * without LJ but with charge in the water-atom neighborlist
990              * for a TIP4p i charge group.
991              * For SPC type water the first atom has LJ and charge,
992              * so there is no such problem.
993              */
994             if (iwater == esolNO)
995             {
996                 bDoCoul_i_sol = bDoCoul_i;
997             }
998             else
999             {
1000                 bDoCoul_i_sol = bDoCoul;
1001             }
1002
1003             if (bDoVdW_i || bDoCoul_i_sol)
1004             {
1005                 /* Loop over the j charge groups */
1006                 for (j = 0; (j < nj); j++)
1007                 {
1008                     jcg = jjcg[j];
1009
1010                     /* Check for large charge groups */
1011                     if (jcg == icg)
1012                     {
1013                         jj0 = i0 + i + 1;
1014                     }
1015                     else
1016                     {
1017                         jj0 = index[jcg];
1018                     }
1019
1020                     jj1 = index[jcg+1];
1021                     /* Finally loop over the atoms in the j-charge group */
1022                     bFree = bPert[i_atom];
1023                     for (jj = jj0; (jj < jj1); jj++)
1024                     {
1025                         bFreeJ = bFree || bPert[jj];
1026                         /* Complicated if, because the water H's should also
1027                          * see perturbed j-particles
1028                          */
1029                         if (iwater == esolNO || i == 0 || bFreeJ)
1030                         {
1031                             bNotEx = NOTEXCL(bExcl, i, jj);
1032
1033                             if (bNotEx)
1034                             {
1035                                 if (bFreeJ)
1036                                 {
1037                                     if (!bDoVdW_i)
1038                                     {
1039                                         if (charge[jj] != 0 || chargeB[jj] != 0)
1040                                         {
1041                                             add_j_to_nblist(coul_free, jj, bLR);
1042                                         }
1043                                     }
1044                                     else if (!bDoCoul_i)
1045                                     {
1046                                         if (bHaveVdW[type[jj]] || bHaveVdW[typeB[jj]])
1047                                         {
1048                                             add_j_to_nblist(vdw_free, jj, bLR);
1049                                         }
1050                                     }
1051                                     else
1052                                     {
1053                                         if (bHaveVdW[type[jj]] || bHaveVdW[typeB[jj]])
1054                                         {
1055                                             if (charge[jj] != 0 || chargeB[jj] != 0)
1056                                             {
1057                                                 add_j_to_nblist(vdwc_free, jj, bLR);
1058                                             }
1059                                             else
1060                                             {
1061                                                 add_j_to_nblist(vdw_free, jj, bLR);
1062                                             }
1063                                         }
1064                                         else if (charge[jj] != 0 || chargeB[jj] != 0)
1065                                         {
1066                                             add_j_to_nblist(coul_free, jj, bLR);
1067                                         }
1068                                     }
1069                                 }
1070                                 else if (!bDoVdW_i)
1071                                 {
1072                                     /* This is done whether or not bWater is set */
1073                                     if (charge[jj] != 0)
1074                                     {
1075                                         add_j_to_nblist(coul, jj, bLR);
1076                                     }
1077                                 }
1078                                 else if (!bDoCoul_i_sol)
1079                                 {
1080                                     if (bHaveVdW[type[jj]])
1081                                     {
1082                                         add_j_to_nblist(vdw, jj, bLR);
1083                                     }
1084                                 }
1085                                 else
1086                                 {
1087                                     if (bHaveVdW[type[jj]])
1088                                     {
1089                                         if (charge[jj] != 0)
1090                                         {
1091                                             add_j_to_nblist(vdwc, jj, bLR);
1092                                         }
1093                                         else
1094                                         {
1095                                             add_j_to_nblist(vdw, jj, bLR);
1096                                         }
1097                                     }
1098                                     else if (charge[jj] != 0)
1099                                     {
1100                                         add_j_to_nblist(coul, jj, bLR);
1101                                     }
1102                                 }
1103                             }
1104                         }
1105                     }
1106                 }
1107             }
1108             close_i_nblist(vdw);
1109             close_i_nblist(coul);
1110             close_i_nblist(vdwc);
1111             close_i_nblist(vdw_free);
1112             close_i_nblist(coul_free);
1113             close_i_nblist(vdwc_free);
1114         }
1115     }
1116 }
1117
1118 static void
1119 put_in_list_adress(gmx_bool              bHaveVdW[],
1120                    int                   ngid,
1121                    t_mdatoms     *       md,
1122                    int                   icg,
1123                    int                   jgid,
1124                    int                   nj,
1125                    atom_id               jjcg[],
1126                    atom_id               index[],
1127                    t_excl                bExcl[],
1128                    int                   shift,
1129                    t_forcerec     *      fr,
1130                    gmx_bool              bLR,
1131                    gmx_bool              bDoVdW,
1132                    gmx_bool              bDoCoul,
1133                    int                   solvent_opt)
1134 {
1135     /* The a[] index has been removed,
1136      * to put it back in i_atom should be a[i0] and jj should be a[jj].
1137      */
1138     t_nblist  *   vdwc;
1139     t_nblist  *   vdw;
1140     t_nblist  *   coul;
1141     t_nblist  *   vdwc_adress  = NULL;
1142     t_nblist  *   vdw_adress   = NULL;
1143     t_nblist  *   coul_adress  = NULL;
1144     t_nblist  *   vdwc_ww      = NULL;
1145     t_nblist  *   coul_ww      = NULL;
1146
1147     int           i, j, jcg, igid, gid, nbl_ind, nbl_ind_adress;
1148     atom_id       jj, jj0, jj1, i_atom;
1149     int           i0, nicg, len;
1150
1151     int          *cginfo;
1152     int          *type, *typeB;
1153     real         *charge, *chargeB;
1154     real         *wf;
1155     real          qi, qiB, qq, rlj;
1156     gmx_bool      bFreeEnergy, bFree, bFreeJ, bNotEx, *bPert;
1157     gmx_bool      bDoVdW_i, bDoCoul_i, bDoCoul_i_sol;
1158     gmx_bool      b_hybrid;
1159     gmx_bool      j_all_atom;
1160     int           iwater, jwater;
1161     t_nblist     *nlist, *nlist_adress;
1162     gmx_bool      bEnergyGroupCG;
1163
1164     /* Copy some pointers */
1165     cginfo  = fr->cginfo;
1166     charge  = md->chargeA;
1167     chargeB = md->chargeB;
1168     type    = md->typeA;
1169     typeB   = md->typeB;
1170     bPert   = md->bPerturbed;
1171     wf      = md->wf;
1172
1173     /* Get atom range */
1174     i0     = index[icg];
1175     nicg   = index[icg+1]-i0;
1176
1177     /* Get the i charge group info */
1178     igid   = GET_CGINFO_GID(cginfo[icg]);
1179
1180     iwater = (solvent_opt != esolNO) ? GET_CGINFO_SOLOPT(cginfo[icg]) : esolNO;
1181
1182     if (md->nPerturbed)
1183     {
1184         gmx_fatal(FARGS, "AdResS does not support free energy pertubation\n");
1185     }
1186
1187     /* Unpack pointers to neighbourlist structs */
1188     if (fr->nnblists == 2)
1189     {
1190         nbl_ind        = 0;
1191         nbl_ind_adress = 1;
1192     }
1193     else
1194     {
1195         nbl_ind        = fr->gid2nblists[GID(igid, jgid, ngid)];
1196         nbl_ind_adress = nbl_ind+fr->nnblists/2;
1197     }
1198     if (bLR)
1199     {
1200         nlist        = fr->nblists[nbl_ind].nlist_lr;
1201         nlist_adress = fr->nblists[nbl_ind_adress].nlist_lr;
1202     }
1203     else
1204     {
1205         nlist        = fr->nblists[nbl_ind].nlist_sr;
1206         nlist_adress = fr->nblists[nbl_ind_adress].nlist_sr;
1207     }
1208
1209
1210     vdwc = &nlist[eNL_VDWQQ];
1211     vdw  = &nlist[eNL_VDW];
1212     coul = &nlist[eNL_QQ];
1213
1214     vdwc_adress = &nlist_adress[eNL_VDWQQ];
1215     vdw_adress  = &nlist_adress[eNL_VDW];
1216     coul_adress = &nlist_adress[eNL_QQ];
1217
1218     /* We do not support solvent optimization with AdResS for now.
1219        For this we would need hybrid solvent-other kernels */
1220
1221     /* no solvent as i charge group */
1222     /* Loop over the atoms in the i charge group */
1223     for (i = 0; i < nicg; i++)
1224     {
1225         i_atom  = i0+i;
1226         gid     = GID(igid, jgid, ngid);
1227         qi      = charge[i_atom];
1228
1229         /* Create new i_atom for each energy group */
1230         if (bDoVdW && bDoCoul)
1231         {
1232             new_i_nblist(vdwc, i_atom, shift, gid);
1233             new_i_nblist(vdwc_adress, i_atom, shift, gid);
1234
1235         }
1236         if (bDoVdW)
1237         {
1238             new_i_nblist(vdw, i_atom, shift, gid);
1239             new_i_nblist(vdw_adress, i_atom, shift, gid);
1240
1241         }
1242         if (bDoCoul)
1243         {
1244             new_i_nblist(coul, i_atom, shift, gid);
1245             new_i_nblist(coul_adress, i_atom, shift, gid);
1246         }
1247         bDoVdW_i  = (bDoVdW  && bHaveVdW[type[i_atom]]);
1248         bDoCoul_i = (bDoCoul && qi != 0);
1249
1250         /* Here we find out whether the energy groups interaction belong to a
1251          * coarse-grained (vsite) or atomistic interaction. Note that, beacuse
1252          * interactions between coarse-grained and other (atomistic) energygroups
1253          * are excluded automatically by grompp, it is sufficient to check for
1254          * the group id of atom i (igid) */
1255         bEnergyGroupCG = !egp_explicit(fr, igid);
1256
1257         if (bDoVdW_i || bDoCoul_i)
1258         {
1259             /* Loop over the j charge groups */
1260             for (j = 0; (j < nj); j++)
1261             {
1262                 jcg = jjcg[j];
1263
1264                 /* Check for large charge groups */
1265                 if (jcg == icg)
1266                 {
1267                     jj0 = i0 + i + 1;
1268                 }
1269                 else
1270                 {
1271                     jj0 = index[jcg];
1272                 }
1273
1274                 jj1 = index[jcg+1];
1275                 /* Finally loop over the atoms in the j-charge group */
1276                 for (jj = jj0; jj < jj1; jj++)
1277                 {
1278                     bNotEx = NOTEXCL(bExcl, i, jj);
1279
1280                     /* Now we have to exclude interactions which will be zero
1281                      * anyway due to the AdResS weights (in previous implementations
1282                      * this was done in the force kernel). This is necessary as
1283                      * pure interactions (those with b_hybrid=false, i.e. w_i*w_j==1 or 0)
1284                      * are put into neighbour lists which will be passed to the
1285                      * standard (optimized) kernels for speed. The interactions with
1286                      * b_hybrid=true are placed into the _adress neighbour lists and
1287                      * processed by the generic AdResS kernel.
1288                      */
1289                     if ( (bEnergyGroupCG &&
1290                           wf[i_atom] >= 1-GMX_REAL_EPS && wf[jj] >= 1-GMX_REAL_EPS ) ||
1291                          ( !bEnergyGroupCG && wf[jj] <= GMX_REAL_EPS ) )
1292                     {
1293                         continue;
1294                     }
1295
1296                     b_hybrid = !((wf[i_atom] >= 1-GMX_REAL_EPS && wf[jj] >= 1-GMX_REAL_EPS) ||
1297                                  (wf[i_atom] <= GMX_REAL_EPS && wf[jj] <= GMX_REAL_EPS));
1298
1299                     if (bNotEx)
1300                     {
1301                         if (!bDoVdW_i)
1302                         {
1303                             if (charge[jj] != 0)
1304                             {
1305                                 if (!b_hybrid)
1306                                 {
1307                                     add_j_to_nblist(coul, jj, bLR);
1308                                 }
1309                                 else
1310                                 {
1311                                     add_j_to_nblist(coul_adress, jj, bLR);
1312                                 }
1313                             }
1314                         }
1315                         else if (!bDoCoul_i)
1316                         {
1317                             if (bHaveVdW[type[jj]])
1318                             {
1319                                 if (!b_hybrid)
1320                                 {
1321                                     add_j_to_nblist(vdw, jj, bLR);
1322                                 }
1323                                 else
1324                                 {
1325                                     add_j_to_nblist(vdw_adress, jj, bLR);
1326                                 }
1327                             }
1328                         }
1329                         else
1330                         {
1331                             if (bHaveVdW[type[jj]])
1332                             {
1333                                 if (charge[jj] != 0)
1334                                 {
1335                                     if (!b_hybrid)
1336                                     {
1337                                         add_j_to_nblist(vdwc, jj, bLR);
1338                                     }
1339                                     else
1340                                     {
1341                                         add_j_to_nblist(vdwc_adress, jj, bLR);
1342                                     }
1343                                 }
1344                                 else
1345                                 {
1346                                     if (!b_hybrid)
1347                                     {
1348                                         add_j_to_nblist(vdw, jj, bLR);
1349                                     }
1350                                     else
1351                                     {
1352                                         add_j_to_nblist(vdw_adress, jj, bLR);
1353                                     }
1354
1355                                 }
1356                             }
1357                             else if (charge[jj] != 0)
1358                             {
1359                                 if (!b_hybrid)
1360                                 {
1361                                     add_j_to_nblist(coul, jj, bLR);
1362                                 }
1363                                 else
1364                                 {
1365                                     add_j_to_nblist(coul_adress, jj, bLR);
1366                                 }
1367
1368                             }
1369                         }
1370                     }
1371                 }
1372             }
1373
1374             close_i_nblist(vdw);
1375             close_i_nblist(coul);
1376             close_i_nblist(vdwc);
1377             close_i_nblist(vdw_adress);
1378             close_i_nblist(coul_adress);
1379             close_i_nblist(vdwc_adress);
1380         }
1381     }
1382 }
1383
1384 static void
1385 put_in_list_qmmm(gmx_bool gmx_unused              bHaveVdW[],
1386                  int                              ngid,
1387                  t_mdatoms gmx_unused     *       md,
1388                  int                              icg,
1389                  int                              jgid,
1390                  int                              nj,
1391                  atom_id                          jjcg[],
1392                  atom_id                          index[],
1393                  t_excl                           bExcl[],
1394                  int                              shift,
1395                  t_forcerec                *      fr,
1396                  gmx_bool                         bLR,
1397                  gmx_bool  gmx_unused             bDoVdW,
1398                  gmx_bool  gmx_unused             bDoCoul,
1399                  int       gmx_unused             solvent_opt)
1400 {
1401     t_nblist  *   coul;
1402     int           i, j, jcg, igid, gid;
1403     atom_id       jj, jj0, jj1, i_atom;
1404     int           i0, nicg;
1405     gmx_bool      bNotEx;
1406
1407     /* Get atom range */
1408     i0     = index[icg];
1409     nicg   = index[icg+1]-i0;
1410
1411     /* Get the i charge group info */
1412     igid   = GET_CGINFO_GID(fr->cginfo[icg]);
1413
1414     coul = &fr->QMMMlist;
1415
1416     /* Loop over atoms in the ith charge group */
1417     for (i = 0; i < nicg; i++)
1418     {
1419         i_atom = i0+i;
1420         gid    = GID(igid, jgid, ngid);
1421         /* Create new i_atom for each energy group */
1422         new_i_nblist(coul, i_atom, shift, gid);
1423
1424         /* Loop over the j charge groups */
1425         for (j = 0; j < nj; j++)
1426         {
1427             jcg = jjcg[j];
1428
1429             /* Charge groups cannot have QM and MM atoms simultaneously */
1430             if (jcg != icg)
1431             {
1432                 jj0 = index[jcg];
1433                 jj1 = index[jcg+1];
1434                 /* Finally loop over the atoms in the j-charge group */
1435                 for (jj = jj0; jj < jj1; jj++)
1436                 {
1437                     bNotEx = NOTEXCL(bExcl, i, jj);
1438                     if (bNotEx)
1439                     {
1440                         add_j_to_nblist(coul, jj, bLR);
1441                     }
1442                 }
1443             }
1444         }
1445         close_i_nblist(coul);
1446     }
1447 }
1448
1449 static void
1450 put_in_list_cg(gmx_bool  gmx_unused             bHaveVdW[],
1451                int                              ngid,
1452                t_mdatoms  gmx_unused    *       md,
1453                int                              icg,
1454                int                              jgid,
1455                int                              nj,
1456                atom_id                          jjcg[],
1457                atom_id                          index[],
1458                t_excl                           bExcl[],
1459                int                              shift,
1460                t_forcerec                *      fr,
1461                gmx_bool                         bLR,
1462                gmx_bool   gmx_unused            bDoVdW,
1463                gmx_bool   gmx_unused            bDoCoul,
1464                int        gmx_unused            solvent_opt)
1465 {
1466     int          cginfo;
1467     int          igid, gid, nbl_ind;
1468     t_nblist *   vdwc;
1469     int          j, jcg;
1470
1471     cginfo = fr->cginfo[icg];
1472
1473     igid = GET_CGINFO_GID(cginfo);
1474     gid  = GID(igid, jgid, ngid);
1475
1476     /* Unpack pointers to neighbourlist structs */
1477     if (fr->nnblists == 1)
1478     {
1479         nbl_ind = 0;
1480     }
1481     else
1482     {
1483         nbl_ind = fr->gid2nblists[gid];
1484     }
1485     if (bLR)
1486     {
1487         vdwc = &fr->nblists[nbl_ind].nlist_lr[eNL_VDWQQ];
1488     }
1489     else
1490     {
1491         vdwc = &fr->nblists[nbl_ind].nlist_sr[eNL_VDWQQ];
1492     }
1493
1494     /* Make a new neighbor list for charge group icg.
1495      * Currently simply one neighbor list is made with LJ and Coulomb.
1496      * If required, zero interactions could be removed here
1497      * or in the force loop.
1498      */
1499     new_i_nblist(vdwc, index[icg], shift, gid);
1500     vdwc->iinr_end[vdwc->nri] = index[icg+1];
1501
1502     for (j = 0; (j < nj); j++)
1503     {
1504         jcg = jjcg[j];
1505         /* Skip the icg-icg pairs if all self interactions are excluded */
1506         if (!(jcg == icg && GET_CGINFO_EXCL_INTRA(cginfo)))
1507         {
1508             /* Here we add the j charge group jcg to the list,
1509              * exclusions are also added to the list.
1510              */
1511             add_j_to_nblist_cg(vdwc, index[jcg], index[jcg+1], bExcl, icg == jcg, bLR);
1512         }
1513     }
1514
1515     close_i_nblist(vdwc);
1516 }
1517
1518 static void setexcl(atom_id start, atom_id end, t_blocka *excl, gmx_bool b,
1519                     t_excl bexcl[])
1520 {
1521     atom_id i, k;
1522
1523     if (b)
1524     {
1525         for (i = start; i < end; i++)
1526         {
1527             for (k = excl->index[i]; k < excl->index[i+1]; k++)
1528             {
1529                 SETEXCL(bexcl, i-start, excl->a[k]);
1530             }
1531         }
1532     }
1533     else
1534     {
1535         for (i = start; i < end; i++)
1536         {
1537             for (k = excl->index[i]; k < excl->index[i+1]; k++)
1538             {
1539                 RMEXCL(bexcl, i-start, excl->a[k]);
1540             }
1541         }
1542     }
1543 }
1544
1545 int calc_naaj(int icg, int cgtot)
1546 {
1547     int naaj;
1548
1549     if ((cgtot % 2) == 1)
1550     {
1551         /* Odd number of charge groups, easy */
1552         naaj = 1 + (cgtot/2);
1553     }
1554     else if ((cgtot % 4) == 0)
1555     {
1556         /* Multiple of four is hard */
1557         if (icg < cgtot/2)
1558         {
1559             if ((icg % 2) == 0)
1560             {
1561                 naaj = 1+(cgtot/2);
1562             }
1563             else
1564             {
1565                 naaj = cgtot/2;
1566             }
1567         }
1568         else
1569         {
1570             if ((icg % 2) == 1)
1571             {
1572                 naaj = 1+(cgtot/2);
1573             }
1574             else
1575             {
1576                 naaj = cgtot/2;
1577             }
1578         }
1579     }
1580     else
1581     {
1582         /* cgtot/2 = odd */
1583         if ((icg % 2) == 0)
1584         {
1585             naaj = 1+(cgtot/2);
1586         }
1587         else
1588         {
1589             naaj = cgtot/2;
1590         }
1591     }
1592 #ifdef DEBUG
1593     fprintf(log, "naaj=%d\n", naaj);
1594 #endif
1595
1596     return naaj;
1597 }
1598
1599 /************************************************
1600  *
1601  *  S I M P L E      C O R E     S T U F F
1602  *
1603  ************************************************/
1604
1605 static real calc_image_tric(rvec xi, rvec xj, matrix box,
1606                             rvec b_inv, int *shift)
1607 {
1608     /* This code assumes that the cut-off is smaller than
1609      * a half times the smallest diagonal element of the box.
1610      */
1611     const real h25 = 2.5;
1612     real       dx, dy, dz;
1613     real       r2;
1614     int        tx, ty, tz;
1615
1616     /* Compute diff vector */
1617     dz = xj[ZZ] - xi[ZZ];
1618     dy = xj[YY] - xi[YY];
1619     dx = xj[XX] - xi[XX];
1620
1621     /* Perform NINT operation, using trunc operation, therefore
1622      * we first add 2.5 then subtract 2 again
1623      */
1624     tz  = dz*b_inv[ZZ] + h25;
1625     tz -= 2;
1626     dz -= tz*box[ZZ][ZZ];
1627     dy -= tz*box[ZZ][YY];
1628     dx -= tz*box[ZZ][XX];
1629
1630     ty  = dy*b_inv[YY] + h25;
1631     ty -= 2;
1632     dy -= ty*box[YY][YY];
1633     dx -= ty*box[YY][XX];
1634
1635     tx  = dx*b_inv[XX]+h25;
1636     tx -= 2;
1637     dx -= tx*box[XX][XX];
1638
1639     /* Distance squared */
1640     r2 = (dx*dx) + (dy*dy) + (dz*dz);
1641
1642     *shift = XYZ2IS(tx, ty, tz);
1643
1644     return r2;
1645 }
1646
1647 static real calc_image_rect(rvec xi, rvec xj, rvec box_size,
1648                             rvec b_inv, int *shift)
1649 {
1650     const real h15 = 1.5;
1651     real       ddx, ddy, ddz;
1652     real       dx, dy, dz;
1653     real       r2;
1654     int        tx, ty, tz;
1655
1656     /* Compute diff vector */
1657     dx = xj[XX] - xi[XX];
1658     dy = xj[YY] - xi[YY];
1659     dz = xj[ZZ] - xi[ZZ];
1660
1661     /* Perform NINT operation, using trunc operation, therefore
1662      * we first add 1.5 then subtract 1 again
1663      */
1664     tx = dx*b_inv[XX] + h15;
1665     ty = dy*b_inv[YY] + h15;
1666     tz = dz*b_inv[ZZ] + h15;
1667     tx--;
1668     ty--;
1669     tz--;
1670
1671     /* Correct diff vector for translation */
1672     ddx = tx*box_size[XX] - dx;
1673     ddy = ty*box_size[YY] - dy;
1674     ddz = tz*box_size[ZZ] - dz;
1675
1676     /* Distance squared */
1677     r2 = (ddx*ddx) + (ddy*ddy) + (ddz*ddz);
1678
1679     *shift = XYZ2IS(tx, ty, tz);
1680
1681     return r2;
1682 }
1683
1684 static void add_simple(t_ns_buf *nsbuf, int nrj, atom_id cg_j,
1685                        gmx_bool bHaveVdW[], int ngid, t_mdatoms *md,
1686                        int icg, int jgid, t_block *cgs, t_excl bexcl[],
1687                        int shift, t_forcerec *fr, put_in_list_t *put_in_list)
1688 {
1689     if (nsbuf->nj + nrj > MAX_CG)
1690     {
1691         put_in_list(bHaveVdW, ngid, md, icg, jgid, nsbuf->ncg, nsbuf->jcg,
1692                     cgs->index, bexcl, shift, fr, FALSE, TRUE, TRUE, fr->solvent_opt);
1693         /* Reset buffer contents */
1694         nsbuf->ncg = nsbuf->nj = 0;
1695     }
1696     nsbuf->jcg[nsbuf->ncg++] = cg_j;
1697     nsbuf->nj               += nrj;
1698 }
1699
1700 static void ns_inner_tric(rvec x[], int icg, int *i_egp_flags,
1701                           int njcg, atom_id jcg[],
1702                           matrix box, rvec b_inv, real rcut2,
1703                           t_block *cgs, t_ns_buf **ns_buf,
1704                           gmx_bool bHaveVdW[], int ngid, t_mdatoms *md,
1705                           t_excl bexcl[], t_forcerec *fr,
1706                           put_in_list_t *put_in_list)
1707 {
1708     int       shift;
1709     int       j, nrj, jgid;
1710     int      *cginfo = fr->cginfo;
1711     atom_id   cg_j, *cgindex;
1712     t_ns_buf *nsbuf;
1713
1714     cgindex = cgs->index;
1715     shift   = CENTRAL;
1716     for (j = 0; (j < njcg); j++)
1717     {
1718         cg_j   = jcg[j];
1719         nrj    = cgindex[cg_j+1]-cgindex[cg_j];
1720         if (calc_image_tric(x[icg], x[cg_j], box, b_inv, &shift) < rcut2)
1721         {
1722             jgid  = GET_CGINFO_GID(cginfo[cg_j]);
1723             if (!(i_egp_flags[jgid] & EGP_EXCL))
1724             {
1725                 add_simple(&ns_buf[jgid][shift], nrj, cg_j,
1726                            bHaveVdW, ngid, md, icg, jgid, cgs, bexcl, shift, fr,
1727                            put_in_list);
1728             }
1729         }
1730     }
1731 }
1732
1733 static void ns_inner_rect(rvec x[], int icg, int *i_egp_flags,
1734                           int njcg, atom_id jcg[],
1735                           gmx_bool bBox, rvec box_size, rvec b_inv, real rcut2,
1736                           t_block *cgs, t_ns_buf **ns_buf,
1737                           gmx_bool bHaveVdW[], int ngid, t_mdatoms *md,
1738                           t_excl bexcl[], t_forcerec *fr,
1739                           put_in_list_t *put_in_list)
1740 {
1741     int       shift;
1742     int       j, nrj, jgid;
1743     int      *cginfo = fr->cginfo;
1744     atom_id   cg_j, *cgindex;
1745     t_ns_buf *nsbuf;
1746
1747     cgindex = cgs->index;
1748     if (bBox)
1749     {
1750         shift = CENTRAL;
1751         for (j = 0; (j < njcg); j++)
1752         {
1753             cg_j   = jcg[j];
1754             nrj    = cgindex[cg_j+1]-cgindex[cg_j];
1755             if (calc_image_rect(x[icg], x[cg_j], box_size, b_inv, &shift) < rcut2)
1756             {
1757                 jgid  = GET_CGINFO_GID(cginfo[cg_j]);
1758                 if (!(i_egp_flags[jgid] & EGP_EXCL))
1759                 {
1760                     add_simple(&ns_buf[jgid][shift], nrj, cg_j,
1761                                bHaveVdW, ngid, md, icg, jgid, cgs, bexcl, shift, fr,
1762                                put_in_list);
1763                 }
1764             }
1765         }
1766     }
1767     else
1768     {
1769         for (j = 0; (j < njcg); j++)
1770         {
1771             cg_j   = jcg[j];
1772             nrj    = cgindex[cg_j+1]-cgindex[cg_j];
1773             if ((rcut2 == 0) || (distance2(x[icg], x[cg_j]) < rcut2))
1774             {
1775                 jgid  = GET_CGINFO_GID(cginfo[cg_j]);
1776                 if (!(i_egp_flags[jgid] & EGP_EXCL))
1777                 {
1778                     add_simple(&ns_buf[jgid][CENTRAL], nrj, cg_j,
1779                                bHaveVdW, ngid, md, icg, jgid, cgs, bexcl, CENTRAL, fr,
1780                                put_in_list);
1781                 }
1782             }
1783         }
1784     }
1785 }
1786
1787 /* ns_simple_core needs to be adapted for QMMM still 2005 */
1788
1789 static int ns_simple_core(t_forcerec *fr,
1790                           gmx_localtop_t *top,
1791                           t_mdatoms *md,
1792                           matrix box, rvec box_size,
1793                           t_excl bexcl[], atom_id *aaj,
1794                           int ngid, t_ns_buf **ns_buf,
1795                           put_in_list_t *put_in_list, gmx_bool bHaveVdW[])
1796 {
1797     int          naaj, k;
1798     real         rlist2;
1799     int          nsearch, icg, jcg, igid, i0, nri, nn;
1800     int         *cginfo;
1801     t_ns_buf    *nsbuf;
1802     /* atom_id  *i_atoms; */
1803     t_block     *cgs  = &(top->cgs);
1804     t_blocka    *excl = &(top->excls);
1805     rvec         b_inv;
1806     int          m;
1807     gmx_bool     bBox, bTriclinic;
1808     int         *i_egp_flags;
1809
1810     rlist2 = sqr(fr->rlist);
1811
1812     bBox = (fr->ePBC != epbcNONE);
1813     if (bBox)
1814     {
1815         for (m = 0; (m < DIM); m++)
1816         {
1817             b_inv[m] = divide_err(1.0, box_size[m]);
1818         }
1819         bTriclinic = TRICLINIC(box);
1820     }
1821     else
1822     {
1823         bTriclinic = FALSE;
1824     }
1825
1826     cginfo = fr->cginfo;
1827
1828     nsearch = 0;
1829     for (icg = fr->cg0; (icg < fr->hcg); icg++)
1830     {
1831         /*
1832            i0        = cgs->index[icg];
1833            nri       = cgs->index[icg+1]-i0;
1834            i_atoms   = &(cgs->a[i0]);
1835            i_eg_excl = fr->eg_excl + ngid*md->cENER[*i_atoms];
1836            setexcl(nri,i_atoms,excl,TRUE,bexcl);
1837          */
1838         igid        = GET_CGINFO_GID(cginfo[icg]);
1839         i_egp_flags = fr->egp_flags + ngid*igid;
1840         setexcl(cgs->index[icg], cgs->index[icg+1], excl, TRUE, bexcl);
1841
1842         naaj = calc_naaj(icg, cgs->nr);
1843         if (bTriclinic)
1844         {
1845             ns_inner_tric(fr->cg_cm, icg, i_egp_flags, naaj, &(aaj[icg]),
1846                           box, b_inv, rlist2, cgs, ns_buf,
1847                           bHaveVdW, ngid, md, bexcl, fr, put_in_list);
1848         }
1849         else
1850         {
1851             ns_inner_rect(fr->cg_cm, icg, i_egp_flags, naaj, &(aaj[icg]),
1852                           bBox, box_size, b_inv, rlist2, cgs, ns_buf,
1853                           bHaveVdW, ngid, md, bexcl, fr, put_in_list);
1854         }
1855         nsearch += naaj;
1856
1857         for (nn = 0; (nn < ngid); nn++)
1858         {
1859             for (k = 0; (k < SHIFTS); k++)
1860             {
1861                 nsbuf = &(ns_buf[nn][k]);
1862                 if (nsbuf->ncg > 0)
1863                 {
1864                     put_in_list(bHaveVdW, ngid, md, icg, nn, nsbuf->ncg, nsbuf->jcg,
1865                                 cgs->index, bexcl, k, fr, FALSE, TRUE, TRUE, fr->solvent_opt);
1866                     nsbuf->ncg = nsbuf->nj = 0;
1867                 }
1868             }
1869         }
1870         /* setexcl(nri,i_atoms,excl,FALSE,bexcl); */
1871         setexcl(cgs->index[icg], cgs->index[icg+1], excl, FALSE, bexcl);
1872     }
1873     close_neighbor_lists(fr, FALSE);
1874
1875     return nsearch;
1876 }
1877
1878 /************************************************
1879  *
1880  *    N S 5     G R I D     S T U F F
1881  *
1882  ************************************************/
1883
1884 static gmx_inline void get_dx(int Nx, real gridx, real rc2, int xgi, real x,
1885                               int *dx0, int *dx1, real *dcx2)
1886 {
1887     real dcx, tmp;
1888     int  xgi0, xgi1, i;
1889
1890     if (xgi < 0)
1891     {
1892         *dx0 = 0;
1893         xgi0 = -1;
1894         *dx1 = -1;
1895         xgi1 = 0;
1896     }
1897     else if (xgi >= Nx)
1898     {
1899         *dx0 = Nx;
1900         xgi0 = Nx-1;
1901         *dx1 = Nx-1;
1902         xgi1 = Nx;
1903     }
1904     else
1905     {
1906         dcx2[xgi] = 0;
1907         *dx0      = xgi;
1908         xgi0      = xgi-1;
1909         *dx1      = xgi;
1910         xgi1      = xgi+1;
1911     }
1912
1913     for (i = xgi0; i >= 0; i--)
1914     {
1915         dcx = (i+1)*gridx-x;
1916         tmp = dcx*dcx;
1917         if (tmp >= rc2)
1918         {
1919             break;
1920         }
1921         *dx0    = i;
1922         dcx2[i] = tmp;
1923     }
1924     for (i = xgi1; i < Nx; i++)
1925     {
1926         dcx = i*gridx-x;
1927         tmp = dcx*dcx;
1928         if (tmp >= rc2)
1929         {
1930             break;
1931         }
1932         *dx1    = i;
1933         dcx2[i] = tmp;
1934     }
1935 }
1936
1937 static gmx_inline void get_dx_dd(int Nx, real gridx, real rc2, int xgi, real x,
1938                                  int ncpddc, int shift_min, int shift_max,
1939                                  int *g0, int *g1, real *dcx2)
1940 {
1941     real dcx, tmp;
1942     int  g_min, g_max, shift_home;
1943
1944     if (xgi < 0)
1945     {
1946         g_min = 0;
1947         g_max = Nx - 1;
1948         *g0   = 0;
1949         *g1   = -1;
1950     }
1951     else if (xgi >= Nx)
1952     {
1953         g_min = 0;
1954         g_max = Nx - 1;
1955         *g0   = Nx;
1956         *g1   = Nx - 1;
1957     }
1958     else
1959     {
1960         if (ncpddc == 0)
1961         {
1962             g_min = 0;
1963             g_max = Nx - 1;
1964         }
1965         else
1966         {
1967             if (xgi < ncpddc)
1968             {
1969                 shift_home = 0;
1970             }
1971             else
1972             {
1973                 shift_home = -1;
1974             }
1975             g_min = (shift_min == shift_home ? 0          : ncpddc);
1976             g_max = (shift_max == shift_home ? ncpddc - 1 : Nx - 1);
1977         }
1978         if (shift_min > 0)
1979         {
1980             *g0 = g_min;
1981             *g1 = g_min - 1;
1982         }
1983         else if (shift_max < 0)
1984         {
1985             *g0 = g_max + 1;
1986             *g1 = g_max;
1987         }
1988         else
1989         {
1990             *g0       = xgi;
1991             *g1       = xgi;
1992             dcx2[xgi] = 0;
1993         }
1994     }
1995
1996     while (*g0 > g_min)
1997     {
1998         /* Check one grid cell down */
1999         dcx = ((*g0 - 1) + 1)*gridx - x;
2000         tmp = dcx*dcx;
2001         if (tmp >= rc2)
2002         {
2003             break;
2004         }
2005         (*g0)--;
2006         dcx2[*g0] = tmp;
2007     }
2008
2009     while (*g1 < g_max)
2010     {
2011         /* Check one grid cell up */
2012         dcx = (*g1 + 1)*gridx - x;
2013         tmp = dcx*dcx;
2014         if (tmp >= rc2)
2015         {
2016             break;
2017         }
2018         (*g1)++;
2019         dcx2[*g1] = tmp;
2020     }
2021 }
2022
2023
2024 #define sqr(x) ((x)*(x))
2025 #define calc_dx2(XI, YI, ZI, y) (sqr(XI-y[XX]) + sqr(YI-y[YY]) + sqr(ZI-y[ZZ]))
2026 #define calc_cyl_dx2(XI, YI, y) (sqr(XI-y[XX]) + sqr(YI-y[YY]))
2027 /****************************************************
2028  *
2029  *    F A S T   N E I G H B O R  S E A R C H I N G
2030  *
2031  *    Optimized neighboursearching routine using grid
2032  *    at least 1x1x1, see GROMACS manual
2033  *
2034  ****************************************************/
2035
2036
2037 static void get_cutoff2(t_forcerec *fr, gmx_bool bDoLongRange,
2038                         real *rvdw2, real *rcoul2,
2039                         real *rs2, real *rm2, real *rl2)
2040 {
2041     *rs2 = sqr(fr->rlist);
2042
2043     if (bDoLongRange && fr->bTwinRange)
2044     {
2045         /* With plain cut-off or RF we need to make the list exactly
2046          * up to the cut-off and the cut-off's can be different,
2047          * so we can not simply set them to rlistlong.
2048          * To keep this code compatible with (exotic) old cases,
2049          * we also create lists up to rvdw/rcoulomb for PME and Ewald.
2050          * The interaction check should correspond to:
2051          * !ir_vdw/coulomb_might_be_zero_at_cutoff from inputrec.c.
2052          */
2053         if (((fr->vdwtype == evdwCUT || fr->vdwtype == evdwPME) &&
2054              fr->vdw_modifier == eintmodNONE) ||
2055             fr->rvdw <= fr->rlist)
2056         {
2057             *rvdw2  = sqr(fr->rvdw);
2058         }
2059         else
2060         {
2061             *rvdw2  = sqr(fr->rlistlong);
2062         }
2063         if (((fr->eeltype == eelCUT ||
2064               (EEL_RF(fr->eeltype) && fr->eeltype != eelRF_ZERO) ||
2065               fr->eeltype == eelPME ||
2066               fr->eeltype == eelEWALD) &&
2067              fr->coulomb_modifier == eintmodNONE) ||
2068             fr->rcoulomb <= fr->rlist)
2069         {
2070             *rcoul2 = sqr(fr->rcoulomb);
2071         }
2072         else
2073         {
2074             *rcoul2 = sqr(fr->rlistlong);
2075         }
2076     }
2077     else
2078     {
2079         /* Workaround for a gcc -O3 or -ffast-math problem */
2080         *rvdw2  = *rs2;
2081         *rcoul2 = *rs2;
2082     }
2083     *rm2 = min(*rvdw2, *rcoul2);
2084     *rl2 = max(*rvdw2, *rcoul2);
2085 }
2086
2087 static void init_nsgrid_lists(t_forcerec *fr, int ngid, gmx_ns_t *ns)
2088 {
2089     real rvdw2, rcoul2, rs2, rm2, rl2;
2090     int  j;
2091
2092     get_cutoff2(fr, TRUE, &rvdw2, &rcoul2, &rs2, &rm2, &rl2);
2093
2094     /* Short range buffers */
2095     snew(ns->nl_sr, ngid);
2096     /* Counters */
2097     snew(ns->nsr, ngid);
2098     snew(ns->nlr_ljc, ngid);
2099     snew(ns->nlr_one, ngid);
2100
2101     /* Always allocate both list types, since rcoulomb might now change with PME load balancing */
2102     /* Long range VdW and Coul buffers */
2103     snew(ns->nl_lr_ljc, ngid);
2104     /* Long range VdW or Coul only buffers */
2105     snew(ns->nl_lr_one, ngid);
2106
2107     for (j = 0; (j < ngid); j++)
2108     {
2109         snew(ns->nl_sr[j], MAX_CG);
2110         snew(ns->nl_lr_ljc[j], MAX_CG);
2111         snew(ns->nl_lr_one[j], MAX_CG);
2112     }
2113     if (debug)
2114     {
2115         fprintf(debug,
2116                 "ns5_core: rs2 = %g, rm2 = %g, rl2 = %g (nm^2)\n",
2117                 rs2, rm2, rl2);
2118     }
2119 }
2120
2121 static int nsgrid_core(t_commrec *cr, t_forcerec *fr,
2122                        matrix box, int ngid,
2123                        gmx_localtop_t *top,
2124                        t_grid *grid,
2125                        t_excl bexcl[], gmx_bool *bExcludeAlleg,
2126                        t_mdatoms *md,
2127                        put_in_list_t *put_in_list,
2128                        gmx_bool bHaveVdW[],
2129                        gmx_bool bDoLongRange, gmx_bool bMakeQMMMnblist)
2130 {
2131     gmx_ns_t     *ns;
2132     atom_id     **nl_lr_ljc, **nl_lr_one, **nl_sr;
2133     int          *nlr_ljc, *nlr_one, *nsr;
2134     gmx_domdec_t *dd     = NULL;
2135     t_block      *cgs    = &(top->cgs);
2136     int          *cginfo = fr->cginfo;
2137     /* atom_id *i_atoms,*cgsindex=cgs->index; */
2138     ivec          sh0, sh1, shp;
2139     int           cell_x, cell_y, cell_z;
2140     int           d, tx, ty, tz, dx, dy, dz, cj;
2141 #ifdef ALLOW_OFFDIAG_LT_HALFDIAG
2142     int           zsh_ty, zsh_tx, ysh_tx;
2143 #endif
2144     int           dx0, dx1, dy0, dy1, dz0, dz1;
2145     int           Nx, Ny, Nz, shift = -1, j, nrj, nns, nn = -1;
2146     real          gridx, gridy, gridz, grid_x, grid_y, grid_z;
2147     real         *dcx2, *dcy2, *dcz2;
2148     int           zgi, ygi, xgi;
2149     int           cg0, cg1, icg = -1, cgsnr, i0, igid, nri, naaj, max_jcg;
2150     int           jcg0, jcg1, jjcg, cgj0, jgid;
2151     int          *grida, *gridnra, *gridind;
2152     gmx_bool      rvdw_lt_rcoul, rcoul_lt_rvdw;
2153     rvec          xi, *cgcm, grid_offset;
2154     real          r2, rs2, rvdw2, rcoul2, rm2, rl2, XI, YI, ZI, dcx, dcy, dcz, tmp1, tmp2;
2155     int          *i_egp_flags;
2156     gmx_bool      bDomDec, bTriclinicX, bTriclinicY;
2157     ivec          ncpddc;
2158
2159     ns = &fr->ns;
2160
2161     bDomDec = DOMAINDECOMP(cr);
2162     if (bDomDec)
2163     {
2164         dd = cr->dd;
2165     }
2166
2167     bTriclinicX = ((YY < grid->npbcdim &&
2168                     (!bDomDec || dd->nc[YY] == 1) && box[YY][XX] != 0) ||
2169                    (ZZ < grid->npbcdim &&
2170                     (!bDomDec || dd->nc[ZZ] == 1) && box[ZZ][XX] != 0));
2171     bTriclinicY =  (ZZ < grid->npbcdim &&
2172                     (!bDomDec || dd->nc[ZZ] == 1) && box[ZZ][YY] != 0);
2173
2174     cgsnr    = cgs->nr;
2175
2176     get_cutoff2(fr, bDoLongRange, &rvdw2, &rcoul2, &rs2, &rm2, &rl2);
2177
2178     rvdw_lt_rcoul = (rvdw2 >= rcoul2);
2179     rcoul_lt_rvdw = (rcoul2 >= rvdw2);
2180
2181     if (bMakeQMMMnblist)
2182     {
2183         rm2 = rl2;
2184         rs2 = rl2;
2185     }
2186
2187     nl_sr     = ns->nl_sr;
2188     nsr       = ns->nsr;
2189     nl_lr_ljc = ns->nl_lr_ljc;
2190     nl_lr_one = ns->nl_lr_one;
2191     nlr_ljc   = ns->nlr_ljc;
2192     nlr_one   = ns->nlr_one;
2193
2194     /* Unpack arrays */
2195     cgcm    = fr->cg_cm;
2196     Nx      = grid->n[XX];
2197     Ny      = grid->n[YY];
2198     Nz      = grid->n[ZZ];
2199     grida   = grid->a;
2200     gridind = grid->index;
2201     gridnra = grid->nra;
2202     nns     = 0;
2203
2204     gridx      = grid->cell_size[XX];
2205     gridy      = grid->cell_size[YY];
2206     gridz      = grid->cell_size[ZZ];
2207     grid_x     = 1/gridx;
2208     grid_y     = 1/gridy;
2209     grid_z     = 1/gridz;
2210     copy_rvec(grid->cell_offset, grid_offset);
2211     copy_ivec(grid->ncpddc, ncpddc);
2212     dcx2       = grid->dcx2;
2213     dcy2       = grid->dcy2;
2214     dcz2       = grid->dcz2;
2215
2216 #ifdef ALLOW_OFFDIAG_LT_HALFDIAG
2217     zsh_ty = floor(-box[ZZ][YY]/box[YY][YY]+0.5);
2218     zsh_tx = floor(-box[ZZ][XX]/box[XX][XX]+0.5);
2219     ysh_tx = floor(-box[YY][XX]/box[XX][XX]+0.5);
2220     if (zsh_tx != 0 && ysh_tx != 0)
2221     {
2222         /* This could happen due to rounding, when both ratios are 0.5 */
2223         ysh_tx = 0;
2224     }
2225 #endif
2226
2227     debug_gmx();
2228
2229     if (fr->n_tpi)
2230     {
2231         /* We only want a list for the test particle */
2232         cg0 = cgsnr - 1;
2233     }
2234     else
2235     {
2236         cg0 = grid->icg0;
2237     }
2238     cg1 = grid->icg1;
2239
2240     /* Set the shift range */
2241     for (d = 0; d < DIM; d++)
2242     {
2243         sh0[d] = -1;
2244         sh1[d] = 1;
2245         /* Check if we need periodicity shifts.
2246          * Without PBC or with domain decomposition we don't need them.
2247          */
2248         if (d >= ePBC2npbcdim(fr->ePBC) || (bDomDec && dd->nc[d] > 1))
2249         {
2250             shp[d] = 0;
2251         }
2252         else
2253         {
2254             if (d == XX &&
2255                 box[XX][XX] - fabs(box[YY][XX]) - fabs(box[ZZ][XX]) < sqrt(rl2))
2256             {
2257                 shp[d] = 2;
2258             }
2259             else
2260             {
2261                 shp[d] = 1;
2262             }
2263         }
2264     }
2265
2266     /* Loop over charge groups */
2267     for (icg = cg0; (icg < cg1); icg++)
2268     {
2269         igid = GET_CGINFO_GID(cginfo[icg]);
2270         /* Skip this charge group if all energy groups are excluded! */
2271         if (bExcludeAlleg[igid])
2272         {
2273             continue;
2274         }
2275
2276         i0   = cgs->index[icg];
2277
2278         if (bMakeQMMMnblist)
2279         {
2280             /* Skip this charge group if it is not a QM atom while making a
2281              * QM/MM neighbourlist
2282              */
2283             if (md->bQM[i0] == FALSE)
2284             {
2285                 continue; /* MM particle, go to next particle */
2286             }
2287
2288             /* Compute the number of charge groups that fall within the control
2289              * of this one (icg)
2290              */
2291             naaj    = calc_naaj(icg, cgsnr);
2292             jcg0    = icg;
2293             jcg1    = icg + naaj;
2294             max_jcg = cgsnr;
2295         }
2296         else
2297         {
2298             /* make a normal neighbourlist */
2299
2300             if (bDomDec)
2301             {
2302                 /* Get the j charge-group and dd cell shift ranges */
2303                 dd_get_ns_ranges(cr->dd, icg, &jcg0, &jcg1, sh0, sh1);
2304                 max_jcg = 0;
2305             }
2306             else
2307             {
2308                 /* Compute the number of charge groups that fall within the control
2309                  * of this one (icg)
2310                  */
2311                 naaj = calc_naaj(icg, cgsnr);
2312                 jcg0 = icg;
2313                 jcg1 = icg + naaj;
2314
2315                 if (fr->n_tpi)
2316                 {
2317                     /* The i-particle is awlways the test particle,
2318                      * so we want all j-particles
2319                      */
2320                     max_jcg = cgsnr - 1;
2321                 }
2322                 else
2323                 {
2324                     max_jcg  = jcg1 - cgsnr;
2325                 }
2326             }
2327         }
2328
2329         i_egp_flags = fr->egp_flags + igid*ngid;
2330
2331         /* Set the exclusions for the atoms in charge group icg using a bitmask */
2332         setexcl(i0, cgs->index[icg+1], &top->excls, TRUE, bexcl);
2333
2334         ci2xyz(grid, icg, &cell_x, &cell_y, &cell_z);
2335
2336         /* Changed iicg to icg, DvdS 990115
2337          * (but see consistency check above, DvdS 990330)
2338          */
2339 #ifdef NS5DB
2340         fprintf(log, "icg=%5d, naaj=%5d, cell %d %d %d\n",
2341                 icg, naaj, cell_x, cell_y, cell_z);
2342 #endif
2343         /* Loop over shift vectors in three dimensions */
2344         for (tz = -shp[ZZ]; tz <= shp[ZZ]; tz++)
2345         {
2346             ZI = cgcm[icg][ZZ]+tz*box[ZZ][ZZ];
2347             /* Calculate range of cells in Z direction that have the shift tz */
2348             zgi = cell_z + tz*Nz;
2349 #define FAST_DD_NS
2350 #ifndef FAST_DD_NS
2351             get_dx(Nz, gridz, rl2, zgi, ZI, &dz0, &dz1, dcz2);
2352 #else
2353             get_dx_dd(Nz, gridz, rl2, zgi, ZI-grid_offset[ZZ],
2354                       ncpddc[ZZ], sh0[ZZ], sh1[ZZ], &dz0, &dz1, dcz2);
2355 #endif
2356             if (dz0 > dz1)
2357             {
2358                 continue;
2359             }
2360             for (ty = -shp[YY]; ty <= shp[YY]; ty++)
2361             {
2362                 YI = cgcm[icg][YY]+ty*box[YY][YY]+tz*box[ZZ][YY];
2363                 /* Calculate range of cells in Y direction that have the shift ty */
2364                 if (bTriclinicY)
2365                 {
2366                     ygi = (int)(Ny + (YI - grid_offset[YY])*grid_y) - Ny;
2367                 }
2368                 else
2369                 {
2370                     ygi = cell_y + ty*Ny;
2371                 }
2372 #ifndef FAST_DD_NS
2373                 get_dx(Ny, gridy, rl2, ygi, YI, &dy0, &dy1, dcy2);
2374 #else
2375                 get_dx_dd(Ny, gridy, rl2, ygi, YI-grid_offset[YY],
2376                           ncpddc[YY], sh0[YY], sh1[YY], &dy0, &dy1, dcy2);
2377 #endif
2378                 if (dy0 > dy1)
2379                 {
2380                     continue;
2381                 }
2382                 for (tx = -shp[XX]; tx <= shp[XX]; tx++)
2383                 {
2384                     XI = cgcm[icg][XX]+tx*box[XX][XX]+ty*box[YY][XX]+tz*box[ZZ][XX];
2385                     /* Calculate range of cells in X direction that have the shift tx */
2386                     if (bTriclinicX)
2387                     {
2388                         xgi = (int)(Nx + (XI - grid_offset[XX])*grid_x) - Nx;
2389                     }
2390                     else
2391                     {
2392                         xgi = cell_x + tx*Nx;
2393                     }
2394 #ifndef FAST_DD_NS
2395                     get_dx(Nx, gridx, rl2, xgi*Nx, XI, &dx0, &dx1, dcx2);
2396 #else
2397                     get_dx_dd(Nx, gridx, rl2, xgi, XI-grid_offset[XX],
2398                               ncpddc[XX], sh0[XX], sh1[XX], &dx0, &dx1, dcx2);
2399 #endif
2400                     if (dx0 > dx1)
2401                     {
2402                         continue;
2403                     }
2404                     /* Adress: an explicit cg that has a weigthing function of 0 is excluded
2405                      *  from the neigbour list as it will not interact  */
2406                     if (fr->adress_type != eAdressOff)
2407                     {
2408                         if (md->wf[cgs->index[icg]] <= GMX_REAL_EPS && egp_explicit(fr, igid))
2409                         {
2410                             continue;
2411                         }
2412                     }
2413                     /* Get shift vector */
2414                     shift = XYZ2IS(tx, ty, tz);
2415 #ifdef NS5DB
2416                     range_check(shift, 0, SHIFTS);
2417 #endif
2418                     for (nn = 0; (nn < ngid); nn++)
2419                     {
2420                         nsr[nn]      = 0;
2421                         nlr_ljc[nn]  = 0;
2422                         nlr_one[nn]  = 0;
2423                     }
2424 #ifdef NS5DB
2425                     fprintf(log, "shift: %2d, dx0,1: %2d,%2d, dy0,1: %2d,%2d, dz0,1: %2d,%2d\n",
2426                             shift, dx0, dx1, dy0, dy1, dz0, dz1);
2427                     fprintf(log, "cgcm: %8.3f  %8.3f  %8.3f\n", cgcm[icg][XX],
2428                             cgcm[icg][YY], cgcm[icg][ZZ]);
2429                     fprintf(log, "xi:   %8.3f  %8.3f  %8.3f\n", XI, YI, ZI);
2430 #endif
2431                     for (dx = dx0; (dx <= dx1); dx++)
2432                     {
2433                         tmp1 = rl2 - dcx2[dx];
2434                         for (dy = dy0; (dy <= dy1); dy++)
2435                         {
2436                             tmp2 = tmp1 - dcy2[dy];
2437                             if (tmp2 > 0)
2438                             {
2439                                 for (dz = dz0; (dz <= dz1); dz++)
2440                                 {
2441                                     if (tmp2 > dcz2[dz])
2442                                     {
2443                                         /* Find grid-cell cj in which possible neighbours are */
2444                                         cj   = xyz2ci(Ny, Nz, dx, dy, dz);
2445
2446                                         /* Check out how many cgs (nrj) there in this cell */
2447                                         nrj  = gridnra[cj];
2448
2449                                         /* Find the offset in the cg list */
2450                                         cgj0 = gridind[cj];
2451
2452                                         /* Check if all j's are out of range so we
2453                                          * can skip the whole cell.
2454                                          * Should save some time, especially with DD.
2455                                          */
2456                                         if (nrj == 0 ||
2457                                             (grida[cgj0] >= max_jcg &&
2458                                              (grida[cgj0] >= jcg1 || grida[cgj0+nrj-1] < jcg0)))
2459                                         {
2460                                             continue;
2461                                         }
2462
2463                                         /* Loop over cgs */
2464                                         for (j = 0; (j < nrj); j++)
2465                                         {
2466                                             jjcg = grida[cgj0+j];
2467
2468                                             /* check whether this guy is in range! */
2469                                             if ((jjcg >= jcg0 && jjcg < jcg1) ||
2470                                                 (jjcg < max_jcg))
2471                                             {
2472                                                 r2 = calc_dx2(XI, YI, ZI, cgcm[jjcg]);
2473                                                 if (r2 < rl2)
2474                                                 {
2475                                                     /* jgid = gid[cgsatoms[cgsindex[jjcg]]]; */
2476                                                     jgid = GET_CGINFO_GID(cginfo[jjcg]);
2477                                                     /* check energy group exclusions */
2478                                                     if (!(i_egp_flags[jgid] & EGP_EXCL))
2479                                                     {
2480                                                         if (r2 < rs2)
2481                                                         {
2482                                                             if (nsr[jgid] >= MAX_CG)
2483                                                             {
2484                                                                 /* Add to short-range list */
2485                                                                 put_in_list(bHaveVdW, ngid, md, icg, jgid,
2486                                                                             nsr[jgid], nl_sr[jgid],
2487                                                                             cgs->index, /* cgsatoms, */ bexcl,
2488                                                                             shift, fr, FALSE, TRUE, TRUE, fr->solvent_opt);
2489                                                                 nsr[jgid] = 0;
2490                                                             }
2491                                                             nl_sr[jgid][nsr[jgid]++] = jjcg;
2492                                                         }
2493                                                         else if (r2 < rm2)
2494                                                         {
2495                                                             if (nlr_ljc[jgid] >= MAX_CG)
2496                                                             {
2497                                                                 /* Add to LJ+coulomb long-range list */
2498                                                                 put_in_list(bHaveVdW, ngid, md, icg, jgid,
2499                                                                             nlr_ljc[jgid], nl_lr_ljc[jgid], top->cgs.index,
2500                                                                             bexcl, shift, fr, TRUE, TRUE, TRUE, fr->solvent_opt);
2501                                                                 nlr_ljc[jgid] = 0;
2502                                                             }
2503                                                             nl_lr_ljc[jgid][nlr_ljc[jgid]++] = jjcg;
2504                                                         }
2505                                                         else
2506                                                         {
2507                                                             if (nlr_one[jgid] >= MAX_CG)
2508                                                             {
2509                                                                 /* Add to long-range list with only coul, or only LJ */
2510                                                                 put_in_list(bHaveVdW, ngid, md, icg, jgid,
2511                                                                             nlr_one[jgid], nl_lr_one[jgid], top->cgs.index,
2512                                                                             bexcl, shift, fr, TRUE, rvdw_lt_rcoul, rcoul_lt_rvdw, fr->solvent_opt);
2513                                                                 nlr_one[jgid] = 0;
2514                                                             }
2515                                                             nl_lr_one[jgid][nlr_one[jgid]++] = jjcg;
2516                                                         }
2517                                                     }
2518                                                 }
2519                                                 nns++;
2520                                             }
2521                                         }
2522                                     }
2523                                 }
2524                             }
2525                         }
2526                     }
2527                     /* CHECK whether there is anything left in the buffers */
2528                     for (nn = 0; (nn < ngid); nn++)
2529                     {
2530                         if (nsr[nn] > 0)
2531                         {
2532                             put_in_list(bHaveVdW, ngid, md, icg, nn, nsr[nn], nl_sr[nn],
2533                                         cgs->index, /* cgsatoms, */ bexcl,
2534                                         shift, fr, FALSE, TRUE, TRUE, fr->solvent_opt);
2535                         }
2536
2537                         if (nlr_ljc[nn] > 0)
2538                         {
2539                             put_in_list(bHaveVdW, ngid, md, icg, nn, nlr_ljc[nn],
2540                                         nl_lr_ljc[nn], top->cgs.index,
2541                                         bexcl, shift, fr, TRUE, TRUE, TRUE, fr->solvent_opt);
2542                         }
2543
2544                         if (nlr_one[nn] > 0)
2545                         {
2546                             put_in_list(bHaveVdW, ngid, md, icg, nn, nlr_one[nn],
2547                                         nl_lr_one[nn], top->cgs.index,
2548                                         bexcl, shift, fr, TRUE, rvdw_lt_rcoul, rcoul_lt_rvdw, fr->solvent_opt);
2549                         }
2550                     }
2551                 }
2552             }
2553         }
2554         /* setexcl(nri,i_atoms,&top->atoms.excl,FALSE,bexcl); */
2555         setexcl(cgs->index[icg], cgs->index[icg+1], &top->excls, FALSE, bexcl);
2556     }
2557     /* No need to perform any left-over force calculations anymore (as we used to do here)
2558      * since we now save the proper long-range lists for later evaluation.
2559      */
2560
2561     debug_gmx();
2562
2563     /* Close neighbourlists */
2564     close_neighbor_lists(fr, bMakeQMMMnblist);
2565
2566     return nns;
2567 }
2568
2569 void ns_realloc_natoms(gmx_ns_t *ns, int natoms)
2570 {
2571     int i;
2572
2573     if (natoms > ns->nra_alloc)
2574     {
2575         ns->nra_alloc = over_alloc_dd(natoms);
2576         srenew(ns->bexcl, ns->nra_alloc);
2577         for (i = 0; i < ns->nra_alloc; i++)
2578         {
2579             ns->bexcl[i] = 0;
2580         }
2581     }
2582 }
2583
2584 void init_ns(FILE *fplog, const t_commrec *cr,
2585              gmx_ns_t *ns, t_forcerec *fr,
2586              const gmx_mtop_t *mtop)
2587 {
2588     int  mt, icg, nr_in_cg, maxcg, i, j, jcg, ngid, ncg;
2589     t_block *cgs;
2590     char *ptr;
2591
2592     /* Compute largest charge groups size (# atoms) */
2593     nr_in_cg = 1;
2594     for (mt = 0; mt < mtop->nmoltype; mt++)
2595     {
2596         cgs = &mtop->moltype[mt].cgs;
2597         for (icg = 0; (icg < cgs->nr); icg++)
2598         {
2599             nr_in_cg = max(nr_in_cg, (int)(cgs->index[icg+1]-cgs->index[icg]));
2600         }
2601     }
2602
2603     /* Verify whether largest charge group is <= max cg.
2604      * This is determined by the type of the local exclusion type
2605      * Exclusions are stored in bits. (If the type is not large
2606      * enough, enlarge it, unsigned char -> unsigned short -> unsigned long)
2607      */
2608     maxcg = sizeof(t_excl)*8;
2609     if (nr_in_cg > maxcg)
2610     {
2611         gmx_fatal(FARGS, "Max #atoms in a charge group: %d > %d\n",
2612                   nr_in_cg, maxcg);
2613     }
2614
2615     ngid = mtop->groups.grps[egcENER].nr;
2616     snew(ns->bExcludeAlleg, ngid);
2617     for (i = 0; i < ngid; i++)
2618     {
2619         ns->bExcludeAlleg[i] = TRUE;
2620         for (j = 0; j < ngid; j++)
2621         {
2622             if (!(fr->egp_flags[i*ngid+j] & EGP_EXCL))
2623             {
2624                 ns->bExcludeAlleg[i] = FALSE;
2625             }
2626         }
2627     }
2628
2629     if (fr->bGrid)
2630     {
2631         /* Grid search */
2632         ns->grid = init_grid(fplog, fr);
2633         init_nsgrid_lists(fr, ngid, ns);
2634     }
2635     else
2636     {
2637         /* Simple search */
2638         snew(ns->ns_buf, ngid);
2639         for (i = 0; (i < ngid); i++)
2640         {
2641             snew(ns->ns_buf[i], SHIFTS);
2642         }
2643         ncg = ncg_mtop(mtop);
2644         snew(ns->simple_aaj, 2*ncg);
2645         for (jcg = 0; (jcg < ncg); jcg++)
2646         {
2647             ns->simple_aaj[jcg]     = jcg;
2648             ns->simple_aaj[jcg+ncg] = jcg;
2649         }
2650     }
2651
2652     /* Create array that determines whether or not atoms have VdW */
2653     snew(ns->bHaveVdW, fr->ntype);
2654     for (i = 0; (i < fr->ntype); i++)
2655     {
2656         for (j = 0; (j < fr->ntype); j++)
2657         {
2658             ns->bHaveVdW[i] = (ns->bHaveVdW[i] ||
2659                                (fr->bBHAM ?
2660                                 ((BHAMA(fr->nbfp, fr->ntype, i, j) != 0) ||
2661                                  (BHAMB(fr->nbfp, fr->ntype, i, j) != 0) ||
2662                                  (BHAMC(fr->nbfp, fr->ntype, i, j) != 0)) :
2663                                 ((C6(fr->nbfp, fr->ntype, i, j) != 0) ||
2664                                  (C12(fr->nbfp, fr->ntype, i, j) != 0))));
2665         }
2666     }
2667     if (debug)
2668     {
2669         pr_bvec(debug, 0, "bHaveVdW", ns->bHaveVdW, fr->ntype, TRUE);
2670     }
2671
2672     ns->nra_alloc = 0;
2673     ns->bexcl     = NULL;
2674     if (!DOMAINDECOMP(cr))
2675     {
2676         ns_realloc_natoms(ns, mtop->natoms);
2677     }
2678
2679     ns->nblist_initialized = FALSE;
2680
2681     /* nbr list debug dump */
2682     {
2683         char *ptr = getenv("GMX_DUMP_NL");
2684         if (ptr)
2685         {
2686             ns->dump_nl = strtol(ptr, NULL, 10);
2687             if (fplog)
2688             {
2689                 fprintf(fplog, "GMX_DUMP_NL = %d", ns->dump_nl);
2690             }
2691         }
2692         else
2693         {
2694             ns->dump_nl = 0;
2695         }
2696     }
2697 }
2698
2699
2700 int search_neighbours(FILE *log, t_forcerec *fr,
2701                       matrix box,
2702                       gmx_localtop_t *top,
2703                       gmx_groups_t *groups,
2704                       t_commrec *cr,
2705                       t_nrnb *nrnb, t_mdatoms *md,
2706                       gmx_bool bFillGrid,
2707                       gmx_bool bDoLongRangeNS)
2708 {
2709     t_block  *cgs = &(top->cgs);
2710     rvec     box_size, grid_x0, grid_x1;
2711     int      i, j, m, ngid;
2712     real     min_size, grid_dens;
2713     int      nsearch;
2714     gmx_bool     bGrid;
2715     char     *ptr;
2716     gmx_bool     *i_egp_flags;
2717     int      cg_start, cg_end, start, end;
2718     gmx_ns_t *ns;
2719     t_grid   *grid;
2720     gmx_domdec_zones_t *dd_zones;
2721     put_in_list_t *put_in_list;
2722
2723     ns = &fr->ns;
2724
2725     /* Set some local variables */
2726     bGrid = fr->bGrid;
2727     ngid  = groups->grps[egcENER].nr;
2728
2729     for (m = 0; (m < DIM); m++)
2730     {
2731         box_size[m] = box[m][m];
2732     }
2733
2734     if (fr->ePBC != epbcNONE)
2735     {
2736         if (sqr(fr->rlistlong) >= max_cutoff2(fr->ePBC, box))
2737         {
2738             gmx_fatal(FARGS, "One of the box vectors has become shorter than twice the cut-off length or box_yy-|box_zy| or box_zz has become smaller than the cut-off.");
2739         }
2740         if (!bGrid)
2741         {
2742             min_size = min(box_size[XX], min(box_size[YY], box_size[ZZ]));
2743             if (2*fr->rlistlong >= min_size)
2744             {
2745                 gmx_fatal(FARGS, "One of the box diagonal elements has become smaller than twice the cut-off length.");
2746             }
2747         }
2748     }
2749
2750     if (DOMAINDECOMP(cr))
2751     {
2752         ns_realloc_natoms(ns, cgs->index[cgs->nr]);
2753     }
2754     debug_gmx();
2755
2756     /* Reset the neighbourlists */
2757     reset_neighbor_lists(fr, TRUE, TRUE);
2758
2759     if (bGrid && bFillGrid)
2760     {
2761
2762         grid = ns->grid;
2763         if (DOMAINDECOMP(cr))
2764         {
2765             dd_zones = domdec_zones(cr->dd);
2766         }
2767         else
2768         {
2769             dd_zones = NULL;
2770
2771             get_nsgrid_boundaries(grid->nboundeddim, box, NULL, NULL, NULL, NULL,
2772                                   cgs->nr, fr->cg_cm, grid_x0, grid_x1, &grid_dens);
2773
2774             grid_first(log, grid, NULL, NULL, box, grid_x0, grid_x1,
2775                        fr->rlistlong, grid_dens);
2776         }
2777         debug_gmx();
2778
2779         start = 0;
2780         end   = cgs->nr;
2781
2782         if (DOMAINDECOMP(cr))
2783         {
2784             end = cgs->nr;
2785             fill_grid(dd_zones, grid, end, -1, end, fr->cg_cm);
2786             grid->icg0 = 0;
2787             grid->icg1 = dd_zones->izone[dd_zones->nizone-1].cg1;
2788         }
2789         else
2790         {
2791             fill_grid(NULL, grid, cgs->nr, fr->cg0, fr->hcg, fr->cg_cm);
2792             grid->icg0 = fr->cg0;
2793             grid->icg1 = fr->hcg;
2794             debug_gmx();
2795         }
2796
2797         calc_elemnr(grid, start, end, cgs->nr);
2798         calc_ptrs(grid);
2799         grid_last(grid, start, end, cgs->nr);
2800
2801         if (gmx_debug_at)
2802         {
2803             check_grid(grid);
2804             print_grid(debug, grid);
2805         }
2806     }
2807     else if (fr->n_tpi)
2808     {
2809         /* Set the grid cell index for the test particle only.
2810          * The cell to cg index is not corrected, but that does not matter.
2811          */
2812         fill_grid(NULL, ns->grid, fr->hcg, fr->hcg-1, fr->hcg, fr->cg_cm);
2813     }
2814     debug_gmx();
2815
2816     if (fr->adress_type == eAdressOff)
2817     {
2818         if (!fr->ns.bCGlist)
2819         {
2820             put_in_list = put_in_list_at;
2821         }
2822         else
2823         {
2824             put_in_list = put_in_list_cg;
2825         }
2826     }
2827     else
2828     {
2829         put_in_list = put_in_list_adress;
2830     }
2831
2832     /* Do the core! */
2833     if (bGrid)
2834     {
2835         grid    = ns->grid;
2836         nsearch = nsgrid_core(cr, fr, box, ngid, top,
2837                               grid, ns->bexcl, ns->bExcludeAlleg,
2838                               md, put_in_list, ns->bHaveVdW,
2839                               bDoLongRangeNS, FALSE);
2840
2841         /* neighbour searching withouth QMMM! QM atoms have zero charge in
2842          * the classical calculation. The charge-charge interaction
2843          * between QM and MM atoms is handled in the QMMM core calculation
2844          * (see QMMM.c). The VDW however, we'd like to compute classically
2845          * and the QM MM atom pairs have just been put in the
2846          * corresponding neighbourlists. in case of QMMM we still need to
2847          * fill a special QMMM neighbourlist that contains all neighbours
2848          * of the QM atoms. If bQMMM is true, this list will now be made:
2849          */
2850         if (fr->bQMMM && fr->qr->QMMMscheme != eQMMMschemeoniom)
2851         {
2852             nsearch += nsgrid_core(cr, fr, box, ngid, top,
2853                                    grid, ns->bexcl, ns->bExcludeAlleg,
2854                                    md, put_in_list_qmmm, ns->bHaveVdW,
2855                                    bDoLongRangeNS, TRUE);
2856         }
2857     }
2858     else
2859     {
2860         nsearch = ns_simple_core(fr, top, md, box, box_size,
2861                                  ns->bexcl, ns->simple_aaj,
2862                                  ngid, ns->ns_buf, put_in_list, ns->bHaveVdW);
2863     }
2864     debug_gmx();
2865
2866 #ifdef DEBUG
2867     pr_nsblock(log);
2868 #endif
2869
2870     inc_nrnb(nrnb, eNR_NS, nsearch);
2871     /* inc_nrnb(nrnb,eNR_LR,fr->nlr); */
2872
2873     return nsearch;
2874 }
2875
2876 int natoms_beyond_ns_buffer(t_inputrec *ir, t_forcerec *fr, t_block *cgs,
2877                             matrix scale_tot, rvec *x)
2878 {
2879     int  cg0, cg1, cg, a0, a1, a, i, j;
2880     real rint, hbuf2, scale;
2881     rvec *cg_cm, cgsc;
2882     gmx_bool bIsotropic;
2883     int  nBeyond;
2884
2885     nBeyond = 0;
2886
2887     rint = max(ir->rcoulomb, ir->rvdw);
2888     if (ir->rlist < rint)
2889     {
2890         gmx_fatal(FARGS, "The neighbor search buffer has negative size: %f nm",
2891                   ir->rlist - rint);
2892     }
2893     cg_cm = fr->cg_cm;
2894
2895     cg0 = fr->cg0;
2896     cg1 = fr->hcg;
2897
2898     if (!EI_DYNAMICS(ir->eI) || !DYNAMIC_BOX(*ir))
2899     {
2900         hbuf2 = sqr(0.5*(ir->rlist - rint));
2901         for (cg = cg0; cg < cg1; cg++)
2902         {
2903             a0 = cgs->index[cg];
2904             a1 = cgs->index[cg+1];
2905             for (a = a0; a < a1; a++)
2906             {
2907                 if (distance2(cg_cm[cg], x[a]) > hbuf2)
2908                 {
2909                     nBeyond++;
2910                 }
2911             }
2912         }
2913     }
2914     else
2915     {
2916         bIsotropic = TRUE;
2917         scale      = scale_tot[0][0];
2918         for (i = 1; i < DIM; i++)
2919         {
2920             /* With anisotropic scaling, the original spherical ns volumes become
2921              * ellipsoids. To avoid costly transformations we use the minimum
2922              * eigenvalue of the scaling matrix for determining the buffer size.
2923              * Since the lower half is 0, the eigenvalues are the diagonal elements.
2924              */
2925             scale = min(scale, scale_tot[i][i]);
2926             if (scale_tot[i][i] != scale_tot[i-1][i-1])
2927             {
2928                 bIsotropic = FALSE;
2929             }
2930             for (j = 0; j < i; j++)
2931             {
2932                 if (scale_tot[i][j] != 0)
2933                 {
2934                     bIsotropic = FALSE;
2935                 }
2936             }
2937         }
2938         hbuf2 = sqr(0.5*(scale*ir->rlist - rint));
2939         if (bIsotropic)
2940         {
2941             for (cg = cg0; cg < cg1; cg++)
2942             {
2943                 svmul(scale, cg_cm[cg], cgsc);
2944                 a0 = cgs->index[cg];
2945                 a1 = cgs->index[cg+1];
2946                 for (a = a0; a < a1; a++)
2947                 {
2948                     if (distance2(cgsc, x[a]) > hbuf2)
2949                     {
2950                         nBeyond++;
2951                     }
2952                 }
2953             }
2954         }
2955         else
2956         {
2957             /* Anistropic scaling */
2958             for (cg = cg0; cg < cg1; cg++)
2959             {
2960                 /* Since scale_tot contains the transpose of the scaling matrix,
2961                  * we need to multiply with the transpose.
2962                  */
2963                 tmvmul_ur0(scale_tot, cg_cm[cg], cgsc);
2964                 a0 = cgs->index[cg];
2965                 a1 = cgs->index[cg+1];
2966                 for (a = a0; a < a1; a++)
2967                 {
2968                     if (distance2(cgsc, x[a]) > hbuf2)
2969                     {
2970                         nBeyond++;
2971                     }
2972                 }
2973             }
2974         }
2975     }
2976
2977     return nBeyond;
2978 }