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