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