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