Merge branch release-4-6 into master
[alexxy/gromacs.git] / src / gromacs / mdlib / domdec_top.c
1 /* -*- mode: c; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; c-file-style: "stroustrup"; -*-
2  *
3  *
4  * This file is part of Gromacs        Copyright (c) 1991-2008
5  * David van der Spoel, Erik Lindahl, Berk Hess, University of Groningen.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * To help us fund GROMACS development, we humbly ask that you cite
13  * the research papers on the package. Check out http://www.gromacs.org
14  *
15  * And Hey:
16  * Gnomes, ROck Monsters And Chili Sauce
17  */
18
19 #ifdef HAVE_CONFIG_H
20 #include <config.h>
21 #endif
22
23 #include <string.h>
24 #include "typedefs.h"
25 #include "smalloc.h"
26 #include "domdec.h"
27 #include "domdec_network.h"
28 #include "names.h"
29 #include "network.h"
30 #include "vec.h"
31 #include "pbc.h"
32 #include "chargegroup.h"
33 #include "gmx_random.h"
34 #include "topsort.h"
35 #include "mtop_util.h"
36 #include "mshift.h"
37 #include "vsite.h"
38 #include "gmx_ga2la.h"
39 #include "force.h"
40 #include "gmx_omp_nthreads.h"
41
42 /* for dd_init_local_state */
43 #define NITEM_DD_INIT_LOCAL_STATE 5
44
45 typedef struct {
46     int  *index;  /* Index for each atom into il                  */
47     int  *il;     /* ftype|type|a0|...|an|ftype|...               */
48 } gmx_reverse_ilist_t;
49
50 typedef struct {
51     int  a_start;
52     int  a_end;
53     int  natoms_mol;
54     int  type;
55 } gmx_molblock_ind_t;
56
57 typedef struct gmx_reverse_top {
58     gmx_bool             bExclRequired; /* Do we require all exclusions to be assigned? */
59     gmx_bool             bConstr;       /* Are there constraints in this revserse top?  */
60     gmx_bool             bSettle;       /* Are there settles in this revserse top?  */
61     gmx_bool             bBCheck;       /* All bonded interactions have to be assigned? */
62     gmx_bool             bMultiCGmols;  /* Are the multi charge-group molecules?        */
63     gmx_reverse_ilist_t *ril_mt;        /* Reverse ilist for all moltypes      */
64     int                  ril_mt_tot_size;
65     int                  ilsort;        /* The sorting state of bondeds for free energy */
66     gmx_molblock_ind_t  *mbi;
67     int                  nmolblock;
68
69     /* Work data structures for multi-threading */
70     int         nthread;
71     t_idef     *idef_thread;
72     int      ***vsite_pbc;
73     int       **vsite_pbc_nalloc;
74     int        *nbonded_thread;
75     t_blocka   *excl_thread;
76     int        *excl_count_thread;
77
78     /* Pointers only used for an error message */
79     gmx_mtop_t     *err_top_global;
80     gmx_localtop_t *err_top_local;
81 } gmx_reverse_top_t;
82
83 static int nral_rt(int ftype)
84 {
85     /* Returns the number of atom entries for il in gmx_reverse_top_t */
86     int nral;
87
88     nral = NRAL(ftype);
89     if (interaction_function[ftype].flags & IF_VSITE)
90     {
91         /* With vsites the reverse topology contains
92          * two extra entries for PBC.
93          */
94         nral += 2;
95     }
96
97     return nral;
98 }
99
100 /* This function tells which interactions need to be assigned exactly once */
101 static gmx_bool dd_check_ftype(int ftype, gmx_bool bBCheck,
102                                gmx_bool bConstr, gmx_bool bSettle)
103 {
104     return (((interaction_function[ftype].flags & IF_BOND) &&
105              !(interaction_function[ftype].flags & IF_VSITE) &&
106              (bBCheck || !(interaction_function[ftype].flags & IF_LIMZERO))) ||
107             (bConstr && (ftype == F_CONSTR || ftype == F_CONSTRNC)) ||
108             (bSettle && ftype == F_SETTLE));
109 }
110
111 static void print_error_header(FILE *fplog, char *moltypename, int nprint)
112 {
113     fprintf(fplog, "\nMolecule type '%s'\n", moltypename);
114     fprintf(stderr, "\nMolecule type '%s'\n", moltypename);
115     fprintf(fplog,
116             "the first %d missing interactions, except for exclusions:\n",
117             nprint);
118     fprintf(stderr,
119             "the first %d missing interactions, except for exclusions:\n",
120             nprint);
121 }
122
123 static void print_missing_interactions_mb(FILE *fplog, t_commrec *cr,
124                                           gmx_reverse_top_t *rt,
125                                           char *moltypename,
126                                           gmx_reverse_ilist_t *ril,
127                                           int a_start, int a_end,
128                                           int nat_mol, int nmol,
129                                           t_idef *idef)
130 {
131     int      nril_mol, *assigned, *gatindex;
132     int      ftype, ftype_j, nral, i, j_mol, j, k, a0, a0_mol, mol, a, a_gl;
133     int      nprint;
134     t_ilist *il;
135     t_iatom *ia;
136     gmx_bool bFound;
137
138     nril_mol = ril->index[nat_mol];
139     snew(assigned, nmol*nril_mol);
140
141     gatindex = cr->dd->gatindex;
142     for (ftype = 0; ftype < F_NRE; ftype++)
143     {
144         if (dd_check_ftype(ftype, rt->bBCheck, rt->bConstr, rt->bSettle))
145         {
146             nral = NRAL(ftype);
147             il   = &idef->il[ftype];
148             ia   = il->iatoms;
149             for (i = 0; i < il->nr; i += 1+nral)
150             {
151                 a0     = gatindex[ia[1]];
152                 /* Check if this interaction is in
153                  * the currently checked molblock.
154                  */
155                 if (a0 >= a_start && a0 < a_end)
156                 {
157                     mol    = (a0 - a_start)/nat_mol;
158                     a0_mol = (a0 - a_start) - mol*nat_mol;
159                     j_mol  = ril->index[a0_mol];
160                     bFound = FALSE;
161                     while (j_mol < ril->index[a0_mol+1] && !bFound)
162                     {
163                         j       = mol*nril_mol + j_mol;
164                         ftype_j = ril->il[j_mol];
165                         /* Here we need to check if this interaction has
166                          * not already been assigned, since we could have
167                          * multiply defined interactions.
168                          */
169                         if (ftype == ftype_j && ia[0] == ril->il[j_mol+1] &&
170                             assigned[j] == 0)
171                         {
172                             /* Check the atoms */
173                             bFound = TRUE;
174                             for (a = 0; a < nral; a++)
175                             {
176                                 if (gatindex[ia[1+a]] !=
177                                     a_start + mol*nat_mol + ril->il[j_mol+2+a])
178                                 {
179                                     bFound = FALSE;
180                                 }
181                             }
182                             if (bFound)
183                             {
184                                 assigned[j] = 1;
185                             }
186                         }
187                         j_mol += 2 + nral_rt(ftype_j);
188                     }
189                     if (!bFound)
190                     {
191                         gmx_incons("Some interactions seem to be assigned multiple times");
192                     }
193                 }
194                 ia += 1 + nral;
195             }
196         }
197     }
198
199     gmx_sumi(nmol*nril_mol, assigned, cr);
200
201     nprint = 10;
202     i      = 0;
203     for (mol = 0; mol < nmol; mol++)
204     {
205         j_mol = 0;
206         while (j_mol < nril_mol)
207         {
208             ftype = ril->il[j_mol];
209             nral  = NRAL(ftype);
210             j     = mol*nril_mol + j_mol;
211             if (assigned[j] == 0 &&
212                 !(interaction_function[ftype].flags & IF_VSITE))
213             {
214                 if (DDMASTER(cr->dd))
215                 {
216                     if (i == 0)
217                     {
218                         print_error_header(fplog, moltypename, nprint);
219                     }
220                     fprintf(fplog, "%20s atoms",
221                             interaction_function[ftype].longname);
222                     fprintf(stderr, "%20s atoms",
223                             interaction_function[ftype].longname);
224                     for (a = 0; a < nral; a++)
225                     {
226                         fprintf(fplog, "%5d", ril->il[j_mol+2+a]+1);
227                         fprintf(stderr, "%5d", ril->il[j_mol+2+a]+1);
228                     }
229                     while (a < 4)
230                     {
231                         fprintf(fplog, "     ");
232                         fprintf(stderr, "     ");
233                         a++;
234                     }
235                     fprintf(fplog, " global");
236                     fprintf(stderr, " global");
237                     for (a = 0; a < nral; a++)
238                     {
239                         fprintf(fplog, "%6d",
240                                 a_start+mol*nat_mol+ril->il[j_mol+2+a]+1);
241                         fprintf(stderr, "%6d",
242                                 a_start+mol*nat_mol+ril->il[j_mol+2+a]+1);
243                     }
244                     fprintf(fplog, "\n");
245                     fprintf(stderr, "\n");
246                 }
247                 i++;
248                 if (i >= nprint)
249                 {
250                     break;
251                 }
252             }
253             j_mol += 2 + nral_rt(ftype);
254         }
255     }
256
257     sfree(assigned);
258 }
259
260 static void print_missing_interactions_atoms(FILE *fplog, t_commrec *cr,
261                                              gmx_mtop_t *mtop, t_idef *idef)
262 {
263     int                mb, a_start, a_end;
264     gmx_molblock_t    *molb;
265     gmx_reverse_top_t *rt;
266
267     rt = cr->dd->reverse_top;
268
269     /* Print the atoms in the missing interactions per molblock */
270     a_end = 0;
271     for (mb = 0; mb < mtop->nmolblock; mb++)
272     {
273         molb    = &mtop->molblock[mb];
274         a_start = a_end;
275         a_end   = a_start + molb->nmol*molb->natoms_mol;
276
277         print_missing_interactions_mb(fplog, cr, rt,
278                                       *(mtop->moltype[molb->type].name),
279                                       &rt->ril_mt[molb->type],
280                                       a_start, a_end, molb->natoms_mol,
281                                       molb->nmol,
282                                       idef);
283     }
284 }
285
286 void dd_print_missing_interactions(FILE *fplog, t_commrec *cr, int local_count,  gmx_mtop_t *top_global, t_state *state_local)
287 {
288     int             ndiff_tot, cl[F_NRE], n, ndiff, rest_global, rest_local;
289     int             ftype, nral;
290     char            buf[STRLEN];
291     gmx_domdec_t   *dd;
292     gmx_mtop_t     *err_top_global;
293     gmx_localtop_t *err_top_local;
294
295     dd = cr->dd;
296
297     err_top_global = dd->reverse_top->err_top_global;
298     err_top_local  = dd->reverse_top->err_top_local;
299
300     if (fplog)
301     {
302         fprintf(fplog, "\nNot all bonded interactions have been properly assigned to the domain decomposition cells\n");
303         fflush(fplog);
304     }
305
306     ndiff_tot = local_count - dd->nbonded_global;
307
308     for (ftype = 0; ftype < F_NRE; ftype++)
309     {
310         nral      = NRAL(ftype);
311         cl[ftype] = err_top_local->idef.il[ftype].nr/(1+nral);
312     }
313
314     gmx_sumi(F_NRE, cl, cr);
315
316     if (DDMASTER(dd))
317     {
318         fprintf(fplog, "\nA list of missing interactions:\n");
319         fprintf(stderr, "\nA list of missing interactions:\n");
320         rest_global = dd->nbonded_global;
321         rest_local  = local_count;
322         for (ftype = 0; ftype < F_NRE; ftype++)
323         {
324             /* In the reverse and local top all constraints are merged
325              * into F_CONSTR. So in the if statement we skip F_CONSTRNC
326              * and add these constraints when doing F_CONSTR.
327              */
328             if (((interaction_function[ftype].flags & IF_BOND) &&
329                  (dd->reverse_top->bBCheck
330                   || !(interaction_function[ftype].flags & IF_LIMZERO)))
331                 || (dd->reverse_top->bConstr && ftype == F_CONSTR)
332                 || (dd->reverse_top->bSettle && ftype == F_SETTLE))
333             {
334                 nral = NRAL(ftype);
335                 n    = gmx_mtop_ftype_count(err_top_global, ftype);
336                 if (ftype == F_CONSTR)
337                 {
338                     n += gmx_mtop_ftype_count(err_top_global, F_CONSTRNC);
339                 }
340                 ndiff = cl[ftype] - n;
341                 if (ndiff != 0)
342                 {
343                     sprintf(buf, "%20s of %6d missing %6d",
344                             interaction_function[ftype].longname, n, -ndiff);
345                     fprintf(fplog, "%s\n", buf);
346                     fprintf(stderr, "%s\n", buf);
347                 }
348                 rest_global -= n;
349                 rest_local  -= cl[ftype];
350             }
351         }
352
353         ndiff = rest_local - rest_global;
354         if (ndiff != 0)
355         {
356             sprintf(buf, "%20s of %6d missing %6d", "exclusions",
357                     rest_global, -ndiff);
358             fprintf(fplog, "%s\n", buf);
359             fprintf(stderr, "%s\n", buf);
360         }
361     }
362
363     print_missing_interactions_atoms(fplog, cr, err_top_global,
364                                      &err_top_local->idef);
365     write_dd_pdb("dd_dump_err", 0, "dump", top_global, cr,
366                  -1, state_local->x, state_local->box);
367     if (DDMASTER(dd))
368     {
369         if (ndiff_tot > 0)
370         {
371             gmx_incons("One or more interactions were multiple assigned in the domain decompostion");
372         }
373         else
374         {
375             gmx_fatal(FARGS, "%d of the %d bonded interactions could not be calculated because some atoms involved moved further apart than the multi-body cut-off distance (%g nm) or the two-body cut-off distance (%g nm), see option -rdd, for pairs and tabulated bonds also see option -ddcheck", -ndiff_tot, cr->dd->nbonded_global, dd_cutoff_mbody(cr->dd), dd_cutoff_twobody(cr->dd));
376         }
377     }
378 }
379
380 static void global_atomnr_to_moltype_ind(gmx_reverse_top_t *rt, int i_gl,
381                                          int *mb, int *mt, int *mol, int *i_mol)
382 {
383     int molb;
384
385
386     gmx_molblock_ind_t *mbi   = rt->mbi;
387     int                 start = 0;
388     int                 end   =  rt->nmolblock; /* exclusive */
389     int                 mid;
390
391     /* binary search for molblock_ind */
392     while (TRUE)
393     {
394         mid = (start+end)/2;
395         if (i_gl >= mbi[mid].a_end)
396         {
397             start = mid+1;
398         }
399         else if (i_gl < mbi[mid].a_start)
400         {
401             end = mid;
402         }
403         else
404         {
405             break;
406         }
407     }
408
409     *mb  = mid;
410     mbi += mid;
411
412     *mt    = mbi->type;
413     *mol   = (i_gl - mbi->a_start) / mbi->natoms_mol;
414     *i_mol = (i_gl - mbi->a_start) - (*mol)*mbi->natoms_mol;
415 }
416
417 static int count_excls(t_block *cgs, t_blocka *excls, int *n_intercg_excl)
418 {
419     int n, n_inter, cg, at0, at1, at, excl, atj;
420
421     n               = 0;
422     *n_intercg_excl = 0;
423     for (cg = 0; cg < cgs->nr; cg++)
424     {
425         at0 = cgs->index[cg];
426         at1 = cgs->index[cg+1];
427         for (at = at0; at < at1; at++)
428         {
429             for (excl = excls->index[at]; excl < excls->index[at+1]; excl++)
430             {
431                 atj = excls->a[excl];
432                 if (atj > at)
433                 {
434                     n++;
435                     if (atj < at0 || atj >= at1)
436                     {
437                         (*n_intercg_excl)++;
438                     }
439                 }
440             }
441         }
442     }
443
444     return n;
445 }
446
447 static int low_make_reverse_ilist(t_ilist *il_mt, t_atom *atom,
448                                   int **vsite_pbc,
449                                   int *count,
450                                   gmx_bool bConstr, gmx_bool bSettle,
451                                   gmx_bool bBCheck,
452                                   int *r_index, int *r_il,
453                                   gmx_bool bLinkToAllAtoms,
454                                   gmx_bool bAssign)
455 {
456     int      ftype, nral, i, j, nlink, link;
457     t_ilist *il;
458     t_iatom *ia;
459     atom_id  a;
460     int      nint;
461     gmx_bool bVSite;
462
463     nint = 0;
464     for (ftype = 0; ftype < F_NRE; ftype++)
465     {
466         if ((interaction_function[ftype].flags & (IF_BOND | IF_VSITE)) ||
467             (bConstr && (ftype == F_CONSTR || ftype == F_CONSTRNC)) ||
468             (bSettle && ftype == F_SETTLE))
469         {
470             bVSite = (interaction_function[ftype].flags & IF_VSITE);
471             nral   = NRAL(ftype);
472             il     = &il_mt[ftype];
473             ia     = il->iatoms;
474             for (i = 0; i < il->nr; i += 1+nral)
475             {
476                 ia = il->iatoms + i;
477                 if (bLinkToAllAtoms)
478                 {
479                     if (bVSite)
480                     {
481                         /* We don't need the virtual sites for the cg-links */
482                         nlink = 0;
483                     }
484                     else
485                     {
486                         nlink = nral;
487                     }
488                 }
489                 else
490                 {
491                     /* Couple to the first atom in the interaction */
492                     nlink = 1;
493                 }
494                 for (link = 0; link < nlink; link++)
495                 {
496                     a = ia[1+link];
497                     if (bAssign)
498                     {
499                         r_il[r_index[a]+count[a]] =
500                             (ftype == F_CONSTRNC ? F_CONSTR : ftype);
501                         r_il[r_index[a]+count[a]+1] = ia[0];
502                         for (j = 1; j < 1+nral; j++)
503                         {
504                             /* Store the molecular atom number */
505                             r_il[r_index[a]+count[a]+1+j] = ia[j];
506                         }
507                     }
508                     if (interaction_function[ftype].flags & IF_VSITE)
509                     {
510                         if (bAssign)
511                         {
512                             /* Add an entry to iatoms for storing
513                              * which of the constructing atoms are
514                              * vsites again.
515                              */
516                             r_il[r_index[a]+count[a]+2+nral] = 0;
517                             for (j = 2; j < 1+nral; j++)
518                             {
519                                 if (atom[ia[j]].ptype == eptVSite)
520                                 {
521                                     r_il[r_index[a]+count[a]+2+nral] |= (2<<j);
522                                 }
523                             }
524                             /* Store vsite pbc atom in a second extra entry */
525                             r_il[r_index[a]+count[a]+2+nral+1] =
526                                 (vsite_pbc ? vsite_pbc[ftype-F_VSITE2][i/(1+nral)] : -2);
527                         }
528                     }
529                     else
530                     {
531                         /* We do not count vsites since they are always
532                          * uniquely assigned and can be assigned
533                          * to multiple nodes with recursive vsites.
534                          */
535                         if (bBCheck ||
536                             !(interaction_function[ftype].flags & IF_LIMZERO))
537                         {
538                             nint++;
539                         }
540                     }
541                     count[a] += 2 + nral_rt(ftype);
542                 }
543             }
544         }
545     }
546
547     return nint;
548 }
549
550 static int make_reverse_ilist(gmx_moltype_t *molt,
551                               int **vsite_pbc,
552                               gmx_bool bConstr, gmx_bool bSettle,
553                               gmx_bool bBCheck,
554                               gmx_bool bLinkToAllAtoms,
555                               gmx_reverse_ilist_t *ril_mt)
556 {
557     int nat_mt, *count, i, nint_mt;
558
559     /* Count the interactions */
560     nat_mt = molt->atoms.nr;
561     snew(count, nat_mt);
562     low_make_reverse_ilist(molt->ilist, molt->atoms.atom, vsite_pbc,
563                            count,
564                            bConstr, bSettle, bBCheck, NULL, NULL,
565                            bLinkToAllAtoms, FALSE);
566
567     snew(ril_mt->index, nat_mt+1);
568     ril_mt->index[0] = 0;
569     for (i = 0; i < nat_mt; i++)
570     {
571         ril_mt->index[i+1] = ril_mt->index[i] + count[i];
572         count[i]           = 0;
573     }
574     snew(ril_mt->il, ril_mt->index[nat_mt]);
575
576     /* Store the interactions */
577     nint_mt =
578         low_make_reverse_ilist(molt->ilist, molt->atoms.atom, vsite_pbc,
579                                count,
580                                bConstr, bSettle, bBCheck,
581                                ril_mt->index, ril_mt->il,
582                                bLinkToAllAtoms, TRUE);
583
584     sfree(count);
585
586     return nint_mt;
587 }
588
589 static void destroy_reverse_ilist(gmx_reverse_ilist_t *ril)
590 {
591     sfree(ril->index);
592     sfree(ril->il);
593 }
594
595 static gmx_reverse_top_t *make_reverse_top(gmx_mtop_t *mtop, gmx_bool bFE,
596                                            int ***vsite_pbc_molt,
597                                            gmx_bool bConstr, gmx_bool bSettle,
598                                            gmx_bool bBCheck, int *nint)
599 {
600     int                mt, i, mb;
601     gmx_reverse_top_t *rt;
602     int               *nint_mt;
603     gmx_moltype_t     *molt;
604     int                thread;
605
606     snew(rt, 1);
607
608     /* Should we include constraints (for SHAKE) in rt? */
609     rt->bConstr = bConstr;
610     rt->bSettle = bSettle;
611     rt->bBCheck = bBCheck;
612
613     rt->bMultiCGmols = FALSE;
614     snew(nint_mt, mtop->nmoltype);
615     snew(rt->ril_mt, mtop->nmoltype);
616     rt->ril_mt_tot_size = 0;
617     for (mt = 0; mt < mtop->nmoltype; mt++)
618     {
619         molt = &mtop->moltype[mt];
620         if (molt->cgs.nr > 1)
621         {
622             rt->bMultiCGmols = TRUE;
623         }
624
625         /* Make the atom to interaction list for this molecule type */
626         nint_mt[mt] =
627             make_reverse_ilist(molt, vsite_pbc_molt ? vsite_pbc_molt[mt] : NULL,
628                                rt->bConstr, rt->bSettle, rt->bBCheck, FALSE,
629                                &rt->ril_mt[mt]);
630
631         rt->ril_mt_tot_size += rt->ril_mt[mt].index[molt->atoms.nr];
632     }
633     if (debug)
634     {
635         fprintf(debug, "The total size of the atom to interaction index is %d integers\n", rt->ril_mt_tot_size);
636     }
637
638     *nint = 0;
639     for (mb = 0; mb < mtop->nmolblock; mb++)
640     {
641         *nint += mtop->molblock[mb].nmol*nint_mt[mtop->molblock[mb].type];
642     }
643     sfree(nint_mt);
644
645     if (bFE && gmx_mtop_bondeds_free_energy(mtop))
646     {
647         rt->ilsort = ilsortFE_UNSORTED;
648     }
649     else
650     {
651         rt->ilsort = ilsortNO_FE;
652     }
653
654     /* Make a molblock index for fast searching */
655     snew(rt->mbi, mtop->nmolblock);
656     rt->nmolblock = mtop->nmolblock;
657     i             = 0;
658     for (mb = 0; mb < mtop->nmolblock; mb++)
659     {
660         rt->mbi[mb].a_start    = i;
661         i += mtop->molblock[mb].nmol*mtop->molblock[mb].natoms_mol;
662         rt->mbi[mb].a_end      = i;
663         rt->mbi[mb].natoms_mol = mtop->molblock[mb].natoms_mol;
664         rt->mbi[mb].type       = mtop->molblock[mb].type;
665     }
666
667     rt->nthread = gmx_omp_nthreads_get(emntDomdec);
668     snew(rt->idef_thread, rt->nthread);
669     if (vsite_pbc_molt != NULL)
670     {
671         snew(rt->vsite_pbc, rt->nthread);
672         snew(rt->vsite_pbc_nalloc, rt->nthread);
673         for (thread = 0; thread < rt->nthread; thread++)
674         {
675             snew(rt->vsite_pbc[thread], F_VSITEN-F_VSITE2+1);
676             snew(rt->vsite_pbc_nalloc[thread], F_VSITEN-F_VSITE2+1);
677         }
678     }
679     snew(rt->nbonded_thread, rt->nthread);
680     snew(rt->excl_thread, rt->nthread);
681     snew(rt->excl_count_thread, rt->nthread);
682
683     return rt;
684 }
685
686 void dd_make_reverse_top(FILE *fplog,
687                          gmx_domdec_t *dd, gmx_mtop_t *mtop,
688                          gmx_vsite_t *vsite,
689                          t_inputrec *ir, gmx_bool bBCheck)
690 {
691     int             mb, n_recursive_vsite, nexcl, nexcl_icg, a;
692     gmx_molblock_t *molb;
693     gmx_moltype_t  *molt;
694
695     if (fplog)
696     {
697         fprintf(fplog, "\nLinking all bonded interactions to atoms\n");
698     }
699
700     /* If normal and/or settle constraints act only within charge groups,
701      * we can store them in the reverse top and simply assign them to domains.
702      * Otherwise we need to assign them to multiple domains and set up
703      * the parallel version constraint algoirthm(s).
704      */
705
706     dd->reverse_top = make_reverse_top(mtop, ir->efep != efepNO,
707                                        vsite ? vsite->vsite_pbc_molt : NULL,
708                                        !dd->bInterCGcons, !dd->bInterCGsettles,
709                                        bBCheck, &dd->nbonded_global);
710
711     if (dd->reverse_top->ril_mt_tot_size >= 200000 &&
712         mtop->mols.nr > 1 &&
713         mtop->nmolblock == 1 && mtop->molblock[0].nmol == 1)
714     {
715         /* mtop comes from a pre Gromacs 4 tpr file */
716         const char *note = "NOTE: The tpr file used for this simulation is in an old format, for less memory usage and possibly more performance create a new tpr file with an up to date version of grompp";
717         if (fplog)
718         {
719             fprintf(fplog, "\n%s\n\n", note);
720         }
721         if (DDMASTER(dd))
722         {
723             fprintf(stderr, "\n%s\n\n", note);
724         }
725     }
726
727     dd->reverse_top->bExclRequired = IR_EXCL_FORCES(*ir);
728
729     nexcl              = 0;
730     dd->n_intercg_excl = 0;
731     for (mb = 0; mb < mtop->nmolblock; mb++)
732     {
733         molb                = &mtop->molblock[mb];
734         molt                = &mtop->moltype[molb->type];
735         nexcl              += molb->nmol*count_excls(&molt->cgs, &molt->excls, &nexcl_icg);
736         dd->n_intercg_excl += molb->nmol*nexcl_icg;
737     }
738     if (dd->reverse_top->bExclRequired)
739     {
740         dd->nbonded_global += nexcl;
741         if (EEL_FULL(ir->coulombtype) && dd->n_intercg_excl > 0 && fplog)
742         {
743             fprintf(fplog, "There are %d inter charge-group exclusions,\n"
744                     "will use an extra communication step for exclusion forces for %s\n",
745                     dd->n_intercg_excl, eel_names[ir->coulombtype]);
746         }
747     }
748
749     if (vsite && vsite->n_intercg_vsite > 0)
750     {
751         if (fplog)
752         {
753             fprintf(fplog, "There are %d inter charge-group virtual sites,\n"
754                     "will an extra communication step for selected coordinates and forces\n",
755                     vsite->n_intercg_vsite);
756         }
757         init_domdec_vsites(dd, vsite->n_intercg_vsite);
758     }
759
760     if (dd->bInterCGcons || dd->bInterCGsettles)
761     {
762         init_domdec_constraints(dd, mtop);
763     }
764     if (fplog)
765     {
766         fprintf(fplog, "\n");
767     }
768 }
769
770 static inline void add_ifunc(int nral, t_iatom *tiatoms, t_ilist *il)
771 {
772     t_iatom *liatoms;
773     int      k;
774
775     if (il->nr+1+nral > il->nalloc)
776     {
777         il->nalloc = over_alloc_large(il->nr+1+nral);
778         srenew(il->iatoms, il->nalloc);
779     }
780     liatoms = il->iatoms + il->nr;
781     for (k = 0; k <= nral; k++)
782     {
783         liatoms[k] = tiatoms[k];
784     }
785     il->nr += 1 + nral;
786 }
787
788 static void add_posres(int mol, int a_mol, const gmx_molblock_t *molb,
789                        t_iatom *iatoms, const t_iparams *ip_in,
790                        t_idef *idef)
791 {
792     int        n, a_molb;
793     t_iparams *ip;
794
795     /* This position restraint has not been added yet,
796      * so it's index is the current number of position restraints.
797      */
798     n = idef->il[F_POSRES].nr/2;
799     if (n+1 > idef->iparams_posres_nalloc)
800     {
801         idef->iparams_posres_nalloc = over_alloc_dd(n+1);
802         srenew(idef->iparams_posres, idef->iparams_posres_nalloc);
803     }
804     ip = &idef->iparams_posres[n];
805     /* Copy the force constants */
806     *ip = ip_in[iatoms[0]];
807
808     /* Get the position restraint coordinates from the molblock */
809     a_molb = mol*molb->natoms_mol + a_mol;
810     if (a_molb >= molb->nposres_xA)
811     {
812         gmx_incons("Not enough position restraint coordinates");
813     }
814     ip->posres.pos0A[XX] = molb->posres_xA[a_molb][XX];
815     ip->posres.pos0A[YY] = molb->posres_xA[a_molb][YY];
816     ip->posres.pos0A[ZZ] = molb->posres_xA[a_molb][ZZ];
817     if (molb->nposres_xB > 0)
818     {
819         ip->posres.pos0B[XX] = molb->posres_xB[a_molb][XX];
820         ip->posres.pos0B[YY] = molb->posres_xB[a_molb][YY];
821         ip->posres.pos0B[ZZ] = molb->posres_xB[a_molb][ZZ];
822     }
823     else
824     {
825         ip->posres.pos0B[XX] = ip->posres.pos0A[XX];
826         ip->posres.pos0B[YY] = ip->posres.pos0A[YY];
827         ip->posres.pos0B[ZZ] = ip->posres.pos0A[ZZ];
828     }
829     /* Set the parameter index for idef->iparams_posre */
830     iatoms[0] = n;
831 }
832
833 static void add_fbposres(int mol, int a_mol, const gmx_molblock_t *molb,
834                          t_iatom *iatoms, const t_iparams *ip_in,
835                          t_idef *idef)
836 {
837     int        n, a_molb;
838     t_iparams *ip;
839
840     /* This flat-bottom position restraint has not been added yet,
841      * so it's index is the current number of position restraints.
842      */
843     n = idef->il[F_FBPOSRES].nr/2;
844     if (n+1 > idef->iparams_fbposres_nalloc)
845     {
846         idef->iparams_fbposres_nalloc = over_alloc_dd(n+1);
847         srenew(idef->iparams_fbposres, idef->iparams_fbposres_nalloc);
848     }
849     ip = &idef->iparams_fbposres[n];
850     /* Copy the force constants */
851     *ip = ip_in[iatoms[0]];
852
853     /* Get the position restriant coordinats from the molblock */
854     a_molb = mol*molb->natoms_mol + a_mol;
855     if (a_molb >= molb->nposres_xA)
856     {
857         gmx_incons("Not enough position restraint coordinates");
858     }
859     /* Take reference positions from A position of normal posres */
860     ip->fbposres.pos0[XX] = molb->posres_xA[a_molb][XX];
861     ip->fbposres.pos0[YY] = molb->posres_xA[a_molb][YY];
862     ip->fbposres.pos0[ZZ] = molb->posres_xA[a_molb][ZZ];
863
864     /* Note: no B-type for flat-bottom posres */
865
866     /* Set the parameter index for idef->iparams_posre */
867     iatoms[0] = n;
868 }
869
870 static void add_vsite(gmx_ga2la_t ga2la, int *index, int *rtil,
871                       int ftype, int nral,
872                       gmx_bool bHomeA, int a, int a_gl, int a_mol,
873                       t_iatom *iatoms,
874                       t_idef *idef, int **vsite_pbc, int *vsite_pbc_nalloc)
875 {
876     int     k, ak_gl, vsi, pbc_a_mol;
877     t_iatom tiatoms[1+MAXATOMLIST], *iatoms_r;
878     int     j, ftype_r, nral_r;
879
880     /* Copy the type */
881     tiatoms[0] = iatoms[0];
882
883     if (bHomeA)
884     {
885         /* We know the local index of the first atom */
886         tiatoms[1] = a;
887     }
888     else
889     {
890         /* Convert later in make_local_vsites */
891         tiatoms[1] = -a_gl - 1;
892     }
893
894     for (k = 2; k < 1+nral; k++)
895     {
896         ak_gl = a_gl + iatoms[k] - a_mol;
897         if (!ga2la_get_home(ga2la, ak_gl, &tiatoms[k]))
898         {
899             /* Copy the global index, convert later in make_local_vsites */
900             tiatoms[k] = -(ak_gl + 1);
901         }
902     }
903
904     /* Add this interaction to the local topology */
905     add_ifunc(nral, tiatoms, &idef->il[ftype]);
906     if (vsite_pbc)
907     {
908         vsi = idef->il[ftype].nr/(1+nral) - 1;
909         if (vsi >= vsite_pbc_nalloc[ftype-F_VSITE2])
910         {
911             vsite_pbc_nalloc[ftype-F_VSITE2] = over_alloc_large(vsi+1);
912             srenew(vsite_pbc[ftype-F_VSITE2], vsite_pbc_nalloc[ftype-F_VSITE2]);
913         }
914         if (bHomeA)
915         {
916             pbc_a_mol = iatoms[1+nral+1];
917             if (pbc_a_mol < 0)
918             {
919                 /* The pbc flag is one of the following two options:
920                  * -2: vsite and all constructing atoms are within the same cg, no pbc
921                  * -1: vsite and its first constructing atom are in the same cg, do pbc
922                  */
923                 vsite_pbc[ftype-F_VSITE2][vsi] = pbc_a_mol;
924             }
925             else
926             {
927                 /* Set the pbc atom for this vsite so we can make its pbc
928                  * identical to the rest of the atoms in its charge group.
929                  * Since the order of the atoms does not change within a charge
930                  * group, we do not need the global to local atom index.
931                  */
932                 vsite_pbc[ftype-F_VSITE2][vsi] = a + pbc_a_mol - iatoms[1];
933             }
934         }
935         else
936         {
937             /* This vsite is non-home (required for recursion),
938              * and therefore there is no charge group to match pbc with.
939              * But we always turn on full_pbc to assure that higher order
940              * recursion works correctly.
941              */
942             vsite_pbc[ftype-F_VSITE2][vsi] = -1;
943         }
944     }
945
946     if (iatoms[1+nral])
947     {
948         /* Check for recursion */
949         for (k = 2; k < 1+nral; k++)
950         {
951             if ((iatoms[1+nral] & (2<<k)) && (tiatoms[k] < 0))
952             {
953                 /* This construction atoms is a vsite and not a home atom */
954                 if (gmx_debug_at)
955                 {
956                     fprintf(debug, "Constructing atom %d of vsite atom %d is a vsite and non-home\n", iatoms[k]+1, a_mol+1);
957                 }
958                 /* Find the vsite construction */
959
960                 /* Check all interactions assigned to this atom */
961                 j = index[iatoms[k]];
962                 while (j < index[iatoms[k]+1])
963                 {
964                     ftype_r = rtil[j++];
965                     nral_r  = NRAL(ftype_r);
966                     if (interaction_function[ftype_r].flags & IF_VSITE)
967                     {
968                         /* Add this vsite (recursion) */
969                         add_vsite(ga2la, index, rtil, ftype_r, nral_r,
970                                   FALSE, -1, a_gl+iatoms[k]-iatoms[1], iatoms[k],
971                                   rtil+j, idef, vsite_pbc, vsite_pbc_nalloc);
972                         j += 1 + nral_r + 2;
973                     }
974                     else
975                     {
976                         j += 1 + nral_r;
977                     }
978                 }
979             }
980         }
981     }
982 }
983
984 static void make_la2lc(gmx_domdec_t *dd)
985 {
986     int *cgindex, *la2lc, cg, a;
987
988     cgindex = dd->cgindex;
989
990     if (dd->nat_tot > dd->la2lc_nalloc)
991     {
992         dd->la2lc_nalloc = over_alloc_dd(dd->nat_tot);
993         snew(dd->la2lc, dd->la2lc_nalloc);
994     }
995     la2lc = dd->la2lc;
996
997     /* Make the local atom to local cg index */
998     for (cg = 0; cg < dd->ncg_tot; cg++)
999     {
1000         for (a = cgindex[cg]; a < cgindex[cg+1]; a++)
1001         {
1002             la2lc[a] = cg;
1003         }
1004     }
1005 }
1006
1007 static real dd_dist2(t_pbc *pbc_null, rvec *cg_cm, const int *la2lc, int i, int j)
1008 {
1009     rvec dx;
1010
1011     if (pbc_null)
1012     {
1013         pbc_dx_aiuc(pbc_null, cg_cm[la2lc[i]], cg_cm[la2lc[j]], dx);
1014     }
1015     else
1016     {
1017         rvec_sub(cg_cm[la2lc[i]], cg_cm[la2lc[j]], dx);
1018     }
1019
1020     return norm2(dx);
1021 }
1022
1023 /* Append the nsrc t_blocka block structures in src to *dest */
1024 static void combine_blocka(t_blocka *dest, const t_blocka *src, int nsrc)
1025 {
1026     int ni, na, s, i;
1027
1028     ni = src[nsrc-1].nr;
1029     na = 0;
1030     for (s = 0; s < nsrc; s++)
1031     {
1032         na += src[s].nra;
1033     }
1034     if (ni + 1 > dest->nalloc_index)
1035     {
1036         dest->nalloc_index = over_alloc_large(ni+1);
1037         srenew(dest->index, dest->nalloc_index);
1038     }
1039     if (dest->nra + na > dest->nalloc_a)
1040     {
1041         dest->nalloc_a = over_alloc_large(dest->nra+na);
1042         srenew(dest->a, dest->nalloc_a);
1043     }
1044     for (s = 0; s < nsrc; s++)
1045     {
1046         for (i = dest->nr+1; i < src[s].nr+1; i++)
1047         {
1048             dest->index[i] = dest->nra + src[s].index[i];
1049         }
1050         for (i = 0; i < src[s].nra; i++)
1051         {
1052             dest->a[dest->nra+i] = src[s].a[i];
1053         }
1054         dest->nr   = src[s].nr;
1055         dest->nra += src[s].nra;
1056     }
1057 }
1058
1059 /* Append the nsrc t_idef structures in src to *dest,
1060  * virtual sites need special attention, as pbc info differs per vsite.
1061  */
1062 static void combine_idef(t_idef *dest, const t_idef *src, int nsrc,
1063                          gmx_vsite_t *vsite, int ***vsite_pbc_t)
1064 {
1065     int            ftype, n, s, i;
1066     t_ilist       *ild;
1067     const t_ilist *ils;
1068     gmx_bool       vpbc;
1069     int            nral1 = 0, ftv = 0;
1070
1071     for (ftype = 0; ftype < F_NRE; ftype++)
1072     {
1073         n = 0;
1074         for (s = 0; s < nsrc; s++)
1075         {
1076             n += src[s].il[ftype].nr;
1077         }
1078         if (n > 0)
1079         {
1080             ild = &dest->il[ftype];
1081
1082             if (ild->nr + n > ild->nalloc)
1083             {
1084                 ild->nalloc = over_alloc_large(ild->nr+n);
1085                 srenew(ild->iatoms, ild->nalloc);
1086             }
1087
1088             vpbc = ((interaction_function[ftype].flags & IF_VSITE) &&
1089                     vsite->vsite_pbc_loc != NULL);
1090             if (vpbc)
1091             {
1092                 nral1 = 1 + NRAL(ftype);
1093                 ftv   = ftype - F_VSITE2;
1094                 if ((ild->nr + n)/nral1 > vsite->vsite_pbc_loc_nalloc[ftv])
1095                 {
1096                     vsite->vsite_pbc_loc_nalloc[ftv] =
1097                         over_alloc_large((ild->nr + n)/nral1);
1098                     srenew(vsite->vsite_pbc_loc[ftv],
1099                            vsite->vsite_pbc_loc_nalloc[ftv]);
1100                 }
1101             }
1102
1103             for (s = 0; s < nsrc; s++)
1104             {
1105                 ils = &src[s].il[ftype];
1106                 for (i = 0; i < ils->nr; i++)
1107                 {
1108                     ild->iatoms[ild->nr+i] = ils->iatoms[i];
1109                 }
1110                 if (vpbc)
1111                 {
1112                     for (i = 0; i < ils->nr; i += nral1)
1113                     {
1114                         vsite->vsite_pbc_loc[ftv][(ild->nr+i)/nral1] =
1115                             vsite_pbc_t[s][ftv][i/nral1];
1116                     }
1117                 }
1118
1119                 ild->nr += ils->nr;
1120             }
1121         }
1122     }
1123
1124     /* Position restraints need an additional treatment */
1125     if (dest->il[F_POSRES].nr > 0)
1126     {
1127         n = dest->il[F_POSRES].nr/2;
1128         if (n > dest->iparams_posres_nalloc)
1129         {
1130             dest->iparams_posres_nalloc = over_alloc_large(n);
1131             srenew(dest->iparams_posres, dest->iparams_posres_nalloc);
1132         }
1133         /* Set n to the number of original position restraints in dest */
1134         for (s = 0; s < nsrc; s++)
1135         {
1136             n -= src[s].il[F_POSRES].nr/2;
1137         }
1138         for (s = 0; s < nsrc; s++)
1139         {
1140             for (i = 0; i < src[s].il[F_POSRES].nr/2; i++)
1141             {
1142                 /* Correct the index into iparams_posres */
1143                 dest->il[F_POSRES].iatoms[n*2] = n;
1144                 /* Copy the position restraint force parameters */
1145                 dest->iparams_posres[n] = src[s].iparams_posres[i];
1146                 n++;
1147             }
1148         }
1149     }
1150 }
1151
1152 /* This function looks up and assigns bonded interactions for zone iz.
1153  * With thread parallelizing each thread acts on a different atom range:
1154  * at_start to at_end.
1155  */
1156 static int make_bondeds_zone(gmx_domdec_t *dd,
1157                              const gmx_domdec_zones_t *zones,
1158                              const gmx_molblock_t *molb,
1159                              gmx_bool bRCheckMB, ivec rcheck, gmx_bool bRCheck2B,
1160                              real rc2,
1161                              int *la2lc, t_pbc *pbc_null, rvec *cg_cm,
1162                              const t_iparams *ip_in,
1163                              t_idef *idef,
1164                              int **vsite_pbc,
1165                              int *vsite_pbc_nalloc,
1166                              int iz, int nzone,
1167                              int at_start, int at_end)
1168 {
1169     int                           i, i_gl, mb, mt, mol, i_mol, j, ftype, nral, d, k;
1170     int                          *index, *rtil;
1171     t_iatom                      *iatoms, tiatoms[1+MAXATOMLIST];
1172     gmx_bool                      bBCheck, bUse, bLocal;
1173     ivec                          k_zero, k_plus;
1174     gmx_ga2la_t                   ga2la;
1175     int                           a_loc;
1176     int                           kz;
1177     int                           nizone;
1178     const gmx_domdec_ns_ranges_t *izone;
1179     gmx_reverse_top_t            *rt;
1180     int                           nbonded_local;
1181
1182     nizone = zones->nizone;
1183     izone  = zones->izone;
1184
1185     rt = dd->reverse_top;
1186
1187     bBCheck = rt->bBCheck;
1188
1189     nbonded_local = 0;
1190
1191     ga2la = dd->ga2la;
1192
1193     for (i = at_start; i < at_end; i++)
1194     {
1195         /* Get the global atom number */
1196         i_gl = dd->gatindex[i];
1197         global_atomnr_to_moltype_ind(rt, i_gl, &mb, &mt, &mol, &i_mol);
1198         /* Check all interactions assigned to this atom */
1199         index = rt->ril_mt[mt].index;
1200         rtil  = rt->ril_mt[mt].il;
1201         j     = index[i_mol];
1202         while (j < index[i_mol+1])
1203         {
1204             ftype  = rtil[j++];
1205             iatoms = rtil + j;
1206             nral   = NRAL(ftype);
1207             if (ftype == F_SETTLE)
1208             {
1209                 /* Settles are only in the reverse top when they
1210                  * operate within a charge group. So we can assign
1211                  * them without checks. We do this only for performance
1212                  * reasons; it could be handled by the code below.
1213                  */
1214                 if (iz == 0)
1215                 {
1216                     /* Home zone: add this settle to the local topology */
1217                     tiatoms[0] = iatoms[0];
1218                     tiatoms[1] = i;
1219                     tiatoms[2] = i + iatoms[2] - iatoms[1];
1220                     tiatoms[3] = i + iatoms[3] - iatoms[1];
1221                     add_ifunc(nral, tiatoms, &idef->il[ftype]);
1222                     nbonded_local++;
1223                 }
1224                 j += 1 + nral;
1225             }
1226             else if (interaction_function[ftype].flags & IF_VSITE)
1227             {
1228                 /* The vsite construction goes where the vsite itself is */
1229                 if (iz == 0)
1230                 {
1231                     add_vsite(dd->ga2la, index, rtil, ftype, nral,
1232                               TRUE, i, i_gl, i_mol,
1233                               iatoms, idef, vsite_pbc, vsite_pbc_nalloc);
1234                 }
1235                 j += 1 + nral + 2;
1236             }
1237             else
1238             {
1239                 /* Copy the type */
1240                 tiatoms[0] = iatoms[0];
1241
1242                 if (nral == 1)
1243                 {
1244                     /* Assign single-body interactions to the home zone */
1245                     if (iz == 0)
1246                     {
1247                         bUse       = TRUE;
1248                         tiatoms[1] = i;
1249                         if (ftype == F_POSRES)
1250                         {
1251                             add_posres(mol, i_mol, &molb[mb], tiatoms, ip_in,
1252                                        idef);
1253                         }
1254                         else if (ftype == F_FBPOSRES)
1255                         {
1256                             add_fbposres(mol, i_mol, &molb[mb], tiatoms, ip_in,
1257                                          idef);
1258                         }
1259                     }
1260                     else
1261                     {
1262                         bUse = FALSE;
1263                     }
1264                 }
1265                 else if (nral == 2)
1266                 {
1267                     /* This is a two-body interaction, we can assign
1268                      * analogous to the non-bonded assignments.
1269                      */
1270                     if (!ga2la_get(ga2la, i_gl+iatoms[2]-i_mol, &a_loc, &kz))
1271                     {
1272                         bUse = FALSE;
1273                     }
1274                     else
1275                     {
1276                         if (kz >= nzone)
1277                         {
1278                             kz -= nzone;
1279                         }
1280                         /* Check zone interaction assignments */
1281                         bUse = ((iz < nizone && iz <= kz &&
1282                                  izone[iz].j0 <= kz && kz < izone[iz].j1) ||
1283                                 (kz < nizone &&iz >  kz &&
1284                                  izone[kz].j0 <= iz && iz < izone[kz].j1));
1285                         if (bUse)
1286                         {
1287                             tiatoms[1] = i;
1288                             tiatoms[2] = a_loc;
1289                             /* If necessary check the cgcm distance */
1290                             if (bRCheck2B &&
1291                                 dd_dist2(pbc_null, cg_cm, la2lc,
1292                                          tiatoms[1], tiatoms[2]) >= rc2)
1293                             {
1294                                 bUse = FALSE;
1295                             }
1296                         }
1297                     }
1298                 }
1299                 else
1300                 {
1301                     /* Assign this multi-body bonded interaction to
1302                      * the local node if we have all the atoms involved
1303                      * (local or communicated) and the minimum zone shift
1304                      * in each dimension is zero, for dimensions
1305                      * with 2 DD cells an extra check may be necessary.
1306                      */
1307                     bUse = TRUE;
1308                     clear_ivec(k_zero);
1309                     clear_ivec(k_plus);
1310                     for (k = 1; k <= nral && bUse; k++)
1311                     {
1312                         bLocal = ga2la_get(ga2la, i_gl+iatoms[k]-i_mol,
1313                                            &a_loc, &kz);
1314                         if (!bLocal || kz >= zones->n)
1315                         {
1316                             /* We do not have this atom of this interaction
1317                              * locally, or it comes from more than one cell
1318                              * away.
1319                              */
1320                             bUse = FALSE;
1321                         }
1322                         else
1323                         {
1324                             tiatoms[k] = a_loc;
1325                             for (d = 0; d < DIM; d++)
1326                             {
1327                                 if (zones->shift[kz][d] == 0)
1328                                 {
1329                                     k_zero[d] = k;
1330                                 }
1331                                 else
1332                                 {
1333                                     k_plus[d] = k;
1334                                 }
1335                             }
1336                         }
1337                     }
1338                     bUse = (bUse &&
1339                             k_zero[XX] && k_zero[YY] && k_zero[ZZ]);
1340                     if (bRCheckMB)
1341                     {
1342                         for (d = 0; (d < DIM && bUse); d++)
1343                         {
1344                             /* Check if the cg_cm distance falls within
1345                              * the cut-off to avoid possible multiple
1346                              * assignments of bonded interactions.
1347                              */
1348                             if (rcheck[d] &&
1349                                 k_plus[d] &&
1350                                 dd_dist2(pbc_null, cg_cm, la2lc,
1351                                          tiatoms[k_zero[d]], tiatoms[k_plus[d]]) >= rc2)
1352                             {
1353                                 bUse = FALSE;
1354                             }
1355                         }
1356                     }
1357                 }
1358                 if (bUse)
1359                 {
1360                     /* Add this interaction to the local topology */
1361                     add_ifunc(nral, tiatoms, &idef->il[ftype]);
1362                     /* Sum so we can check in global_stat
1363                      * if we have everything.
1364                      */
1365                     if (bBCheck ||
1366                         !(interaction_function[ftype].flags & IF_LIMZERO))
1367                     {
1368                         nbonded_local++;
1369                     }
1370                 }
1371                 j += 1 + nral;
1372             }
1373         }
1374     }
1375
1376     return nbonded_local;
1377 }
1378
1379 static void set_no_exclusions_zone(gmx_domdec_t *dd, gmx_domdec_zones_t *zones,
1380                                    int iz, t_blocka *lexcls)
1381 {
1382     int  a0, a1, a;
1383
1384     a0 = dd->cgindex[zones->cg_range[iz]];
1385     a1 = dd->cgindex[zones->cg_range[iz+1]];
1386
1387     for (a = a0+1; a < a1+1; a++)
1388     {
1389         lexcls->index[a] = lexcls->nra;
1390     }
1391 }
1392
1393 static int make_exclusions_zone(gmx_domdec_t *dd, gmx_domdec_zones_t *zones,
1394                                 const gmx_moltype_t *moltype,
1395                                 gmx_bool bRCheck, real rc2,
1396                                 int *la2lc, t_pbc *pbc_null, rvec *cg_cm,
1397                                 const int *cginfo,
1398                                 t_blocka *lexcls,
1399                                 int iz,
1400                                 int cg_start, int cg_end)
1401 {
1402     int             nizone, n, count, jla0, jla1, jla;
1403     int             cg, la0, la1, la, a_gl, mb, mt, mol, a_mol, j, aj_mol;
1404     const t_blocka *excls;
1405     gmx_ga2la_t     ga2la;
1406     int             a_loc;
1407     int             cell;
1408
1409     ga2la = dd->ga2la;
1410
1411     jla0 = dd->cgindex[zones->izone[iz].jcg0];
1412     jla1 = dd->cgindex[zones->izone[iz].jcg1];
1413
1414     /* We set the end index, but note that we might not start at zero here */
1415     lexcls->nr = dd->cgindex[cg_end];
1416
1417     n     = lexcls->nra;
1418     count = 0;
1419     for (cg = cg_start; cg < cg_end; cg++)
1420     {
1421         /* Here we assume the number of exclusions in one charge group
1422          * is never larger than 1000.
1423          */
1424         if (n+1000 > lexcls->nalloc_a)
1425         {
1426             lexcls->nalloc_a = over_alloc_large(n+1000);
1427             srenew(lexcls->a, lexcls->nalloc_a);
1428         }
1429         la0 = dd->cgindex[cg];
1430         la1 = dd->cgindex[cg+1];
1431         if (GET_CGINFO_EXCL_INTER(cginfo[cg]) ||
1432             !GET_CGINFO_EXCL_INTRA(cginfo[cg]))
1433         {
1434             /* Copy the exclusions from the global top */
1435             for (la = la0; la < la1; la++)
1436             {
1437                 lexcls->index[la] = n;
1438                 a_gl              = dd->gatindex[la];
1439                 global_atomnr_to_moltype_ind(dd->reverse_top, a_gl, &mb, &mt, &mol, &a_mol);
1440                 excls = &moltype[mt].excls;
1441                 for (j = excls->index[a_mol]; j < excls->index[a_mol+1]; j++)
1442                 {
1443                     aj_mol = excls->a[j];
1444                     /* This computation of jla is only correct intra-cg */
1445                     jla = la + aj_mol - a_mol;
1446                     if (jla >= la0 && jla < la1)
1447                     {
1448                         /* This is an intra-cg exclusion. We can skip
1449                          *  the global indexing and distance checking.
1450                          */
1451                         /* Intra-cg exclusions are only required
1452                          * for the home zone.
1453                          */
1454                         if (iz == 0)
1455                         {
1456                             lexcls->a[n++] = jla;
1457                             /* Check to avoid double counts */
1458                             if (jla > la)
1459                             {
1460                                 count++;
1461                             }
1462                         }
1463                     }
1464                     else
1465                     {
1466                         /* This is a inter-cg exclusion */
1467                         /* Since exclusions are pair interactions,
1468                          * just like non-bonded interactions,
1469                          * they can be assigned properly up
1470                          * to the DD cutoff (not cutoff_min as
1471                          * for the other bonded interactions).
1472                          */
1473                         if (ga2la_get(ga2la, a_gl+aj_mol-a_mol, &jla, &cell))
1474                         {
1475                             if (iz == 0 && cell == 0)
1476                             {
1477                                 lexcls->a[n++] = jla;
1478                                 /* Check to avoid double counts */
1479                                 if (jla > la)
1480                                 {
1481                                     count++;
1482                                 }
1483                             }
1484                             else if (jla >= jla0 && jla < jla1 &&
1485                                      (!bRCheck ||
1486                                       dd_dist2(pbc_null, cg_cm, la2lc, la, jla) < rc2))
1487                             {
1488                                 /* jla > la, since jla0 > la */
1489                                 lexcls->a[n++] = jla;
1490                                 count++;
1491                             }
1492                         }
1493                     }
1494                 }
1495             }
1496         }
1497         else
1498         {
1499             /* There are no inter-cg excls and this cg is self-excluded.
1500              * These exclusions are only required for zone 0,
1501              * since other zones do not see themselves.
1502              */
1503             if (iz == 0)
1504             {
1505                 for (la = la0; la < la1; la++)
1506                 {
1507                     lexcls->index[la] = n;
1508                     for (j = la0; j < la1; j++)
1509                     {
1510                         lexcls->a[n++] = j;
1511                     }
1512                 }
1513                 count += ((la1 - la0)*(la1 - la0 - 1))/2;
1514             }
1515             else
1516             {
1517                 /* We don't need exclusions for this cg */
1518                 for (la = la0; la < la1; la++)
1519                 {
1520                     lexcls->index[la] = n;
1521                 }
1522             }
1523         }
1524     }
1525
1526     lexcls->index[lexcls->nr] = n;
1527     lexcls->nra               = n;
1528
1529     return count;
1530 }
1531
1532 static void check_alloc_index(t_blocka *ba, int nindex_max)
1533 {
1534     if (nindex_max+1 > ba->nalloc_index)
1535     {
1536         ba->nalloc_index = over_alloc_dd(nindex_max+1);
1537         srenew(ba->index, ba->nalloc_index);
1538     }
1539 }
1540
1541 static void check_exclusions_alloc(gmx_domdec_t *dd, gmx_domdec_zones_t *zones,
1542                                    t_blocka *lexcls)
1543 {
1544     int nr;
1545     int thread;
1546
1547     nr = dd->cgindex[zones->izone[zones->nizone-1].cg1];
1548
1549     check_alloc_index(lexcls, nr);
1550
1551     for (thread = 1; thread < dd->reverse_top->nthread; thread++)
1552     {
1553         check_alloc_index(&dd->reverse_top->excl_thread[thread], nr);
1554     }
1555 }
1556
1557 static void finish_local_exclusions(gmx_domdec_t *dd, gmx_domdec_zones_t *zones,
1558                                     t_blocka *lexcls)
1559 {
1560     int la0, la;
1561
1562     lexcls->nr = dd->cgindex[zones->izone[zones->nizone-1].cg1];
1563
1564     if (dd->n_intercg_excl == 0)
1565     {
1566         /* There are no exclusions involving non-home charge groups,
1567          * but we need to set the indices for neighborsearching.
1568          */
1569         la0 = dd->cgindex[zones->izone[0].cg1];
1570         for (la = la0; la < lexcls->nr; la++)
1571         {
1572             lexcls->index[la] = lexcls->nra;
1573         }
1574
1575         /* nr is only used to loop over the exclusions for Ewald and RF,
1576          * so we can set it to the number of home atoms for efficiency.
1577          */
1578         lexcls->nr = dd->cgindex[zones->izone[0].cg1];
1579     }
1580 }
1581
1582 static void clear_idef(t_idef *idef)
1583 {
1584     int  ftype;
1585
1586     /* Clear the counts */
1587     for (ftype = 0; ftype < F_NRE; ftype++)
1588     {
1589         idef->il[ftype].nr = 0;
1590     }
1591 }
1592
1593 static int make_local_bondeds_excls(gmx_domdec_t *dd,
1594                                     gmx_domdec_zones_t *zones,
1595                                     const gmx_mtop_t *mtop,
1596                                     const int *cginfo,
1597                                     gmx_bool bRCheckMB, ivec rcheck, gmx_bool bRCheck2B,
1598                                     real rc,
1599                                     int *la2lc, t_pbc *pbc_null, rvec *cg_cm,
1600                                     t_idef *idef, gmx_vsite_t *vsite,
1601                                     t_blocka *lexcls, int *excl_count)
1602 {
1603     int                nzone_bondeds, nzone_excl;
1604     int                iz, cg0, cg1;
1605     real               rc2;
1606     int                nbonded_local;
1607     int                thread;
1608     gmx_reverse_top_t *rt;
1609
1610     if (dd->reverse_top->bMultiCGmols)
1611     {
1612         nzone_bondeds = zones->n;
1613     }
1614     else
1615     {
1616         /* Only single charge group molecules, so interactions don't
1617          * cross zone boundaries and we only need to assign in the home zone.
1618          */
1619         nzone_bondeds = 1;
1620     }
1621
1622     if (dd->n_intercg_excl > 0)
1623     {
1624         /* We only use exclusions from i-zones to i- and j-zones */
1625         nzone_excl = zones->nizone;
1626     }
1627     else
1628     {
1629         /* There are no inter-cg exclusions and only zone 0 sees itself */
1630         nzone_excl = 1;
1631     }
1632
1633     check_exclusions_alloc(dd, zones, lexcls);
1634
1635     rt = dd->reverse_top;
1636
1637     rc2 = rc*rc;
1638
1639     /* Clear the counts */
1640     clear_idef(idef);
1641     nbonded_local = 0;
1642
1643     lexcls->nr    = 0;
1644     lexcls->nra   = 0;
1645     *excl_count   = 0;
1646
1647     for (iz = 0; iz < nzone_bondeds; iz++)
1648     {
1649         cg0 = zones->cg_range[iz];
1650         cg1 = zones->cg_range[iz+1];
1651
1652 #pragma omp parallel for num_threads(rt->nthread) schedule(static)
1653         for (thread = 0; thread < rt->nthread; thread++)
1654         {
1655             int       cg0t, cg1t;
1656             t_idef   *idef_t;
1657             int       ftype;
1658             int     **vsite_pbc;
1659             int      *vsite_pbc_nalloc;
1660             t_blocka *excl_t;
1661
1662             cg0t = cg0 + ((cg1 - cg0)* thread   )/rt->nthread;
1663             cg1t = cg0 + ((cg1 - cg0)*(thread+1))/rt->nthread;
1664
1665             if (thread == 0)
1666             {
1667                 idef_t = idef;
1668             }
1669             else
1670             {
1671                 idef_t = &rt->idef_thread[thread];
1672                 clear_idef(idef_t);
1673             }
1674
1675             if (vsite && vsite->bHaveChargeGroups && vsite->n_intercg_vsite > 0)
1676             {
1677                 if (thread == 0)
1678                 {
1679                     vsite_pbc        = vsite->vsite_pbc_loc;
1680                     vsite_pbc_nalloc = vsite->vsite_pbc_loc_nalloc;
1681                 }
1682                 else
1683                 {
1684                     vsite_pbc        = rt->vsite_pbc[thread];
1685                     vsite_pbc_nalloc = rt->vsite_pbc_nalloc[thread];
1686                 }
1687             }
1688             else
1689             {
1690                 vsite_pbc        = NULL;
1691                 vsite_pbc_nalloc = NULL;
1692             }
1693
1694             rt->nbonded_thread[thread] =
1695                 make_bondeds_zone(dd, zones,
1696                                   mtop->molblock,
1697                                   bRCheckMB, rcheck, bRCheck2B, rc2,
1698                                   la2lc, pbc_null, cg_cm, idef->iparams,
1699                                   idef_t,
1700                                   vsite_pbc, vsite_pbc_nalloc,
1701                                   iz, zones->n,
1702                                   dd->cgindex[cg0t], dd->cgindex[cg1t]);
1703
1704             if (iz < nzone_excl)
1705             {
1706                 if (thread == 0)
1707                 {
1708                     excl_t = lexcls;
1709                 }
1710                 else
1711                 {
1712                     excl_t      = &rt->excl_thread[thread];
1713                     excl_t->nr  = 0;
1714                     excl_t->nra = 0;
1715                 }
1716
1717                 rt->excl_count_thread[thread] =
1718                     make_exclusions_zone(dd, zones,
1719                                          mtop->moltype, bRCheck2B, rc2,
1720                                          la2lc, pbc_null, cg_cm, cginfo,
1721                                          excl_t,
1722                                          iz,
1723                                          cg0t, cg1t);
1724             }
1725         }
1726
1727         if (rt->nthread > 1)
1728         {
1729             combine_idef(idef, rt->idef_thread+1, rt->nthread-1,
1730                          vsite, rt->vsite_pbc+1);
1731         }
1732
1733         for (thread = 0; thread < rt->nthread; thread++)
1734         {
1735             nbonded_local += rt->nbonded_thread[thread];
1736         }
1737
1738         if (iz < nzone_excl)
1739         {
1740             if (rt->nthread > 1)
1741             {
1742                 combine_blocka(lexcls, rt->excl_thread+1, rt->nthread-1);
1743             }
1744
1745             for (thread = 0; thread < rt->nthread; thread++)
1746             {
1747                 *excl_count += rt->excl_count_thread[thread];
1748             }
1749         }
1750     }
1751
1752     /* Some zones might not have exclusions, but some code still needs to
1753      * loop over the index, so we set the indices here.
1754      */
1755     for (iz = nzone_excl; iz < zones->nizone; iz++)
1756     {
1757         set_no_exclusions_zone(dd, zones, iz, lexcls);
1758     }
1759
1760     finish_local_exclusions(dd, zones, lexcls);
1761     if (debug)
1762     {
1763         fprintf(debug, "We have %d exclusions, check count %d\n",
1764                 lexcls->nra, *excl_count);
1765     }
1766
1767     return nbonded_local;
1768 }
1769
1770 void dd_make_local_cgs(gmx_domdec_t *dd, t_block *lcgs)
1771 {
1772     lcgs->nr    = dd->ncg_tot;
1773     lcgs->index = dd->cgindex;
1774 }
1775
1776 void dd_make_local_top(gmx_domdec_t *dd, gmx_domdec_zones_t *zones,
1777                        int npbcdim, matrix box,
1778                        rvec cellsize_min, ivec npulse,
1779                        t_forcerec *fr,
1780                        rvec *cgcm_or_x,
1781                        gmx_vsite_t *vsite,
1782                        gmx_mtop_t *mtop, gmx_localtop_t *ltop)
1783 {
1784     gmx_bool bUniqueExcl, bRCheckMB, bRCheck2B, bRCheckExcl;
1785     real     rc = -1;
1786     ivec     rcheck;
1787     int      d, nexcl;
1788     t_pbc    pbc, *pbc_null = NULL;
1789
1790     if (debug)
1791     {
1792         fprintf(debug, "Making local topology\n");
1793     }
1794
1795     dd_make_local_cgs(dd, &ltop->cgs);
1796
1797     bRCheckMB   = FALSE;
1798     bRCheck2B   = FALSE;
1799     bRCheckExcl = FALSE;
1800
1801     if (dd->reverse_top->bMultiCGmols)
1802     {
1803         /* We need to check to which cell bondeds should be assigned */
1804         rc = dd_cutoff_twobody(dd);
1805         if (debug)
1806         {
1807             fprintf(debug, "Two-body bonded cut-off distance is %g\n", rc);
1808         }
1809
1810         /* Should we check cg_cm distances when assigning bonded interactions? */
1811         for (d = 0; d < DIM; d++)
1812         {
1813             rcheck[d] = FALSE;
1814             /* Only need to check for dimensions where the part of the box
1815              * that is not communicated is smaller than the cut-off.
1816              */
1817             if (d < npbcdim && dd->nc[d] > 1 &&
1818                 (dd->nc[d] - npulse[d])*cellsize_min[d] < 2*rc)
1819             {
1820                 if (dd->nc[d] == 2)
1821                 {
1822                     rcheck[d] = TRUE;
1823                     bRCheckMB = TRUE;
1824                 }
1825                 /* Check for interactions between two atoms,
1826                  * where we can allow interactions up to the cut-off,
1827                  * instead of up to the smallest cell dimension.
1828                  */
1829                 bRCheck2B = TRUE;
1830             }
1831             if (debug)
1832             {
1833                 fprintf(debug,
1834                         "dim %d cellmin %f bonded rcheck[%d] = %d, bRCheck2B = %d\n",
1835                         d, cellsize_min[d], d, rcheck[d], bRCheck2B);
1836             }
1837         }
1838         if (dd->reverse_top->bExclRequired)
1839         {
1840             bRCheckExcl = bRCheck2B;
1841         }
1842         else
1843         {
1844             /* If we don't have forces on exclusions,
1845              * we don't care about exclusions being assigned mulitple times.
1846              */
1847             bRCheckExcl = FALSE;
1848         }
1849         if (bRCheckMB || bRCheck2B)
1850         {
1851             make_la2lc(dd);
1852             if (fr->bMolPBC)
1853             {
1854                 set_pbc_dd(&pbc, fr->ePBC, dd, TRUE, box);
1855                 pbc_null = &pbc;
1856             }
1857             else
1858             {
1859                 pbc_null = NULL;
1860             }
1861         }
1862     }
1863
1864     dd->nbonded_local =
1865         make_local_bondeds_excls(dd, zones, mtop, fr->cginfo,
1866                                  bRCheckMB, rcheck, bRCheck2B, rc,
1867                                  dd->la2lc,
1868                                  pbc_null, cgcm_or_x,
1869                                  &ltop->idef, vsite,
1870                                  &ltop->excls, &nexcl);
1871
1872     /* The ilist is not sorted yet,
1873      * we can only do this when we have the charge arrays.
1874      */
1875     ltop->idef.ilsort = ilsortUNKNOWN;
1876
1877     if (dd->reverse_top->bExclRequired)
1878     {
1879         dd->nbonded_local += nexcl;
1880
1881         forcerec_set_excl_load(fr, ltop, NULL);
1882     }
1883
1884     ltop->atomtypes  = mtop->atomtypes;
1885
1886     /* For an error message only */
1887     dd->reverse_top->err_top_global = mtop;
1888     dd->reverse_top->err_top_local  = ltop;
1889 }
1890
1891 void dd_sort_local_top(gmx_domdec_t *dd, t_mdatoms *mdatoms,
1892                        gmx_localtop_t *ltop)
1893 {
1894     if (dd->reverse_top->ilsort == ilsortNO_FE)
1895     {
1896         ltop->idef.ilsort = ilsortNO_FE;
1897     }
1898     else
1899     {
1900         gmx_sort_ilist_fe(&ltop->idef, mdatoms->chargeA, mdatoms->chargeB);
1901     }
1902 }
1903
1904 gmx_localtop_t *dd_init_local_top(gmx_mtop_t *top_global)
1905 {
1906     gmx_localtop_t *top;
1907     int             i;
1908
1909     snew(top, 1);
1910
1911     top->idef.ntypes    = top_global->ffparams.ntypes;
1912     top->idef.atnr      = top_global->ffparams.atnr;
1913     top->idef.functype  = top_global->ffparams.functype;
1914     top->idef.iparams   = top_global->ffparams.iparams;
1915     top->idef.fudgeQQ   = top_global->ffparams.fudgeQQ;
1916     top->idef.cmap_grid = top_global->ffparams.cmap_grid;
1917
1918     for (i = 0; i < F_NRE; i++)
1919     {
1920         top->idef.il[i].iatoms = NULL;
1921         top->idef.il[i].nalloc = 0;
1922     }
1923     top->idef.ilsort   = ilsortUNKNOWN;
1924
1925     return top;
1926 }
1927
1928 void dd_init_local_state(gmx_domdec_t *dd,
1929                          t_state *state_global, t_state *state_local)
1930 {
1931     int buf[NITEM_DD_INIT_LOCAL_STATE];
1932
1933     if (DDMASTER(dd))
1934     {
1935         buf[0] = state_global->flags;
1936         buf[1] = state_global->ngtc;
1937         buf[2] = state_global->nnhpres;
1938         buf[3] = state_global->nhchainlength;
1939         buf[4] = state_global->dfhist.nlambda;
1940     }
1941     dd_bcast(dd, NITEM_DD_INIT_LOCAL_STATE*sizeof(int), buf);
1942
1943     init_state(state_local, 0, buf[1], buf[2], buf[3], buf[4]);
1944     state_local->flags = buf[0];
1945
1946     /* With Langevin Dynamics we need to make proper storage space
1947      * in the global and local state for the random numbers.
1948      */
1949     if (state_local->flags & (1<<estLD_RNG))
1950     {
1951         if (DDMASTER(dd) && state_global->nrngi > 1)
1952         {
1953             state_global->nrng = dd->nnodes*gmx_rng_n();
1954             srenew(state_global->ld_rng, state_global->nrng);
1955         }
1956         state_local->nrng = gmx_rng_n();
1957         snew(state_local->ld_rng, state_local->nrng);
1958     }
1959     if (state_local->flags & (1<<estLD_RNGI))
1960     {
1961         if (DDMASTER(dd) && state_global->nrngi > 1)
1962         {
1963             state_global->nrngi = dd->nnodes;
1964             srenew(state_global->ld_rngi, state_global->nrngi);
1965         }
1966         snew(state_local->ld_rngi, 1);
1967     }
1968 }
1969
1970 static void check_link(t_blocka *link, int cg_gl, int cg_gl_j)
1971 {
1972     int      k, aj;
1973     gmx_bool bFound;
1974
1975     bFound = FALSE;
1976     for (k = link->index[cg_gl]; k < link->index[cg_gl+1]; k++)
1977     {
1978         if (link->a[k] == cg_gl_j)
1979         {
1980             bFound = TRUE;
1981         }
1982     }
1983     if (!bFound)
1984     {
1985         /* Add this charge group link */
1986         if (link->index[cg_gl+1]+1 > link->nalloc_a)
1987         {
1988             link->nalloc_a = over_alloc_large(link->index[cg_gl+1]+1);
1989             srenew(link->a, link->nalloc_a);
1990         }
1991         link->a[link->index[cg_gl+1]] = cg_gl_j;
1992         link->index[cg_gl+1]++;
1993     }
1994 }
1995
1996 static int *make_at2cg(t_block *cgs)
1997 {
1998     int *at2cg, cg, a;
1999
2000     snew(at2cg, cgs->index[cgs->nr]);
2001     for (cg = 0; cg < cgs->nr; cg++)
2002     {
2003         for (a = cgs->index[cg]; a < cgs->index[cg+1]; a++)
2004         {
2005             at2cg[a] = cg;
2006         }
2007     }
2008
2009     return at2cg;
2010 }
2011
2012 t_blocka *make_charge_group_links(gmx_mtop_t *mtop, gmx_domdec_t *dd,
2013                                   cginfo_mb_t *cginfo_mb)
2014 {
2015     gmx_reverse_top_t  *rt;
2016     int                 mb, cg_offset, cg, cg_gl, a, aj, i, j, ftype, nral, nlink_mol, mol, ncgi;
2017     gmx_molblock_t     *molb;
2018     gmx_moltype_t      *molt;
2019     t_block            *cgs;
2020     t_blocka           *excls;
2021     int                *a2c;
2022     gmx_reverse_ilist_t ril;
2023     t_blocka           *link;
2024     cginfo_mb_t        *cgi_mb;
2025
2026     /* For each charge group make a list of other charge groups
2027      * in the system that a linked to it via bonded interactions
2028      * which are also stored in reverse_top.
2029      */
2030
2031     rt = dd->reverse_top;
2032
2033     snew(link, 1);
2034     snew(link->index, ncg_mtop(mtop)+1);
2035     link->nalloc_a = 0;
2036     link->a        = NULL;
2037
2038     link->index[0] = 0;
2039     cg_offset      = 0;
2040     ncgi           = 0;
2041     for (mb = 0; mb < mtop->nmolblock; mb++)
2042     {
2043         molb = &mtop->molblock[mb];
2044         if (molb->nmol == 0)
2045         {
2046             continue;
2047         }
2048         molt  = &mtop->moltype[molb->type];
2049         cgs   = &molt->cgs;
2050         excls = &molt->excls;
2051         a2c   = make_at2cg(cgs);
2052         /* Make a reverse ilist in which the interactions are linked
2053          * to all atoms, not only the first atom as in gmx_reverse_top.
2054          * The constraints are discarded here.
2055          */
2056         make_reverse_ilist(molt, NULL, FALSE, FALSE, FALSE, TRUE, &ril);
2057
2058         cgi_mb = &cginfo_mb[mb];
2059
2060         for (cg = 0; cg < cgs->nr; cg++)
2061         {
2062             cg_gl                = cg_offset + cg;
2063             link->index[cg_gl+1] = link->index[cg_gl];
2064             for (a = cgs->index[cg]; a < cgs->index[cg+1]; a++)
2065             {
2066                 i = ril.index[a];
2067                 while (i < ril.index[a+1])
2068                 {
2069                     ftype = ril.il[i++];
2070                     nral  = NRAL(ftype);
2071                     /* Skip the ifunc index */
2072                     i++;
2073                     for (j = 0; j < nral; j++)
2074                     {
2075                         aj = ril.il[i+j];
2076                         if (a2c[aj] != cg)
2077                         {
2078                             check_link(link, cg_gl, cg_offset+a2c[aj]);
2079                         }
2080                     }
2081                     i += nral_rt(ftype);
2082                 }
2083                 if (rt->bExclRequired)
2084                 {
2085                     /* Exclusions always go both ways */
2086                     for (j = excls->index[a]; j < excls->index[a+1]; j++)
2087                     {
2088                         aj = excls->a[j];
2089                         if (a2c[aj] != cg)
2090                         {
2091                             check_link(link, cg_gl, cg_offset+a2c[aj]);
2092                         }
2093                     }
2094                 }
2095             }
2096             if (link->index[cg_gl+1] - link->index[cg_gl] > 0)
2097             {
2098                 SET_CGINFO_BOND_INTER(cgi_mb->cginfo[cg]);
2099                 ncgi++;
2100             }
2101         }
2102         nlink_mol = link->index[cg_offset+cgs->nr] - link->index[cg_offset];
2103
2104         cg_offset += cgs->nr;
2105
2106         destroy_reverse_ilist(&ril);
2107         sfree(a2c);
2108
2109         if (debug)
2110         {
2111             fprintf(debug, "molecule type '%s' %d cgs has %d cg links through bonded interac.\n", *molt->name, cgs->nr, nlink_mol);
2112         }
2113
2114         if (molb->nmol > 1)
2115         {
2116             /* Copy the data for the rest of the molecules in this block */
2117             link->nalloc_a += (molb->nmol - 1)*nlink_mol;
2118             srenew(link->a, link->nalloc_a);
2119             for (mol = 1; mol < molb->nmol; mol++)
2120             {
2121                 for (cg = 0; cg < cgs->nr; cg++)
2122                 {
2123                     cg_gl                = cg_offset + cg;
2124                     link->index[cg_gl+1] =
2125                         link->index[cg_gl+1-cgs->nr] + nlink_mol;
2126                     for (j = link->index[cg_gl]; j < link->index[cg_gl+1]; j++)
2127                     {
2128                         link->a[j] = link->a[j-nlink_mol] + cgs->nr;
2129                     }
2130                     if (link->index[cg_gl+1] - link->index[cg_gl] > 0 &&
2131                         cg_gl - cgi_mb->cg_start < cgi_mb->cg_mod)
2132                     {
2133                         SET_CGINFO_BOND_INTER(cgi_mb->cginfo[cg_gl - cgi_mb->cg_start]);
2134                         ncgi++;
2135                     }
2136                 }
2137                 cg_offset += cgs->nr;
2138             }
2139         }
2140     }
2141
2142     if (debug)
2143     {
2144         fprintf(debug, "Of the %d charge groups %d are linked via bonded interactions\n", ncg_mtop(mtop), ncgi);
2145     }
2146
2147     return link;
2148 }
2149
2150 static void bonded_cg_distance_mol(gmx_moltype_t *molt, int *at2cg,
2151                                    gmx_bool bBCheck, gmx_bool bExcl, rvec *cg_cm,
2152                                    real *r_2b, int *ft2b, int *a2_1, int *a2_2,
2153                                    real *r_mb, int *ftmb, int *am_1, int *am_2)
2154 {
2155     int       ftype, nral, i, j, ai, aj, cgi, cgj;
2156     t_ilist  *il;
2157     t_blocka *excls;
2158     real      r2_2b, r2_mb, rij2;
2159
2160     r2_2b = 0;
2161     r2_mb = 0;
2162     for (ftype = 0; ftype < F_NRE; ftype++)
2163     {
2164         if (dd_check_ftype(ftype, bBCheck, FALSE, FALSE))
2165         {
2166             il   = &molt->ilist[ftype];
2167             nral = NRAL(ftype);
2168             if (nral > 1)
2169             {
2170                 for (i = 0; i < il->nr; i += 1+nral)
2171                 {
2172                     for (ai = 0; ai < nral; ai++)
2173                     {
2174                         cgi = at2cg[il->iatoms[i+1+ai]];
2175                         for (aj = 0; aj < nral; aj++)
2176                         {
2177                             cgj = at2cg[il->iatoms[i+1+aj]];
2178                             if (cgi != cgj)
2179                             {
2180                                 rij2 = distance2(cg_cm[cgi], cg_cm[cgj]);
2181                                 if (nral == 2 && rij2 > r2_2b)
2182                                 {
2183                                     r2_2b = rij2;
2184                                     *ft2b = ftype;
2185                                     *a2_1 = il->iatoms[i+1+ai];
2186                                     *a2_2 = il->iatoms[i+1+aj];
2187                                 }
2188                                 if (nral >  2 && rij2 > r2_mb)
2189                                 {
2190                                     r2_mb = rij2;
2191                                     *ftmb = ftype;
2192                                     *am_1 = il->iatoms[i+1+ai];
2193                                     *am_2 = il->iatoms[i+1+aj];
2194                                 }
2195                             }
2196                         }
2197                     }
2198                 }
2199             }
2200         }
2201     }
2202     if (bExcl)
2203     {
2204         excls = &molt->excls;
2205         for (ai = 0; ai < excls->nr; ai++)
2206         {
2207             cgi = at2cg[ai];
2208             for (j = excls->index[ai]; j < excls->index[ai+1]; j++)
2209             {
2210                 cgj = at2cg[excls->a[j]];
2211                 if (cgi != cgj)
2212                 {
2213                     rij2 = distance2(cg_cm[cgi], cg_cm[cgj]);
2214                     if (rij2 > r2_2b)
2215                     {
2216                         r2_2b = rij2;
2217                     }
2218                 }
2219             }
2220         }
2221     }
2222
2223     *r_2b = sqrt(r2_2b);
2224     *r_mb = sqrt(r2_mb);
2225 }
2226
2227 static void get_cgcm_mol(gmx_moltype_t *molt, gmx_ffparams_t *ffparams,
2228                          int ePBC, t_graph *graph, matrix box,
2229                          gmx_vsite_t *vsite,
2230                          rvec *x, rvec *xs, rvec *cg_cm)
2231 {
2232     int n, i;
2233
2234     if (ePBC != epbcNONE)
2235     {
2236         mk_mshift(NULL, graph, ePBC, box, x);
2237
2238         shift_x(graph, box, x, xs);
2239         /* By doing an extra mk_mshift the molecules that are broken
2240          * because they were e.g. imported from another software
2241          * will be made whole again. Such are the healing powers
2242          * of GROMACS.
2243          */
2244         mk_mshift(NULL, graph, ePBC, box, xs);
2245     }
2246     else
2247     {
2248         /* We copy the coordinates so the original coordinates remain
2249          * unchanged, just to be 100% sure that we do not affect
2250          * binary reproducibility of simulations.
2251          */
2252         n = molt->cgs.index[molt->cgs.nr];
2253         for (i = 0; i < n; i++)
2254         {
2255             copy_rvec(x[i], xs[i]);
2256         }
2257     }
2258
2259     if (vsite)
2260     {
2261         construct_vsites(vsite, xs, 0.0, NULL,
2262                          ffparams->iparams, molt->ilist,
2263                          epbcNONE, TRUE, NULL, NULL, NULL);
2264     }
2265
2266     calc_cgcm(NULL, 0, molt->cgs.nr, &molt->cgs, xs, cg_cm);
2267 }
2268
2269 static int have_vsite_molt(gmx_moltype_t *molt)
2270 {
2271     int      i;
2272     gmx_bool bVSite;
2273
2274     bVSite = FALSE;
2275     for (i = 0; i < F_NRE; i++)
2276     {
2277         if ((interaction_function[i].flags & IF_VSITE) &&
2278             molt->ilist[i].nr > 0)
2279         {
2280             bVSite = TRUE;
2281         }
2282     }
2283
2284     return bVSite;
2285 }
2286
2287 void dd_bonded_cg_distance(FILE *fplog,
2288                            gmx_mtop_t *mtop,
2289                            t_inputrec *ir, rvec *x, matrix box,
2290                            gmx_bool bBCheck,
2291                            real *r_2b, real *r_mb)
2292 {
2293     gmx_bool        bExclRequired;
2294     int             mb, cg_offset, at_offset, *at2cg, mol;
2295     t_graph         graph;
2296     gmx_vsite_t    *vsite;
2297     gmx_molblock_t *molb;
2298     gmx_moltype_t  *molt;
2299     rvec           *xs, *cg_cm;
2300     real            rmol_2b, rmol_mb;
2301     int             ft2b  = -1, a_2b_1 = -1, a_2b_2 = -1, ftmb = -1, a_mb_1 = -1, a_mb_2 = -1;
2302     int             ftm2b = -1, amol_2b_1 = -1, amol_2b_2 = -1, ftmmb = -1, amol_mb_1 = -1, amol_mb_2 = -1;
2303
2304     bExclRequired = IR_EXCL_FORCES(*ir);
2305
2306     vsite = init_vsite(mtop, NULL, TRUE);
2307
2308     *r_2b     = 0;
2309     *r_mb     = 0;
2310     cg_offset = 0;
2311     at_offset = 0;
2312     for (mb = 0; mb < mtop->nmolblock; mb++)
2313     {
2314         molb = &mtop->molblock[mb];
2315         molt = &mtop->moltype[molb->type];
2316         if (molt->cgs.nr == 1 || molb->nmol == 0)
2317         {
2318             cg_offset += molb->nmol*molt->cgs.nr;
2319             at_offset += molb->nmol*molt->atoms.nr;
2320         }
2321         else
2322         {
2323             if (ir->ePBC != epbcNONE)
2324             {
2325                 mk_graph_ilist(NULL, molt->ilist, 0, molt->atoms.nr, FALSE, FALSE,
2326                                &graph);
2327             }
2328
2329             at2cg = make_at2cg(&molt->cgs);
2330             snew(xs, molt->atoms.nr);
2331             snew(cg_cm, molt->cgs.nr);
2332             for (mol = 0; mol < molb->nmol; mol++)
2333             {
2334                 get_cgcm_mol(molt, &mtop->ffparams, ir->ePBC, &graph, box,
2335                              have_vsite_molt(molt) ? vsite : NULL,
2336                              x+at_offset, xs, cg_cm);
2337
2338                 bonded_cg_distance_mol(molt, at2cg, bBCheck, bExclRequired, cg_cm,
2339                                        &rmol_2b, &ftm2b, &amol_2b_1, &amol_2b_2,
2340                                        &rmol_mb, &ftmmb, &amol_mb_1, &amol_mb_2);
2341                 if (rmol_2b > *r_2b)
2342                 {
2343                     *r_2b  = rmol_2b;
2344                     ft2b   = ftm2b;
2345                     a_2b_1 = at_offset + amol_2b_1;
2346                     a_2b_2 = at_offset + amol_2b_2;
2347                 }
2348                 if (rmol_mb > *r_mb)
2349                 {
2350                     *r_mb  = rmol_mb;
2351                     ftmb   = ftmmb;
2352                     a_mb_1 = at_offset + amol_mb_1;
2353                     a_mb_2 = at_offset + amol_mb_2;
2354                 }
2355
2356                 cg_offset += molt->cgs.nr;
2357                 at_offset += molt->atoms.nr;
2358             }
2359             sfree(cg_cm);
2360             sfree(xs);
2361             sfree(at2cg);
2362             if (ir->ePBC != epbcNONE)
2363             {
2364                 done_graph(&graph);
2365             }
2366         }
2367     }
2368
2369     /* We should have a vsite free routine, but here we can simply free */
2370     sfree(vsite);
2371
2372     if (fplog && (ft2b >= 0 || ftmb >= 0))
2373     {
2374         fprintf(fplog,
2375                 "Initial maximum inter charge-group distances:\n");
2376         if (ft2b >= 0)
2377         {
2378             fprintf(fplog,
2379                     "    two-body bonded interactions: %5.3f nm, %s, atoms %d %d\n",
2380                     *r_2b, interaction_function[ft2b].longname,
2381                     a_2b_1+1, a_2b_2+1);
2382         }
2383         if (ftmb >= 0)
2384         {
2385             fprintf(fplog,
2386                     "  multi-body bonded interactions: %5.3f nm, %s, atoms %d %d\n",
2387                     *r_mb, interaction_function[ftmb].longname,
2388                     a_mb_1+1, a_mb_2+1);
2389         }
2390     }
2391 }