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