Move more timing routines into timing/.
[alexxy/gromacs.git] / src / gromacs / mdlib / domdec.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 <stdio.h>
24 #include <time.h>
25 #include <math.h>
26 #include <string.h>
27 #include <stdlib.h>
28 #include "typedefs.h"
29 #include "smalloc.h"
30 #include "gmx_fatal.h"
31 #include "gmx_fatal_collective.h"
32 #include "vec.h"
33 #include "domdec.h"
34 #include "domdec_network.h"
35 #include "nrnb.h"
36 #include "pbc.h"
37 #include "chargegroup.h"
38 #include "constr.h"
39 #include "mdatoms.h"
40 #include "names.h"
41 #include "force.h"
42 #include "pme.h"
43 #include "pull.h"
44 #include "pull_rotation.h"
45 #include "mdrun.h"
46 #include "nsgrid.h"
47 #include "shellfc.h"
48 #include "mtop_util.h"
49 #include "gmx_ga2la.h"
50 #include "gmx_sort.h"
51 #include "macros.h"
52 #include "nbnxn_search.h"
53 #include "bondf.h"
54 #include "gmx_omp_nthreads.h"
55
56 #include "gromacs/fileio/futil.h"
57 #include "gromacs/fileio/gmxfio.h"
58 #include "gromacs/fileio/pdbio.h"
59 #include "gromacs/timing/wallcycle.h"
60 #include "gromacs/utility/gmxmpi.h"
61
62 #define DDRANK(dd, rank)    (rank)
63 #define DDMASTERRANK(dd)   (dd->masterrank)
64
65 typedef struct gmx_domdec_master
66 {
67     /* The cell boundaries */
68     real **cell_x;
69     /* The global charge group division */
70     int   *ncg;    /* Number of home charge groups for each node */
71     int   *index;  /* Index of nnodes+1 into cg */
72     int   *cg;     /* Global charge group index */
73     int   *nat;    /* Number of home atoms for each node. */
74     int   *ibuf;   /* Buffer for communication */
75     rvec  *vbuf;   /* Buffer for state scattering and gathering */
76 } gmx_domdec_master_t;
77
78 typedef struct
79 {
80     /* The numbers of charge groups to send and receive for each cell
81      * that requires communication, the last entry contains the total
82      * number of atoms that needs to be communicated.
83      */
84     int  nsend[DD_MAXIZONE+2];
85     int  nrecv[DD_MAXIZONE+2];
86     /* The charge groups to send */
87     int *index;
88     int  nalloc;
89     /* The atom range for non-in-place communication */
90     int  cell2at0[DD_MAXIZONE];
91     int  cell2at1[DD_MAXIZONE];
92 } gmx_domdec_ind_t;
93
94 typedef struct
95 {
96     int               np;       /* Number of grid pulses in this dimension */
97     int               np_dlb;   /* For dlb, for use with edlbAUTO          */
98     gmx_domdec_ind_t *ind;      /* The indices to communicate, size np     */
99     int               np_nalloc;
100     gmx_bool          bInPlace; /* Can we communicate in place?            */
101 } gmx_domdec_comm_dim_t;
102
103 typedef struct
104 {
105     gmx_bool *bCellMin;    /* Temp. var.: is this cell size at the limit     */
106     real     *cell_f;      /* State var.: cell boundaries, box relative      */
107     real     *old_cell_f;  /* Temp. var.: old cell size                      */
108     real     *cell_f_max0; /* State var.: max lower boundary, incl neighbors */
109     real     *cell_f_min1; /* State var.: min upper boundary, incl neighbors */
110     real     *bound_min;   /* Temp. var.: lower limit for cell boundary      */
111     real     *bound_max;   /* Temp. var.: upper limit for cell boundary      */
112     gmx_bool  bLimited;    /* State var.: is DLB limited in this dim and row */
113     real     *buf_ncd;     /* Temp. var.                                     */
114 } gmx_domdec_root_t;
115
116 #define DD_NLOAD_MAX 9
117
118 /* Here floats are accurate enough, since these variables
119  * only influence the load balancing, not the actual MD results.
120  */
121 typedef struct
122 {
123     int    nload;
124     float *load;
125     float  sum;
126     float  max;
127     float  sum_m;
128     float  cvol_min;
129     float  mdf;
130     float  pme;
131     int    flags;
132 } gmx_domdec_load_t;
133
134 typedef struct
135 {
136     int  nsc;
137     int  ind_gl;
138     int  ind;
139 } gmx_cgsort_t;
140
141 typedef struct
142 {
143     gmx_cgsort_t *sort;
144     gmx_cgsort_t *sort2;
145     int           sort_nalloc;
146     gmx_cgsort_t *sort_new;
147     int           sort_new_nalloc;
148     int          *ibuf;
149     int           ibuf_nalloc;
150 } gmx_domdec_sort_t;
151
152 typedef struct
153 {
154     rvec *v;
155     int   nalloc;
156 } vec_rvec_t;
157
158 /* This enum determines the order of the coordinates.
159  * ddnatHOME and ddnatZONE should be first and second,
160  * the others can be ordered as wanted.
161  */
162 enum {
163     ddnatHOME, ddnatZONE, ddnatVSITE, ddnatCON, ddnatNR
164 };
165
166 enum {
167     edlbAUTO, edlbNO, edlbYES, edlbNR
168 };
169 const char *edlb_names[edlbNR] = { "auto", "no", "yes" };
170
171 typedef struct
172 {
173     int      dim;       /* The dimension                                          */
174     gmx_bool dim_match; /* Tells if DD and PME dims match                         */
175     int      nslab;     /* The number of PME slabs in this dimension              */
176     real    *slb_dim_f; /* Cell sizes for determining the PME comm. with SLB    */
177     int     *pp_min;    /* The minimum pp node location, size nslab               */
178     int     *pp_max;    /* The maximum pp node location,size nslab                */
179     int      maxshift;  /* The maximum shift for coordinate redistribution in PME */
180 } gmx_ddpme_t;
181
182 typedef struct
183 {
184     real min0;    /* The minimum bottom of this zone                        */
185     real max1;    /* The maximum top of this zone                           */
186     real min1;    /* The minimum top of this zone                           */
187     real mch0;    /* The maximum bottom communicaton height for this zone   */
188     real mch1;    /* The maximum top communicaton height for this zone      */
189     real p1_0;    /* The bottom value of the first cell in this zone        */
190     real p1_1;    /* The top value of the first cell in this zone           */
191 } gmx_ddzone_t;
192
193 typedef struct
194 {
195     gmx_domdec_ind_t ind;
196     int             *ibuf;
197     int              ibuf_nalloc;
198     vec_rvec_t       vbuf;
199     int              nsend;
200     int              nat;
201     int              nsend_zone;
202 } dd_comm_setup_work_t;
203
204 typedef struct gmx_domdec_comm
205 {
206     /* All arrays are indexed with 0 to dd->ndim (not Cartesian indexing),
207      * unless stated otherwise.
208      */
209
210     /* The number of decomposition dimensions for PME, 0: no PME */
211     int         npmedecompdim;
212     /* The number of nodes doing PME (PP/PME or only PME) */
213     int         npmenodes;
214     int         npmenodes_x;
215     int         npmenodes_y;
216     /* The communication setup including the PME only nodes */
217     gmx_bool    bCartesianPP_PME;
218     ivec        ntot;
219     int         cartpmedim;
220     int        *pmenodes;          /* size npmenodes                         */
221     int        *ddindex2simnodeid; /* size npmenodes, only with bCartesianPP
222                                     * but with bCartesianPP_PME              */
223     gmx_ddpme_t ddpme[2];
224
225     /* The DD particle-particle nodes only */
226     gmx_bool bCartesianPP;
227     int     *ddindex2ddnodeid; /* size npmenode, only with bCartesianPP_PME */
228
229     /* The global charge groups */
230     t_block cgs_gl;
231
232     /* Should we sort the cgs */
233     int                nstSortCG;
234     gmx_domdec_sort_t *sort;
235
236     /* Are there charge groups? */
237     gmx_bool bCGs;
238
239     /* Are there bonded and multi-body interactions between charge groups? */
240     gmx_bool bInterCGBondeds;
241     gmx_bool bInterCGMultiBody;
242
243     /* Data for the optional bonded interaction atom communication range */
244     gmx_bool  bBondComm;
245     t_blocka *cglink;
246     char     *bLocalCG;
247
248     /* The DLB option */
249     int      eDLB;
250     /* Are we actually using DLB? */
251     gmx_bool bDynLoadBal;
252
253     /* Cell sizes for static load balancing, first index cartesian */
254     real **slb_frac;
255
256     /* The width of the communicated boundaries */
257     real     cutoff_mbody;
258     real     cutoff;
259     /* The minimum cell size (including triclinic correction) */
260     rvec     cellsize_min;
261     /* For dlb, for use with edlbAUTO */
262     rvec     cellsize_min_dlb;
263     /* The lower limit for the DD cell size with DLB */
264     real     cellsize_limit;
265     /* Effectively no NB cut-off limit with DLB for systems without PBC? */
266     gmx_bool bVacDLBNoLimit;
267
268     /* With PME load balancing we set limits on DLB */
269     gmx_bool bPMELoadBalDLBLimits;
270     /* DLB needs to take into account that we want to allow this maximum
271      * cut-off (for PME load balancing), this could limit cell boundaries.
272      */
273     real PMELoadBal_max_cutoff;
274
275     /* tric_dir is only stored here because dd_get_ns_ranges needs it */
276     ivec tric_dir;
277     /* box0 and box_size are required with dim's without pbc and -gcom */
278     rvec box0;
279     rvec box_size;
280
281     /* The cell boundaries */
282     rvec cell_x0;
283     rvec cell_x1;
284
285     /* The old location of the cell boundaries, to check cg displacements */
286     rvec old_cell_x0;
287     rvec old_cell_x1;
288
289     /* The communication setup and charge group boundaries for the zones */
290     gmx_domdec_zones_t zones;
291
292     /* The zone limits for DD dimensions 1 and 2 (not 0), determined from
293      * cell boundaries of neighboring cells for dynamic load balancing.
294      */
295     gmx_ddzone_t zone_d1[2];
296     gmx_ddzone_t zone_d2[2][2];
297
298     /* The coordinate/force communication setup and indices */
299     gmx_domdec_comm_dim_t cd[DIM];
300     /* The maximum number of cells to communicate with in one dimension */
301     int                   maxpulse;
302
303     /* Which cg distribution is stored on the master node */
304     int master_cg_ddp_count;
305
306     /* The number of cg's received from the direct neighbors */
307     int  zone_ncg1[DD_MAXZONE];
308
309     /* The atom counts, the range for each type t is nat[t-1] <= at < nat[t] */
310     int  nat[ddnatNR];
311
312     /* Array for signalling if atoms have moved to another domain */
313     int  *moved;
314     int   moved_nalloc;
315
316     /* Communication buffer for general use */
317     int  *buf_int;
318     int   nalloc_int;
319
320     /* Communication buffer for general use */
321     vec_rvec_t vbuf;
322
323     /* Temporary storage for thread parallel communication setup */
324     int                   nth;
325     dd_comm_setup_work_t *dth;
326
327     /* Communication buffers only used with multiple grid pulses */
328     int       *buf_int2;
329     int        nalloc_int2;
330     vec_rvec_t vbuf2;
331
332     /* Communication buffers for local redistribution */
333     int  **cggl_flag;
334     int    cggl_flag_nalloc[DIM*2];
335     rvec **cgcm_state;
336     int    cgcm_state_nalloc[DIM*2];
337
338     /* Cell sizes for dynamic load balancing */
339     gmx_domdec_root_t **root;
340     real               *cell_f_row;
341     real                cell_f0[DIM];
342     real                cell_f1[DIM];
343     real                cell_f_max0[DIM];
344     real                cell_f_min1[DIM];
345
346     /* Stuff for load communication */
347     gmx_bool           bRecordLoad;
348     gmx_domdec_load_t *load;
349 #ifdef GMX_MPI
350     MPI_Comm          *mpi_comm_load;
351 #endif
352
353     /* Maximum DLB scaling per load balancing step in percent */
354     int dlb_scale_lim;
355
356     /* Cycle counters */
357     float  cycl[ddCyclNr];
358     int    cycl_n[ddCyclNr];
359     float  cycl_max[ddCyclNr];
360     /* Flop counter (0=no,1=yes,2=with (eFlop-1)*5% noise */
361     int    eFlop;
362     double flop;
363     int    flop_n;
364     /* Have often have did we have load measurements */
365     int    n_load_have;
366     /* Have often have we collected the load measurements */
367     int    n_load_collect;
368
369     /* Statistics */
370     double sum_nat[ddnatNR-ddnatZONE];
371     int    ndecomp;
372     int    nload;
373     double load_step;
374     double load_sum;
375     double load_max;
376     ivec   load_lim;
377     double load_mdf;
378     double load_pme;
379
380     /* The last partition step */
381     gmx_large_int_t partition_step;
382
383     /* Debugging */
384     int  nstDDDump;
385     int  nstDDDumpGrid;
386     int  DD_debug;
387 } gmx_domdec_comm_t;
388
389 /* The size per charge group of the cggl_flag buffer in gmx_domdec_comm_t */
390 #define DD_CGIBS 2
391
392 /* The flags for the cggl_flag buffer in gmx_domdec_comm_t */
393 #define DD_FLAG_NRCG  65535
394 #define DD_FLAG_FW(d) (1<<(16+(d)*2))
395 #define DD_FLAG_BW(d) (1<<(16+(d)*2+1))
396
397 /* Zone permutation required to obtain consecutive charge groups
398  * for neighbor searching.
399  */
400 static const int zone_perm[3][4] = { {0, 0, 0, 0}, {1, 0, 0, 0}, {3, 0, 1, 2} };
401
402 /* dd_zo and dd_zp3/dd_zp2 are set up such that i zones with non-zero
403  * components see only j zones with that component 0.
404  */
405
406 /* The DD zone order */
407 static const ivec dd_zo[DD_MAXZONE] =
408 {{0, 0, 0}, {1, 0, 0}, {1, 1, 0}, {0, 1, 0}, {0, 1, 1}, {0, 0, 1}, {1, 0, 1}, {1, 1, 1}};
409
410 /* The 3D setup */
411 #define dd_z3n  8
412 #define dd_zp3n 4
413 static const ivec dd_zp3[dd_zp3n] = {{0, 0, 8}, {1, 3, 6}, {2, 5, 6}, {3, 5, 7}};
414
415 /* The 2D setup */
416 #define dd_z2n  4
417 #define dd_zp2n 2
418 static const ivec dd_zp2[dd_zp2n] = {{0, 0, 4}, {1, 3, 4}};
419
420 /* The 1D setup */
421 #define dd_z1n  2
422 #define dd_zp1n 1
423 static const ivec dd_zp1[dd_zp1n] = {{0, 0, 2}};
424
425 /* Factors used to avoid problems due to rounding issues */
426 #define DD_CELL_MARGIN       1.0001
427 #define DD_CELL_MARGIN2      1.00005
428 /* Factor to account for pressure scaling during nstlist steps */
429 #define DD_PRES_SCALE_MARGIN 1.02
430
431 /* Allowed performance loss before we DLB or warn */
432 #define DD_PERF_LOSS 0.05
433
434 #define DD_CELL_F_SIZE(dd, di) ((dd)->nc[(dd)->dim[(di)]]+1+(di)*2+1+(di))
435
436 /* Use separate MPI send and receive commands
437  * when nnodes <= GMX_DD_NNODES_SENDRECV.
438  * This saves memory (and some copying for small nnodes).
439  * For high parallelization scatter and gather calls are used.
440  */
441 #define GMX_DD_NNODES_SENDRECV 4
442
443
444 /*
445    #define dd_index(n,i) ((((i)[ZZ]*(n)[YY] + (i)[YY])*(n)[XX]) + (i)[XX])
446
447    static void index2xyz(ivec nc,int ind,ivec xyz)
448    {
449    xyz[XX] = ind % nc[XX];
450    xyz[YY] = (ind / nc[XX]) % nc[YY];
451    xyz[ZZ] = ind / (nc[YY]*nc[XX]);
452    }
453  */
454
455 /* This order is required to minimize the coordinate communication in PME
456  * which uses decomposition in the x direction.
457  */
458 #define dd_index(n, i) ((((i)[XX]*(n)[YY] + (i)[YY])*(n)[ZZ]) + (i)[ZZ])
459
460 static void ddindex2xyz(ivec nc, int ind, ivec xyz)
461 {
462     xyz[XX] = ind / (nc[YY]*nc[ZZ]);
463     xyz[YY] = (ind / nc[ZZ]) % nc[YY];
464     xyz[ZZ] = ind % nc[ZZ];
465 }
466
467 static int ddcoord2ddnodeid(gmx_domdec_t *dd, ivec c)
468 {
469     int ddindex;
470     int ddnodeid = -1;
471
472     ddindex = dd_index(dd->nc, c);
473     if (dd->comm->bCartesianPP_PME)
474     {
475         ddnodeid = dd->comm->ddindex2ddnodeid[ddindex];
476     }
477     else if (dd->comm->bCartesianPP)
478     {
479 #ifdef GMX_MPI
480         MPI_Cart_rank(dd->mpi_comm_all, c, &ddnodeid);
481 #endif
482     }
483     else
484     {
485         ddnodeid = ddindex;
486     }
487
488     return ddnodeid;
489 }
490
491 static gmx_bool dynamic_dd_box(gmx_ddbox_t *ddbox, t_inputrec *ir)
492 {
493     return (ddbox->nboundeddim < DIM || DYNAMIC_BOX(*ir));
494 }
495
496 int ddglatnr(gmx_domdec_t *dd, int i)
497 {
498     int atnr;
499
500     if (dd == NULL)
501     {
502         atnr = i + 1;
503     }
504     else
505     {
506         if (i >= dd->comm->nat[ddnatNR-1])
507         {
508             gmx_fatal(FARGS, "glatnr called with %d, which is larger than the local number of atoms (%d)", i, dd->comm->nat[ddnatNR-1]);
509         }
510         atnr = dd->gatindex[i] + 1;
511     }
512
513     return atnr;
514 }
515
516 t_block *dd_charge_groups_global(gmx_domdec_t *dd)
517 {
518     return &dd->comm->cgs_gl;
519 }
520
521 static void vec_rvec_init(vec_rvec_t *v)
522 {
523     v->nalloc = 0;
524     v->v      = NULL;
525 }
526
527 static void vec_rvec_check_alloc(vec_rvec_t *v, int n)
528 {
529     if (n > v->nalloc)
530     {
531         v->nalloc = over_alloc_dd(n);
532         srenew(v->v, v->nalloc);
533     }
534 }
535
536 void dd_store_state(gmx_domdec_t *dd, t_state *state)
537 {
538     int i;
539
540     if (state->ddp_count != dd->ddp_count)
541     {
542         gmx_incons("The state does not the domain decomposition state");
543     }
544
545     state->ncg_gl = dd->ncg_home;
546     if (state->ncg_gl > state->cg_gl_nalloc)
547     {
548         state->cg_gl_nalloc = over_alloc_dd(state->ncg_gl);
549         srenew(state->cg_gl, state->cg_gl_nalloc);
550     }
551     for (i = 0; i < state->ncg_gl; i++)
552     {
553         state->cg_gl[i] = dd->index_gl[i];
554     }
555
556     state->ddp_count_cg_gl = dd->ddp_count;
557 }
558
559 gmx_domdec_zones_t *domdec_zones(gmx_domdec_t *dd)
560 {
561     return &dd->comm->zones;
562 }
563
564 void dd_get_ns_ranges(gmx_domdec_t *dd, int icg,
565                       int *jcg0, int *jcg1, ivec shift0, ivec shift1)
566 {
567     gmx_domdec_zones_t *zones;
568     int                 izone, d, dim;
569
570     zones = &dd->comm->zones;
571
572     izone = 0;
573     while (icg >= zones->izone[izone].cg1)
574     {
575         izone++;
576     }
577
578     if (izone == 0)
579     {
580         *jcg0 = icg;
581     }
582     else if (izone < zones->nizone)
583     {
584         *jcg0 = zones->izone[izone].jcg0;
585     }
586     else
587     {
588         gmx_fatal(FARGS, "DD icg %d out of range: izone (%d) >= nizone (%d)",
589                   icg, izone, zones->nizone);
590     }
591
592     *jcg1 = zones->izone[izone].jcg1;
593
594     for (d = 0; d < dd->ndim; d++)
595     {
596         dim         = dd->dim[d];
597         shift0[dim] = zones->izone[izone].shift0[dim];
598         shift1[dim] = zones->izone[izone].shift1[dim];
599         if (dd->comm->tric_dir[dim] || (dd->bGridJump && d > 0))
600         {
601             /* A conservative approach, this can be optimized */
602             shift0[dim] -= 1;
603             shift1[dim] += 1;
604         }
605     }
606 }
607
608 int dd_natoms_vsite(gmx_domdec_t *dd)
609 {
610     return dd->comm->nat[ddnatVSITE];
611 }
612
613 void dd_get_constraint_range(gmx_domdec_t *dd, int *at_start, int *at_end)
614 {
615     *at_start = dd->comm->nat[ddnatCON-1];
616     *at_end   = dd->comm->nat[ddnatCON];
617 }
618
619 void dd_move_x(gmx_domdec_t *dd, matrix box, rvec x[])
620 {
621     int                    nzone, nat_tot, n, d, p, i, j, at0, at1, zone;
622     int                   *index, *cgindex;
623     gmx_domdec_comm_t     *comm;
624     gmx_domdec_comm_dim_t *cd;
625     gmx_domdec_ind_t      *ind;
626     rvec                   shift = {0, 0, 0}, *buf, *rbuf;
627     gmx_bool               bPBC, bScrew;
628
629     comm = dd->comm;
630
631     cgindex = dd->cgindex;
632
633     buf = comm->vbuf.v;
634
635     nzone   = 1;
636     nat_tot = dd->nat_home;
637     for (d = 0; d < dd->ndim; d++)
638     {
639         bPBC   = (dd->ci[dd->dim[d]] == 0);
640         bScrew = (bPBC && dd->bScrewPBC && dd->dim[d] == XX);
641         if (bPBC)
642         {
643             copy_rvec(box[dd->dim[d]], shift);
644         }
645         cd = &comm->cd[d];
646         for (p = 0; p < cd->np; p++)
647         {
648             ind   = &cd->ind[p];
649             index = ind->index;
650             n     = 0;
651             if (!bPBC)
652             {
653                 for (i = 0; i < ind->nsend[nzone]; i++)
654                 {
655                     at0 = cgindex[index[i]];
656                     at1 = cgindex[index[i]+1];
657                     for (j = at0; j < at1; j++)
658                     {
659                         copy_rvec(x[j], buf[n]);
660                         n++;
661                     }
662                 }
663             }
664             else if (!bScrew)
665             {
666                 for (i = 0; i < ind->nsend[nzone]; i++)
667                 {
668                     at0 = cgindex[index[i]];
669                     at1 = cgindex[index[i]+1];
670                     for (j = at0; j < at1; j++)
671                     {
672                         /* We need to shift the coordinates */
673                         rvec_add(x[j], shift, buf[n]);
674                         n++;
675                     }
676                 }
677             }
678             else
679             {
680                 for (i = 0; i < ind->nsend[nzone]; i++)
681                 {
682                     at0 = cgindex[index[i]];
683                     at1 = cgindex[index[i]+1];
684                     for (j = at0; j < at1; j++)
685                     {
686                         /* Shift x */
687                         buf[n][XX] = x[j][XX] + shift[XX];
688                         /* Rotate y and z.
689                          * This operation requires a special shift force
690                          * treatment, which is performed in calc_vir.
691                          */
692                         buf[n][YY] = box[YY][YY] - x[j][YY];
693                         buf[n][ZZ] = box[ZZ][ZZ] - x[j][ZZ];
694                         n++;
695                     }
696                 }
697             }
698
699             if (cd->bInPlace)
700             {
701                 rbuf = x + nat_tot;
702             }
703             else
704             {
705                 rbuf = comm->vbuf2.v;
706             }
707             /* Send and receive the coordinates */
708             dd_sendrecv_rvec(dd, d, dddirBackward,
709                              buf,  ind->nsend[nzone+1],
710                              rbuf, ind->nrecv[nzone+1]);
711             if (!cd->bInPlace)
712             {
713                 j = 0;
714                 for (zone = 0; zone < nzone; zone++)
715                 {
716                     for (i = ind->cell2at0[zone]; i < ind->cell2at1[zone]; i++)
717                     {
718                         copy_rvec(rbuf[j], x[i]);
719                         j++;
720                     }
721                 }
722             }
723             nat_tot += ind->nrecv[nzone+1];
724         }
725         nzone += nzone;
726     }
727 }
728
729 void dd_move_f(gmx_domdec_t *dd, rvec f[], rvec *fshift)
730 {
731     int                    nzone, nat_tot, n, d, p, i, j, at0, at1, zone;
732     int                   *index, *cgindex;
733     gmx_domdec_comm_t     *comm;
734     gmx_domdec_comm_dim_t *cd;
735     gmx_domdec_ind_t      *ind;
736     rvec                  *buf, *sbuf;
737     ivec                   vis;
738     int                    is;
739     gmx_bool               bPBC, bScrew;
740
741     comm = dd->comm;
742
743     cgindex = dd->cgindex;
744
745     buf = comm->vbuf.v;
746
747     n       = 0;
748     nzone   = comm->zones.n/2;
749     nat_tot = dd->nat_tot;
750     for (d = dd->ndim-1; d >= 0; d--)
751     {
752         bPBC   = (dd->ci[dd->dim[d]] == 0);
753         bScrew = (bPBC && dd->bScrewPBC && dd->dim[d] == XX);
754         if (fshift == NULL && !bScrew)
755         {
756             bPBC = FALSE;
757         }
758         /* Determine which shift vector we need */
759         clear_ivec(vis);
760         vis[dd->dim[d]] = 1;
761         is              = IVEC2IS(vis);
762
763         cd = &comm->cd[d];
764         for (p = cd->np-1; p >= 0; p--)
765         {
766             ind      = &cd->ind[p];
767             nat_tot -= ind->nrecv[nzone+1];
768             if (cd->bInPlace)
769             {
770                 sbuf = f + nat_tot;
771             }
772             else
773             {
774                 sbuf = comm->vbuf2.v;
775                 j    = 0;
776                 for (zone = 0; zone < nzone; zone++)
777                 {
778                     for (i = ind->cell2at0[zone]; i < ind->cell2at1[zone]; i++)
779                     {
780                         copy_rvec(f[i], sbuf[j]);
781                         j++;
782                     }
783                 }
784             }
785             /* Communicate the forces */
786             dd_sendrecv_rvec(dd, d, dddirForward,
787                              sbuf, ind->nrecv[nzone+1],
788                              buf,  ind->nsend[nzone+1]);
789             index = ind->index;
790             /* Add the received forces */
791             n = 0;
792             if (!bPBC)
793             {
794                 for (i = 0; i < ind->nsend[nzone]; i++)
795                 {
796                     at0 = cgindex[index[i]];
797                     at1 = cgindex[index[i]+1];
798                     for (j = at0; j < at1; j++)
799                     {
800                         rvec_inc(f[j], buf[n]);
801                         n++;
802                     }
803                 }
804             }
805             else if (!bScrew)
806             {
807                 for (i = 0; i < ind->nsend[nzone]; i++)
808                 {
809                     at0 = cgindex[index[i]];
810                     at1 = cgindex[index[i]+1];
811                     for (j = at0; j < at1; j++)
812                     {
813                         rvec_inc(f[j], buf[n]);
814                         /* Add this force to the shift force */
815                         rvec_inc(fshift[is], buf[n]);
816                         n++;
817                     }
818                 }
819             }
820             else
821             {
822                 for (i = 0; i < ind->nsend[nzone]; i++)
823                 {
824                     at0 = cgindex[index[i]];
825                     at1 = cgindex[index[i]+1];
826                     for (j = at0; j < at1; j++)
827                     {
828                         /* Rotate the force */
829                         f[j][XX] += buf[n][XX];
830                         f[j][YY] -= buf[n][YY];
831                         f[j][ZZ] -= buf[n][ZZ];
832                         if (fshift)
833                         {
834                             /* Add this force to the shift force */
835                             rvec_inc(fshift[is], buf[n]);
836                         }
837                         n++;
838                     }
839                 }
840             }
841         }
842         nzone /= 2;
843     }
844 }
845
846 void dd_atom_spread_real(gmx_domdec_t *dd, real v[])
847 {
848     int                    nzone, nat_tot, n, d, p, i, j, at0, at1, zone;
849     int                   *index, *cgindex;
850     gmx_domdec_comm_t     *comm;
851     gmx_domdec_comm_dim_t *cd;
852     gmx_domdec_ind_t      *ind;
853     real                  *buf, *rbuf;
854
855     comm = dd->comm;
856
857     cgindex = dd->cgindex;
858
859     buf = &comm->vbuf.v[0][0];
860
861     nzone   = 1;
862     nat_tot = dd->nat_home;
863     for (d = 0; d < dd->ndim; d++)
864     {
865         cd = &comm->cd[d];
866         for (p = 0; p < cd->np; p++)
867         {
868             ind   = &cd->ind[p];
869             index = ind->index;
870             n     = 0;
871             for (i = 0; i < ind->nsend[nzone]; i++)
872             {
873                 at0 = cgindex[index[i]];
874                 at1 = cgindex[index[i]+1];
875                 for (j = at0; j < at1; j++)
876                 {
877                     buf[n] = v[j];
878                     n++;
879                 }
880             }
881
882             if (cd->bInPlace)
883             {
884                 rbuf = v + nat_tot;
885             }
886             else
887             {
888                 rbuf = &comm->vbuf2.v[0][0];
889             }
890             /* Send and receive the coordinates */
891             dd_sendrecv_real(dd, d, dddirBackward,
892                              buf,  ind->nsend[nzone+1],
893                              rbuf, ind->nrecv[nzone+1]);
894             if (!cd->bInPlace)
895             {
896                 j = 0;
897                 for (zone = 0; zone < nzone; zone++)
898                 {
899                     for (i = ind->cell2at0[zone]; i < ind->cell2at1[zone]; i++)
900                     {
901                         v[i] = rbuf[j];
902                         j++;
903                     }
904                 }
905             }
906             nat_tot += ind->nrecv[nzone+1];
907         }
908         nzone += nzone;
909     }
910 }
911
912 void dd_atom_sum_real(gmx_domdec_t *dd, real v[])
913 {
914     int                    nzone, nat_tot, n, d, p, i, j, at0, at1, zone;
915     int                   *index, *cgindex;
916     gmx_domdec_comm_t     *comm;
917     gmx_domdec_comm_dim_t *cd;
918     gmx_domdec_ind_t      *ind;
919     real                  *buf, *sbuf;
920
921     comm = dd->comm;
922
923     cgindex = dd->cgindex;
924
925     buf = &comm->vbuf.v[0][0];
926
927     n       = 0;
928     nzone   = comm->zones.n/2;
929     nat_tot = dd->nat_tot;
930     for (d = dd->ndim-1; d >= 0; d--)
931     {
932         cd = &comm->cd[d];
933         for (p = cd->np-1; p >= 0; p--)
934         {
935             ind      = &cd->ind[p];
936             nat_tot -= ind->nrecv[nzone+1];
937             if (cd->bInPlace)
938             {
939                 sbuf = v + nat_tot;
940             }
941             else
942             {
943                 sbuf = &comm->vbuf2.v[0][0];
944                 j    = 0;
945                 for (zone = 0; zone < nzone; zone++)
946                 {
947                     for (i = ind->cell2at0[zone]; i < ind->cell2at1[zone]; i++)
948                     {
949                         sbuf[j] = v[i];
950                         j++;
951                     }
952                 }
953             }
954             /* Communicate the forces */
955             dd_sendrecv_real(dd, d, dddirForward,
956                              sbuf, ind->nrecv[nzone+1],
957                              buf,  ind->nsend[nzone+1]);
958             index = ind->index;
959             /* Add the received forces */
960             n = 0;
961             for (i = 0; i < ind->nsend[nzone]; i++)
962             {
963                 at0 = cgindex[index[i]];
964                 at1 = cgindex[index[i]+1];
965                 for (j = at0; j < at1; j++)
966                 {
967                     v[j] += buf[n];
968                     n++;
969                 }
970             }
971         }
972         nzone /= 2;
973     }
974 }
975
976 static void print_ddzone(FILE *fp, int d, int i, int j, gmx_ddzone_t *zone)
977 {
978     fprintf(fp, "zone d0 %d d1 %d d2 %d  min0 %6.3f max1 %6.3f mch0 %6.3f mch1 %6.3f p1_0 %6.3f p1_1 %6.3f\n",
979             d, i, j,
980             zone->min0, zone->max1,
981             zone->mch0, zone->mch0,
982             zone->p1_0, zone->p1_1);
983 }
984
985
986 #define DDZONECOMM_MAXZONE  5
987 #define DDZONECOMM_BUFSIZE  3
988
989 static void dd_sendrecv_ddzone(const gmx_domdec_t *dd,
990                                int ddimind, int direction,
991                                gmx_ddzone_t *buf_s, int n_s,
992                                gmx_ddzone_t *buf_r, int n_r)
993 {
994 #define ZBS  DDZONECOMM_BUFSIZE
995     rvec vbuf_s[DDZONECOMM_MAXZONE*ZBS];
996     rvec vbuf_r[DDZONECOMM_MAXZONE*ZBS];
997     int  i;
998
999     for (i = 0; i < n_s; i++)
1000     {
1001         vbuf_s[i*ZBS  ][0] = buf_s[i].min0;
1002         vbuf_s[i*ZBS  ][1] = buf_s[i].max1;
1003         vbuf_s[i*ZBS  ][2] = buf_s[i].min1;
1004         vbuf_s[i*ZBS+1][0] = buf_s[i].mch0;
1005         vbuf_s[i*ZBS+1][1] = buf_s[i].mch1;
1006         vbuf_s[i*ZBS+1][2] = 0;
1007         vbuf_s[i*ZBS+2][0] = buf_s[i].p1_0;
1008         vbuf_s[i*ZBS+2][1] = buf_s[i].p1_1;
1009         vbuf_s[i*ZBS+2][2] = 0;
1010     }
1011
1012     dd_sendrecv_rvec(dd, ddimind, direction,
1013                      vbuf_s, n_s*ZBS,
1014                      vbuf_r, n_r*ZBS);
1015
1016     for (i = 0; i < n_r; i++)
1017     {
1018         buf_r[i].min0 = vbuf_r[i*ZBS  ][0];
1019         buf_r[i].max1 = vbuf_r[i*ZBS  ][1];
1020         buf_r[i].min1 = vbuf_r[i*ZBS  ][2];
1021         buf_r[i].mch0 = vbuf_r[i*ZBS+1][0];
1022         buf_r[i].mch1 = vbuf_r[i*ZBS+1][1];
1023         buf_r[i].p1_0 = vbuf_r[i*ZBS+2][0];
1024         buf_r[i].p1_1 = vbuf_r[i*ZBS+2][1];
1025     }
1026
1027 #undef ZBS
1028 }
1029
1030 static void dd_move_cellx(gmx_domdec_t *dd, gmx_ddbox_t *ddbox,
1031                           rvec cell_ns_x0, rvec cell_ns_x1)
1032 {
1033     int                d, d1, dim, dim1, pos, buf_size, i, j, k, p, npulse, npulse_min;
1034     gmx_ddzone_t      *zp;
1035     gmx_ddzone_t       buf_s[DDZONECOMM_MAXZONE];
1036     gmx_ddzone_t       buf_r[DDZONECOMM_MAXZONE];
1037     gmx_ddzone_t       buf_e[DDZONECOMM_MAXZONE];
1038     rvec               extr_s[2], extr_r[2];
1039     rvec               dh;
1040     real               dist_d, c = 0, det;
1041     gmx_domdec_comm_t *comm;
1042     gmx_bool           bPBC, bUse;
1043
1044     comm = dd->comm;
1045
1046     for (d = 1; d < dd->ndim; d++)
1047     {
1048         dim      = dd->dim[d];
1049         zp       = (d == 1) ? &comm->zone_d1[0] : &comm->zone_d2[0][0];
1050         zp->min0 = cell_ns_x0[dim];
1051         zp->max1 = cell_ns_x1[dim];
1052         zp->min1 = cell_ns_x1[dim];
1053         zp->mch0 = cell_ns_x0[dim];
1054         zp->mch1 = cell_ns_x1[dim];
1055         zp->p1_0 = cell_ns_x0[dim];
1056         zp->p1_1 = cell_ns_x1[dim];
1057     }
1058
1059     for (d = dd->ndim-2; d >= 0; d--)
1060     {
1061         dim  = dd->dim[d];
1062         bPBC = (dim < ddbox->npbcdim);
1063
1064         /* Use an rvec to store two reals */
1065         extr_s[d][0] = comm->cell_f0[d+1];
1066         extr_s[d][1] = comm->cell_f1[d+1];
1067         extr_s[d][2] = comm->cell_f1[d+1];
1068
1069         pos = 0;
1070         /* Store the extremes in the backward sending buffer,
1071          * so the get updated separately from the forward communication.
1072          */
1073         for (d1 = d; d1 < dd->ndim-1; d1++)
1074         {
1075             /* We invert the order to be able to use the same loop for buf_e */
1076             buf_s[pos].min0 = extr_s[d1][1];
1077             buf_s[pos].max1 = extr_s[d1][0];
1078             buf_s[pos].min1 = extr_s[d1][2];
1079             buf_s[pos].mch0 = 0;
1080             buf_s[pos].mch1 = 0;
1081             /* Store the cell corner of the dimension we communicate along */
1082             buf_s[pos].p1_0 = comm->cell_x0[dim];
1083             buf_s[pos].p1_1 = 0;
1084             pos++;
1085         }
1086
1087         buf_s[pos] = (dd->ndim == 2) ? comm->zone_d1[0] : comm->zone_d2[0][0];
1088         pos++;
1089
1090         if (dd->ndim == 3 && d == 0)
1091         {
1092             buf_s[pos] = comm->zone_d2[0][1];
1093             pos++;
1094             buf_s[pos] = comm->zone_d1[0];
1095             pos++;
1096         }
1097
1098         /* We only need to communicate the extremes
1099          * in the forward direction
1100          */
1101         npulse = comm->cd[d].np;
1102         if (bPBC)
1103         {
1104             /* Take the minimum to avoid double communication */
1105             npulse_min = min(npulse, dd->nc[dim]-1-npulse);
1106         }
1107         else
1108         {
1109             /* Without PBC we should really not communicate over
1110              * the boundaries, but implementing that complicates
1111              * the communication setup and therefore we simply
1112              * do all communication, but ignore some data.
1113              */
1114             npulse_min = npulse;
1115         }
1116         for (p = 0; p < npulse_min; p++)
1117         {
1118             /* Communicate the extremes forward */
1119             bUse = (bPBC || dd->ci[dim] > 0);
1120
1121             dd_sendrecv_rvec(dd, d, dddirForward,
1122                              extr_s+d, dd->ndim-d-1,
1123                              extr_r+d, dd->ndim-d-1);
1124
1125             if (bUse)
1126             {
1127                 for (d1 = d; d1 < dd->ndim-1; d1++)
1128                 {
1129                     extr_s[d1][0] = max(extr_s[d1][0], extr_r[d1][0]);
1130                     extr_s[d1][1] = min(extr_s[d1][1], extr_r[d1][1]);
1131                     extr_s[d1][2] = min(extr_s[d1][2], extr_r[d1][2]);
1132                 }
1133             }
1134         }
1135
1136         buf_size = pos;
1137         for (p = 0; p < npulse; p++)
1138         {
1139             /* Communicate all the zone information backward */
1140             bUse = (bPBC || dd->ci[dim] < dd->nc[dim] - 1);
1141
1142             dd_sendrecv_ddzone(dd, d, dddirBackward,
1143                                buf_s, buf_size,
1144                                buf_r, buf_size);
1145
1146             clear_rvec(dh);
1147             if (p > 0)
1148             {
1149                 for (d1 = d+1; d1 < dd->ndim; d1++)
1150                 {
1151                     /* Determine the decrease of maximum required
1152                      * communication height along d1 due to the distance along d,
1153                      * this avoids a lot of useless atom communication.
1154                      */
1155                     dist_d = comm->cell_x1[dim] - buf_r[0].p1_0;
1156
1157                     if (ddbox->tric_dir[dim])
1158                     {
1159                         /* c is the off-diagonal coupling between the cell planes
1160                          * along directions d and d1.
1161                          */
1162                         c = ddbox->v[dim][dd->dim[d1]][dim];
1163                     }
1164                     else
1165                     {
1166                         c = 0;
1167                     }
1168                     det = (1 + c*c)*comm->cutoff*comm->cutoff - dist_d*dist_d;
1169                     if (det > 0)
1170                     {
1171                         dh[d1] = comm->cutoff - (c*dist_d + sqrt(det))/(1 + c*c);
1172                     }
1173                     else
1174                     {
1175                         /* A negative value signals out of range */
1176                         dh[d1] = -1;
1177                     }
1178                 }
1179             }
1180
1181             /* Accumulate the extremes over all pulses */
1182             for (i = 0; i < buf_size; i++)
1183             {
1184                 if (p == 0)
1185                 {
1186                     buf_e[i] = buf_r[i];
1187                 }
1188                 else
1189                 {
1190                     if (bUse)
1191                     {
1192                         buf_e[i].min0 = min(buf_e[i].min0, buf_r[i].min0);
1193                         buf_e[i].max1 = max(buf_e[i].max1, buf_r[i].max1);
1194                         buf_e[i].min1 = min(buf_e[i].min1, buf_r[i].min1);
1195                     }
1196
1197                     if (dd->ndim == 3 && d == 0 && i == buf_size - 1)
1198                     {
1199                         d1 = 1;
1200                     }
1201                     else
1202                     {
1203                         d1 = d + 1;
1204                     }
1205                     if (bUse && dh[d1] >= 0)
1206                     {
1207                         buf_e[i].mch0 = max(buf_e[i].mch0, buf_r[i].mch0-dh[d1]);
1208                         buf_e[i].mch1 = max(buf_e[i].mch1, buf_r[i].mch1-dh[d1]);
1209                     }
1210                 }
1211                 /* Copy the received buffer to the send buffer,
1212                  * to pass the data through with the next pulse.
1213                  */
1214                 buf_s[i] = buf_r[i];
1215             }
1216             if (((bPBC || dd->ci[dim]+npulse < dd->nc[dim]) && p == npulse-1) ||
1217                 (!bPBC && dd->ci[dim]+1+p == dd->nc[dim]-1))
1218             {
1219                 /* Store the extremes */
1220                 pos = 0;
1221
1222                 for (d1 = d; d1 < dd->ndim-1; d1++)
1223                 {
1224                     extr_s[d1][1] = min(extr_s[d1][1], buf_e[pos].min0);
1225                     extr_s[d1][0] = max(extr_s[d1][0], buf_e[pos].max1);
1226                     extr_s[d1][2] = min(extr_s[d1][2], buf_e[pos].min1);
1227                     pos++;
1228                 }
1229
1230                 if (d == 1 || (d == 0 && dd->ndim == 3))
1231                 {
1232                     for (i = d; i < 2; i++)
1233                     {
1234                         comm->zone_d2[1-d][i] = buf_e[pos];
1235                         pos++;
1236                     }
1237                 }
1238                 if (d == 0)
1239                 {
1240                     comm->zone_d1[1] = buf_e[pos];
1241                     pos++;
1242                 }
1243             }
1244         }
1245     }
1246
1247     if (dd->ndim >= 2)
1248     {
1249         dim = dd->dim[1];
1250         for (i = 0; i < 2; i++)
1251         {
1252             if (debug)
1253             {
1254                 print_ddzone(debug, 1, i, 0, &comm->zone_d1[i]);
1255             }
1256             cell_ns_x0[dim] = min(cell_ns_x0[dim], comm->zone_d1[i].min0);
1257             cell_ns_x1[dim] = max(cell_ns_x1[dim], comm->zone_d1[i].max1);
1258         }
1259     }
1260     if (dd->ndim >= 3)
1261     {
1262         dim = dd->dim[2];
1263         for (i = 0; i < 2; i++)
1264         {
1265             for (j = 0; j < 2; j++)
1266             {
1267                 if (debug)
1268                 {
1269                     print_ddzone(debug, 2, i, j, &comm->zone_d2[i][j]);
1270                 }
1271                 cell_ns_x0[dim] = min(cell_ns_x0[dim], comm->zone_d2[i][j].min0);
1272                 cell_ns_x1[dim] = max(cell_ns_x1[dim], comm->zone_d2[i][j].max1);
1273             }
1274         }
1275     }
1276     for (d = 1; d < dd->ndim; d++)
1277     {
1278         comm->cell_f_max0[d] = extr_s[d-1][0];
1279         comm->cell_f_min1[d] = extr_s[d-1][1];
1280         if (debug)
1281         {
1282             fprintf(debug, "Cell fraction d %d, max0 %f, min1 %f\n",
1283                     d, comm->cell_f_max0[d], comm->cell_f_min1[d]);
1284         }
1285     }
1286 }
1287
1288 static void dd_collect_cg(gmx_domdec_t *dd,
1289                           t_state      *state_local)
1290 {
1291     gmx_domdec_master_t *ma = NULL;
1292     int                  buf2[2], *ibuf, i, ncg_home = 0, *cg = NULL, nat_home = 0;
1293     t_block             *cgs_gl;
1294
1295     if (state_local->ddp_count == dd->comm->master_cg_ddp_count)
1296     {
1297         /* The master has the correct distribution */
1298         return;
1299     }
1300
1301     if (state_local->ddp_count == dd->ddp_count)
1302     {
1303         ncg_home = dd->ncg_home;
1304         cg       = dd->index_gl;
1305         nat_home = dd->nat_home;
1306     }
1307     else if (state_local->ddp_count_cg_gl == state_local->ddp_count)
1308     {
1309         cgs_gl = &dd->comm->cgs_gl;
1310
1311         ncg_home = state_local->ncg_gl;
1312         cg       = state_local->cg_gl;
1313         nat_home = 0;
1314         for (i = 0; i < ncg_home; i++)
1315         {
1316             nat_home += cgs_gl->index[cg[i]+1] - cgs_gl->index[cg[i]];
1317         }
1318     }
1319     else
1320     {
1321         gmx_incons("Attempted to collect a vector for a state for which the charge group distribution is unknown");
1322     }
1323
1324     buf2[0] = dd->ncg_home;
1325     buf2[1] = dd->nat_home;
1326     if (DDMASTER(dd))
1327     {
1328         ma   = dd->ma;
1329         ibuf = ma->ibuf;
1330     }
1331     else
1332     {
1333         ibuf = NULL;
1334     }
1335     /* Collect the charge group and atom counts on the master */
1336     dd_gather(dd, 2*sizeof(int), buf2, ibuf);
1337
1338     if (DDMASTER(dd))
1339     {
1340         ma->index[0] = 0;
1341         for (i = 0; i < dd->nnodes; i++)
1342         {
1343             ma->ncg[i]     = ma->ibuf[2*i];
1344             ma->nat[i]     = ma->ibuf[2*i+1];
1345             ma->index[i+1] = ma->index[i] + ma->ncg[i];
1346
1347         }
1348         /* Make byte counts and indices */
1349         for (i = 0; i < dd->nnodes; i++)
1350         {
1351             ma->ibuf[i]            = ma->ncg[i]*sizeof(int);
1352             ma->ibuf[dd->nnodes+i] = ma->index[i]*sizeof(int);
1353         }
1354         if (debug)
1355         {
1356             fprintf(debug, "Initial charge group distribution: ");
1357             for (i = 0; i < dd->nnodes; i++)
1358             {
1359                 fprintf(debug, " %d", ma->ncg[i]);
1360             }
1361             fprintf(debug, "\n");
1362         }
1363     }
1364
1365     /* Collect the charge group indices on the master */
1366     dd_gatherv(dd,
1367                dd->ncg_home*sizeof(int), dd->index_gl,
1368                DDMASTER(dd) ? ma->ibuf : NULL,
1369                DDMASTER(dd) ? ma->ibuf+dd->nnodes : NULL,
1370                DDMASTER(dd) ? ma->cg : NULL);
1371
1372     dd->comm->master_cg_ddp_count = state_local->ddp_count;
1373 }
1374
1375 static void dd_collect_vec_sendrecv(gmx_domdec_t *dd,
1376                                     rvec *lv, rvec *v)
1377 {
1378     gmx_domdec_master_t *ma;
1379     int                  n, i, c, a, nalloc = 0;
1380     rvec                *buf = NULL;
1381     t_block             *cgs_gl;
1382
1383     ma = dd->ma;
1384
1385     if (!DDMASTER(dd))
1386     {
1387 #ifdef GMX_MPI
1388         MPI_Send(lv, dd->nat_home*sizeof(rvec), MPI_BYTE, DDMASTERRANK(dd),
1389                  dd->rank, dd->mpi_comm_all);
1390 #endif
1391     }
1392     else
1393     {
1394         /* Copy the master coordinates to the global array */
1395         cgs_gl = &dd->comm->cgs_gl;
1396
1397         n = DDMASTERRANK(dd);
1398         a = 0;
1399         for (i = ma->index[n]; i < ma->index[n+1]; i++)
1400         {
1401             for (c = cgs_gl->index[ma->cg[i]]; c < cgs_gl->index[ma->cg[i]+1]; c++)
1402             {
1403                 copy_rvec(lv[a++], v[c]);
1404             }
1405         }
1406
1407         for (n = 0; n < dd->nnodes; n++)
1408         {
1409             if (n != dd->rank)
1410             {
1411                 if (ma->nat[n] > nalloc)
1412                 {
1413                     nalloc = over_alloc_dd(ma->nat[n]);
1414                     srenew(buf, nalloc);
1415                 }
1416 #ifdef GMX_MPI
1417                 MPI_Recv(buf, ma->nat[n]*sizeof(rvec), MPI_BYTE, DDRANK(dd, n),
1418                          n, dd->mpi_comm_all, MPI_STATUS_IGNORE);
1419 #endif
1420                 a = 0;
1421                 for (i = ma->index[n]; i < ma->index[n+1]; i++)
1422                 {
1423                     for (c = cgs_gl->index[ma->cg[i]]; c < cgs_gl->index[ma->cg[i]+1]; c++)
1424                     {
1425                         copy_rvec(buf[a++], v[c]);
1426                     }
1427                 }
1428             }
1429         }
1430         sfree(buf);
1431     }
1432 }
1433
1434 static void get_commbuffer_counts(gmx_domdec_t *dd,
1435                                   int **counts, int **disps)
1436 {
1437     gmx_domdec_master_t *ma;
1438     int                  n;
1439
1440     ma = dd->ma;
1441
1442     /* Make the rvec count and displacment arrays */
1443     *counts  = ma->ibuf;
1444     *disps   = ma->ibuf + dd->nnodes;
1445     for (n = 0; n < dd->nnodes; n++)
1446     {
1447         (*counts)[n] = ma->nat[n]*sizeof(rvec);
1448         (*disps)[n]  = (n == 0 ? 0 : (*disps)[n-1] + (*counts)[n-1]);
1449     }
1450 }
1451
1452 static void dd_collect_vec_gatherv(gmx_domdec_t *dd,
1453                                    rvec *lv, rvec *v)
1454 {
1455     gmx_domdec_master_t *ma;
1456     int                 *rcounts = NULL, *disps = NULL;
1457     int                  n, i, c, a;
1458     rvec                *buf = NULL;
1459     t_block             *cgs_gl;
1460
1461     ma = dd->ma;
1462
1463     if (DDMASTER(dd))
1464     {
1465         get_commbuffer_counts(dd, &rcounts, &disps);
1466
1467         buf = ma->vbuf;
1468     }
1469
1470     dd_gatherv(dd, dd->nat_home*sizeof(rvec), lv, rcounts, disps, buf);
1471
1472     if (DDMASTER(dd))
1473     {
1474         cgs_gl = &dd->comm->cgs_gl;
1475
1476         a = 0;
1477         for (n = 0; n < dd->nnodes; n++)
1478         {
1479             for (i = ma->index[n]; i < ma->index[n+1]; i++)
1480             {
1481                 for (c = cgs_gl->index[ma->cg[i]]; c < cgs_gl->index[ma->cg[i]+1]; c++)
1482                 {
1483                     copy_rvec(buf[a++], v[c]);
1484                 }
1485             }
1486         }
1487     }
1488 }
1489
1490 void dd_collect_vec(gmx_domdec_t *dd,
1491                     t_state *state_local, rvec *lv, rvec *v)
1492 {
1493     gmx_domdec_master_t *ma;
1494     int                  n, i, c, a, nalloc = 0;
1495     rvec                *buf = NULL;
1496
1497     dd_collect_cg(dd, state_local);
1498
1499     if (dd->nnodes <= GMX_DD_NNODES_SENDRECV)
1500     {
1501         dd_collect_vec_sendrecv(dd, lv, v);
1502     }
1503     else
1504     {
1505         dd_collect_vec_gatherv(dd, lv, v);
1506     }
1507 }
1508
1509
1510 void dd_collect_state(gmx_domdec_t *dd,
1511                       t_state *state_local, t_state *state)
1512 {
1513     int est, i, j, nh;
1514
1515     nh = state->nhchainlength;
1516
1517     if (DDMASTER(dd))
1518     {
1519         for (i = 0; i < efptNR; i++)
1520         {
1521             state->lambda[i] = state_local->lambda[i];
1522         }
1523         state->fep_state = state_local->fep_state;
1524         state->veta      = state_local->veta;
1525         state->vol0      = state_local->vol0;
1526         copy_mat(state_local->box, state->box);
1527         copy_mat(state_local->boxv, state->boxv);
1528         copy_mat(state_local->svir_prev, state->svir_prev);
1529         copy_mat(state_local->fvir_prev, state->fvir_prev);
1530         copy_mat(state_local->pres_prev, state->pres_prev);
1531
1532         for (i = 0; i < state_local->ngtc; i++)
1533         {
1534             for (j = 0; j < nh; j++)
1535             {
1536                 state->nosehoover_xi[i*nh+j]        = state_local->nosehoover_xi[i*nh+j];
1537                 state->nosehoover_vxi[i*nh+j]       = state_local->nosehoover_vxi[i*nh+j];
1538             }
1539             state->therm_integral[i] = state_local->therm_integral[i];
1540         }
1541         for (i = 0; i < state_local->nnhpres; i++)
1542         {
1543             for (j = 0; j < nh; j++)
1544             {
1545                 state->nhpres_xi[i*nh+j]        = state_local->nhpres_xi[i*nh+j];
1546                 state->nhpres_vxi[i*nh+j]       = state_local->nhpres_vxi[i*nh+j];
1547             }
1548         }
1549     }
1550     for (est = 0; est < estNR; est++)
1551     {
1552         if (EST_DISTR(est) && (state_local->flags & (1<<est)))
1553         {
1554             switch (est)
1555             {
1556                 case estX:
1557                     dd_collect_vec(dd, state_local, state_local->x, state->x);
1558                     break;
1559                 case estV:
1560                     dd_collect_vec(dd, state_local, state_local->v, state->v);
1561                     break;
1562                 case estSDX:
1563                     dd_collect_vec(dd, state_local, state_local->sd_X, state->sd_X);
1564                     break;
1565                 case estCGP:
1566                     dd_collect_vec(dd, state_local, state_local->cg_p, state->cg_p);
1567                     break;
1568                 case estLD_RNG:
1569                     if (state->nrngi == 1)
1570                     {
1571                         if (DDMASTER(dd))
1572                         {
1573                             for (i = 0; i < state_local->nrng; i++)
1574                             {
1575                                 state->ld_rng[i] = state_local->ld_rng[i];
1576                             }
1577                         }
1578                     }
1579                     else
1580                     {
1581                         dd_gather(dd, state_local->nrng*sizeof(state->ld_rng[0]),
1582                                   state_local->ld_rng, state->ld_rng);
1583                     }
1584                     break;
1585                 case estLD_RNGI:
1586                     if (state->nrngi == 1)
1587                     {
1588                         if (DDMASTER(dd))
1589                         {
1590                             state->ld_rngi[0] = state_local->ld_rngi[0];
1591                         }
1592                     }
1593                     else
1594                     {
1595                         dd_gather(dd, sizeof(state->ld_rngi[0]),
1596                                   state_local->ld_rngi, state->ld_rngi);
1597                     }
1598                     break;
1599                 case estDISRE_INITF:
1600                 case estDISRE_RM3TAV:
1601                 case estORIRE_INITF:
1602                 case estORIRE_DTAV:
1603                     break;
1604                 default:
1605                     gmx_incons("Unknown state entry encountered in dd_collect_state");
1606             }
1607         }
1608     }
1609 }
1610
1611 static void dd_realloc_state(t_state *state, rvec **f, int nalloc)
1612 {
1613     int est;
1614
1615     if (debug)
1616     {
1617         fprintf(debug, "Reallocating state: currently %d, required %d, allocating %d\n", state->nalloc, nalloc, over_alloc_dd(nalloc));
1618     }
1619
1620     state->nalloc = over_alloc_dd(nalloc);
1621
1622     for (est = 0; est < estNR; est++)
1623     {
1624         if (EST_DISTR(est) && (state->flags & (1<<est)))
1625         {
1626             switch (est)
1627             {
1628                 case estX:
1629                     srenew(state->x, state->nalloc);
1630                     break;
1631                 case estV:
1632                     srenew(state->v, state->nalloc);
1633                     break;
1634                 case estSDX:
1635                     srenew(state->sd_X, state->nalloc);
1636                     break;
1637                 case estCGP:
1638                     srenew(state->cg_p, state->nalloc);
1639                     break;
1640                 case estLD_RNG:
1641                 case estLD_RNGI:
1642                 case estDISRE_INITF:
1643                 case estDISRE_RM3TAV:
1644                 case estORIRE_INITF:
1645                 case estORIRE_DTAV:
1646                     /* No reallocation required */
1647                     break;
1648                 default:
1649                     gmx_incons("Unknown state entry encountered in dd_realloc_state");
1650             }
1651         }
1652     }
1653
1654     if (f != NULL)
1655     {
1656         srenew(*f, state->nalloc);
1657     }
1658 }
1659
1660 static void dd_check_alloc_ncg(t_forcerec *fr, t_state *state, rvec **f,
1661                                int nalloc)
1662 {
1663     if (nalloc > fr->cg_nalloc)
1664     {
1665         if (debug)
1666         {
1667             fprintf(debug, "Reallocating forcerec: currently %d, required %d, allocating %d\n", fr->cg_nalloc, nalloc, over_alloc_dd(nalloc));
1668         }
1669         fr->cg_nalloc = over_alloc_dd(nalloc);
1670         srenew(fr->cginfo, fr->cg_nalloc);
1671         if (fr->cutoff_scheme == ecutsGROUP)
1672         {
1673             srenew(fr->cg_cm, fr->cg_nalloc);
1674         }
1675     }
1676     if (fr->cutoff_scheme == ecutsVERLET && nalloc > state->nalloc)
1677     {
1678         /* We don't use charge groups, we use x in state to set up
1679          * the atom communication.
1680          */
1681         dd_realloc_state(state, f, nalloc);
1682     }
1683 }
1684
1685 static void dd_distribute_vec_sendrecv(gmx_domdec_t *dd, t_block *cgs,
1686                                        rvec *v, rvec *lv)
1687 {
1688     gmx_domdec_master_t *ma;
1689     int                  n, i, c, a, nalloc = 0;
1690     rvec                *buf = NULL;
1691
1692     if (DDMASTER(dd))
1693     {
1694         ma  = dd->ma;
1695
1696         for (n = 0; n < dd->nnodes; n++)
1697         {
1698             if (n != dd->rank)
1699             {
1700                 if (ma->nat[n] > nalloc)
1701                 {
1702                     nalloc = over_alloc_dd(ma->nat[n]);
1703                     srenew(buf, nalloc);
1704                 }
1705                 /* Use lv as a temporary buffer */
1706                 a = 0;
1707                 for (i = ma->index[n]; i < ma->index[n+1]; i++)
1708                 {
1709                     for (c = cgs->index[ma->cg[i]]; c < cgs->index[ma->cg[i]+1]; c++)
1710                     {
1711                         copy_rvec(v[c], buf[a++]);
1712                     }
1713                 }
1714                 if (a != ma->nat[n])
1715                 {
1716                     gmx_fatal(FARGS, "Internal error a (%d) != nat (%d)",
1717                               a, ma->nat[n]);
1718                 }
1719
1720 #ifdef GMX_MPI
1721                 MPI_Send(buf, ma->nat[n]*sizeof(rvec), MPI_BYTE,
1722                          DDRANK(dd, n), n, dd->mpi_comm_all);
1723 #endif
1724             }
1725         }
1726         sfree(buf);
1727         n = DDMASTERRANK(dd);
1728         a = 0;
1729         for (i = ma->index[n]; i < ma->index[n+1]; i++)
1730         {
1731             for (c = cgs->index[ma->cg[i]]; c < cgs->index[ma->cg[i]+1]; c++)
1732             {
1733                 copy_rvec(v[c], lv[a++]);
1734             }
1735         }
1736     }
1737     else
1738     {
1739 #ifdef GMX_MPI
1740         MPI_Recv(lv, dd->nat_home*sizeof(rvec), MPI_BYTE, DDMASTERRANK(dd),
1741                  MPI_ANY_TAG, dd->mpi_comm_all, MPI_STATUS_IGNORE);
1742 #endif
1743     }
1744 }
1745
1746 static void dd_distribute_vec_scatterv(gmx_domdec_t *dd, t_block *cgs,
1747                                        rvec *v, rvec *lv)
1748 {
1749     gmx_domdec_master_t *ma;
1750     int                 *scounts = NULL, *disps = NULL;
1751     int                  n, i, c, a, nalloc = 0;
1752     rvec                *buf = NULL;
1753
1754     if (DDMASTER(dd))
1755     {
1756         ma  = dd->ma;
1757
1758         get_commbuffer_counts(dd, &scounts, &disps);
1759
1760         buf = ma->vbuf;
1761         a   = 0;
1762         for (n = 0; n < dd->nnodes; n++)
1763         {
1764             for (i = ma->index[n]; i < ma->index[n+1]; i++)
1765             {
1766                 for (c = cgs->index[ma->cg[i]]; c < cgs->index[ma->cg[i]+1]; c++)
1767                 {
1768                     copy_rvec(v[c], buf[a++]);
1769                 }
1770             }
1771         }
1772     }
1773
1774     dd_scatterv(dd, scounts, disps, buf, dd->nat_home*sizeof(rvec), lv);
1775 }
1776
1777 static void dd_distribute_vec(gmx_domdec_t *dd, t_block *cgs, rvec *v, rvec *lv)
1778 {
1779     if (dd->nnodes <= GMX_DD_NNODES_SENDRECV)
1780     {
1781         dd_distribute_vec_sendrecv(dd, cgs, v, lv);
1782     }
1783     else
1784     {
1785         dd_distribute_vec_scatterv(dd, cgs, v, lv);
1786     }
1787 }
1788
1789 static void dd_distribute_dfhist(gmx_domdec_t *dd, df_history_t *dfhist)
1790 {
1791     int i;
1792     dd_bcast(dd, sizeof(int), &dfhist->bEquil);
1793     dd_bcast(dd, sizeof(int), &dfhist->nlambda);
1794     dd_bcast(dd, sizeof(real), &dfhist->wl_delta);
1795
1796     if (dfhist->nlambda > 0)
1797     {
1798         int nlam = dfhist->nlambda;
1799         dd_bcast(dd, sizeof(int)*nlam, dfhist->n_at_lam);
1800         dd_bcast(dd, sizeof(real)*nlam, dfhist->wl_histo);
1801         dd_bcast(dd, sizeof(real)*nlam, dfhist->sum_weights);
1802         dd_bcast(dd, sizeof(real)*nlam, dfhist->sum_dg);
1803         dd_bcast(dd, sizeof(real)*nlam, dfhist->sum_minvar);
1804         dd_bcast(dd, sizeof(real)*nlam, dfhist->sum_variance);
1805
1806         for (i = 0; i<nlam; i++) {
1807             dd_bcast(dd, sizeof(real)*nlam, dfhist->accum_p[i]);
1808             dd_bcast(dd, sizeof(real)*nlam, dfhist->accum_m[i]);
1809             dd_bcast(dd, sizeof(real)*nlam, dfhist->accum_p2[i]);
1810             dd_bcast(dd, sizeof(real)*nlam, dfhist->accum_m2[i]);
1811             dd_bcast(dd, sizeof(real)*nlam, dfhist->Tij[i]);
1812             dd_bcast(dd, sizeof(real)*nlam, dfhist->Tij_empirical[i]);
1813         }
1814     }
1815 }
1816
1817 static void dd_distribute_state(gmx_domdec_t *dd, t_block *cgs,
1818                                 t_state *state, t_state *state_local,
1819                                 rvec **f)
1820 {
1821     int  i, j, nh;
1822
1823     nh = state->nhchainlength;
1824
1825     if (DDMASTER(dd))
1826     {
1827         for (i = 0; i < efptNR; i++)
1828         {
1829             state_local->lambda[i] = state->lambda[i];
1830         }
1831         state_local->fep_state = state->fep_state;
1832         state_local->veta      = state->veta;
1833         state_local->vol0      = state->vol0;
1834         copy_mat(state->box, state_local->box);
1835         copy_mat(state->box_rel, state_local->box_rel);
1836         copy_mat(state->boxv, state_local->boxv);
1837         copy_mat(state->svir_prev, state_local->svir_prev);
1838         copy_mat(state->fvir_prev, state_local->fvir_prev);
1839         copy_df_history(&state_local->dfhist,&state->dfhist);
1840         for (i = 0; i < state_local->ngtc; i++)
1841         {
1842             for (j = 0; j < nh; j++)
1843             {
1844                 state_local->nosehoover_xi[i*nh+j]        = state->nosehoover_xi[i*nh+j];
1845                 state_local->nosehoover_vxi[i*nh+j]       = state->nosehoover_vxi[i*nh+j];
1846             }
1847             state_local->therm_integral[i] = state->therm_integral[i];
1848         }
1849         for (i = 0; i < state_local->nnhpres; i++)
1850         {
1851             for (j = 0; j < nh; j++)
1852             {
1853                 state_local->nhpres_xi[i*nh+j]        = state->nhpres_xi[i*nh+j];
1854                 state_local->nhpres_vxi[i*nh+j]       = state->nhpres_vxi[i*nh+j];
1855             }
1856         }
1857     }
1858     dd_bcast(dd, ((efptNR)*sizeof(real)), state_local->lambda);
1859     dd_bcast(dd, sizeof(int), &state_local->fep_state);
1860     dd_bcast(dd, sizeof(real), &state_local->veta);
1861     dd_bcast(dd, sizeof(real), &state_local->vol0);
1862     dd_bcast(dd, sizeof(state_local->box), state_local->box);
1863     dd_bcast(dd, sizeof(state_local->box_rel), state_local->box_rel);
1864     dd_bcast(dd, sizeof(state_local->boxv), state_local->boxv);
1865     dd_bcast(dd, sizeof(state_local->svir_prev), state_local->svir_prev);
1866     dd_bcast(dd, sizeof(state_local->fvir_prev), state_local->fvir_prev);
1867     dd_bcast(dd, ((state_local->ngtc*nh)*sizeof(double)), state_local->nosehoover_xi);
1868     dd_bcast(dd, ((state_local->ngtc*nh)*sizeof(double)), state_local->nosehoover_vxi);
1869     dd_bcast(dd, state_local->ngtc*sizeof(double), state_local->therm_integral);
1870     dd_bcast(dd, ((state_local->nnhpres*nh)*sizeof(double)), state_local->nhpres_xi);
1871     dd_bcast(dd, ((state_local->nnhpres*nh)*sizeof(double)), state_local->nhpres_vxi);
1872
1873     /* communicate df_history -- required for restarting from checkpoint */
1874     dd_distribute_dfhist(dd,&state_local->dfhist);
1875
1876     if (dd->nat_home > state_local->nalloc)
1877     {
1878         dd_realloc_state(state_local, f, dd->nat_home);
1879     }
1880     for (i = 0; i < estNR; i++)
1881     {
1882         if (EST_DISTR(i) && (state_local->flags & (1<<i)))
1883         {
1884             switch (i)
1885             {
1886                 case estX:
1887                     dd_distribute_vec(dd, cgs, state->x, state_local->x);
1888                     break;
1889                 case estV:
1890                     dd_distribute_vec(dd, cgs, state->v, state_local->v);
1891                     break;
1892                 case estSDX:
1893                     dd_distribute_vec(dd, cgs, state->sd_X, state_local->sd_X);
1894                     break;
1895                 case estCGP:
1896                     dd_distribute_vec(dd, cgs, state->cg_p, state_local->cg_p);
1897                     break;
1898                 case estLD_RNG:
1899                     if (state->nrngi == 1)
1900                     {
1901                         dd_bcastc(dd,
1902                                   state_local->nrng*sizeof(state_local->ld_rng[0]),
1903                                   state->ld_rng, state_local->ld_rng);
1904                     }
1905                     else
1906                     {
1907                         dd_scatter(dd,
1908                                    state_local->nrng*sizeof(state_local->ld_rng[0]),
1909                                    state->ld_rng, state_local->ld_rng);
1910                     }
1911                     break;
1912                 case estLD_RNGI:
1913                     if (state->nrngi == 1)
1914                     {
1915                         dd_bcastc(dd, sizeof(state_local->ld_rngi[0]),
1916                                   state->ld_rngi, state_local->ld_rngi);
1917                     }
1918                     else
1919                     {
1920                         dd_scatter(dd, sizeof(state_local->ld_rngi[0]),
1921                                    state->ld_rngi, state_local->ld_rngi);
1922                     }
1923                     break;
1924                 case estDISRE_INITF:
1925                 case estDISRE_RM3TAV:
1926                 case estORIRE_INITF:
1927                 case estORIRE_DTAV:
1928                     /* Not implemented yet */
1929                     break;
1930                 default:
1931                     gmx_incons("Unknown state entry encountered in dd_distribute_state");
1932             }
1933         }
1934     }
1935 }
1936
1937 static char dim2char(int dim)
1938 {
1939     char c = '?';
1940
1941     switch (dim)
1942     {
1943         case XX: c = 'X'; break;
1944         case YY: c = 'Y'; break;
1945         case ZZ: c = 'Z'; break;
1946         default: gmx_fatal(FARGS, "Unknown dim %d", dim);
1947     }
1948
1949     return c;
1950 }
1951
1952 static void write_dd_grid_pdb(const char *fn, gmx_large_int_t step,
1953                               gmx_domdec_t *dd, matrix box, gmx_ddbox_t *ddbox)
1954 {
1955     rvec   grid_s[2], *grid_r = NULL, cx, r;
1956     char   fname[STRLEN], format[STRLEN], buf[22];
1957     FILE  *out;
1958     int    a, i, d, z, y, x;
1959     matrix tric;
1960     real   vol;
1961
1962     copy_rvec(dd->comm->cell_x0, grid_s[0]);
1963     copy_rvec(dd->comm->cell_x1, grid_s[1]);
1964
1965     if (DDMASTER(dd))
1966     {
1967         snew(grid_r, 2*dd->nnodes);
1968     }
1969
1970     dd_gather(dd, 2*sizeof(rvec), grid_s[0], DDMASTER(dd) ? grid_r[0] : NULL);
1971
1972     if (DDMASTER(dd))
1973     {
1974         for (d = 0; d < DIM; d++)
1975         {
1976             for (i = 0; i < DIM; i++)
1977             {
1978                 if (d == i)
1979                 {
1980                     tric[d][i] = 1;
1981                 }
1982                 else
1983                 {
1984                     if (d < ddbox->npbcdim && dd->nc[d] > 1)
1985                     {
1986                         tric[d][i] = box[i][d]/box[i][i];
1987                     }
1988                     else
1989                     {
1990                         tric[d][i] = 0;
1991                     }
1992                 }
1993             }
1994         }
1995         sprintf(fname, "%s_%s.pdb", fn, gmx_step_str(step, buf));
1996         sprintf(format, "%s%s\n", get_pdbformat(), "%6.2f%6.2f");
1997         out = gmx_fio_fopen(fname, "w");
1998         gmx_write_pdb_box(out, dd->bScrewPBC ? epbcSCREW : epbcXYZ, box);
1999         a = 1;
2000         for (i = 0; i < dd->nnodes; i++)
2001         {
2002             vol = dd->nnodes/(box[XX][XX]*box[YY][YY]*box[ZZ][ZZ]);
2003             for (d = 0; d < DIM; d++)
2004             {
2005                 vol *= grid_r[i*2+1][d] - grid_r[i*2][d];
2006             }
2007             for (z = 0; z < 2; z++)
2008             {
2009                 for (y = 0; y < 2; y++)
2010                 {
2011                     for (x = 0; x < 2; x++)
2012                     {
2013                         cx[XX] = grid_r[i*2+x][XX];
2014                         cx[YY] = grid_r[i*2+y][YY];
2015                         cx[ZZ] = grid_r[i*2+z][ZZ];
2016                         mvmul(tric, cx, r);
2017                         fprintf(out, format, "ATOM", a++, "CA", "GLY", ' ', 1+i,
2018                                 ' ', 10*r[XX], 10*r[YY], 10*r[ZZ], 1.0, vol);
2019                     }
2020                 }
2021             }
2022             for (d = 0; d < DIM; d++)
2023             {
2024                 for (x = 0; x < 4; x++)
2025                 {
2026                     switch (d)
2027                     {
2028                         case 0: y = 1 + i*8 + 2*x; break;
2029                         case 1: y = 1 + i*8 + 2*x - (x % 2); break;
2030                         case 2: y = 1 + i*8 + x; break;
2031                     }
2032                     fprintf(out, "%6s%5d%5d\n", "CONECT", y, y+(1<<d));
2033                 }
2034             }
2035         }
2036         gmx_fio_fclose(out);
2037         sfree(grid_r);
2038     }
2039 }
2040
2041 void write_dd_pdb(const char *fn, gmx_large_int_t step, const char *title,
2042                   gmx_mtop_t *mtop, t_commrec *cr,
2043                   int natoms, rvec x[], matrix box)
2044 {
2045     char          fname[STRLEN], format[STRLEN], format4[STRLEN], buf[22];
2046     FILE         *out;
2047     int           i, ii, resnr, c;
2048     char         *atomname, *resname;
2049     real          b;
2050     gmx_domdec_t *dd;
2051
2052     dd = cr->dd;
2053     if (natoms == -1)
2054     {
2055         natoms = dd->comm->nat[ddnatVSITE];
2056     }
2057
2058     sprintf(fname, "%s_%s_n%d.pdb", fn, gmx_step_str(step, buf), cr->sim_nodeid);
2059
2060     sprintf(format, "%s%s\n", get_pdbformat(), "%6.2f%6.2f");
2061     sprintf(format4, "%s%s\n", get_pdbformat4(), "%6.2f%6.2f");
2062
2063     out = gmx_fio_fopen(fname, "w");
2064
2065     fprintf(out, "TITLE     %s\n", title);
2066     gmx_write_pdb_box(out, dd->bScrewPBC ? epbcSCREW : epbcXYZ, box);
2067     for (i = 0; i < natoms; i++)
2068     {
2069         ii = dd->gatindex[i];
2070         gmx_mtop_atominfo_global(mtop, ii, &atomname, &resnr, &resname);
2071         if (i < dd->comm->nat[ddnatZONE])
2072         {
2073             c = 0;
2074             while (i >= dd->cgindex[dd->comm->zones.cg_range[c+1]])
2075             {
2076                 c++;
2077             }
2078             b = c;
2079         }
2080         else if (i < dd->comm->nat[ddnatVSITE])
2081         {
2082             b = dd->comm->zones.n;
2083         }
2084         else
2085         {
2086             b = dd->comm->zones.n + 1;
2087         }
2088         fprintf(out, strlen(atomname) < 4 ? format : format4,
2089                 "ATOM", (ii+1)%100000,
2090                 atomname, resname, ' ', resnr%10000, ' ',
2091                 10*x[i][XX], 10*x[i][YY], 10*x[i][ZZ], 1.0, b);
2092     }
2093     fprintf(out, "TER\n");
2094
2095     gmx_fio_fclose(out);
2096 }
2097
2098 real dd_cutoff_mbody(gmx_domdec_t *dd)
2099 {
2100     gmx_domdec_comm_t *comm;
2101     int                di;
2102     real               r;
2103
2104     comm = dd->comm;
2105
2106     r = -1;
2107     if (comm->bInterCGBondeds)
2108     {
2109         if (comm->cutoff_mbody > 0)
2110         {
2111             r = comm->cutoff_mbody;
2112         }
2113         else
2114         {
2115             /* cutoff_mbody=0 means we do not have DLB */
2116             r = comm->cellsize_min[dd->dim[0]];
2117             for (di = 1; di < dd->ndim; di++)
2118             {
2119                 r = min(r, comm->cellsize_min[dd->dim[di]]);
2120             }
2121             if (comm->bBondComm)
2122             {
2123                 r = max(r, comm->cutoff_mbody);
2124             }
2125             else
2126             {
2127                 r = min(r, comm->cutoff);
2128             }
2129         }
2130     }
2131
2132     return r;
2133 }
2134
2135 real dd_cutoff_twobody(gmx_domdec_t *dd)
2136 {
2137     real r_mb;
2138
2139     r_mb = dd_cutoff_mbody(dd);
2140
2141     return max(dd->comm->cutoff, r_mb);
2142 }
2143
2144
2145 static void dd_cart_coord2pmecoord(gmx_domdec_t *dd, ivec coord, ivec coord_pme)
2146 {
2147     int nc, ntot;
2148
2149     nc   = dd->nc[dd->comm->cartpmedim];
2150     ntot = dd->comm->ntot[dd->comm->cartpmedim];
2151     copy_ivec(coord, coord_pme);
2152     coord_pme[dd->comm->cartpmedim] =
2153         nc + (coord[dd->comm->cartpmedim]*(ntot - nc) + (ntot - nc)/2)/nc;
2154 }
2155
2156 static int low_ddindex2pmeindex(int ndd, int npme, int ddindex)
2157 {
2158     /* Here we assign a PME node to communicate with this DD node
2159      * by assuming that the major index of both is x.
2160      * We add cr->npmenodes/2 to obtain an even distribution.
2161      */
2162     return (ddindex*npme + npme/2)/ndd;
2163 }
2164
2165 static int ddindex2pmeindex(const gmx_domdec_t *dd, int ddindex)
2166 {
2167     return low_ddindex2pmeindex(dd->nnodes, dd->comm->npmenodes, ddindex);
2168 }
2169
2170 static int cr_ddindex2pmeindex(const t_commrec *cr, int ddindex)
2171 {
2172     return low_ddindex2pmeindex(cr->dd->nnodes, cr->npmenodes, ddindex);
2173 }
2174
2175 static int *dd_pmenodes(t_commrec *cr)
2176 {
2177     int *pmenodes;
2178     int  n, i, p0, p1;
2179
2180     snew(pmenodes, cr->npmenodes);
2181     n = 0;
2182     for (i = 0; i < cr->dd->nnodes; i++)
2183     {
2184         p0 = cr_ddindex2pmeindex(cr, i);
2185         p1 = cr_ddindex2pmeindex(cr, i+1);
2186         if (i+1 == cr->dd->nnodes || p1 > p0)
2187         {
2188             if (debug)
2189             {
2190                 fprintf(debug, "pmenode[%d] = %d\n", n, i+1+n);
2191             }
2192             pmenodes[n] = i + 1 + n;
2193             n++;
2194         }
2195     }
2196
2197     return pmenodes;
2198 }
2199
2200 static int gmx_ddcoord2pmeindex(t_commrec *cr, int x, int y, int z)
2201 {
2202     gmx_domdec_t *dd;
2203     ivec          coords, coords_pme, nc;
2204     int           slab;
2205
2206     dd = cr->dd;
2207     /*
2208        if (dd->comm->bCartesian) {
2209        gmx_ddindex2xyz(dd->nc,ddindex,coords);
2210        dd_coords2pmecoords(dd,coords,coords_pme);
2211        copy_ivec(dd->ntot,nc);
2212        nc[dd->cartpmedim]         -= dd->nc[dd->cartpmedim];
2213        coords_pme[dd->cartpmedim] -= dd->nc[dd->cartpmedim];
2214
2215        slab = (coords_pme[XX]*nc[YY] + coords_pme[YY])*nc[ZZ] + coords_pme[ZZ];
2216        } else {
2217        slab = (ddindex*cr->npmenodes + cr->npmenodes/2)/dd->nnodes;
2218        }
2219      */
2220     coords[XX] = x;
2221     coords[YY] = y;
2222     coords[ZZ] = z;
2223     slab       = ddindex2pmeindex(dd, dd_index(dd->nc, coords));
2224
2225     return slab;
2226 }
2227
2228 static int ddcoord2simnodeid(t_commrec *cr, int x, int y, int z)
2229 {
2230     gmx_domdec_comm_t *comm;
2231     ivec               coords;
2232     int                ddindex, nodeid = -1;
2233
2234     comm = cr->dd->comm;
2235
2236     coords[XX] = x;
2237     coords[YY] = y;
2238     coords[ZZ] = z;
2239     if (comm->bCartesianPP_PME)
2240     {
2241 #ifdef GMX_MPI
2242         MPI_Cart_rank(cr->mpi_comm_mysim, coords, &nodeid);
2243 #endif
2244     }
2245     else
2246     {
2247         ddindex = dd_index(cr->dd->nc, coords);
2248         if (comm->bCartesianPP)
2249         {
2250             nodeid = comm->ddindex2simnodeid[ddindex];
2251         }
2252         else
2253         {
2254             if (comm->pmenodes)
2255             {
2256                 nodeid = ddindex + gmx_ddcoord2pmeindex(cr, x, y, z);
2257             }
2258             else
2259             {
2260                 nodeid = ddindex;
2261             }
2262         }
2263     }
2264
2265     return nodeid;
2266 }
2267
2268 static int dd_simnode2pmenode(t_commrec *cr, int sim_nodeid)
2269 {
2270     gmx_domdec_t      *dd;
2271     gmx_domdec_comm_t *comm;
2272     ivec               coord, coord_pme;
2273     int                i;
2274     int                pmenode = -1;
2275
2276     dd   = cr->dd;
2277     comm = dd->comm;
2278
2279     /* This assumes a uniform x domain decomposition grid cell size */
2280     if (comm->bCartesianPP_PME)
2281     {
2282 #ifdef GMX_MPI
2283         MPI_Cart_coords(cr->mpi_comm_mysim, sim_nodeid, DIM, coord);
2284         if (coord[comm->cartpmedim] < dd->nc[comm->cartpmedim])
2285         {
2286             /* This is a PP node */
2287             dd_cart_coord2pmecoord(dd, coord, coord_pme);
2288             MPI_Cart_rank(cr->mpi_comm_mysim, coord_pme, &pmenode);
2289         }
2290 #endif
2291     }
2292     else if (comm->bCartesianPP)
2293     {
2294         if (sim_nodeid < dd->nnodes)
2295         {
2296             pmenode = dd->nnodes + ddindex2pmeindex(dd, sim_nodeid);
2297         }
2298     }
2299     else
2300     {
2301         /* This assumes DD cells with identical x coordinates
2302          * are numbered sequentially.
2303          */
2304         if (dd->comm->pmenodes == NULL)
2305         {
2306             if (sim_nodeid < dd->nnodes)
2307             {
2308                 /* The DD index equals the nodeid */
2309                 pmenode = dd->nnodes + ddindex2pmeindex(dd, sim_nodeid);
2310             }
2311         }
2312         else
2313         {
2314             i = 0;
2315             while (sim_nodeid > dd->comm->pmenodes[i])
2316             {
2317                 i++;
2318             }
2319             if (sim_nodeid < dd->comm->pmenodes[i])
2320             {
2321                 pmenode = dd->comm->pmenodes[i];
2322             }
2323         }
2324     }
2325
2326     return pmenode;
2327 }
2328
2329 void get_pme_nnodes(const gmx_domdec_t *dd,
2330                     int *npmenodes_x, int *npmenodes_y)
2331 {
2332     if (dd != NULL)
2333     {
2334         *npmenodes_x = dd->comm->npmenodes_x;
2335         *npmenodes_y = dd->comm->npmenodes_y;
2336     }
2337     else
2338     {
2339         *npmenodes_x = 1;
2340         *npmenodes_y = 1;
2341     }
2342 }
2343
2344 gmx_bool gmx_pmeonlynode(t_commrec *cr, int sim_nodeid)
2345 {
2346     gmx_bool bPMEOnlyNode;
2347
2348     if (DOMAINDECOMP(cr))
2349     {
2350         bPMEOnlyNode = (dd_simnode2pmenode(cr, sim_nodeid) == -1);
2351     }
2352     else
2353     {
2354         bPMEOnlyNode = FALSE;
2355     }
2356
2357     return bPMEOnlyNode;
2358 }
2359
2360 void get_pme_ddnodes(t_commrec *cr, int pmenodeid,
2361                      int *nmy_ddnodes, int **my_ddnodes, int *node_peer)
2362 {
2363     gmx_domdec_t *dd;
2364     int           x, y, z;
2365     ivec          coord, coord_pme;
2366
2367     dd = cr->dd;
2368
2369     snew(*my_ddnodes, (dd->nnodes+cr->npmenodes-1)/cr->npmenodes);
2370
2371     *nmy_ddnodes = 0;
2372     for (x = 0; x < dd->nc[XX]; x++)
2373     {
2374         for (y = 0; y < dd->nc[YY]; y++)
2375         {
2376             for (z = 0; z < dd->nc[ZZ]; z++)
2377             {
2378                 if (dd->comm->bCartesianPP_PME)
2379                 {
2380                     coord[XX] = x;
2381                     coord[YY] = y;
2382                     coord[ZZ] = z;
2383                     dd_cart_coord2pmecoord(dd, coord, coord_pme);
2384                     if (dd->ci[XX] == coord_pme[XX] &&
2385                         dd->ci[YY] == coord_pme[YY] &&
2386                         dd->ci[ZZ] == coord_pme[ZZ])
2387                     {
2388                         (*my_ddnodes)[(*nmy_ddnodes)++] = ddcoord2simnodeid(cr, x, y, z);
2389                     }
2390                 }
2391                 else
2392                 {
2393                     /* The slab corresponds to the nodeid in the PME group */
2394                     if (gmx_ddcoord2pmeindex(cr, x, y, z) == pmenodeid)
2395                     {
2396                         (*my_ddnodes)[(*nmy_ddnodes)++] = ddcoord2simnodeid(cr, x, y, z);
2397                     }
2398                 }
2399             }
2400         }
2401     }
2402
2403     /* The last PP-only node is the peer node */
2404     *node_peer = (*my_ddnodes)[*nmy_ddnodes-1];
2405
2406     if (debug)
2407     {
2408         fprintf(debug, "Receive coordinates from PP nodes:");
2409         for (x = 0; x < *nmy_ddnodes; x++)
2410         {
2411             fprintf(debug, " %d", (*my_ddnodes)[x]);
2412         }
2413         fprintf(debug, "\n");
2414     }
2415 }
2416
2417 static gmx_bool receive_vir_ener(t_commrec *cr)
2418 {
2419     gmx_domdec_comm_t *comm;
2420     int                pmenode, coords[DIM], rank;
2421     gmx_bool           bReceive;
2422
2423     bReceive = TRUE;
2424     if (cr->npmenodes < cr->dd->nnodes)
2425     {
2426         comm = cr->dd->comm;
2427         if (comm->bCartesianPP_PME)
2428         {
2429             pmenode = dd_simnode2pmenode(cr, cr->sim_nodeid);
2430 #ifdef GMX_MPI
2431             MPI_Cart_coords(cr->mpi_comm_mysim, cr->sim_nodeid, DIM, coords);
2432             coords[comm->cartpmedim]++;
2433             if (coords[comm->cartpmedim] < cr->dd->nc[comm->cartpmedim])
2434             {
2435                 MPI_Cart_rank(cr->mpi_comm_mysim, coords, &rank);
2436                 if (dd_simnode2pmenode(cr, rank) == pmenode)
2437                 {
2438                     /* This is not the last PP node for pmenode */
2439                     bReceive = FALSE;
2440                 }
2441             }
2442 #endif
2443         }
2444         else
2445         {
2446             pmenode = dd_simnode2pmenode(cr, cr->sim_nodeid);
2447             if (cr->sim_nodeid+1 < cr->nnodes &&
2448                 dd_simnode2pmenode(cr, cr->sim_nodeid+1) == pmenode)
2449             {
2450                 /* This is not the last PP node for pmenode */
2451                 bReceive = FALSE;
2452             }
2453         }
2454     }
2455
2456     return bReceive;
2457 }
2458
2459 static void set_zones_ncg_home(gmx_domdec_t *dd)
2460 {
2461     gmx_domdec_zones_t *zones;
2462     int                 i;
2463
2464     zones = &dd->comm->zones;
2465
2466     zones->cg_range[0] = 0;
2467     for (i = 1; i < zones->n+1; i++)
2468     {
2469         zones->cg_range[i] = dd->ncg_home;
2470     }
2471     /* zone_ncg1[0] should always be equal to ncg_home */
2472     dd->comm->zone_ncg1[0] = dd->ncg_home;
2473 }
2474
2475 static void rebuild_cgindex(gmx_domdec_t *dd,
2476                             const int *gcgs_index, t_state *state)
2477 {
2478     int nat, i, *ind, *dd_cg_gl, *cgindex, cg_gl;
2479
2480     ind        = state->cg_gl;
2481     dd_cg_gl   = dd->index_gl;
2482     cgindex    = dd->cgindex;
2483     nat        = 0;
2484     cgindex[0] = nat;
2485     for (i = 0; i < state->ncg_gl; i++)
2486     {
2487         cgindex[i]  = nat;
2488         cg_gl       = ind[i];
2489         dd_cg_gl[i] = cg_gl;
2490         nat        += gcgs_index[cg_gl+1] - gcgs_index[cg_gl];
2491     }
2492     cgindex[i] = nat;
2493
2494     dd->ncg_home = state->ncg_gl;
2495     dd->nat_home = nat;
2496
2497     set_zones_ncg_home(dd);
2498 }
2499
2500 static int ddcginfo(const cginfo_mb_t *cginfo_mb, int cg)
2501 {
2502     while (cg >= cginfo_mb->cg_end)
2503     {
2504         cginfo_mb++;
2505     }
2506
2507     return cginfo_mb->cginfo[(cg - cginfo_mb->cg_start) % cginfo_mb->cg_mod];
2508 }
2509
2510 static void dd_set_cginfo(int *index_gl, int cg0, int cg1,
2511                           t_forcerec *fr, char *bLocalCG)
2512 {
2513     cginfo_mb_t *cginfo_mb;
2514     int         *cginfo;
2515     int          cg;
2516
2517     if (fr != NULL)
2518     {
2519         cginfo_mb = fr->cginfo_mb;
2520         cginfo    = fr->cginfo;
2521
2522         for (cg = cg0; cg < cg1; cg++)
2523         {
2524             cginfo[cg] = ddcginfo(cginfo_mb, index_gl[cg]);
2525         }
2526     }
2527
2528     if (bLocalCG != NULL)
2529     {
2530         for (cg = cg0; cg < cg1; cg++)
2531         {
2532             bLocalCG[index_gl[cg]] = TRUE;
2533         }
2534     }
2535 }
2536
2537 static void make_dd_indices(gmx_domdec_t *dd,
2538                             const int *gcgs_index, int cg_start)
2539 {
2540     int          nzone, zone, zone1, cg0, cg1, cg1_p1, cg, cg_gl, a, a_gl;
2541     int         *zone2cg, *zone_ncg1, *index_gl, *gatindex;
2542     gmx_ga2la_t *ga2la;
2543     char        *bLocalCG;
2544     gmx_bool     bCGs;
2545
2546     bLocalCG = dd->comm->bLocalCG;
2547
2548     if (dd->nat_tot > dd->gatindex_nalloc)
2549     {
2550         dd->gatindex_nalloc = over_alloc_dd(dd->nat_tot);
2551         srenew(dd->gatindex, dd->gatindex_nalloc);
2552     }
2553
2554     nzone      = dd->comm->zones.n;
2555     zone2cg    = dd->comm->zones.cg_range;
2556     zone_ncg1  = dd->comm->zone_ncg1;
2557     index_gl   = dd->index_gl;
2558     gatindex   = dd->gatindex;
2559     bCGs       = dd->comm->bCGs;
2560
2561     if (zone2cg[1] != dd->ncg_home)
2562     {
2563         gmx_incons("dd->ncg_zone is not up to date");
2564     }
2565
2566     /* Make the local to global and global to local atom index */
2567     a = dd->cgindex[cg_start];
2568     for (zone = 0; zone < nzone; zone++)
2569     {
2570         if (zone == 0)
2571         {
2572             cg0 = cg_start;
2573         }
2574         else
2575         {
2576             cg0 = zone2cg[zone];
2577         }
2578         cg1    = zone2cg[zone+1];
2579         cg1_p1 = cg0 + zone_ncg1[zone];
2580
2581         for (cg = cg0; cg < cg1; cg++)
2582         {
2583             zone1 = zone;
2584             if (cg >= cg1_p1)
2585             {
2586                 /* Signal that this cg is from more than one pulse away */
2587                 zone1 += nzone;
2588             }
2589             cg_gl = index_gl[cg];
2590             if (bCGs)
2591             {
2592                 for (a_gl = gcgs_index[cg_gl]; a_gl < gcgs_index[cg_gl+1]; a_gl++)
2593                 {
2594                     gatindex[a] = a_gl;
2595                     ga2la_set(dd->ga2la, a_gl, a, zone1);
2596                     a++;
2597                 }
2598             }
2599             else
2600             {
2601                 gatindex[a] = cg_gl;
2602                 ga2la_set(dd->ga2la, cg_gl, a, zone1);
2603                 a++;
2604             }
2605         }
2606     }
2607 }
2608
2609 static int check_bLocalCG(gmx_domdec_t *dd, int ncg_sys, const char *bLocalCG,
2610                           const char *where)
2611 {
2612     int ncg, i, ngl, nerr;
2613
2614     nerr = 0;
2615     if (bLocalCG == NULL)
2616     {
2617         return nerr;
2618     }
2619     for (i = 0; i < dd->ncg_tot; i++)
2620     {
2621         if (!bLocalCG[dd->index_gl[i]])
2622         {
2623             fprintf(stderr,
2624                     "DD node %d, %s: cg %d, global cg %d is not marked in bLocalCG (ncg_home %d)\n", dd->rank, where, i+1, dd->index_gl[i]+1, dd->ncg_home);
2625             nerr++;
2626         }
2627     }
2628     ngl = 0;
2629     for (i = 0; i < ncg_sys; i++)
2630     {
2631         if (bLocalCG[i])
2632         {
2633             ngl++;
2634         }
2635     }
2636     if (ngl != dd->ncg_tot)
2637     {
2638         fprintf(stderr, "DD node %d, %s: In bLocalCG %d cgs are marked as local, whereas there are %d\n", dd->rank, where, ngl, dd->ncg_tot);
2639         nerr++;
2640     }
2641
2642     return nerr;
2643 }
2644
2645 static void check_index_consistency(gmx_domdec_t *dd,
2646                                     int natoms_sys, int ncg_sys,
2647                                     const char *where)
2648 {
2649     int   nerr, ngl, i, a, cell;
2650     int  *have;
2651
2652     nerr = 0;
2653
2654     if (dd->comm->DD_debug > 1)
2655     {
2656         snew(have, natoms_sys);
2657         for (a = 0; a < dd->nat_tot; a++)
2658         {
2659             if (have[dd->gatindex[a]] > 0)
2660             {
2661                 fprintf(stderr, "DD node %d: global atom %d occurs twice: index %d and %d\n", dd->rank, dd->gatindex[a]+1, have[dd->gatindex[a]], a+1);
2662             }
2663             else
2664             {
2665                 have[dd->gatindex[a]] = a + 1;
2666             }
2667         }
2668         sfree(have);
2669     }
2670
2671     snew(have, dd->nat_tot);
2672
2673     ngl  = 0;
2674     for (i = 0; i < natoms_sys; i++)
2675     {
2676         if (ga2la_get(dd->ga2la, i, &a, &cell))
2677         {
2678             if (a >= dd->nat_tot)
2679             {
2680                 fprintf(stderr, "DD node %d: global atom %d marked as local atom %d, which is larger than nat_tot (%d)\n", dd->rank, i+1, a+1, dd->nat_tot);
2681                 nerr++;
2682             }
2683             else
2684             {
2685                 have[a] = 1;
2686                 if (dd->gatindex[a] != i)
2687                 {
2688                     fprintf(stderr, "DD node %d: global atom %d marked as local atom %d, which has global atom index %d\n", dd->rank, i+1, a+1, dd->gatindex[a]+1);
2689                     nerr++;
2690                 }
2691             }
2692             ngl++;
2693         }
2694     }
2695     if (ngl != dd->nat_tot)
2696     {
2697         fprintf(stderr,
2698                 "DD node %d, %s: %d global atom indices, %d local atoms\n",
2699                 dd->rank, where, ngl, dd->nat_tot);
2700     }
2701     for (a = 0; a < dd->nat_tot; a++)
2702     {
2703         if (have[a] == 0)
2704         {
2705             fprintf(stderr,
2706                     "DD node %d, %s: local atom %d, global %d has no global index\n",
2707                     dd->rank, where, a+1, dd->gatindex[a]+1);
2708         }
2709     }
2710     sfree(have);
2711
2712     nerr += check_bLocalCG(dd, ncg_sys, dd->comm->bLocalCG, where);
2713
2714     if (nerr > 0)
2715     {
2716         gmx_fatal(FARGS, "DD node %d, %s: %d atom/cg index inconsistencies",
2717                   dd->rank, where, nerr);
2718     }
2719 }
2720
2721 static void clear_dd_indices(gmx_domdec_t *dd, int cg_start, int a_start)
2722 {
2723     int   i;
2724     char *bLocalCG;
2725
2726     if (a_start == 0)
2727     {
2728         /* Clear the whole list without searching */
2729         ga2la_clear(dd->ga2la);
2730     }
2731     else
2732     {
2733         for (i = a_start; i < dd->nat_tot; i++)
2734         {
2735             ga2la_del(dd->ga2la, dd->gatindex[i]);
2736         }
2737     }
2738
2739     bLocalCG = dd->comm->bLocalCG;
2740     if (bLocalCG)
2741     {
2742         for (i = cg_start; i < dd->ncg_tot; i++)
2743         {
2744             bLocalCG[dd->index_gl[i]] = FALSE;
2745         }
2746     }
2747
2748     dd_clear_local_vsite_indices(dd);
2749
2750     if (dd->constraints)
2751     {
2752         dd_clear_local_constraint_indices(dd);
2753     }
2754 }
2755
2756 /* This function should be used for moving the domain boudaries during DLB,
2757  * for obtaining the minimum cell size. It checks the initially set limit
2758  * comm->cellsize_min, for bonded and initial non-bonded cut-offs,
2759  * and, possibly, a longer cut-off limit set for PME load balancing.
2760  */
2761 static real cellsize_min_dlb(gmx_domdec_comm_t *comm, int dim_ind, int dim)
2762 {
2763     real cellsize_min;
2764
2765     cellsize_min = comm->cellsize_min[dim];
2766
2767     if (!comm->bVacDLBNoLimit)
2768     {
2769         /* The cut-off might have changed, e.g. by PME load balacning,
2770          * from the value used to set comm->cellsize_min, so check it.
2771          */
2772         cellsize_min = max(cellsize_min, comm->cutoff/comm->cd[dim_ind].np_dlb);
2773
2774         if (comm->bPMELoadBalDLBLimits)
2775         {
2776             /* Check for the cut-off limit set by the PME load balancing */
2777             cellsize_min = max(cellsize_min, comm->PMELoadBal_max_cutoff/comm->cd[dim_ind].np_dlb);
2778         }
2779     }
2780
2781     return cellsize_min;
2782 }
2783
2784 static real grid_jump_limit(gmx_domdec_comm_t *comm, real cutoff,
2785                             int dim_ind)
2786 {
2787     real grid_jump_limit;
2788
2789     /* The distance between the boundaries of cells at distance
2790      * x+-1,y+-1 or y+-1,z+-1 is limited by the cut-off restrictions
2791      * and by the fact that cells should not be shifted by more than
2792      * half their size, such that cg's only shift by one cell
2793      * at redecomposition.
2794      */
2795     grid_jump_limit = comm->cellsize_limit;
2796     if (!comm->bVacDLBNoLimit)
2797     {
2798         if (comm->bPMELoadBalDLBLimits)
2799         {
2800             cutoff = max(cutoff, comm->PMELoadBal_max_cutoff);
2801         }
2802         grid_jump_limit = max(grid_jump_limit,
2803                               cutoff/comm->cd[dim_ind].np);
2804     }
2805
2806     return grid_jump_limit;
2807 }
2808
2809 static gmx_bool check_grid_jump(gmx_large_int_t step,
2810                                 gmx_domdec_t   *dd,
2811                                 real            cutoff,
2812                                 gmx_ddbox_t    *ddbox,
2813                                 gmx_bool        bFatal)
2814 {
2815     gmx_domdec_comm_t *comm;
2816     int                d, dim;
2817     real               limit, bfac;
2818     gmx_bool           bInvalid;
2819
2820     bInvalid = FALSE;
2821
2822     comm = dd->comm;
2823
2824     for (d = 1; d < dd->ndim; d++)
2825     {
2826         dim   = dd->dim[d];
2827         limit = grid_jump_limit(comm, cutoff, d);
2828         bfac  = ddbox->box_size[dim];
2829         if (ddbox->tric_dir[dim])
2830         {
2831             bfac *= ddbox->skew_fac[dim];
2832         }
2833         if ((comm->cell_f1[d] - comm->cell_f_max0[d])*bfac <  limit ||
2834                                                               (comm->cell_f0[d] - comm->cell_f_min1[d])*bfac > -limit)
2835         {
2836             bInvalid = TRUE;
2837
2838             if (bFatal)
2839             {
2840                 char buf[22];
2841
2842                 /* This error should never be triggered under normal
2843                  * circumstances, but you never know ...
2844                  */
2845                 gmx_fatal(FARGS, "Step %s: The domain decomposition grid has shifted too much in the %c-direction around cell %d %d %d. This should not have happened. Running with less nodes might avoid this issue.",
2846                           gmx_step_str(step, buf),
2847                           dim2char(dim), dd->ci[XX], dd->ci[YY], dd->ci[ZZ]);
2848             }
2849         }
2850     }
2851
2852     return bInvalid;
2853 }
2854
2855 static int dd_load_count(gmx_domdec_comm_t *comm)
2856 {
2857     return (comm->eFlop ? comm->flop_n : comm->cycl_n[ddCyclF]);
2858 }
2859
2860 static float dd_force_load(gmx_domdec_comm_t *comm)
2861 {
2862     float load;
2863
2864     if (comm->eFlop)
2865     {
2866         load = comm->flop;
2867         if (comm->eFlop > 1)
2868         {
2869             load *= 1.0 + (comm->eFlop - 1)*(0.1*rand()/RAND_MAX - 0.05);
2870         }
2871     }
2872     else
2873     {
2874         load = comm->cycl[ddCyclF];
2875         if (comm->cycl_n[ddCyclF] > 1)
2876         {
2877             /* Subtract the maximum of the last n cycle counts
2878              * to get rid of possible high counts due to other soures,
2879              * for instance system activity, that would otherwise
2880              * affect the dynamic load balancing.
2881              */
2882             load -= comm->cycl_max[ddCyclF];
2883         }
2884     }
2885
2886     return load;
2887 }
2888
2889 static void set_slb_pme_dim_f(gmx_domdec_t *dd, int dim, real **dim_f)
2890 {
2891     gmx_domdec_comm_t *comm;
2892     int                i;
2893
2894     comm = dd->comm;
2895
2896     snew(*dim_f, dd->nc[dim]+1);
2897     (*dim_f)[0] = 0;
2898     for (i = 1; i < dd->nc[dim]; i++)
2899     {
2900         if (comm->slb_frac[dim])
2901         {
2902             (*dim_f)[i] = (*dim_f)[i-1] + comm->slb_frac[dim][i-1];
2903         }
2904         else
2905         {
2906             (*dim_f)[i] = (real)i/(real)dd->nc[dim];
2907         }
2908     }
2909     (*dim_f)[dd->nc[dim]] = 1;
2910 }
2911
2912 static void init_ddpme(gmx_domdec_t *dd, gmx_ddpme_t *ddpme, int dimind)
2913 {
2914     int  pmeindex, slab, nso, i;
2915     ivec xyz;
2916
2917     if (dimind == 0 && dd->dim[0] == YY && dd->comm->npmenodes_x == 1)
2918     {
2919         ddpme->dim = YY;
2920     }
2921     else
2922     {
2923         ddpme->dim = dimind;
2924     }
2925     ddpme->dim_match = (ddpme->dim == dd->dim[dimind]);
2926
2927     ddpme->nslab = (ddpme->dim == 0 ?
2928                     dd->comm->npmenodes_x :
2929                     dd->comm->npmenodes_y);
2930
2931     if (ddpme->nslab <= 1)
2932     {
2933         return;
2934     }
2935
2936     nso = dd->comm->npmenodes/ddpme->nslab;
2937     /* Determine for each PME slab the PP location range for dimension dim */
2938     snew(ddpme->pp_min, ddpme->nslab);
2939     snew(ddpme->pp_max, ddpme->nslab);
2940     for (slab = 0; slab < ddpme->nslab; slab++)
2941     {
2942         ddpme->pp_min[slab] = dd->nc[dd->dim[dimind]] - 1;
2943         ddpme->pp_max[slab] = 0;
2944     }
2945     for (i = 0; i < dd->nnodes; i++)
2946     {
2947         ddindex2xyz(dd->nc, i, xyz);
2948         /* For y only use our y/z slab.
2949          * This assumes that the PME x grid size matches the DD grid size.
2950          */
2951         if (dimind == 0 || xyz[XX] == dd->ci[XX])
2952         {
2953             pmeindex = ddindex2pmeindex(dd, i);
2954             if (dimind == 0)
2955             {
2956                 slab = pmeindex/nso;
2957             }
2958             else
2959             {
2960                 slab = pmeindex % ddpme->nslab;
2961             }
2962             ddpme->pp_min[slab] = min(ddpme->pp_min[slab], xyz[dimind]);
2963             ddpme->pp_max[slab] = max(ddpme->pp_max[slab], xyz[dimind]);
2964         }
2965     }
2966
2967     set_slb_pme_dim_f(dd, ddpme->dim, &ddpme->slb_dim_f);
2968 }
2969
2970 int dd_pme_maxshift_x(gmx_domdec_t *dd)
2971 {
2972     if (dd->comm->ddpme[0].dim == XX)
2973     {
2974         return dd->comm->ddpme[0].maxshift;
2975     }
2976     else
2977     {
2978         return 0;
2979     }
2980 }
2981
2982 int dd_pme_maxshift_y(gmx_domdec_t *dd)
2983 {
2984     if (dd->comm->ddpme[0].dim == YY)
2985     {
2986         return dd->comm->ddpme[0].maxshift;
2987     }
2988     else if (dd->comm->npmedecompdim >= 2 && dd->comm->ddpme[1].dim == YY)
2989     {
2990         return dd->comm->ddpme[1].maxshift;
2991     }
2992     else
2993     {
2994         return 0;
2995     }
2996 }
2997
2998 static void set_pme_maxshift(gmx_domdec_t *dd, gmx_ddpme_t *ddpme,
2999                              gmx_bool bUniform, gmx_ddbox_t *ddbox, real *cell_f)
3000 {
3001     gmx_domdec_comm_t *comm;
3002     int                nc, ns, s;
3003     int               *xmin, *xmax;
3004     real               range, pme_boundary;
3005     int                sh;
3006
3007     comm = dd->comm;
3008     nc   = dd->nc[ddpme->dim];
3009     ns   = ddpme->nslab;
3010
3011     if (!ddpme->dim_match)
3012     {
3013         /* PP decomposition is not along dim: the worst situation */
3014         sh = ns/2;
3015     }
3016     else if (ns <= 3 || (bUniform && ns == nc))
3017     {
3018         /* The optimal situation */
3019         sh = 1;
3020     }
3021     else
3022     {
3023         /* We need to check for all pme nodes which nodes they
3024          * could possibly need to communicate with.
3025          */
3026         xmin = ddpme->pp_min;
3027         xmax = ddpme->pp_max;
3028         /* Allow for atoms to be maximally 2/3 times the cut-off
3029          * out of their DD cell. This is a reasonable balance between
3030          * between performance and support for most charge-group/cut-off
3031          * combinations.
3032          */
3033         range  = 2.0/3.0*comm->cutoff/ddbox->box_size[ddpme->dim];
3034         /* Avoid extra communication when we are exactly at a boundary */
3035         range *= 0.999;
3036
3037         sh = 1;
3038         for (s = 0; s < ns; s++)
3039         {
3040             /* PME slab s spreads atoms between box frac. s/ns and (s+1)/ns */
3041             pme_boundary = (real)s/ns;
3042             while (sh+1 < ns &&
3043                    ((s-(sh+1) >= 0 &&
3044                      cell_f[xmax[s-(sh+1)   ]+1]     + range > pme_boundary) ||
3045                     (s-(sh+1) <  0 &&
3046                      cell_f[xmax[s-(sh+1)+ns]+1] - 1 + range > pme_boundary)))
3047             {
3048                 sh++;
3049             }
3050             pme_boundary = (real)(s+1)/ns;
3051             while (sh+1 < ns &&
3052                    ((s+(sh+1) <  ns &&
3053                      cell_f[xmin[s+(sh+1)   ]  ]     - range < pme_boundary) ||
3054                     (s+(sh+1) >= ns &&
3055                      cell_f[xmin[s+(sh+1)-ns]  ] + 1 - range < pme_boundary)))
3056             {
3057                 sh++;
3058             }
3059         }
3060     }
3061
3062     ddpme->maxshift = sh;
3063
3064     if (debug)
3065     {
3066         fprintf(debug, "PME slab communication range for dim %d is %d\n",
3067                 ddpme->dim, ddpme->maxshift);
3068     }
3069 }
3070
3071 static void check_box_size(gmx_domdec_t *dd, gmx_ddbox_t *ddbox)
3072 {
3073     int d, dim;
3074
3075     for (d = 0; d < dd->ndim; d++)
3076     {
3077         dim = dd->dim[d];
3078         if (dim < ddbox->nboundeddim &&
3079             ddbox->box_size[dim]*ddbox->skew_fac[dim] <
3080             dd->nc[dim]*dd->comm->cellsize_limit*DD_CELL_MARGIN)
3081         {
3082             gmx_fatal(FARGS, "The %c-size of the box (%f) times the triclinic skew factor (%f) is smaller than the number of DD cells (%d) times the smallest allowed cell size (%f)\n",
3083                       dim2char(dim), ddbox->box_size[dim], ddbox->skew_fac[dim],
3084                       dd->nc[dim], dd->comm->cellsize_limit);
3085         }
3086     }
3087 }
3088
3089 static void set_dd_cell_sizes_slb(gmx_domdec_t *dd, gmx_ddbox_t *ddbox,
3090                                   gmx_bool bMaster, ivec npulse)
3091 {
3092     gmx_domdec_comm_t *comm;
3093     int                d, j;
3094     rvec               cellsize_min;
3095     real              *cell_x, cell_dx, cellsize;
3096
3097     comm = dd->comm;
3098
3099     for (d = 0; d < DIM; d++)
3100     {
3101         cellsize_min[d] = ddbox->box_size[d]*ddbox->skew_fac[d];
3102         npulse[d]       = 1;
3103         if (dd->nc[d] == 1 || comm->slb_frac[d] == NULL)
3104         {
3105             /* Uniform grid */
3106             cell_dx = ddbox->box_size[d]/dd->nc[d];
3107             if (bMaster)
3108             {
3109                 for (j = 0; j < dd->nc[d]+1; j++)
3110                 {
3111                     dd->ma->cell_x[d][j] = ddbox->box0[d] + j*cell_dx;
3112                 }
3113             }
3114             else
3115             {
3116                 comm->cell_x0[d] = ddbox->box0[d] + (dd->ci[d]  )*cell_dx;
3117                 comm->cell_x1[d] = ddbox->box0[d] + (dd->ci[d]+1)*cell_dx;
3118             }
3119             cellsize = cell_dx*ddbox->skew_fac[d];
3120             while (cellsize*npulse[d] < comm->cutoff && npulse[d] < dd->nc[d]-1)
3121             {
3122                 npulse[d]++;
3123             }
3124             cellsize_min[d] = cellsize;
3125         }
3126         else
3127         {
3128             /* Statically load balanced grid */
3129             /* Also when we are not doing a master distribution we determine
3130              * all cell borders in a loop to obtain identical values
3131              * to the master distribution case and to determine npulse.
3132              */
3133             if (bMaster)
3134             {
3135                 cell_x = dd->ma->cell_x[d];
3136             }
3137             else
3138             {
3139                 snew(cell_x, dd->nc[d]+1);
3140             }
3141             cell_x[0] = ddbox->box0[d];
3142             for (j = 0; j < dd->nc[d]; j++)
3143             {
3144                 cell_dx     = ddbox->box_size[d]*comm->slb_frac[d][j];
3145                 cell_x[j+1] = cell_x[j] + cell_dx;
3146                 cellsize    = cell_dx*ddbox->skew_fac[d];
3147                 while (cellsize*npulse[d] < comm->cutoff &&
3148                        npulse[d] < dd->nc[d]-1)
3149                 {
3150                     npulse[d]++;
3151                 }
3152                 cellsize_min[d] = min(cellsize_min[d], cellsize);
3153             }
3154             if (!bMaster)
3155             {
3156                 comm->cell_x0[d] = cell_x[dd->ci[d]];
3157                 comm->cell_x1[d] = cell_x[dd->ci[d]+1];
3158                 sfree(cell_x);
3159             }
3160         }
3161         /* The following limitation is to avoid that a cell would receive
3162          * some of its own home charge groups back over the periodic boundary.
3163          * Double charge groups cause trouble with the global indices.
3164          */
3165         if (d < ddbox->npbcdim &&
3166             dd->nc[d] > 1 && npulse[d] >= dd->nc[d])
3167         {
3168             gmx_fatal_collective(FARGS, NULL, dd,
3169                                  "The box size in direction %c (%f) times the triclinic skew factor (%f) is too small for a cut-off of %f with %d domain decomposition cells, use 1 or more than %d %s or increase the box size in this direction",
3170                                  dim2char(d), ddbox->box_size[d], ddbox->skew_fac[d],
3171                                  comm->cutoff,
3172                                  dd->nc[d], dd->nc[d],
3173                                  dd->nnodes > dd->nc[d] ? "cells" : "processors");
3174         }
3175     }
3176
3177     if (!comm->bDynLoadBal)
3178     {
3179         copy_rvec(cellsize_min, comm->cellsize_min);
3180     }
3181
3182     for (d = 0; d < comm->npmedecompdim; d++)
3183     {
3184         set_pme_maxshift(dd, &comm->ddpme[d],
3185                          comm->slb_frac[dd->dim[d]] == NULL, ddbox,
3186                          comm->ddpme[d].slb_dim_f);
3187     }
3188 }
3189
3190
3191 static void dd_cell_sizes_dlb_root_enforce_limits(gmx_domdec_t *dd,
3192                                                   int d, int dim, gmx_domdec_root_t *root,
3193                                                   gmx_ddbox_t *ddbox,
3194                                                   gmx_bool bUniform, gmx_large_int_t step, real cellsize_limit_f, int range[])
3195 {
3196     gmx_domdec_comm_t *comm;
3197     int                ncd, i, j, nmin, nmin_old;
3198     gmx_bool           bLimLo, bLimHi;
3199     real              *cell_size;
3200     real               fac, halfway, cellsize_limit_f_i, region_size;
3201     gmx_bool           bPBC, bLastHi = FALSE;
3202     int                nrange[] = {range[0], range[1]};
3203
3204     region_size = root->cell_f[range[1]]-root->cell_f[range[0]];
3205
3206     comm = dd->comm;
3207
3208     ncd = dd->nc[dim];
3209
3210     bPBC = (dim < ddbox->npbcdim);
3211
3212     cell_size = root->buf_ncd;
3213
3214     if (debug)
3215     {
3216         fprintf(debug, "enforce_limits: %d %d\n", range[0], range[1]);
3217     }
3218
3219     /* First we need to check if the scaling does not make cells
3220      * smaller than the smallest allowed size.
3221      * We need to do this iteratively, since if a cell is too small,
3222      * it needs to be enlarged, which makes all the other cells smaller,
3223      * which could in turn make another cell smaller than allowed.
3224      */
3225     for (i = range[0]; i < range[1]; i++)
3226     {
3227         root->bCellMin[i] = FALSE;
3228     }
3229     nmin = 0;
3230     do
3231     {
3232         nmin_old = nmin;
3233         /* We need the total for normalization */
3234         fac = 0;
3235         for (i = range[0]; i < range[1]; i++)
3236         {
3237             if (root->bCellMin[i] == FALSE)
3238             {
3239                 fac += cell_size[i];
3240             }
3241         }
3242         fac = ( region_size - nmin*cellsize_limit_f)/fac; /* substracting cells already set to cellsize_limit_f */
3243         /* Determine the cell boundaries */
3244         for (i = range[0]; i < range[1]; i++)
3245         {
3246             if (root->bCellMin[i] == FALSE)
3247             {
3248                 cell_size[i] *= fac;
3249                 if (!bPBC && (i == 0 || i == dd->nc[dim] -1))
3250                 {
3251                     cellsize_limit_f_i = 0;
3252                 }
3253                 else
3254                 {
3255                     cellsize_limit_f_i = cellsize_limit_f;
3256                 }
3257                 if (cell_size[i] < cellsize_limit_f_i)
3258                 {
3259                     root->bCellMin[i] = TRUE;
3260                     cell_size[i]      = cellsize_limit_f_i;
3261                     nmin++;
3262                 }
3263             }
3264             root->cell_f[i+1] = root->cell_f[i] + cell_size[i];
3265         }
3266     }
3267     while (nmin > nmin_old);
3268
3269     i            = range[1]-1;
3270     cell_size[i] = root->cell_f[i+1] - root->cell_f[i];
3271     /* For this check we should not use DD_CELL_MARGIN,
3272      * but a slightly smaller factor,
3273      * since rounding could get use below the limit.
3274      */
3275     if (bPBC && cell_size[i] < cellsize_limit_f*DD_CELL_MARGIN2/DD_CELL_MARGIN)
3276     {
3277         char buf[22];
3278         gmx_fatal(FARGS, "Step %s: the dynamic load balancing could not balance dimension %c: box size %f, triclinic skew factor %f, #cells %d, minimum cell size %f\n",
3279                   gmx_step_str(step, buf),
3280                   dim2char(dim), ddbox->box_size[dim], ddbox->skew_fac[dim],
3281                   ncd, comm->cellsize_min[dim]);
3282     }
3283
3284     root->bLimited = (nmin > 0) || (range[0] > 0) || (range[1] < ncd);
3285
3286     if (!bUniform)
3287     {
3288         /* Check if the boundary did not displace more than halfway
3289          * each of the cells it bounds, as this could cause problems,
3290          * especially when the differences between cell sizes are large.
3291          * If changes are applied, they will not make cells smaller
3292          * than the cut-off, as we check all the boundaries which
3293          * might be affected by a change and if the old state was ok,
3294          * the cells will at most be shrunk back to their old size.
3295          */
3296         for (i = range[0]+1; i < range[1]; i++)
3297         {
3298             halfway = 0.5*(root->old_cell_f[i] + root->old_cell_f[i-1]);
3299             if (root->cell_f[i] < halfway)
3300             {
3301                 root->cell_f[i] = halfway;
3302                 /* Check if the change also causes shifts of the next boundaries */
3303                 for (j = i+1; j < range[1]; j++)
3304                 {
3305                     if (root->cell_f[j] < root->cell_f[j-1] + cellsize_limit_f)
3306                     {
3307                         root->cell_f[j] =  root->cell_f[j-1] + cellsize_limit_f;
3308                     }
3309                 }
3310             }
3311             halfway = 0.5*(root->old_cell_f[i] + root->old_cell_f[i+1]);
3312             if (root->cell_f[i] > halfway)
3313             {
3314                 root->cell_f[i] = halfway;
3315                 /* Check if the change also causes shifts of the next boundaries */
3316                 for (j = i-1; j >= range[0]+1; j--)
3317                 {
3318                     if (root->cell_f[j] > root->cell_f[j+1] - cellsize_limit_f)
3319                     {
3320                         root->cell_f[j] = root->cell_f[j+1] - cellsize_limit_f;
3321                     }
3322                 }
3323             }
3324         }
3325     }
3326
3327     /* nrange is defined as [lower, upper) range for new call to enforce_limits */
3328     /* find highest violation of LimLo (a) and the following violation of LimHi (thus the lowest following) (b)
3329      * then call enforce_limits for (oldb,a), (a,b). In the next step: (b,nexta). oldb and nexta can be the boundaries.
3330      * for a and b nrange is used */
3331     if (d > 0)
3332     {
3333         /* Take care of the staggering of the cell boundaries */
3334         if (bUniform)
3335         {
3336             for (i = range[0]; i < range[1]; i++)
3337             {
3338                 root->cell_f_max0[i] = root->cell_f[i];
3339                 root->cell_f_min1[i] = root->cell_f[i+1];
3340             }
3341         }
3342         else
3343         {
3344             for (i = range[0]+1; i < range[1]; i++)
3345             {
3346                 bLimLo = (root->cell_f[i] < root->bound_min[i]);
3347                 bLimHi = (root->cell_f[i] > root->bound_max[i]);
3348                 if (bLimLo && bLimHi)
3349                 {
3350                     /* Both limits violated, try the best we can */
3351                     /* For this case we split the original range (range) in two parts and care about the other limitiations in the next iteration. */
3352                     root->cell_f[i] = 0.5*(root->bound_min[i] + root->bound_max[i]);
3353                     nrange[0]       = range[0];
3354                     nrange[1]       = i;
3355                     dd_cell_sizes_dlb_root_enforce_limits(dd, d, dim, root, ddbox, bUniform, step, cellsize_limit_f, nrange);
3356
3357                     nrange[0] = i;
3358                     nrange[1] = range[1];
3359                     dd_cell_sizes_dlb_root_enforce_limits(dd, d, dim, root, ddbox, bUniform, step, cellsize_limit_f, nrange);
3360
3361                     return;
3362                 }
3363                 else if (bLimLo)
3364                 {
3365                     /* root->cell_f[i] = root->bound_min[i]; */
3366                     nrange[1] = i;  /* only store violation location. There could be a LimLo violation following with an higher index */
3367                     bLastHi   = FALSE;
3368                 }
3369                 else if (bLimHi && !bLastHi)
3370                 {
3371                     bLastHi = TRUE;
3372                     if (nrange[1] < range[1])   /* found a LimLo before */
3373                     {
3374                         root->cell_f[nrange[1]] = root->bound_min[nrange[1]];
3375                         dd_cell_sizes_dlb_root_enforce_limits(dd, d, dim, root, ddbox, bUniform, step, cellsize_limit_f, nrange);
3376                         nrange[0] = nrange[1];
3377                     }
3378                     root->cell_f[i] = root->bound_max[i];
3379                     nrange[1]       = i;
3380                     dd_cell_sizes_dlb_root_enforce_limits(dd, d, dim, root, ddbox, bUniform, step, cellsize_limit_f, nrange);
3381                     nrange[0] = i;
3382                     nrange[1] = range[1];
3383                 }
3384             }
3385             if (nrange[1] < range[1])   /* found last a LimLo */
3386             {
3387                 root->cell_f[nrange[1]] = root->bound_min[nrange[1]];
3388                 dd_cell_sizes_dlb_root_enforce_limits(dd, d, dim, root, ddbox, bUniform, step, cellsize_limit_f, nrange);
3389                 nrange[0] = nrange[1];
3390                 nrange[1] = range[1];
3391                 dd_cell_sizes_dlb_root_enforce_limits(dd, d, dim, root, ddbox, bUniform, step, cellsize_limit_f, nrange);
3392             }
3393             else if (nrange[0] > range[0]) /* found at least one LimHi */
3394             {
3395                 dd_cell_sizes_dlb_root_enforce_limits(dd, d, dim, root, ddbox, bUniform, step, cellsize_limit_f, nrange);
3396             }
3397         }
3398     }
3399 }
3400
3401
3402 static void set_dd_cell_sizes_dlb_root(gmx_domdec_t *dd,
3403                                        int d, int dim, gmx_domdec_root_t *root,
3404                                        gmx_ddbox_t *ddbox, gmx_bool bDynamicBox,
3405                                        gmx_bool bUniform, gmx_large_int_t step)
3406 {
3407     gmx_domdec_comm_t *comm;
3408     int                ncd, d1, i, j, pos;
3409     real              *cell_size;
3410     real               load_aver, load_i, imbalance, change, change_max, sc;
3411     real               cellsize_limit_f, dist_min_f, dist_min_f_hard, space;
3412     real               change_limit;
3413     real               relax = 0.5;
3414     gmx_bool           bPBC;
3415     int                range[] = { 0, 0 };
3416
3417     comm = dd->comm;
3418
3419     /* Convert the maximum change from the input percentage to a fraction */
3420     change_limit = comm->dlb_scale_lim*0.01;
3421
3422     ncd = dd->nc[dim];
3423
3424     bPBC = (dim < ddbox->npbcdim);
3425
3426     cell_size = root->buf_ncd;
3427
3428     /* Store the original boundaries */
3429     for (i = 0; i < ncd+1; i++)
3430     {
3431         root->old_cell_f[i] = root->cell_f[i];
3432     }
3433     if (bUniform)
3434     {
3435         for (i = 0; i < ncd; i++)
3436         {
3437             cell_size[i] = 1.0/ncd;
3438         }
3439     }
3440     else if (dd_load_count(comm))
3441     {
3442         load_aver  = comm->load[d].sum_m/ncd;
3443         change_max = 0;
3444         for (i = 0; i < ncd; i++)
3445         {
3446             /* Determine the relative imbalance of cell i */
3447             load_i    = comm->load[d].load[i*comm->load[d].nload+2];
3448             imbalance = (load_i - load_aver)/(load_aver > 0 ? load_aver : 1);
3449             /* Determine the change of the cell size using underrelaxation */
3450             change     = -relax*imbalance;
3451             change_max = max(change_max, max(change, -change));
3452         }
3453         /* Limit the amount of scaling.
3454          * We need to use the same rescaling for all cells in one row,
3455          * otherwise the load balancing might not converge.
3456          */
3457         sc = relax;
3458         if (change_max > change_limit)
3459         {
3460             sc *= change_limit/change_max;
3461         }
3462         for (i = 0; i < ncd; i++)
3463         {
3464             /* Determine the relative imbalance of cell i */
3465             load_i    = comm->load[d].load[i*comm->load[d].nload+2];
3466             imbalance = (load_i - load_aver)/(load_aver > 0 ? load_aver : 1);
3467             /* Determine the change of the cell size using underrelaxation */
3468             change       = -sc*imbalance;
3469             cell_size[i] = (root->cell_f[i+1]-root->cell_f[i])*(1 + change);
3470         }
3471     }
3472
3473     cellsize_limit_f  = cellsize_min_dlb(comm, d, dim)/ddbox->box_size[dim];
3474     cellsize_limit_f *= DD_CELL_MARGIN;
3475     dist_min_f_hard   = grid_jump_limit(comm, comm->cutoff, d)/ddbox->box_size[dim];
3476     dist_min_f        = dist_min_f_hard * DD_CELL_MARGIN;
3477     if (ddbox->tric_dir[dim])
3478     {
3479         cellsize_limit_f /= ddbox->skew_fac[dim];
3480         dist_min_f       /= ddbox->skew_fac[dim];
3481     }
3482     if (bDynamicBox && d > 0)
3483     {
3484         dist_min_f *= DD_PRES_SCALE_MARGIN;
3485     }
3486     if (d > 0 && !bUniform)
3487     {
3488         /* Make sure that the grid is not shifted too much */
3489         for (i = 1; i < ncd; i++)
3490         {
3491             if (root->cell_f_min1[i] - root->cell_f_max0[i-1] < 2 * dist_min_f_hard)
3492             {
3493                 gmx_incons("Inconsistent DD boundary staggering limits!");
3494             }
3495             root->bound_min[i] = root->cell_f_max0[i-1] + dist_min_f;
3496             space              = root->cell_f[i] - (root->cell_f_max0[i-1] + dist_min_f);
3497             if (space > 0)
3498             {
3499                 root->bound_min[i] += 0.5*space;
3500             }
3501             root->bound_max[i] = root->cell_f_min1[i] - dist_min_f;
3502             space              = root->cell_f[i] - (root->cell_f_min1[i] - dist_min_f);
3503             if (space < 0)
3504             {
3505                 root->bound_max[i] += 0.5*space;
3506             }
3507             if (debug)
3508             {
3509                 fprintf(debug,
3510                         "dim %d boundary %d %.3f < %.3f < %.3f < %.3f < %.3f\n",
3511                         d, i,
3512                         root->cell_f_max0[i-1] + dist_min_f,
3513                         root->bound_min[i], root->cell_f[i], root->bound_max[i],
3514                         root->cell_f_min1[i] - dist_min_f);
3515             }
3516         }
3517     }
3518     range[1]          = ncd;
3519     root->cell_f[0]   = 0;
3520     root->cell_f[ncd] = 1;
3521     dd_cell_sizes_dlb_root_enforce_limits(dd, d, dim, root, ddbox, bUniform, step, cellsize_limit_f, range);
3522
3523
3524     /* After the checks above, the cells should obey the cut-off
3525      * restrictions, but it does not hurt to check.
3526      */
3527     for (i = 0; i < ncd; i++)
3528     {
3529         if (debug)
3530         {
3531             fprintf(debug, "Relative bounds dim %d  cell %d: %f %f\n",
3532                     dim, i, root->cell_f[i], root->cell_f[i+1]);
3533         }
3534
3535         if ((bPBC || (i != 0 && i != dd->nc[dim]-1)) &&
3536             root->cell_f[i+1] - root->cell_f[i] <
3537             cellsize_limit_f/DD_CELL_MARGIN)
3538         {
3539             char buf[22];
3540             fprintf(stderr,
3541                     "\nWARNING step %s: direction %c, cell %d too small: %f\n",
3542                     gmx_step_str(step, buf), dim2char(dim), i,
3543                     (root->cell_f[i+1] - root->cell_f[i])
3544                     *ddbox->box_size[dim]*ddbox->skew_fac[dim]);
3545         }
3546     }
3547
3548     pos = ncd + 1;
3549     /* Store the cell boundaries of the lower dimensions at the end */
3550     for (d1 = 0; d1 < d; d1++)
3551     {
3552         root->cell_f[pos++] = comm->cell_f0[d1];
3553         root->cell_f[pos++] = comm->cell_f1[d1];
3554     }
3555
3556     if (d < comm->npmedecompdim)
3557     {
3558         /* The master determines the maximum shift for
3559          * the coordinate communication between separate PME nodes.
3560          */
3561         set_pme_maxshift(dd, &comm->ddpme[d], bUniform, ddbox, root->cell_f);
3562     }
3563     root->cell_f[pos++] = comm->ddpme[0].maxshift;
3564     if (d >= 1)
3565     {
3566         root->cell_f[pos++] = comm->ddpme[1].maxshift;
3567     }
3568 }
3569
3570 static void relative_to_absolute_cell_bounds(gmx_domdec_t *dd,
3571                                              gmx_ddbox_t *ddbox, int dimind)
3572 {
3573     gmx_domdec_comm_t *comm;
3574     int                dim;
3575
3576     comm = dd->comm;
3577
3578     /* Set the cell dimensions */
3579     dim                = dd->dim[dimind];
3580     comm->cell_x0[dim] = comm->cell_f0[dimind]*ddbox->box_size[dim];
3581     comm->cell_x1[dim] = comm->cell_f1[dimind]*ddbox->box_size[dim];
3582     if (dim >= ddbox->nboundeddim)
3583     {
3584         comm->cell_x0[dim] += ddbox->box0[dim];
3585         comm->cell_x1[dim] += ddbox->box0[dim];
3586     }
3587 }
3588
3589 static void distribute_dd_cell_sizes_dlb(gmx_domdec_t *dd,
3590                                          int d, int dim, real *cell_f_row,
3591                                          gmx_ddbox_t *ddbox)
3592 {
3593     gmx_domdec_comm_t *comm;
3594     int                d1, dim1, pos;
3595
3596     comm = dd->comm;
3597
3598 #ifdef GMX_MPI
3599     /* Each node would only need to know two fractions,
3600      * but it is probably cheaper to broadcast the whole array.
3601      */
3602     MPI_Bcast(cell_f_row, DD_CELL_F_SIZE(dd, d)*sizeof(real), MPI_BYTE,
3603               0, comm->mpi_comm_load[d]);
3604 #endif
3605     /* Copy the fractions for this dimension from the buffer */
3606     comm->cell_f0[d] = cell_f_row[dd->ci[dim]  ];
3607     comm->cell_f1[d] = cell_f_row[dd->ci[dim]+1];
3608     /* The whole array was communicated, so set the buffer position */
3609     pos = dd->nc[dim] + 1;
3610     for (d1 = 0; d1 <= d; d1++)
3611     {
3612         if (d1 < d)
3613         {
3614             /* Copy the cell fractions of the lower dimensions */
3615             comm->cell_f0[d1] = cell_f_row[pos++];
3616             comm->cell_f1[d1] = cell_f_row[pos++];
3617         }
3618         relative_to_absolute_cell_bounds(dd, ddbox, d1);
3619     }
3620     /* Convert the communicated shift from float to int */
3621     comm->ddpme[0].maxshift = (int)(cell_f_row[pos++] + 0.5);
3622     if (d >= 1)
3623     {
3624         comm->ddpme[1].maxshift = (int)(cell_f_row[pos++] + 0.5);
3625     }
3626 }
3627
3628 static void set_dd_cell_sizes_dlb_change(gmx_domdec_t *dd,
3629                                          gmx_ddbox_t *ddbox, gmx_bool bDynamicBox,
3630                                          gmx_bool bUniform, gmx_large_int_t step)
3631 {
3632     gmx_domdec_comm_t *comm;
3633     int                d, dim, d1;
3634     gmx_bool           bRowMember, bRowRoot;
3635     real              *cell_f_row;
3636
3637     comm = dd->comm;
3638
3639     for (d = 0; d < dd->ndim; d++)
3640     {
3641         dim        = dd->dim[d];
3642         bRowMember = TRUE;
3643         bRowRoot   = TRUE;
3644         for (d1 = d; d1 < dd->ndim; d1++)
3645         {
3646             if (dd->ci[dd->dim[d1]] > 0)
3647             {
3648                 if (d1 > d)
3649                 {
3650                     bRowMember = FALSE;
3651                 }
3652                 bRowRoot = FALSE;
3653             }
3654         }
3655         if (bRowMember)
3656         {
3657             if (bRowRoot)
3658             {
3659                 set_dd_cell_sizes_dlb_root(dd, d, dim, comm->root[d],
3660                                            ddbox, bDynamicBox, bUniform, step);
3661                 cell_f_row = comm->root[d]->cell_f;
3662             }
3663             else
3664             {
3665                 cell_f_row = comm->cell_f_row;
3666             }
3667             distribute_dd_cell_sizes_dlb(dd, d, dim, cell_f_row, ddbox);
3668         }
3669     }
3670 }
3671
3672 static void set_dd_cell_sizes_dlb_nochange(gmx_domdec_t *dd, gmx_ddbox_t *ddbox)
3673 {
3674     int d;
3675
3676     /* This function assumes the box is static and should therefore
3677      * not be called when the box has changed since the last
3678      * call to dd_partition_system.
3679      */
3680     for (d = 0; d < dd->ndim; d++)
3681     {
3682         relative_to_absolute_cell_bounds(dd, ddbox, d);
3683     }
3684 }
3685
3686
3687
3688 static void set_dd_cell_sizes_dlb(gmx_domdec_t *dd,
3689                                   gmx_ddbox_t *ddbox, gmx_bool bDynamicBox,
3690                                   gmx_bool bUniform, gmx_bool bDoDLB, gmx_large_int_t step,
3691                                   gmx_wallcycle_t wcycle)
3692 {
3693     gmx_domdec_comm_t *comm;
3694     int                dim;
3695
3696     comm = dd->comm;
3697
3698     if (bDoDLB)
3699     {
3700         wallcycle_start(wcycle, ewcDDCOMMBOUND);
3701         set_dd_cell_sizes_dlb_change(dd, ddbox, bDynamicBox, bUniform, step);
3702         wallcycle_stop(wcycle, ewcDDCOMMBOUND);
3703     }
3704     else if (bDynamicBox)
3705     {
3706         set_dd_cell_sizes_dlb_nochange(dd, ddbox);
3707     }
3708
3709     /* Set the dimensions for which no DD is used */
3710     for (dim = 0; dim < DIM; dim++)
3711     {
3712         if (dd->nc[dim] == 1)
3713         {
3714             comm->cell_x0[dim] = 0;
3715             comm->cell_x1[dim] = ddbox->box_size[dim];
3716             if (dim >= ddbox->nboundeddim)
3717             {
3718                 comm->cell_x0[dim] += ddbox->box0[dim];
3719                 comm->cell_x1[dim] += ddbox->box0[dim];
3720             }
3721         }
3722     }
3723 }
3724
3725 static void realloc_comm_ind(gmx_domdec_t *dd, ivec npulse)
3726 {
3727     int                    d, np, i;
3728     gmx_domdec_comm_dim_t *cd;
3729
3730     for (d = 0; d < dd->ndim; d++)
3731     {
3732         cd = &dd->comm->cd[d];
3733         np = npulse[dd->dim[d]];
3734         if (np > cd->np_nalloc)
3735         {
3736             if (debug)
3737             {
3738                 fprintf(debug, "(Re)allocing cd for %c to %d pulses\n",
3739                         dim2char(dd->dim[d]), np);
3740             }
3741             if (DDMASTER(dd) && cd->np_nalloc > 0)
3742             {
3743                 fprintf(stderr, "\nIncreasing the number of cell to communicate in dimension %c to %d for the first time\n", dim2char(dd->dim[d]), np);
3744             }
3745             srenew(cd->ind, np);
3746             for (i = cd->np_nalloc; i < np; i++)
3747             {
3748                 cd->ind[i].index  = NULL;
3749                 cd->ind[i].nalloc = 0;
3750             }
3751             cd->np_nalloc = np;
3752         }
3753         cd->np = np;
3754     }
3755 }
3756
3757
3758 static void set_dd_cell_sizes(gmx_domdec_t *dd,
3759                               gmx_ddbox_t *ddbox, gmx_bool bDynamicBox,
3760                               gmx_bool bUniform, gmx_bool bDoDLB, gmx_large_int_t step,
3761                               gmx_wallcycle_t wcycle)
3762 {
3763     gmx_domdec_comm_t *comm;
3764     int                d;
3765     ivec               npulse;
3766
3767     comm = dd->comm;
3768
3769     /* Copy the old cell boundaries for the cg displacement check */
3770     copy_rvec(comm->cell_x0, comm->old_cell_x0);
3771     copy_rvec(comm->cell_x1, comm->old_cell_x1);
3772
3773     if (comm->bDynLoadBal)
3774     {
3775         if (DDMASTER(dd))
3776         {
3777             check_box_size(dd, ddbox);
3778         }
3779         set_dd_cell_sizes_dlb(dd, ddbox, bDynamicBox, bUniform, bDoDLB, step, wcycle);
3780     }
3781     else
3782     {
3783         set_dd_cell_sizes_slb(dd, ddbox, FALSE, npulse);
3784         realloc_comm_ind(dd, npulse);
3785     }
3786
3787     if (debug)
3788     {
3789         for (d = 0; d < DIM; d++)
3790         {
3791             fprintf(debug, "cell_x[%d] %f - %f skew_fac %f\n",
3792                     d, comm->cell_x0[d], comm->cell_x1[d], ddbox->skew_fac[d]);
3793         }
3794     }
3795 }
3796
3797 static void comm_dd_ns_cell_sizes(gmx_domdec_t *dd,
3798                                   gmx_ddbox_t *ddbox,
3799                                   rvec cell_ns_x0, rvec cell_ns_x1,
3800                                   gmx_large_int_t step)
3801 {
3802     gmx_domdec_comm_t *comm;
3803     int                dim_ind, dim;
3804
3805     comm = dd->comm;
3806
3807     for (dim_ind = 0; dim_ind < dd->ndim; dim_ind++)
3808     {
3809         dim = dd->dim[dim_ind];
3810
3811         /* Without PBC we don't have restrictions on the outer cells */
3812         if (!(dim >= ddbox->npbcdim &&
3813               (dd->ci[dim] == 0 || dd->ci[dim] == dd->nc[dim] - 1)) &&
3814             comm->bDynLoadBal &&
3815             (comm->cell_x1[dim] - comm->cell_x0[dim])*ddbox->skew_fac[dim] <
3816             comm->cellsize_min[dim])
3817         {
3818             char buf[22];
3819             gmx_fatal(FARGS, "Step %s: The %c-size (%f) times the triclinic skew factor (%f) is smaller than the smallest allowed cell size (%f) for domain decomposition grid cell %d %d %d",
3820                       gmx_step_str(step, buf), dim2char(dim),
3821                       comm->cell_x1[dim] - comm->cell_x0[dim],
3822                       ddbox->skew_fac[dim],
3823                       dd->comm->cellsize_min[dim],
3824                       dd->ci[XX], dd->ci[YY], dd->ci[ZZ]);
3825         }
3826     }
3827
3828     if ((dd->bGridJump && dd->ndim > 1) || ddbox->nboundeddim < DIM)
3829     {
3830         /* Communicate the boundaries and update cell_ns_x0/1 */
3831         dd_move_cellx(dd, ddbox, cell_ns_x0, cell_ns_x1);
3832         if (dd->bGridJump && dd->ndim > 1)
3833         {
3834             check_grid_jump(step, dd, dd->comm->cutoff, ddbox, TRUE);
3835         }
3836     }
3837 }
3838
3839 static void make_tric_corr_matrix(int npbcdim, matrix box, matrix tcm)
3840 {
3841     if (YY < npbcdim)
3842     {
3843         tcm[YY][XX] = -box[YY][XX]/box[YY][YY];
3844     }
3845     else
3846     {
3847         tcm[YY][XX] = 0;
3848     }
3849     if (ZZ < npbcdim)
3850     {
3851         tcm[ZZ][XX] = -(box[ZZ][YY]*tcm[YY][XX] + box[ZZ][XX])/box[ZZ][ZZ];
3852         tcm[ZZ][YY] = -box[ZZ][YY]/box[ZZ][ZZ];
3853     }
3854     else
3855     {
3856         tcm[ZZ][XX] = 0;
3857         tcm[ZZ][YY] = 0;
3858     }
3859 }
3860
3861 static void check_screw_box(matrix box)
3862 {
3863     /* Mathematical limitation */
3864     if (box[YY][XX] != 0 || box[ZZ][XX] != 0)
3865     {
3866         gmx_fatal(FARGS, "With screw pbc the unit cell can not have non-zero off-diagonal x-components");
3867     }
3868
3869     /* Limitation due to the asymmetry of the eighth shell method */
3870     if (box[ZZ][YY] != 0)
3871     {
3872         gmx_fatal(FARGS, "pbc=screw with non-zero box_zy is not supported");
3873     }
3874 }
3875
3876 static void distribute_cg(FILE *fplog, gmx_large_int_t step,
3877                           matrix box, ivec tric_dir, t_block *cgs, rvec pos[],
3878                           gmx_domdec_t *dd)
3879 {
3880     gmx_domdec_master_t *ma;
3881     int                **tmp_ind = NULL, *tmp_nalloc = NULL;
3882     int                  i, icg, j, k, k0, k1, d, npbcdim;
3883     matrix               tcm;
3884     rvec                 box_size, cg_cm;
3885     ivec                 ind;
3886     real                 nrcg, inv_ncg, pos_d;
3887     atom_id             *cgindex;
3888     gmx_bool             bUnbounded, bScrew;
3889
3890     ma = dd->ma;
3891
3892     if (tmp_ind == NULL)
3893     {
3894         snew(tmp_nalloc, dd->nnodes);
3895         snew(tmp_ind, dd->nnodes);
3896         for (i = 0; i < dd->nnodes; i++)
3897         {
3898             tmp_nalloc[i] = over_alloc_large(cgs->nr/dd->nnodes+1);
3899             snew(tmp_ind[i], tmp_nalloc[i]);
3900         }
3901     }
3902
3903     /* Clear the count */
3904     for (i = 0; i < dd->nnodes; i++)
3905     {
3906         ma->ncg[i] = 0;
3907         ma->nat[i] = 0;
3908     }
3909
3910     make_tric_corr_matrix(dd->npbcdim, box, tcm);
3911
3912     cgindex = cgs->index;
3913
3914     /* Compute the center of geometry for all charge groups */
3915     for (icg = 0; icg < cgs->nr; icg++)
3916     {
3917         k0      = cgindex[icg];
3918         k1      = cgindex[icg+1];
3919         nrcg    = k1 - k0;
3920         if (nrcg == 1)
3921         {
3922             copy_rvec(pos[k0], cg_cm);
3923         }
3924         else
3925         {
3926             inv_ncg = 1.0/nrcg;
3927
3928             clear_rvec(cg_cm);
3929             for (k = k0; (k < k1); k++)
3930             {
3931                 rvec_inc(cg_cm, pos[k]);
3932             }
3933             for (d = 0; (d < DIM); d++)
3934             {
3935                 cg_cm[d] *= inv_ncg;
3936             }
3937         }
3938         /* Put the charge group in the box and determine the cell index */
3939         for (d = DIM-1; d >= 0; d--)
3940         {
3941             pos_d = cg_cm[d];
3942             if (d < dd->npbcdim)
3943             {
3944                 bScrew = (dd->bScrewPBC && d == XX);
3945                 if (tric_dir[d] && dd->nc[d] > 1)
3946                 {
3947                     /* Use triclinic coordintates for this dimension */
3948                     for (j = d+1; j < DIM; j++)
3949                     {
3950                         pos_d += cg_cm[j]*tcm[j][d];
3951                     }
3952                 }
3953                 while (pos_d >= box[d][d])
3954                 {
3955                     pos_d -= box[d][d];
3956                     rvec_dec(cg_cm, box[d]);
3957                     if (bScrew)
3958                     {
3959                         cg_cm[YY] = box[YY][YY] - cg_cm[YY];
3960                         cg_cm[ZZ] = box[ZZ][ZZ] - cg_cm[ZZ];
3961                     }
3962                     for (k = k0; (k < k1); k++)
3963                     {
3964                         rvec_dec(pos[k], box[d]);
3965                         if (bScrew)
3966                         {
3967                             pos[k][YY] = box[YY][YY] - pos[k][YY];
3968                             pos[k][ZZ] = box[ZZ][ZZ] - pos[k][ZZ];
3969                         }
3970                     }
3971                 }
3972                 while (pos_d < 0)
3973                 {
3974                     pos_d += box[d][d];
3975                     rvec_inc(cg_cm, box[d]);
3976                     if (bScrew)
3977                     {
3978                         cg_cm[YY] = box[YY][YY] - cg_cm[YY];
3979                         cg_cm[ZZ] = box[ZZ][ZZ] - cg_cm[ZZ];
3980                     }
3981                     for (k = k0; (k < k1); k++)
3982                     {
3983                         rvec_inc(pos[k], box[d]);
3984                         if (bScrew)
3985                         {
3986                             pos[k][YY] = box[YY][YY] - pos[k][YY];
3987                             pos[k][ZZ] = box[ZZ][ZZ] - pos[k][ZZ];
3988                         }
3989                     }
3990                 }
3991             }
3992             /* This could be done more efficiently */
3993             ind[d] = 0;
3994             while (ind[d]+1 < dd->nc[d] && pos_d >= ma->cell_x[d][ind[d]+1])
3995             {
3996                 ind[d]++;
3997             }
3998         }
3999         i = dd_index(dd->nc, ind);
4000         if (ma->ncg[i] == tmp_nalloc[i])
4001         {
4002             tmp_nalloc[i] = over_alloc_large(ma->ncg[i]+1);
4003             srenew(tmp_ind[i], tmp_nalloc[i]);
4004         }
4005         tmp_ind[i][ma->ncg[i]] = icg;
4006         ma->ncg[i]++;
4007         ma->nat[i] += cgindex[icg+1] - cgindex[icg];
4008     }
4009
4010     k1 = 0;
4011     for (i = 0; i < dd->nnodes; i++)
4012     {
4013         ma->index[i] = k1;
4014         for (k = 0; k < ma->ncg[i]; k++)
4015         {
4016             ma->cg[k1++] = tmp_ind[i][k];
4017         }
4018     }
4019     ma->index[dd->nnodes] = k1;
4020
4021     for (i = 0; i < dd->nnodes; i++)
4022     {
4023         sfree(tmp_ind[i]);
4024     }
4025     sfree(tmp_ind);
4026     sfree(tmp_nalloc);
4027
4028     if (fplog)
4029     {
4030         char buf[22];
4031         fprintf(fplog, "Charge group distribution at step %s:",
4032                 gmx_step_str(step, buf));
4033         for (i = 0; i < dd->nnodes; i++)
4034         {
4035             fprintf(fplog, " %d", ma->ncg[i]);
4036         }
4037         fprintf(fplog, "\n");
4038     }
4039 }
4040
4041 static void get_cg_distribution(FILE *fplog, gmx_large_int_t step, gmx_domdec_t *dd,
4042                                 t_block *cgs, matrix box, gmx_ddbox_t *ddbox,
4043                                 rvec pos[])
4044 {
4045     gmx_domdec_master_t *ma = NULL;
4046     ivec                 npulse;
4047     int                  i, cg_gl;
4048     int                 *ibuf, buf2[2] = { 0, 0 };
4049     gmx_bool             bMaster = DDMASTER(dd);
4050     if (bMaster)
4051     {
4052         ma = dd->ma;
4053
4054         if (dd->bScrewPBC)
4055         {
4056             check_screw_box(box);
4057         }
4058
4059         set_dd_cell_sizes_slb(dd, ddbox, TRUE, npulse);
4060
4061         distribute_cg(fplog, step, box, ddbox->tric_dir, cgs, pos, dd);
4062         for (i = 0; i < dd->nnodes; i++)
4063         {
4064             ma->ibuf[2*i]   = ma->ncg[i];
4065             ma->ibuf[2*i+1] = ma->nat[i];
4066         }
4067         ibuf = ma->ibuf;
4068     }
4069     else
4070     {
4071         ibuf = NULL;
4072     }
4073     dd_scatter(dd, 2*sizeof(int), ibuf, buf2);
4074
4075     dd->ncg_home = buf2[0];
4076     dd->nat_home = buf2[1];
4077     dd->ncg_tot  = dd->ncg_home;
4078     dd->nat_tot  = dd->nat_home;
4079     if (dd->ncg_home > dd->cg_nalloc || dd->cg_nalloc == 0)
4080     {
4081         dd->cg_nalloc = over_alloc_dd(dd->ncg_home);
4082         srenew(dd->index_gl, dd->cg_nalloc);
4083         srenew(dd->cgindex, dd->cg_nalloc+1);
4084     }
4085     if (bMaster)
4086     {
4087         for (i = 0; i < dd->nnodes; i++)
4088         {
4089             ma->ibuf[i]            = ma->ncg[i]*sizeof(int);
4090             ma->ibuf[dd->nnodes+i] = ma->index[i]*sizeof(int);
4091         }
4092     }
4093
4094     dd_scatterv(dd,
4095                 DDMASTER(dd) ? ma->ibuf : NULL,
4096                 DDMASTER(dd) ? ma->ibuf+dd->nnodes : NULL,
4097                 DDMASTER(dd) ? ma->cg : NULL,
4098                 dd->ncg_home*sizeof(int), dd->index_gl);
4099
4100     /* Determine the home charge group sizes */
4101     dd->cgindex[0] = 0;
4102     for (i = 0; i < dd->ncg_home; i++)
4103     {
4104         cg_gl            = dd->index_gl[i];
4105         dd->cgindex[i+1] =
4106             dd->cgindex[i] + cgs->index[cg_gl+1] - cgs->index[cg_gl];
4107     }
4108
4109     if (debug)
4110     {
4111         fprintf(debug, "Home charge groups:\n");
4112         for (i = 0; i < dd->ncg_home; i++)
4113         {
4114             fprintf(debug, " %d", dd->index_gl[i]);
4115             if (i % 10 == 9)
4116             {
4117                 fprintf(debug, "\n");
4118             }
4119         }
4120         fprintf(debug, "\n");
4121     }
4122 }
4123
4124 static int compact_and_copy_vec_at(int ncg, int *move,
4125                                    int *cgindex,
4126                                    int nvec, int vec,
4127                                    rvec *src, gmx_domdec_comm_t *comm,
4128                                    gmx_bool bCompact)
4129 {
4130     int m, icg, i, i0, i1, nrcg;
4131     int home_pos;
4132     int pos_vec[DIM*2];
4133
4134     home_pos = 0;
4135
4136     for (m = 0; m < DIM*2; m++)
4137     {
4138         pos_vec[m] = 0;
4139     }
4140
4141     i0 = 0;
4142     for (icg = 0; icg < ncg; icg++)
4143     {
4144         i1 = cgindex[icg+1];
4145         m  = move[icg];
4146         if (m == -1)
4147         {
4148             if (bCompact)
4149             {
4150                 /* Compact the home array in place */
4151                 for (i = i0; i < i1; i++)
4152                 {
4153                     copy_rvec(src[i], src[home_pos++]);
4154                 }
4155             }
4156         }
4157         else
4158         {
4159             /* Copy to the communication buffer */
4160             nrcg        = i1 - i0;
4161             pos_vec[m] += 1 + vec*nrcg;
4162             for (i = i0; i < i1; i++)
4163             {
4164                 copy_rvec(src[i], comm->cgcm_state[m][pos_vec[m]++]);
4165             }
4166             pos_vec[m] += (nvec - vec - 1)*nrcg;
4167         }
4168         if (!bCompact)
4169         {
4170             home_pos += i1 - i0;
4171         }
4172         i0 = i1;
4173     }
4174
4175     return home_pos;
4176 }
4177
4178 static int compact_and_copy_vec_cg(int ncg, int *move,
4179                                    int *cgindex,
4180                                    int nvec, rvec *src, gmx_domdec_comm_t *comm,
4181                                    gmx_bool bCompact)
4182 {
4183     int m, icg, i0, i1, nrcg;
4184     int home_pos;
4185     int pos_vec[DIM*2];
4186
4187     home_pos = 0;
4188
4189     for (m = 0; m < DIM*2; m++)
4190     {
4191         pos_vec[m] = 0;
4192     }
4193
4194     i0 = 0;
4195     for (icg = 0; icg < ncg; icg++)
4196     {
4197         i1 = cgindex[icg+1];
4198         m  = move[icg];
4199         if (m == -1)
4200         {
4201             if (bCompact)
4202             {
4203                 /* Compact the home array in place */
4204                 copy_rvec(src[icg], src[home_pos++]);
4205             }
4206         }
4207         else
4208         {
4209             nrcg = i1 - i0;
4210             /* Copy to the communication buffer */
4211             copy_rvec(src[icg], comm->cgcm_state[m][pos_vec[m]]);
4212             pos_vec[m] += 1 + nrcg*nvec;
4213         }
4214         i0 = i1;
4215     }
4216     if (!bCompact)
4217     {
4218         home_pos = ncg;
4219     }
4220
4221     return home_pos;
4222 }
4223
4224 static int compact_ind(int ncg, int *move,
4225                        int *index_gl, int *cgindex,
4226                        int *gatindex,
4227                        gmx_ga2la_t ga2la, char *bLocalCG,
4228                        int *cginfo)
4229 {
4230     int cg, nat, a0, a1, a, a_gl;
4231     int home_pos;
4232
4233     home_pos = 0;
4234     nat      = 0;
4235     for (cg = 0; cg < ncg; cg++)
4236     {
4237         a0 = cgindex[cg];
4238         a1 = cgindex[cg+1];
4239         if (move[cg] == -1)
4240         {
4241             /* Compact the home arrays in place.
4242              * Anything that can be done here avoids access to global arrays.
4243              */
4244             cgindex[home_pos] = nat;
4245             for (a = a0; a < a1; a++)
4246             {
4247                 a_gl          = gatindex[a];
4248                 gatindex[nat] = a_gl;
4249                 /* The cell number stays 0, so we don't need to set it */
4250                 ga2la_change_la(ga2la, a_gl, nat);
4251                 nat++;
4252             }
4253             index_gl[home_pos] = index_gl[cg];
4254             cginfo[home_pos]   = cginfo[cg];
4255             /* The charge group remains local, so bLocalCG does not change */
4256             home_pos++;
4257         }
4258         else
4259         {
4260             /* Clear the global indices */
4261             for (a = a0; a < a1; a++)
4262             {
4263                 ga2la_del(ga2la, gatindex[a]);
4264             }
4265             if (bLocalCG)
4266             {
4267                 bLocalCG[index_gl[cg]] = FALSE;
4268             }
4269         }
4270     }
4271     cgindex[home_pos] = nat;
4272
4273     return home_pos;
4274 }
4275
4276 static void clear_and_mark_ind(int ncg, int *move,
4277                                int *index_gl, int *cgindex, int *gatindex,
4278                                gmx_ga2la_t ga2la, char *bLocalCG,
4279                                int *cell_index)
4280 {
4281     int cg, a0, a1, a;
4282
4283     for (cg = 0; cg < ncg; cg++)
4284     {
4285         if (move[cg] >= 0)
4286         {
4287             a0 = cgindex[cg];
4288             a1 = cgindex[cg+1];
4289             /* Clear the global indices */
4290             for (a = a0; a < a1; a++)
4291             {
4292                 ga2la_del(ga2la, gatindex[a]);
4293             }
4294             if (bLocalCG)
4295             {
4296                 bLocalCG[index_gl[cg]] = FALSE;
4297             }
4298             /* Signal that this cg has moved using the ns cell index.
4299              * Here we set it to -1. fill_grid will change it
4300              * from -1 to NSGRID_SIGNAL_MOVED_FAC*grid->ncells.
4301              */
4302             cell_index[cg] = -1;
4303         }
4304     }
4305 }
4306
4307 static void print_cg_move(FILE *fplog,
4308                           gmx_domdec_t *dd,
4309                           gmx_large_int_t step, int cg, int dim, int dir,
4310                           gmx_bool bHaveLimitdAndCMOld, real limitd,
4311                           rvec cm_old, rvec cm_new, real pos_d)
4312 {
4313     gmx_domdec_comm_t *comm;
4314     char               buf[22];
4315
4316     comm = dd->comm;
4317
4318     fprintf(fplog, "\nStep %s:\n", gmx_step_str(step, buf));
4319     if (bHaveLimitdAndCMOld)
4320     {
4321         fprintf(fplog, "The charge group starting at atom %d moved more than the distance allowed by the domain decomposition (%f) in direction %c\n",
4322                 ddglatnr(dd, dd->cgindex[cg]), limitd, dim2char(dim));
4323     }
4324     else
4325     {
4326         fprintf(fplog, "The charge group starting at atom %d moved than the distance allowed by the domain decomposition in direction %c\n",
4327                 ddglatnr(dd, dd->cgindex[cg]), dim2char(dim));
4328     }
4329     fprintf(fplog, "distance out of cell %f\n",
4330             dir == 1 ? pos_d - comm->cell_x1[dim] : pos_d - comm->cell_x0[dim]);
4331     if (bHaveLimitdAndCMOld)
4332     {
4333         fprintf(fplog, "Old coordinates: %8.3f %8.3f %8.3f\n",
4334                 cm_old[XX], cm_old[YY], cm_old[ZZ]);
4335     }
4336     fprintf(fplog, "New coordinates: %8.3f %8.3f %8.3f\n",
4337             cm_new[XX], cm_new[YY], cm_new[ZZ]);
4338     fprintf(fplog, "Old cell boundaries in direction %c: %8.3f %8.3f\n",
4339             dim2char(dim),
4340             comm->old_cell_x0[dim], comm->old_cell_x1[dim]);
4341     fprintf(fplog, "New cell boundaries in direction %c: %8.3f %8.3f\n",
4342             dim2char(dim),
4343             comm->cell_x0[dim], comm->cell_x1[dim]);
4344 }
4345
4346 static void cg_move_error(FILE *fplog,
4347                           gmx_domdec_t *dd,
4348                           gmx_large_int_t step, int cg, int dim, int dir,
4349                           gmx_bool bHaveLimitdAndCMOld, real limitd,
4350                           rvec cm_old, rvec cm_new, real pos_d)
4351 {
4352     if (fplog)
4353     {
4354         print_cg_move(fplog, dd, step, cg, dim, dir,
4355                       bHaveLimitdAndCMOld, limitd, cm_old, cm_new, pos_d);
4356     }
4357     print_cg_move(stderr, dd, step, cg, dim, dir,
4358                   bHaveLimitdAndCMOld, limitd, cm_old, cm_new, pos_d);
4359     gmx_fatal(FARGS,
4360               "A charge group moved too far between two domain decomposition steps\n"
4361               "This usually means that your system is not well equilibrated");
4362 }
4363
4364 static void rotate_state_atom(t_state *state, int a)
4365 {
4366     int est;
4367
4368     for (est = 0; est < estNR; est++)
4369     {
4370         if (EST_DISTR(est) && (state->flags & (1<<est)))
4371         {
4372             switch (est)
4373             {
4374                 case estX:
4375                     /* Rotate the complete state; for a rectangular box only */
4376                     state->x[a][YY] = state->box[YY][YY] - state->x[a][YY];
4377                     state->x[a][ZZ] = state->box[ZZ][ZZ] - state->x[a][ZZ];
4378                     break;
4379                 case estV:
4380                     state->v[a][YY] = -state->v[a][YY];
4381                     state->v[a][ZZ] = -state->v[a][ZZ];
4382                     break;
4383                 case estSDX:
4384                     state->sd_X[a][YY] = -state->sd_X[a][YY];
4385                     state->sd_X[a][ZZ] = -state->sd_X[a][ZZ];
4386                     break;
4387                 case estCGP:
4388                     state->cg_p[a][YY] = -state->cg_p[a][YY];
4389                     state->cg_p[a][ZZ] = -state->cg_p[a][ZZ];
4390                     break;
4391                 case estDISRE_INITF:
4392                 case estDISRE_RM3TAV:
4393                 case estORIRE_INITF:
4394                 case estORIRE_DTAV:
4395                     /* These are distances, so not affected by rotation */
4396                     break;
4397                 default:
4398                     gmx_incons("Unknown state entry encountered in rotate_state_atom");
4399             }
4400         }
4401     }
4402 }
4403
4404 static int *get_moved(gmx_domdec_comm_t *comm, int natoms)
4405 {
4406     if (natoms > comm->moved_nalloc)
4407     {
4408         /* Contents should be preserved here */
4409         comm->moved_nalloc = over_alloc_dd(natoms);
4410         srenew(comm->moved, comm->moved_nalloc);
4411     }
4412
4413     return comm->moved;
4414 }
4415
4416 static void calc_cg_move(FILE *fplog, gmx_large_int_t step,
4417                          gmx_domdec_t *dd,
4418                          t_state *state,
4419                          ivec tric_dir, matrix tcm,
4420                          rvec cell_x0, rvec cell_x1,
4421                          rvec limitd, rvec limit0, rvec limit1,
4422                          const int *cgindex,
4423                          int cg_start, int cg_end,
4424                          rvec *cg_cm,
4425                          int *move)
4426 {
4427     int      npbcdim;
4428     int      c, i, cg, k, k0, k1, d, dim, dim2, dir, d2, d3, d4, cell_d;
4429     int      mc, cdd, nrcg, ncg_recv, nat_recv, nvs, nvr, nvec, vec;
4430     int      flag;
4431     gmx_bool bScrew;
4432     ivec     dev;
4433     real     inv_ncg, pos_d;
4434     rvec     cm_new;
4435
4436     npbcdim = dd->npbcdim;
4437
4438     for (cg = cg_start; cg < cg_end; cg++)
4439     {
4440         k0   = cgindex[cg];
4441         k1   = cgindex[cg+1];
4442         nrcg = k1 - k0;
4443         if (nrcg == 1)
4444         {
4445             copy_rvec(state->x[k0], cm_new);
4446         }
4447         else
4448         {
4449             inv_ncg = 1.0/nrcg;
4450
4451             clear_rvec(cm_new);
4452             for (k = k0; (k < k1); k++)
4453             {
4454                 rvec_inc(cm_new, state->x[k]);
4455             }
4456             for (d = 0; (d < DIM); d++)
4457             {
4458                 cm_new[d] = inv_ncg*cm_new[d];
4459             }
4460         }
4461
4462         clear_ivec(dev);
4463         /* Do pbc and check DD cell boundary crossings */
4464         for (d = DIM-1; d >= 0; d--)
4465         {
4466             if (dd->nc[d] > 1)
4467             {
4468                 bScrew = (dd->bScrewPBC && d == XX);
4469                 /* Determine the location of this cg in lattice coordinates */
4470                 pos_d = cm_new[d];
4471                 if (tric_dir[d])
4472                 {
4473                     for (d2 = d+1; d2 < DIM; d2++)
4474                     {
4475                         pos_d += cm_new[d2]*tcm[d2][d];
4476                     }
4477                 }
4478                 /* Put the charge group in the triclinic unit-cell */
4479                 if (pos_d >= cell_x1[d])
4480                 {
4481                     if (pos_d >= limit1[d])
4482                     {
4483                         cg_move_error(fplog, dd, step, cg, d, 1, TRUE, limitd[d],
4484                                       cg_cm[cg], cm_new, pos_d);
4485                     }
4486                     dev[d] = 1;
4487                     if (dd->ci[d] == dd->nc[d] - 1)
4488                     {
4489                         rvec_dec(cm_new, state->box[d]);
4490                         if (bScrew)
4491                         {
4492                             cm_new[YY] = state->box[YY][YY] - cm_new[YY];
4493                             cm_new[ZZ] = state->box[ZZ][ZZ] - cm_new[ZZ];
4494                         }
4495                         for (k = k0; (k < k1); k++)
4496                         {
4497                             rvec_dec(state->x[k], state->box[d]);
4498                             if (bScrew)
4499                             {
4500                                 rotate_state_atom(state, k);
4501                             }
4502                         }
4503                     }
4504                 }
4505                 else if (pos_d < cell_x0[d])
4506                 {
4507                     if (pos_d < limit0[d])
4508                     {
4509                         cg_move_error(fplog, dd, step, cg, d, -1, TRUE, limitd[d],
4510                                       cg_cm[cg], cm_new, pos_d);
4511                     }
4512                     dev[d] = -1;
4513                     if (dd->ci[d] == 0)
4514                     {
4515                         rvec_inc(cm_new, state->box[d]);
4516                         if (bScrew)
4517                         {
4518                             cm_new[YY] = state->box[YY][YY] - cm_new[YY];
4519                             cm_new[ZZ] = state->box[ZZ][ZZ] - cm_new[ZZ];
4520                         }
4521                         for (k = k0; (k < k1); k++)
4522                         {
4523                             rvec_inc(state->x[k], state->box[d]);
4524                             if (bScrew)
4525                             {
4526                                 rotate_state_atom(state, k);
4527                             }
4528                         }
4529                     }
4530                 }
4531             }
4532             else if (d < npbcdim)
4533             {
4534                 /* Put the charge group in the rectangular unit-cell */
4535                 while (cm_new[d] >= state->box[d][d])
4536                 {
4537                     rvec_dec(cm_new, state->box[d]);
4538                     for (k = k0; (k < k1); k++)
4539                     {
4540                         rvec_dec(state->x[k], state->box[d]);
4541                     }
4542                 }
4543                 while (cm_new[d] < 0)
4544                 {
4545                     rvec_inc(cm_new, state->box[d]);
4546                     for (k = k0; (k < k1); k++)
4547                     {
4548                         rvec_inc(state->x[k], state->box[d]);
4549                     }
4550                 }
4551             }
4552         }
4553
4554         copy_rvec(cm_new, cg_cm[cg]);
4555
4556         /* Determine where this cg should go */
4557         flag = 0;
4558         mc   = -1;
4559         for (d = 0; d < dd->ndim; d++)
4560         {
4561             dim = dd->dim[d];
4562             if (dev[dim] == 1)
4563             {
4564                 flag |= DD_FLAG_FW(d);
4565                 if (mc == -1)
4566                 {
4567                     mc = d*2;
4568                 }
4569             }
4570             else if (dev[dim] == -1)
4571             {
4572                 flag |= DD_FLAG_BW(d);
4573                 if (mc == -1)
4574                 {
4575                     if (dd->nc[dim] > 2)
4576                     {
4577                         mc = d*2 + 1;
4578                     }
4579                     else
4580                     {
4581                         mc = d*2;
4582                     }
4583                 }
4584             }
4585         }
4586         /* Temporarily store the flag in move */
4587         move[cg] = mc + flag;
4588     }
4589 }
4590
4591 static void dd_redistribute_cg(FILE *fplog, gmx_large_int_t step,
4592                                gmx_domdec_t *dd, ivec tric_dir,
4593                                t_state *state, rvec **f,
4594                                t_forcerec *fr,
4595                                gmx_bool bCompact,
4596                                t_nrnb *nrnb,
4597                                int *ncg_stay_home,
4598                                int *ncg_moved)
4599 {
4600     int               *move;
4601     int                npbcdim;
4602     int                ncg[DIM*2], nat[DIM*2];
4603     int                c, i, cg, k, k0, k1, d, dim, dim2, dir, d2, d3, d4, cell_d;
4604     int                mc, cdd, nrcg, ncg_recv, nat_recv, nvs, nvr, nvec, vec;
4605     int                sbuf[2], rbuf[2];
4606     int                home_pos_cg, home_pos_at, buf_pos;
4607     int                flag;
4608     gmx_bool           bV = FALSE, bSDX = FALSE, bCGP = FALSE;
4609     gmx_bool           bScrew;
4610     ivec               dev;
4611     real               inv_ncg, pos_d;
4612     matrix             tcm;
4613     rvec              *cg_cm = NULL, cell_x0, cell_x1, limitd, limit0, limit1, cm_new;
4614     atom_id           *cgindex;
4615     cginfo_mb_t       *cginfo_mb;
4616     gmx_domdec_comm_t *comm;
4617     int               *moved;
4618     int                nthread, thread;
4619
4620     if (dd->bScrewPBC)
4621     {
4622         check_screw_box(state->box);
4623     }
4624
4625     comm  = dd->comm;
4626     if (fr->cutoff_scheme == ecutsGROUP)
4627     {
4628         cg_cm = fr->cg_cm;
4629     }
4630
4631     for (i = 0; i < estNR; i++)
4632     {
4633         if (EST_DISTR(i))
4634         {
4635             switch (i)
4636             {
4637                 case estX: /* Always present */ break;
4638                 case estV:   bV   = (state->flags & (1<<i)); break;
4639                 case estSDX: bSDX = (state->flags & (1<<i)); break;
4640                 case estCGP: bCGP = (state->flags & (1<<i)); break;
4641                 case estLD_RNG:
4642                 case estLD_RNGI:
4643                 case estDISRE_INITF:
4644                 case estDISRE_RM3TAV:
4645                 case estORIRE_INITF:
4646                 case estORIRE_DTAV:
4647                     /* No processing required */
4648                     break;
4649                 default:
4650                     gmx_incons("Unknown state entry encountered in dd_redistribute_cg");
4651             }
4652         }
4653     }
4654
4655     if (dd->ncg_tot > comm->nalloc_int)
4656     {
4657         comm->nalloc_int = over_alloc_dd(dd->ncg_tot);
4658         srenew(comm->buf_int, comm->nalloc_int);
4659     }
4660     move = comm->buf_int;
4661
4662     /* Clear the count */
4663     for (c = 0; c < dd->ndim*2; c++)
4664     {
4665         ncg[c] = 0;
4666         nat[c] = 0;
4667     }
4668
4669     npbcdim = dd->npbcdim;
4670
4671     for (d = 0; (d < DIM); d++)
4672     {
4673         limitd[d] = dd->comm->cellsize_min[d];
4674         if (d >= npbcdim && dd->ci[d] == 0)
4675         {
4676             cell_x0[d] = -GMX_FLOAT_MAX;
4677         }
4678         else
4679         {
4680             cell_x0[d] = comm->cell_x0[d];
4681         }
4682         if (d >= npbcdim && dd->ci[d] == dd->nc[d] - 1)
4683         {
4684             cell_x1[d] = GMX_FLOAT_MAX;
4685         }
4686         else
4687         {
4688             cell_x1[d] = comm->cell_x1[d];
4689         }
4690         if (d < npbcdim)
4691         {
4692             limit0[d] = comm->old_cell_x0[d] - limitd[d];
4693             limit1[d] = comm->old_cell_x1[d] + limitd[d];
4694         }
4695         else
4696         {
4697             /* We check after communication if a charge group moved
4698              * more than one cell. Set the pre-comm check limit to float_max.
4699              */
4700             limit0[d] = -GMX_FLOAT_MAX;
4701             limit1[d] =  GMX_FLOAT_MAX;
4702         }
4703     }
4704
4705     make_tric_corr_matrix(npbcdim, state->box, tcm);
4706
4707     cgindex = dd->cgindex;
4708
4709     nthread = gmx_omp_nthreads_get(emntDomdec);
4710
4711     /* Compute the center of geometry for all home charge groups
4712      * and put them in the box and determine where they should go.
4713      */
4714 #pragma omp parallel for num_threads(nthread) schedule(static)
4715     for (thread = 0; thread < nthread; thread++)
4716     {
4717         calc_cg_move(fplog, step, dd, state, tric_dir, tcm,
4718                      cell_x0, cell_x1, limitd, limit0, limit1,
4719                      cgindex,
4720                      ( thread   *dd->ncg_home)/nthread,
4721                      ((thread+1)*dd->ncg_home)/nthread,
4722                      fr->cutoff_scheme == ecutsGROUP ? cg_cm : state->x,
4723                      move);
4724     }
4725
4726     for (cg = 0; cg < dd->ncg_home; cg++)
4727     {
4728         if (move[cg] >= 0)
4729         {
4730             mc       = move[cg];
4731             flag     = mc & ~DD_FLAG_NRCG;
4732             mc       = mc & DD_FLAG_NRCG;
4733             move[cg] = mc;
4734
4735             if (ncg[mc]+1 > comm->cggl_flag_nalloc[mc])
4736             {
4737                 comm->cggl_flag_nalloc[mc] = over_alloc_dd(ncg[mc]+1);
4738                 srenew(comm->cggl_flag[mc], comm->cggl_flag_nalloc[mc]*DD_CGIBS);
4739             }
4740             comm->cggl_flag[mc][ncg[mc]*DD_CGIBS  ] = dd->index_gl[cg];
4741             /* We store the cg size in the lower 16 bits
4742              * and the place where the charge group should go
4743              * in the next 6 bits. This saves some communication volume.
4744              */
4745             nrcg = cgindex[cg+1] - cgindex[cg];
4746             comm->cggl_flag[mc][ncg[mc]*DD_CGIBS+1] = nrcg | flag;
4747             ncg[mc] += 1;
4748             nat[mc] += nrcg;
4749         }
4750     }
4751
4752     inc_nrnb(nrnb, eNR_CGCM, dd->nat_home);
4753     inc_nrnb(nrnb, eNR_RESETX, dd->ncg_home);
4754
4755     *ncg_moved = 0;
4756     for (i = 0; i < dd->ndim*2; i++)
4757     {
4758         *ncg_moved += ncg[i];
4759     }
4760
4761     nvec = 1;
4762     if (bV)
4763     {
4764         nvec++;
4765     }
4766     if (bSDX)
4767     {
4768         nvec++;
4769     }
4770     if (bCGP)
4771     {
4772         nvec++;
4773     }
4774
4775     /* Make sure the communication buffers are large enough */
4776     for (mc = 0; mc < dd->ndim*2; mc++)
4777     {
4778         nvr = ncg[mc] + nat[mc]*nvec;
4779         if (nvr > comm->cgcm_state_nalloc[mc])
4780         {
4781             comm->cgcm_state_nalloc[mc] = over_alloc_dd(nvr);
4782             srenew(comm->cgcm_state[mc], comm->cgcm_state_nalloc[mc]);
4783         }
4784     }
4785
4786     switch (fr->cutoff_scheme)
4787     {
4788         case ecutsGROUP:
4789             /* Recalculating cg_cm might be cheaper than communicating,
4790              * but that could give rise to rounding issues.
4791              */
4792             home_pos_cg =
4793                 compact_and_copy_vec_cg(dd->ncg_home, move, cgindex,
4794                                         nvec, cg_cm, comm, bCompact);
4795             break;
4796         case ecutsVERLET:
4797             /* Without charge groups we send the moved atom coordinates
4798              * over twice. This is so the code below can be used without
4799              * many conditionals for both for with and without charge groups.
4800              */
4801             home_pos_cg =
4802                 compact_and_copy_vec_cg(dd->ncg_home, move, cgindex,
4803                                         nvec, state->x, comm, FALSE);
4804             if (bCompact)
4805             {
4806                 home_pos_cg -= *ncg_moved;
4807             }
4808             break;
4809         default:
4810             gmx_incons("unimplemented");
4811             home_pos_cg = 0;
4812     }
4813
4814     vec         = 0;
4815     home_pos_at =
4816         compact_and_copy_vec_at(dd->ncg_home, move, cgindex,
4817                                 nvec, vec++, state->x, comm, bCompact);
4818     if (bV)
4819     {
4820         compact_and_copy_vec_at(dd->ncg_home, move, cgindex,
4821                                 nvec, vec++, state->v, comm, bCompact);
4822     }
4823     if (bSDX)
4824     {
4825         compact_and_copy_vec_at(dd->ncg_home, move, cgindex,
4826                                 nvec, vec++, state->sd_X, comm, bCompact);
4827     }
4828     if (bCGP)
4829     {
4830         compact_and_copy_vec_at(dd->ncg_home, move, cgindex,
4831                                 nvec, vec++, state->cg_p, comm, bCompact);
4832     }
4833
4834     if (bCompact)
4835     {
4836         compact_ind(dd->ncg_home, move,
4837                     dd->index_gl, dd->cgindex, dd->gatindex,
4838                     dd->ga2la, comm->bLocalCG,
4839                     fr->cginfo);
4840     }
4841     else
4842     {
4843         if (fr->cutoff_scheme == ecutsVERLET)
4844         {
4845             moved = get_moved(comm, dd->ncg_home);
4846
4847             for (k = 0; k < dd->ncg_home; k++)
4848             {
4849                 moved[k] = 0;
4850             }
4851         }
4852         else
4853         {
4854             moved = fr->ns.grid->cell_index;
4855         }
4856
4857         clear_and_mark_ind(dd->ncg_home, move,
4858                            dd->index_gl, dd->cgindex, dd->gatindex,
4859                            dd->ga2la, comm->bLocalCG,
4860                            moved);
4861     }
4862
4863     cginfo_mb = fr->cginfo_mb;
4864
4865     *ncg_stay_home = home_pos_cg;
4866     for (d = 0; d < dd->ndim; d++)
4867     {
4868         dim      = dd->dim[d];
4869         ncg_recv = 0;
4870         nat_recv = 0;
4871         nvr      = 0;
4872         for (dir = 0; dir < (dd->nc[dim] == 2 ? 1 : 2); dir++)
4873         {
4874             cdd = d*2 + dir;
4875             /* Communicate the cg and atom counts */
4876             sbuf[0] = ncg[cdd];
4877             sbuf[1] = nat[cdd];
4878             if (debug)
4879             {
4880                 fprintf(debug, "Sending ddim %d dir %d: ncg %d nat %d\n",
4881                         d, dir, sbuf[0], sbuf[1]);
4882             }
4883             dd_sendrecv_int(dd, d, dir, sbuf, 2, rbuf, 2);
4884
4885             if ((ncg_recv+rbuf[0])*DD_CGIBS > comm->nalloc_int)
4886             {
4887                 comm->nalloc_int = over_alloc_dd((ncg_recv+rbuf[0])*DD_CGIBS);
4888                 srenew(comm->buf_int, comm->nalloc_int);
4889             }
4890
4891             /* Communicate the charge group indices, sizes and flags */
4892             dd_sendrecv_int(dd, d, dir,
4893                             comm->cggl_flag[cdd], sbuf[0]*DD_CGIBS,
4894                             comm->buf_int+ncg_recv*DD_CGIBS, rbuf[0]*DD_CGIBS);
4895
4896             nvs = ncg[cdd] + nat[cdd]*nvec;
4897             i   = rbuf[0]  + rbuf[1] *nvec;
4898             vec_rvec_check_alloc(&comm->vbuf, nvr+i);
4899
4900             /* Communicate cgcm and state */
4901             dd_sendrecv_rvec(dd, d, dir,
4902                              comm->cgcm_state[cdd], nvs,
4903                              comm->vbuf.v+nvr, i);
4904             ncg_recv += rbuf[0];
4905             nat_recv += rbuf[1];
4906             nvr      += i;
4907         }
4908
4909         /* Process the received charge groups */
4910         buf_pos = 0;
4911         for (cg = 0; cg < ncg_recv; cg++)
4912         {
4913             flag = comm->buf_int[cg*DD_CGIBS+1];
4914
4915             if (dim >= npbcdim && dd->nc[dim] > 2)
4916             {
4917                 /* No pbc in this dim and more than one domain boundary.
4918                  * We do a separate check if a charge group didn't move too far.
4919                  */
4920                 if (((flag & DD_FLAG_FW(d)) &&
4921                      comm->vbuf.v[buf_pos][dim] > cell_x1[dim]) ||
4922                     ((flag & DD_FLAG_BW(d)) &&
4923                      comm->vbuf.v[buf_pos][dim] < cell_x0[dim]))
4924                 {
4925                     cg_move_error(fplog, dd, step, cg, dim,
4926                                   (flag & DD_FLAG_FW(d)) ? 1 : 0,
4927                                   FALSE, 0,
4928                                   comm->vbuf.v[buf_pos],
4929                                   comm->vbuf.v[buf_pos],
4930                                   comm->vbuf.v[buf_pos][dim]);
4931                 }
4932             }
4933
4934             mc = -1;
4935             if (d < dd->ndim-1)
4936             {
4937                 /* Check which direction this cg should go */
4938                 for (d2 = d+1; (d2 < dd->ndim && mc == -1); d2++)
4939                 {
4940                     if (dd->bGridJump)
4941                     {
4942                         /* The cell boundaries for dimension d2 are not equal
4943                          * for each cell row of the lower dimension(s),
4944                          * therefore we might need to redetermine where
4945                          * this cg should go.
4946                          */
4947                         dim2 = dd->dim[d2];
4948                         /* If this cg crosses the box boundary in dimension d2
4949                          * we can use the communicated flag, so we do not
4950                          * have to worry about pbc.
4951                          */
4952                         if (!((dd->ci[dim2] == dd->nc[dim2]-1 &&
4953                                (flag & DD_FLAG_FW(d2))) ||
4954                               (dd->ci[dim2] == 0 &&
4955                                (flag & DD_FLAG_BW(d2)))))
4956                         {
4957                             /* Clear the two flags for this dimension */
4958                             flag &= ~(DD_FLAG_FW(d2) | DD_FLAG_BW(d2));
4959                             /* Determine the location of this cg
4960                              * in lattice coordinates
4961                              */
4962                             pos_d = comm->vbuf.v[buf_pos][dim2];
4963                             if (tric_dir[dim2])
4964                             {
4965                                 for (d3 = dim2+1; d3 < DIM; d3++)
4966                                 {
4967                                     pos_d +=
4968                                         comm->vbuf.v[buf_pos][d3]*tcm[d3][dim2];
4969                                 }
4970                             }
4971                             /* Check of we are not at the box edge.
4972                              * pbc is only handled in the first step above,
4973                              * but this check could move over pbc while
4974                              * the first step did not due to different rounding.
4975                              */
4976                             if (pos_d >= cell_x1[dim2] &&
4977                                 dd->ci[dim2] != dd->nc[dim2]-1)
4978                             {
4979                                 flag |= DD_FLAG_FW(d2);
4980                             }
4981                             else if (pos_d < cell_x0[dim2] &&
4982                                      dd->ci[dim2] != 0)
4983                             {
4984                                 flag |= DD_FLAG_BW(d2);
4985                             }
4986                             comm->buf_int[cg*DD_CGIBS+1] = flag;
4987                         }
4988                     }
4989                     /* Set to which neighboring cell this cg should go */
4990                     if (flag & DD_FLAG_FW(d2))
4991                     {
4992                         mc = d2*2;
4993                     }
4994                     else if (flag & DD_FLAG_BW(d2))
4995                     {
4996                         if (dd->nc[dd->dim[d2]] > 2)
4997                         {
4998                             mc = d2*2+1;
4999                         }
5000                         else
5001                         {
5002                             mc = d2*2;
5003                         }
5004                     }
5005                 }
5006             }
5007
5008             nrcg = flag & DD_FLAG_NRCG;
5009             if (mc == -1)
5010             {
5011                 if (home_pos_cg+1 > dd->cg_nalloc)
5012                 {
5013                     dd->cg_nalloc = over_alloc_dd(home_pos_cg+1);
5014                     srenew(dd->index_gl, dd->cg_nalloc);
5015                     srenew(dd->cgindex, dd->cg_nalloc+1);
5016                 }
5017                 /* Set the global charge group index and size */
5018                 dd->index_gl[home_pos_cg]  = comm->buf_int[cg*DD_CGIBS];
5019                 dd->cgindex[home_pos_cg+1] = dd->cgindex[home_pos_cg] + nrcg;
5020                 /* Copy the state from the buffer */
5021                 dd_check_alloc_ncg(fr, state, f, home_pos_cg+1);
5022                 if (fr->cutoff_scheme == ecutsGROUP)
5023                 {
5024                     cg_cm = fr->cg_cm;
5025                     copy_rvec(comm->vbuf.v[buf_pos], cg_cm[home_pos_cg]);
5026                 }
5027                 buf_pos++;
5028
5029                 /* Set the cginfo */
5030                 fr->cginfo[home_pos_cg] = ddcginfo(cginfo_mb,
5031                                                    dd->index_gl[home_pos_cg]);
5032                 if (comm->bLocalCG)
5033                 {
5034                     comm->bLocalCG[dd->index_gl[home_pos_cg]] = TRUE;
5035                 }
5036
5037                 if (home_pos_at+nrcg > state->nalloc)
5038                 {
5039                     dd_realloc_state(state, f, home_pos_at+nrcg);
5040                 }
5041                 for (i = 0; i < nrcg; i++)
5042                 {
5043                     copy_rvec(comm->vbuf.v[buf_pos++],
5044                               state->x[home_pos_at+i]);
5045                 }
5046                 if (bV)
5047                 {
5048                     for (i = 0; i < nrcg; i++)
5049                     {
5050                         copy_rvec(comm->vbuf.v[buf_pos++],
5051                                   state->v[home_pos_at+i]);
5052                     }
5053                 }
5054                 if (bSDX)
5055                 {
5056                     for (i = 0; i < nrcg; i++)
5057                     {
5058                         copy_rvec(comm->vbuf.v[buf_pos++],
5059                                   state->sd_X[home_pos_at+i]);
5060                     }
5061                 }
5062                 if (bCGP)
5063                 {
5064                     for (i = 0; i < nrcg; i++)
5065                     {
5066                         copy_rvec(comm->vbuf.v[buf_pos++],
5067                                   state->cg_p[home_pos_at+i]);
5068                     }
5069                 }
5070                 home_pos_cg += 1;
5071                 home_pos_at += nrcg;
5072             }
5073             else
5074             {
5075                 /* Reallocate the buffers if necessary  */
5076                 if (ncg[mc]+1 > comm->cggl_flag_nalloc[mc])
5077                 {
5078                     comm->cggl_flag_nalloc[mc] = over_alloc_dd(ncg[mc]+1);
5079                     srenew(comm->cggl_flag[mc], comm->cggl_flag_nalloc[mc]*DD_CGIBS);
5080                 }
5081                 nvr = ncg[mc] + nat[mc]*nvec;
5082                 if (nvr + 1 + nrcg*nvec > comm->cgcm_state_nalloc[mc])
5083                 {
5084                     comm->cgcm_state_nalloc[mc] = over_alloc_dd(nvr + 1 + nrcg*nvec);
5085                     srenew(comm->cgcm_state[mc], comm->cgcm_state_nalloc[mc]);
5086                 }
5087                 /* Copy from the receive to the send buffers */
5088                 memcpy(comm->cggl_flag[mc] + ncg[mc]*DD_CGIBS,
5089                        comm->buf_int + cg*DD_CGIBS,
5090                        DD_CGIBS*sizeof(int));
5091                 memcpy(comm->cgcm_state[mc][nvr],
5092                        comm->vbuf.v[buf_pos],
5093                        (1+nrcg*nvec)*sizeof(rvec));
5094                 buf_pos += 1 + nrcg*nvec;
5095                 ncg[mc] += 1;
5096                 nat[mc] += nrcg;
5097             }
5098         }
5099     }
5100
5101     /* With sorting (!bCompact) the indices are now only partially up to date
5102      * and ncg_home and nat_home are not the real count, since there are
5103      * "holes" in the arrays for the charge groups that moved to neighbors.
5104      */
5105     if (fr->cutoff_scheme == ecutsVERLET)
5106     {
5107         moved = get_moved(comm, home_pos_cg);
5108
5109         for (i = dd->ncg_home; i < home_pos_cg; i++)
5110         {
5111             moved[i] = 0;
5112         }
5113     }
5114     dd->ncg_home = home_pos_cg;
5115     dd->nat_home = home_pos_at;
5116
5117     if (debug)
5118     {
5119         fprintf(debug,
5120                 "Finished repartitioning: cgs moved out %d, new home %d\n",
5121                 *ncg_moved, dd->ncg_home-*ncg_moved);
5122
5123     }
5124 }
5125
5126 void dd_cycles_add(gmx_domdec_t *dd, float cycles, int ddCycl)
5127 {
5128     dd->comm->cycl[ddCycl] += cycles;
5129     dd->comm->cycl_n[ddCycl]++;
5130     if (cycles > dd->comm->cycl_max[ddCycl])
5131     {
5132         dd->comm->cycl_max[ddCycl] = cycles;
5133     }
5134 }
5135
5136 static double force_flop_count(t_nrnb *nrnb)
5137 {
5138     int         i;
5139     double      sum;
5140     const char *name;
5141
5142     sum = 0;
5143     for (i = 0; i < eNR_NBKERNEL_FREE_ENERGY; i++)
5144     {
5145         /* To get closer to the real timings, we half the count
5146          * for the normal loops and again half it for water loops.
5147          */
5148         name = nrnb_str(i);
5149         if (strstr(name, "W3") != NULL || strstr(name, "W4") != NULL)
5150         {
5151             sum += nrnb->n[i]*0.25*cost_nrnb(i);
5152         }
5153         else
5154         {
5155             sum += nrnb->n[i]*0.50*cost_nrnb(i);
5156         }
5157     }
5158     for (i = eNR_NBKERNEL_FREE_ENERGY; i <= eNR_NB14; i++)
5159     {
5160         name = nrnb_str(i);
5161         if (strstr(name, "W3") != NULL || strstr(name, "W4") != NULL)
5162         {
5163             sum += nrnb->n[i]*cost_nrnb(i);
5164         }
5165     }
5166     for (i = eNR_BONDS; i <= eNR_WALLS; i++)
5167     {
5168         sum += nrnb->n[i]*cost_nrnb(i);
5169     }
5170
5171     return sum;
5172 }
5173
5174 void dd_force_flop_start(gmx_domdec_t *dd, t_nrnb *nrnb)
5175 {
5176     if (dd->comm->eFlop)
5177     {
5178         dd->comm->flop -= force_flop_count(nrnb);
5179     }
5180 }
5181 void dd_force_flop_stop(gmx_domdec_t *dd, t_nrnb *nrnb)
5182 {
5183     if (dd->comm->eFlop)
5184     {
5185         dd->comm->flop += force_flop_count(nrnb);
5186         dd->comm->flop_n++;
5187     }
5188 }
5189
5190 static void clear_dd_cycle_counts(gmx_domdec_t *dd)
5191 {
5192     int i;
5193
5194     for (i = 0; i < ddCyclNr; i++)
5195     {
5196         dd->comm->cycl[i]     = 0;
5197         dd->comm->cycl_n[i]   = 0;
5198         dd->comm->cycl_max[i] = 0;
5199     }
5200     dd->comm->flop   = 0;
5201     dd->comm->flop_n = 0;
5202 }
5203
5204 static void get_load_distribution(gmx_domdec_t *dd, gmx_wallcycle_t wcycle)
5205 {
5206     gmx_domdec_comm_t *comm;
5207     gmx_domdec_load_t *load;
5208     gmx_domdec_root_t *root = NULL;
5209     int                d, dim, cid, i, pos;
5210     float              cell_frac = 0, sbuf[DD_NLOAD_MAX];
5211     gmx_bool           bSepPME;
5212
5213     if (debug)
5214     {
5215         fprintf(debug, "get_load_distribution start\n");
5216     }
5217
5218     wallcycle_start(wcycle, ewcDDCOMMLOAD);
5219
5220     comm = dd->comm;
5221
5222     bSepPME = (dd->pme_nodeid >= 0);
5223
5224     for (d = dd->ndim-1; d >= 0; d--)
5225     {
5226         dim = dd->dim[d];
5227         /* Check if we participate in the communication in this dimension */
5228         if (d == dd->ndim-1 ||
5229             (dd->ci[dd->dim[d+1]] == 0 && dd->ci[dd->dim[dd->ndim-1]] == 0))
5230         {
5231             load = &comm->load[d];
5232             if (dd->bGridJump)
5233             {
5234                 cell_frac = comm->cell_f1[d] - comm->cell_f0[d];
5235             }
5236             pos = 0;
5237             if (d == dd->ndim-1)
5238             {
5239                 sbuf[pos++] = dd_force_load(comm);
5240                 sbuf[pos++] = sbuf[0];
5241                 if (dd->bGridJump)
5242                 {
5243                     sbuf[pos++] = sbuf[0];
5244                     sbuf[pos++] = cell_frac;
5245                     if (d > 0)
5246                     {
5247                         sbuf[pos++] = comm->cell_f_max0[d];
5248                         sbuf[pos++] = comm->cell_f_min1[d];
5249                     }
5250                 }
5251                 if (bSepPME)
5252                 {
5253                     sbuf[pos++] = comm->cycl[ddCyclPPduringPME];
5254                     sbuf[pos++] = comm->cycl[ddCyclPME];
5255                 }
5256             }
5257             else
5258             {
5259                 sbuf[pos++] = comm->load[d+1].sum;
5260                 sbuf[pos++] = comm->load[d+1].max;
5261                 if (dd->bGridJump)
5262                 {
5263                     sbuf[pos++] = comm->load[d+1].sum_m;
5264                     sbuf[pos++] = comm->load[d+1].cvol_min*cell_frac;
5265                     sbuf[pos++] = comm->load[d+1].flags;
5266                     if (d > 0)
5267                     {
5268                         sbuf[pos++] = comm->cell_f_max0[d];
5269                         sbuf[pos++] = comm->cell_f_min1[d];
5270                     }
5271                 }
5272                 if (bSepPME)
5273                 {
5274                     sbuf[pos++] = comm->load[d+1].mdf;
5275                     sbuf[pos++] = comm->load[d+1].pme;
5276                 }
5277             }
5278             load->nload = pos;
5279             /* Communicate a row in DD direction d.
5280              * The communicators are setup such that the root always has rank 0.
5281              */
5282 #ifdef GMX_MPI
5283             MPI_Gather(sbuf, load->nload*sizeof(float), MPI_BYTE,
5284                        load->load, load->nload*sizeof(float), MPI_BYTE,
5285                        0, comm->mpi_comm_load[d]);
5286 #endif
5287             if (dd->ci[dim] == dd->master_ci[dim])
5288             {
5289                 /* We are the root, process this row */
5290                 if (comm->bDynLoadBal)
5291                 {
5292                     root = comm->root[d];
5293                 }
5294                 load->sum      = 0;
5295                 load->max      = 0;
5296                 load->sum_m    = 0;
5297                 load->cvol_min = 1;
5298                 load->flags    = 0;
5299                 load->mdf      = 0;
5300                 load->pme      = 0;
5301                 pos            = 0;
5302                 for (i = 0; i < dd->nc[dim]; i++)
5303                 {
5304                     load->sum += load->load[pos++];
5305                     load->max  = max(load->max, load->load[pos]);
5306                     pos++;
5307                     if (dd->bGridJump)
5308                     {
5309                         if (root->bLimited)
5310                         {
5311                             /* This direction could not be load balanced properly,
5312                              * therefore we need to use the maximum iso the average load.
5313                              */
5314                             load->sum_m = max(load->sum_m, load->load[pos]);
5315                         }
5316                         else
5317                         {
5318                             load->sum_m += load->load[pos];
5319                         }
5320                         pos++;
5321                         load->cvol_min = min(load->cvol_min, load->load[pos]);
5322                         pos++;
5323                         if (d < dd->ndim-1)
5324                         {
5325                             load->flags = (int)(load->load[pos++] + 0.5);
5326                         }
5327                         if (d > 0)
5328                         {
5329                             root->cell_f_max0[i] = load->load[pos++];
5330                             root->cell_f_min1[i] = load->load[pos++];
5331                         }
5332                     }
5333                     if (bSepPME)
5334                     {
5335                         load->mdf = max(load->mdf, load->load[pos]);
5336                         pos++;
5337                         load->pme = max(load->pme, load->load[pos]);
5338                         pos++;
5339                     }
5340                 }
5341                 if (comm->bDynLoadBal && root->bLimited)
5342                 {
5343                     load->sum_m *= dd->nc[dim];
5344                     load->flags |= (1<<d);
5345                 }
5346             }
5347         }
5348     }
5349
5350     if (DDMASTER(dd))
5351     {
5352         comm->nload      += dd_load_count(comm);
5353         comm->load_step  += comm->cycl[ddCyclStep];
5354         comm->load_sum   += comm->load[0].sum;
5355         comm->load_max   += comm->load[0].max;
5356         if (comm->bDynLoadBal)
5357         {
5358             for (d = 0; d < dd->ndim; d++)
5359             {
5360                 if (comm->load[0].flags & (1<<d))
5361                 {
5362                     comm->load_lim[d]++;
5363                 }
5364             }
5365         }
5366         if (bSepPME)
5367         {
5368             comm->load_mdf += comm->load[0].mdf;
5369             comm->load_pme += comm->load[0].pme;
5370         }
5371     }
5372
5373     wallcycle_stop(wcycle, ewcDDCOMMLOAD);
5374
5375     if (debug)
5376     {
5377         fprintf(debug, "get_load_distribution finished\n");
5378     }
5379 }
5380
5381 static float dd_force_imb_perf_loss(gmx_domdec_t *dd)
5382 {
5383     /* Return the relative performance loss on the total run time
5384      * due to the force calculation load imbalance.
5385      */
5386     if (dd->comm->nload > 0)
5387     {
5388         return
5389             (dd->comm->load_max*dd->nnodes - dd->comm->load_sum)/
5390             (dd->comm->load_step*dd->nnodes);
5391     }
5392     else
5393     {
5394         return 0;
5395     }
5396 }
5397
5398 static void print_dd_load_av(FILE *fplog, gmx_domdec_t *dd)
5399 {
5400     char               buf[STRLEN];
5401     int                npp, npme, nnodes, d, limp;
5402     float              imbal, pme_f_ratio, lossf, lossp = 0;
5403     gmx_bool           bLim;
5404     gmx_domdec_comm_t *comm;
5405
5406     comm = dd->comm;
5407     if (DDMASTER(dd) && comm->nload > 0)
5408     {
5409         npp    = dd->nnodes;
5410         npme   = (dd->pme_nodeid >= 0) ? comm->npmenodes : 0;
5411         nnodes = npp + npme;
5412         imbal  = comm->load_max*npp/comm->load_sum - 1;
5413         lossf  = dd_force_imb_perf_loss(dd);
5414         sprintf(buf, " Average load imbalance: %.1f %%\n", imbal*100);
5415         fprintf(fplog, "%s", buf);
5416         fprintf(stderr, "\n");
5417         fprintf(stderr, "%s", buf);
5418         sprintf(buf, " Part of the total run time spent waiting due to load imbalance: %.1f %%\n", lossf*100);
5419         fprintf(fplog, "%s", buf);
5420         fprintf(stderr, "%s", buf);
5421         bLim = FALSE;
5422         if (comm->bDynLoadBal)
5423         {
5424             sprintf(buf, " Steps where the load balancing was limited by -rdd, -rcon and/or -dds:");
5425             for (d = 0; d < dd->ndim; d++)
5426             {
5427                 limp = (200*comm->load_lim[d]+1)/(2*comm->nload);
5428                 sprintf(buf+strlen(buf), " %c %d %%", dim2char(dd->dim[d]), limp);
5429                 if (limp >= 50)
5430                 {
5431                     bLim = TRUE;
5432                 }
5433             }
5434             sprintf(buf+strlen(buf), "\n");
5435             fprintf(fplog, "%s", buf);
5436             fprintf(stderr, "%s", buf);
5437         }
5438         if (npme > 0)
5439         {
5440             pme_f_ratio = comm->load_pme/comm->load_mdf;
5441             lossp       = (comm->load_pme -comm->load_mdf)/comm->load_step;
5442             if (lossp <= 0)
5443             {
5444                 lossp *= (float)npme/(float)nnodes;
5445             }
5446             else
5447             {
5448                 lossp *= (float)npp/(float)nnodes;
5449             }
5450             sprintf(buf, " Average PME mesh/force load: %5.3f\n", pme_f_ratio);
5451             fprintf(fplog, "%s", buf);
5452             fprintf(stderr, "%s", buf);
5453             sprintf(buf, " Part of the total run time spent waiting due to PP/PME imbalance: %.1f %%\n", fabs(lossp)*100);
5454             fprintf(fplog, "%s", buf);
5455             fprintf(stderr, "%s", buf);
5456         }
5457         fprintf(fplog, "\n");
5458         fprintf(stderr, "\n");
5459
5460         if (lossf >= DD_PERF_LOSS)
5461         {
5462             sprintf(buf,
5463                     "NOTE: %.1f %% of the available CPU time was lost due to load imbalance\n"
5464                     "      in the domain decomposition.\n", lossf*100);
5465             if (!comm->bDynLoadBal)
5466             {
5467                 sprintf(buf+strlen(buf), "      You might want to use dynamic load balancing (option -dlb.)\n");
5468             }
5469             else if (bLim)
5470             {
5471                 sprintf(buf+strlen(buf), "      You might want to decrease the cell size limit (options -rdd, -rcon and/or -dds).\n");
5472             }
5473             fprintf(fplog, "%s\n", buf);
5474             fprintf(stderr, "%s\n", buf);
5475         }
5476         if (npme > 0 && fabs(lossp) >= DD_PERF_LOSS)
5477         {
5478             sprintf(buf,
5479                     "NOTE: %.1f %% performance was lost because the PME nodes\n"
5480                     "      had %s work to do than the PP nodes.\n"
5481                     "      You might want to %s the number of PME nodes\n"
5482                     "      or %s the cut-off and the grid spacing.\n",
5483                     fabs(lossp*100),
5484                     (lossp < 0) ? "less"     : "more",
5485                     (lossp < 0) ? "decrease" : "increase",
5486                     (lossp < 0) ? "decrease" : "increase");
5487             fprintf(fplog, "%s\n", buf);
5488             fprintf(stderr, "%s\n", buf);
5489         }
5490     }
5491 }
5492
5493 static float dd_vol_min(gmx_domdec_t *dd)
5494 {
5495     return dd->comm->load[0].cvol_min*dd->nnodes;
5496 }
5497
5498 static gmx_bool dd_load_flags(gmx_domdec_t *dd)
5499 {
5500     return dd->comm->load[0].flags;
5501 }
5502
5503 static float dd_f_imbal(gmx_domdec_t *dd)
5504 {
5505     return dd->comm->load[0].max*dd->nnodes/dd->comm->load[0].sum - 1;
5506 }
5507
5508 float dd_pme_f_ratio(gmx_domdec_t *dd)
5509 {
5510     if (dd->comm->cycl_n[ddCyclPME] > 0)
5511     {
5512         return dd->comm->load[0].pme/dd->comm->load[0].mdf;
5513     }
5514     else
5515     {
5516         return -1.0;
5517     }
5518 }
5519
5520 static void dd_print_load(FILE *fplog, gmx_domdec_t *dd, gmx_large_int_t step)
5521 {
5522     int  flags, d;
5523     char buf[22];
5524
5525     flags = dd_load_flags(dd);
5526     if (flags)
5527     {
5528         fprintf(fplog,
5529                 "DD  load balancing is limited by minimum cell size in dimension");
5530         for (d = 0; d < dd->ndim; d++)
5531         {
5532             if (flags & (1<<d))
5533             {
5534                 fprintf(fplog, " %c", dim2char(dd->dim[d]));
5535             }
5536         }
5537         fprintf(fplog, "\n");
5538     }
5539     fprintf(fplog, "DD  step %s", gmx_step_str(step, buf));
5540     if (dd->comm->bDynLoadBal)
5541     {
5542         fprintf(fplog, "  vol min/aver %5.3f%c",
5543                 dd_vol_min(dd), flags ? '!' : ' ');
5544     }
5545     fprintf(fplog, " load imb.: force %4.1f%%", dd_f_imbal(dd)*100);
5546     if (dd->comm->cycl_n[ddCyclPME])
5547     {
5548         fprintf(fplog, "  pme mesh/force %5.3f", dd_pme_f_ratio(dd));
5549     }
5550     fprintf(fplog, "\n\n");
5551 }
5552
5553 static void dd_print_load_verbose(gmx_domdec_t *dd)
5554 {
5555     if (dd->comm->bDynLoadBal)
5556     {
5557         fprintf(stderr, "vol %4.2f%c ",
5558                 dd_vol_min(dd), dd_load_flags(dd) ? '!' : ' ');
5559     }
5560     fprintf(stderr, "imb F %2d%% ", (int)(dd_f_imbal(dd)*100+0.5));
5561     if (dd->comm->cycl_n[ddCyclPME])
5562     {
5563         fprintf(stderr, "pme/F %4.2f ", dd_pme_f_ratio(dd));
5564     }
5565 }
5566
5567 #ifdef GMX_MPI
5568 static void make_load_communicator(gmx_domdec_t *dd, int dim_ind, ivec loc)
5569 {
5570     MPI_Comm           c_row;
5571     int                dim, i, rank;
5572     ivec               loc_c;
5573     gmx_domdec_root_t *root;
5574     gmx_bool           bPartOfGroup = FALSE;
5575
5576     dim = dd->dim[dim_ind];
5577     copy_ivec(loc, loc_c);
5578     for (i = 0; i < dd->nc[dim]; i++)
5579     {
5580         loc_c[dim] = i;
5581         rank       = dd_index(dd->nc, loc_c);
5582         if (rank == dd->rank)
5583         {
5584             /* This process is part of the group */
5585             bPartOfGroup = TRUE;
5586         }
5587     }
5588     MPI_Comm_split(dd->mpi_comm_all, bPartOfGroup ? 0 : MPI_UNDEFINED, dd->rank,
5589                    &c_row);
5590     if (bPartOfGroup)
5591     {
5592         dd->comm->mpi_comm_load[dim_ind] = c_row;
5593         if (dd->comm->eDLB != edlbNO)
5594         {
5595             if (dd->ci[dim] == dd->master_ci[dim])
5596             {
5597                 /* This is the root process of this row */
5598                 snew(dd->comm->root[dim_ind], 1);
5599                 root = dd->comm->root[dim_ind];
5600                 snew(root->cell_f, DD_CELL_F_SIZE(dd, dim_ind));
5601                 snew(root->old_cell_f, dd->nc[dim]+1);
5602                 snew(root->bCellMin, dd->nc[dim]);
5603                 if (dim_ind > 0)
5604                 {
5605                     snew(root->cell_f_max0, dd->nc[dim]);
5606                     snew(root->cell_f_min1, dd->nc[dim]);
5607                     snew(root->bound_min, dd->nc[dim]);
5608                     snew(root->bound_max, dd->nc[dim]);
5609                 }
5610                 snew(root->buf_ncd, dd->nc[dim]);
5611             }
5612             else
5613             {
5614                 /* This is not a root process, we only need to receive cell_f */
5615                 snew(dd->comm->cell_f_row, DD_CELL_F_SIZE(dd, dim_ind));
5616             }
5617         }
5618         if (dd->ci[dim] == dd->master_ci[dim])
5619         {
5620             snew(dd->comm->load[dim_ind].load, dd->nc[dim]*DD_NLOAD_MAX);
5621         }
5622     }
5623 }
5624 #endif
5625
5626 static void make_load_communicators(gmx_domdec_t *dd)
5627 {
5628 #ifdef GMX_MPI
5629     int  dim0, dim1, i, j;
5630     ivec loc;
5631
5632     if (debug)
5633     {
5634         fprintf(debug, "Making load communicators\n");
5635     }
5636
5637     snew(dd->comm->load, dd->ndim);
5638     snew(dd->comm->mpi_comm_load, dd->ndim);
5639
5640     clear_ivec(loc);
5641     make_load_communicator(dd, 0, loc);
5642     if (dd->ndim > 1)
5643     {
5644         dim0 = dd->dim[0];
5645         for (i = 0; i < dd->nc[dim0]; i++)
5646         {
5647             loc[dim0] = i;
5648             make_load_communicator(dd, 1, loc);
5649         }
5650     }
5651     if (dd->ndim > 2)
5652     {
5653         dim0 = dd->dim[0];
5654         for (i = 0; i < dd->nc[dim0]; i++)
5655         {
5656             loc[dim0] = i;
5657             dim1      = dd->dim[1];
5658             for (j = 0; j < dd->nc[dim1]; j++)
5659             {
5660                 loc[dim1] = j;
5661                 make_load_communicator(dd, 2, loc);
5662             }
5663         }
5664     }
5665
5666     if (debug)
5667     {
5668         fprintf(debug, "Finished making load communicators\n");
5669     }
5670 #endif
5671 }
5672
5673 void setup_dd_grid(FILE *fplog, gmx_domdec_t *dd)
5674 {
5675     gmx_bool                bZYX;
5676     int                     d, dim, i, j, m;
5677     ivec                    tmp, s;
5678     int                     nzone, nzonep;
5679     ivec                    dd_zp[DD_MAXIZONE];
5680     gmx_domdec_zones_t     *zones;
5681     gmx_domdec_ns_ranges_t *izone;
5682
5683     for (d = 0; d < dd->ndim; d++)
5684     {
5685         dim = dd->dim[d];
5686         copy_ivec(dd->ci, tmp);
5687         tmp[dim]           = (tmp[dim] + 1) % dd->nc[dim];
5688         dd->neighbor[d][0] = ddcoord2ddnodeid(dd, tmp);
5689         copy_ivec(dd->ci, tmp);
5690         tmp[dim]           = (tmp[dim] - 1 + dd->nc[dim]) % dd->nc[dim];
5691         dd->neighbor[d][1] = ddcoord2ddnodeid(dd, tmp);
5692         if (debug)
5693         {
5694             fprintf(debug, "DD rank %d neighbor ranks in dir %d are + %d - %d\n",
5695                     dd->rank, dim,
5696                     dd->neighbor[d][0],
5697                     dd->neighbor[d][1]);
5698         }
5699     }
5700
5701     if (fplog)
5702     {
5703         fprintf(fplog, "\nMaking %dD domain decomposition grid %d x %d x %d, home cell index %d %d %d\n\n",
5704                 dd->ndim,
5705                 dd->nc[XX], dd->nc[YY], dd->nc[ZZ],
5706                 dd->ci[XX], dd->ci[YY], dd->ci[ZZ]);
5707     }
5708     switch (dd->ndim)
5709     {
5710         case 3:
5711             nzone  = dd_z3n;
5712             nzonep = dd_zp3n;
5713             for (i = 0; i < nzonep; i++)
5714             {
5715                 copy_ivec(dd_zp3[i], dd_zp[i]);
5716             }
5717             break;
5718         case 2:
5719             nzone  = dd_z2n;
5720             nzonep = dd_zp2n;
5721             for (i = 0; i < nzonep; i++)
5722             {
5723                 copy_ivec(dd_zp2[i], dd_zp[i]);
5724             }
5725             break;
5726         case 1:
5727             nzone  = dd_z1n;
5728             nzonep = dd_zp1n;
5729             for (i = 0; i < nzonep; i++)
5730             {
5731                 copy_ivec(dd_zp1[i], dd_zp[i]);
5732             }
5733             break;
5734         default:
5735             gmx_fatal(FARGS, "Can only do 1, 2 or 3D domain decomposition");
5736             nzone  = 0;
5737             nzonep = 0;
5738     }
5739
5740     zones = &dd->comm->zones;
5741
5742     for (i = 0; i < nzone; i++)
5743     {
5744         m = 0;
5745         clear_ivec(zones->shift[i]);
5746         for (d = 0; d < dd->ndim; d++)
5747         {
5748             zones->shift[i][dd->dim[d]] = dd_zo[i][m++];
5749         }
5750     }
5751
5752     zones->n = nzone;
5753     for (i = 0; i < nzone; i++)
5754     {
5755         for (d = 0; d < DIM; d++)
5756         {
5757             s[d] = dd->ci[d] - zones->shift[i][d];
5758             if (s[d] < 0)
5759             {
5760                 s[d] += dd->nc[d];
5761             }
5762             else if (s[d] >= dd->nc[d])
5763             {
5764                 s[d] -= dd->nc[d];
5765             }
5766         }
5767     }
5768     zones->nizone = nzonep;
5769     for (i = 0; i < zones->nizone; i++)
5770     {
5771         if (dd_zp[i][0] != i)
5772         {
5773             gmx_fatal(FARGS, "Internal inconsistency in the dd grid setup");
5774         }
5775         izone     = &zones->izone[i];
5776         izone->j0 = dd_zp[i][1];
5777         izone->j1 = dd_zp[i][2];
5778         for (dim = 0; dim < DIM; dim++)
5779         {
5780             if (dd->nc[dim] == 1)
5781             {
5782                 /* All shifts should be allowed */
5783                 izone->shift0[dim] = -1;
5784                 izone->shift1[dim] = 1;
5785             }
5786             else
5787             {
5788                 /*
5789                    izone->shift0[d] = 0;
5790                    izone->shift1[d] = 0;
5791                    for(j=izone->j0; j<izone->j1; j++) {
5792                    if (dd->shift[j][d] > dd->shift[i][d])
5793                    izone->shift0[d] = -1;
5794                    if (dd->shift[j][d] < dd->shift[i][d])
5795                    izone->shift1[d] = 1;
5796                    }
5797                  */
5798
5799                 int shift_diff;
5800
5801                 /* Assume the shift are not more than 1 cell */
5802                 izone->shift0[dim] = 1;
5803                 izone->shift1[dim] = -1;
5804                 for (j = izone->j0; j < izone->j1; j++)
5805                 {
5806                     shift_diff = zones->shift[j][dim] - zones->shift[i][dim];
5807                     if (shift_diff < izone->shift0[dim])
5808                     {
5809                         izone->shift0[dim] = shift_diff;
5810                     }
5811                     if (shift_diff > izone->shift1[dim])
5812                     {
5813                         izone->shift1[dim] = shift_diff;
5814                     }
5815                 }
5816             }
5817         }
5818     }
5819
5820     if (dd->comm->eDLB != edlbNO)
5821     {
5822         snew(dd->comm->root, dd->ndim);
5823     }
5824
5825     if (dd->comm->bRecordLoad)
5826     {
5827         make_load_communicators(dd);
5828     }
5829 }
5830
5831 static void make_pp_communicator(FILE *fplog, t_commrec *cr, int reorder)
5832 {
5833     gmx_domdec_t      *dd;
5834     gmx_domdec_comm_t *comm;
5835     int                i, rank, *buf;
5836     ivec               periods;
5837 #ifdef GMX_MPI
5838     MPI_Comm           comm_cart;
5839 #endif
5840
5841     dd   = cr->dd;
5842     comm = dd->comm;
5843
5844 #ifdef GMX_MPI
5845     if (comm->bCartesianPP)
5846     {
5847         /* Set up cartesian communication for the particle-particle part */
5848         if (fplog)
5849         {
5850             fprintf(fplog, "Will use a Cartesian communicator: %d x %d x %d\n",
5851                     dd->nc[XX], dd->nc[YY], dd->nc[ZZ]);
5852         }
5853
5854         for (i = 0; i < DIM; i++)
5855         {
5856             periods[i] = TRUE;
5857         }
5858         MPI_Cart_create(cr->mpi_comm_mygroup, DIM, dd->nc, periods, reorder,
5859                         &comm_cart);
5860         /* We overwrite the old communicator with the new cartesian one */
5861         cr->mpi_comm_mygroup = comm_cart;
5862     }
5863
5864     dd->mpi_comm_all = cr->mpi_comm_mygroup;
5865     MPI_Comm_rank(dd->mpi_comm_all, &dd->rank);
5866
5867     if (comm->bCartesianPP_PME)
5868     {
5869         /* Since we want to use the original cartesian setup for sim,
5870          * and not the one after split, we need to make an index.
5871          */
5872         snew(comm->ddindex2ddnodeid, dd->nnodes);
5873         comm->ddindex2ddnodeid[dd_index(dd->nc, dd->ci)] = dd->rank;
5874         gmx_sumi(dd->nnodes, comm->ddindex2ddnodeid, cr);
5875         /* Get the rank of the DD master,
5876          * above we made sure that the master node is a PP node.
5877          */
5878         if (MASTER(cr))
5879         {
5880             rank = dd->rank;
5881         }
5882         else
5883         {
5884             rank = 0;
5885         }
5886         MPI_Allreduce(&rank, &dd->masterrank, 1, MPI_INT, MPI_SUM, dd->mpi_comm_all);
5887     }
5888     else if (comm->bCartesianPP)
5889     {
5890         if (cr->npmenodes == 0)
5891         {
5892             /* The PP communicator is also
5893              * the communicator for this simulation
5894              */
5895             cr->mpi_comm_mysim = cr->mpi_comm_mygroup;
5896         }
5897         cr->nodeid = dd->rank;
5898
5899         MPI_Cart_coords(dd->mpi_comm_all, dd->rank, DIM, dd->ci);
5900
5901         /* We need to make an index to go from the coordinates
5902          * to the nodeid of this simulation.
5903          */
5904         snew(comm->ddindex2simnodeid, dd->nnodes);
5905         snew(buf, dd->nnodes);
5906         if (cr->duty & DUTY_PP)
5907         {
5908             buf[dd_index(dd->nc, dd->ci)] = cr->sim_nodeid;
5909         }
5910         /* Communicate the ddindex to simulation nodeid index */
5911         MPI_Allreduce(buf, comm->ddindex2simnodeid, dd->nnodes, MPI_INT, MPI_SUM,
5912                       cr->mpi_comm_mysim);
5913         sfree(buf);
5914
5915         /* Determine the master coordinates and rank.
5916          * The DD master should be the same node as the master of this sim.
5917          */
5918         for (i = 0; i < dd->nnodes; i++)
5919         {
5920             if (comm->ddindex2simnodeid[i] == 0)
5921             {
5922                 ddindex2xyz(dd->nc, i, dd->master_ci);
5923                 MPI_Cart_rank(dd->mpi_comm_all, dd->master_ci, &dd->masterrank);
5924             }
5925         }
5926         if (debug)
5927         {
5928             fprintf(debug, "The master rank is %d\n", dd->masterrank);
5929         }
5930     }
5931     else
5932     {
5933         /* No Cartesian communicators */
5934         /* We use the rank in dd->comm->all as DD index */
5935         ddindex2xyz(dd->nc, dd->rank, dd->ci);
5936         /* The simulation master nodeid is 0, so the DD master rank is also 0 */
5937         dd->masterrank = 0;
5938         clear_ivec(dd->master_ci);
5939     }
5940 #endif
5941
5942     if (fplog)
5943     {
5944         fprintf(fplog,
5945                 "Domain decomposition nodeid %d, coordinates %d %d %d\n\n",
5946                 dd->rank, dd->ci[XX], dd->ci[YY], dd->ci[ZZ]);
5947     }
5948     if (debug)
5949     {
5950         fprintf(debug,
5951                 "Domain decomposition nodeid %d, coordinates %d %d %d\n\n",
5952                 dd->rank, dd->ci[XX], dd->ci[YY], dd->ci[ZZ]);
5953     }
5954 }
5955
5956 static void receive_ddindex2simnodeid(t_commrec *cr)
5957 {
5958     gmx_domdec_t      *dd;
5959
5960     gmx_domdec_comm_t *comm;
5961     int               *buf;
5962
5963     dd   = cr->dd;
5964     comm = dd->comm;
5965
5966 #ifdef GMX_MPI
5967     if (!comm->bCartesianPP_PME && comm->bCartesianPP)
5968     {
5969         snew(comm->ddindex2simnodeid, dd->nnodes);
5970         snew(buf, dd->nnodes);
5971         if (cr->duty & DUTY_PP)
5972         {
5973             buf[dd_index(dd->nc, dd->ci)] = cr->sim_nodeid;
5974         }
5975 #ifdef GMX_MPI
5976         /* Communicate the ddindex to simulation nodeid index */
5977         MPI_Allreduce(buf, comm->ddindex2simnodeid, dd->nnodes, MPI_INT, MPI_SUM,
5978                       cr->mpi_comm_mysim);
5979 #endif
5980         sfree(buf);
5981     }
5982 #endif
5983 }
5984
5985 static gmx_domdec_master_t *init_gmx_domdec_master_t(gmx_domdec_t *dd,
5986                                                      int ncg, int natoms)
5987 {
5988     gmx_domdec_master_t *ma;
5989     int                  i;
5990
5991     snew(ma, 1);
5992
5993     snew(ma->ncg, dd->nnodes);
5994     snew(ma->index, dd->nnodes+1);
5995     snew(ma->cg, ncg);
5996     snew(ma->nat, dd->nnodes);
5997     snew(ma->ibuf, dd->nnodes*2);
5998     snew(ma->cell_x, DIM);
5999     for (i = 0; i < DIM; i++)
6000     {
6001         snew(ma->cell_x[i], dd->nc[i]+1);
6002     }
6003
6004     if (dd->nnodes <= GMX_DD_NNODES_SENDRECV)
6005     {
6006         ma->vbuf = NULL;
6007     }
6008     else
6009     {
6010         snew(ma->vbuf, natoms);
6011     }
6012
6013     return ma;
6014 }
6015
6016 static void split_communicator(FILE *fplog, t_commrec *cr, int dd_node_order,
6017                                int reorder)
6018 {
6019     gmx_domdec_t      *dd;
6020     gmx_domdec_comm_t *comm;
6021     int                i, rank;
6022     gmx_bool           bDiv[DIM];
6023     ivec               periods;
6024 #ifdef GMX_MPI
6025     MPI_Comm           comm_cart;
6026 #endif
6027
6028     dd   = cr->dd;
6029     comm = dd->comm;
6030
6031     if (comm->bCartesianPP)
6032     {
6033         for (i = 1; i < DIM; i++)
6034         {
6035             bDiv[i] = ((cr->npmenodes*dd->nc[i]) % (dd->nnodes) == 0);
6036         }
6037         if (bDiv[YY] || bDiv[ZZ])
6038         {
6039             comm->bCartesianPP_PME = TRUE;
6040             /* If we have 2D PME decomposition, which is always in x+y,
6041              * we stack the PME only nodes in z.
6042              * Otherwise we choose the direction that provides the thinnest slab
6043              * of PME only nodes as this will have the least effect
6044              * on the PP communication.
6045              * But for the PME communication the opposite might be better.
6046              */
6047             if (bDiv[ZZ] && (comm->npmenodes_y > 1 ||
6048                              !bDiv[YY] ||
6049                              dd->nc[YY] > dd->nc[ZZ]))
6050             {
6051                 comm->cartpmedim = ZZ;
6052             }
6053             else
6054             {
6055                 comm->cartpmedim = YY;
6056             }
6057             comm->ntot[comm->cartpmedim]
6058                 += (cr->npmenodes*dd->nc[comm->cartpmedim])/dd->nnodes;
6059         }
6060         else if (fplog)
6061         {
6062             fprintf(fplog, "#pmenodes (%d) is not a multiple of nx*ny (%d*%d) or nx*nz (%d*%d)\n", cr->npmenodes, dd->nc[XX], dd->nc[YY], dd->nc[XX], dd->nc[ZZ]);
6063             fprintf(fplog,
6064                     "Will not use a Cartesian communicator for PP <-> PME\n\n");
6065         }
6066     }
6067
6068 #ifdef GMX_MPI
6069     if (comm->bCartesianPP_PME)
6070     {
6071         if (fplog)
6072         {
6073             fprintf(fplog, "Will use a Cartesian communicator for PP <-> PME: %d x %d x %d\n", comm->ntot[XX], comm->ntot[YY], comm->ntot[ZZ]);
6074         }
6075
6076         for (i = 0; i < DIM; i++)
6077         {
6078             periods[i] = TRUE;
6079         }
6080         MPI_Cart_create(cr->mpi_comm_mysim, DIM, comm->ntot, periods, reorder,
6081                         &comm_cart);
6082
6083         MPI_Comm_rank(comm_cart, &rank);
6084         if (MASTERNODE(cr) && rank != 0)
6085         {
6086             gmx_fatal(FARGS, "MPI rank 0 was renumbered by MPI_Cart_create, we do not allow this");
6087         }
6088
6089         /* With this assigment we loose the link to the original communicator
6090          * which will usually be MPI_COMM_WORLD, unless have multisim.
6091          */
6092         cr->mpi_comm_mysim = comm_cart;
6093         cr->sim_nodeid     = rank;
6094
6095         MPI_Cart_coords(cr->mpi_comm_mysim, cr->sim_nodeid, DIM, dd->ci);
6096
6097         if (fplog)
6098         {
6099             fprintf(fplog, "Cartesian nodeid %d, coordinates %d %d %d\n\n",
6100                     cr->sim_nodeid, dd->ci[XX], dd->ci[YY], dd->ci[ZZ]);
6101         }
6102
6103         if (dd->ci[comm->cartpmedim] < dd->nc[comm->cartpmedim])
6104         {
6105             cr->duty = DUTY_PP;
6106         }
6107         if (cr->npmenodes == 0 ||
6108             dd->ci[comm->cartpmedim] >= dd->nc[comm->cartpmedim])
6109         {
6110             cr->duty = DUTY_PME;
6111         }
6112
6113         /* Split the sim communicator into PP and PME only nodes */
6114         MPI_Comm_split(cr->mpi_comm_mysim,
6115                        cr->duty,
6116                        dd_index(comm->ntot, dd->ci),
6117                        &cr->mpi_comm_mygroup);
6118     }
6119     else
6120     {
6121         switch (dd_node_order)
6122         {
6123             case ddnoPP_PME:
6124                 if (fplog)
6125                 {
6126                     fprintf(fplog, "Order of the nodes: PP first, PME last\n");
6127                 }
6128                 break;
6129             case ddnoINTERLEAVE:
6130                 /* Interleave the PP-only and PME-only nodes,
6131                  * as on clusters with dual-core machines this will double
6132                  * the communication bandwidth of the PME processes
6133                  * and thus speed up the PP <-> PME and inter PME communication.
6134                  */
6135                 if (fplog)
6136                 {
6137                     fprintf(fplog, "Interleaving PP and PME nodes\n");
6138                 }
6139                 comm->pmenodes = dd_pmenodes(cr);
6140                 break;
6141             case ddnoCARTESIAN:
6142                 break;
6143             default:
6144                 gmx_fatal(FARGS, "Unknown dd_node_order=%d", dd_node_order);
6145         }
6146
6147         if (dd_simnode2pmenode(cr, cr->sim_nodeid) == -1)
6148         {
6149             cr->duty = DUTY_PME;
6150         }
6151         else
6152         {
6153             cr->duty = DUTY_PP;
6154         }
6155
6156         /* Split the sim communicator into PP and PME only nodes */
6157         MPI_Comm_split(cr->mpi_comm_mysim,
6158                        cr->duty,
6159                        cr->nodeid,
6160                        &cr->mpi_comm_mygroup);
6161         MPI_Comm_rank(cr->mpi_comm_mygroup, &cr->nodeid);
6162     }
6163 #endif
6164
6165     if (fplog)
6166     {
6167         fprintf(fplog, "This is a %s only node\n\n",
6168                 (cr->duty & DUTY_PP) ? "particle-particle" : "PME-mesh");
6169     }
6170 }
6171
6172 void make_dd_communicators(FILE *fplog, t_commrec *cr, int dd_node_order)
6173 {
6174     gmx_domdec_t      *dd;
6175     gmx_domdec_comm_t *comm;
6176     int                CartReorder;
6177
6178     dd   = cr->dd;
6179     comm = dd->comm;
6180
6181     copy_ivec(dd->nc, comm->ntot);
6182
6183     comm->bCartesianPP     = (dd_node_order == ddnoCARTESIAN);
6184     comm->bCartesianPP_PME = FALSE;
6185
6186     /* Reorder the nodes by default. This might change the MPI ranks.
6187      * Real reordering is only supported on very few architectures,
6188      * Blue Gene is one of them.
6189      */
6190     CartReorder = (getenv("GMX_NO_CART_REORDER") == NULL);
6191
6192     if (cr->npmenodes > 0)
6193     {
6194         /* Split the communicator into a PP and PME part */
6195         split_communicator(fplog, cr, dd_node_order, CartReorder);
6196         if (comm->bCartesianPP_PME)
6197         {
6198             /* We (possibly) reordered the nodes in split_communicator,
6199              * so it is no longer required in make_pp_communicator.
6200              */
6201             CartReorder = FALSE;
6202         }
6203     }
6204     else
6205     {
6206         /* All nodes do PP and PME */
6207 #ifdef GMX_MPI
6208         /* We do not require separate communicators */
6209         cr->mpi_comm_mygroup = cr->mpi_comm_mysim;
6210 #endif
6211     }
6212
6213     if (cr->duty & DUTY_PP)
6214     {
6215         /* Copy or make a new PP communicator */
6216         make_pp_communicator(fplog, cr, CartReorder);
6217     }
6218     else
6219     {
6220         receive_ddindex2simnodeid(cr);
6221     }
6222
6223     if (!(cr->duty & DUTY_PME))
6224     {
6225         /* Set up the commnuication to our PME node */
6226         dd->pme_nodeid           = dd_simnode2pmenode(cr, cr->sim_nodeid);
6227         dd->pme_receive_vir_ener = receive_vir_ener(cr);
6228         if (debug)
6229         {
6230             fprintf(debug, "My pme_nodeid %d receive ener %d\n",
6231                     dd->pme_nodeid, dd->pme_receive_vir_ener);
6232         }
6233     }
6234     else
6235     {
6236         dd->pme_nodeid = -1;
6237     }
6238
6239     if (DDMASTER(dd))
6240     {
6241         dd->ma = init_gmx_domdec_master_t(dd,
6242                                           comm->cgs_gl.nr,
6243                                           comm->cgs_gl.index[comm->cgs_gl.nr]);
6244     }
6245 }
6246
6247 static real *get_slb_frac(FILE *fplog, const char *dir, int nc, const char *size_string)
6248 {
6249     real  *slb_frac, tot;
6250     int    i, n;
6251     double dbl;
6252
6253     slb_frac = NULL;
6254     if (nc > 1 && size_string != NULL)
6255     {
6256         if (fplog)
6257         {
6258             fprintf(fplog, "Using static load balancing for the %s direction\n",
6259                     dir);
6260         }
6261         snew(slb_frac, nc);
6262         tot = 0;
6263         for (i = 0; i < nc; i++)
6264         {
6265             dbl = 0;
6266             sscanf(size_string, "%lf%n", &dbl, &n);
6267             if (dbl == 0)
6268             {
6269                 gmx_fatal(FARGS, "Incorrect or not enough DD cell size entries for direction %s: '%s'", dir, size_string);
6270             }
6271             slb_frac[i]  = dbl;
6272             size_string += n;
6273             tot         += slb_frac[i];
6274         }
6275         /* Normalize */
6276         if (fplog)
6277         {
6278             fprintf(fplog, "Relative cell sizes:");
6279         }
6280         for (i = 0; i < nc; i++)
6281         {
6282             slb_frac[i] /= tot;
6283             if (fplog)
6284             {
6285                 fprintf(fplog, " %5.3f", slb_frac[i]);
6286             }
6287         }
6288         if (fplog)
6289         {
6290             fprintf(fplog, "\n");
6291         }
6292     }
6293
6294     return slb_frac;
6295 }
6296
6297 static int multi_body_bondeds_count(gmx_mtop_t *mtop)
6298 {
6299     int                  n, nmol, ftype;
6300     gmx_mtop_ilistloop_t iloop;
6301     t_ilist             *il;
6302
6303     n     = 0;
6304     iloop = gmx_mtop_ilistloop_init(mtop);
6305     while (gmx_mtop_ilistloop_next(iloop, &il, &nmol))
6306     {
6307         for (ftype = 0; ftype < F_NRE; ftype++)
6308         {
6309             if ((interaction_function[ftype].flags & IF_BOND) &&
6310                 NRAL(ftype) >  2)
6311             {
6312                 n += nmol*il[ftype].nr/(1 + NRAL(ftype));
6313             }
6314         }
6315     }
6316
6317     return n;
6318 }
6319
6320 static int dd_nst_env(FILE *fplog, const char *env_var, int def)
6321 {
6322     char *val;
6323     int   nst;
6324
6325     nst = def;
6326     val = getenv(env_var);
6327     if (val)
6328     {
6329         if (sscanf(val, "%d", &nst) <= 0)
6330         {
6331             nst = 1;
6332         }
6333         if (fplog)
6334         {
6335             fprintf(fplog, "Found env.var. %s = %s, using value %d\n",
6336                     env_var, val, nst);
6337         }
6338     }
6339
6340     return nst;
6341 }
6342
6343 static void dd_warning(t_commrec *cr, FILE *fplog, const char *warn_string)
6344 {
6345     if (MASTER(cr))
6346     {
6347         fprintf(stderr, "\n%s\n", warn_string);
6348     }
6349     if (fplog)
6350     {
6351         fprintf(fplog, "\n%s\n", warn_string);
6352     }
6353 }
6354
6355 static void check_dd_restrictions(t_commrec *cr, gmx_domdec_t *dd,
6356                                   t_inputrec *ir, FILE *fplog)
6357 {
6358     if (ir->ePBC == epbcSCREW &&
6359         (dd->nc[XX] == 1 || dd->nc[YY] > 1 || dd->nc[ZZ] > 1))
6360     {
6361         gmx_fatal(FARGS, "With pbc=%s can only do domain decomposition in the x-direction", epbc_names[ir->ePBC]);
6362     }
6363
6364     if (ir->ns_type == ensSIMPLE)
6365     {
6366         gmx_fatal(FARGS, "Domain decomposition does not support simple neighbor searching, use grid searching or use particle decomposition");
6367     }
6368
6369     if (ir->nstlist == 0)
6370     {
6371         gmx_fatal(FARGS, "Domain decomposition does not work with nstlist=0");
6372     }
6373
6374     if (ir->comm_mode == ecmANGULAR && ir->ePBC != epbcNONE)
6375     {
6376         dd_warning(cr, fplog, "comm-mode angular will give incorrect results when the comm group partially crosses a periodic boundary");
6377     }
6378 }
6379
6380 static real average_cellsize_min(gmx_domdec_t *dd, gmx_ddbox_t *ddbox)
6381 {
6382     int  di, d;
6383     real r;
6384
6385     r = ddbox->box_size[XX];
6386     for (di = 0; di < dd->ndim; di++)
6387     {
6388         d = dd->dim[di];
6389         /* Check using the initial average cell size */
6390         r = min(r, ddbox->box_size[d]*ddbox->skew_fac[d]/dd->nc[d]);
6391     }
6392
6393     return r;
6394 }
6395
6396 static int check_dlb_support(FILE *fplog, t_commrec *cr,
6397                              const char *dlb_opt, gmx_bool bRecordLoad,
6398                              unsigned long Flags, t_inputrec *ir)
6399 {
6400     gmx_domdec_t *dd;
6401     int           eDLB = -1;
6402     char          buf[STRLEN];
6403
6404     switch (dlb_opt[0])
6405     {
6406         case 'a': eDLB = edlbAUTO; break;
6407         case 'n': eDLB = edlbNO;   break;
6408         case 'y': eDLB = edlbYES;  break;
6409         default: gmx_incons("Unknown dlb_opt");
6410     }
6411
6412     if (Flags & MD_RERUN)
6413     {
6414         return edlbNO;
6415     }
6416
6417     if (!EI_DYNAMICS(ir->eI))
6418     {
6419         if (eDLB == edlbYES)
6420         {
6421             sprintf(buf, "NOTE: dynamic load balancing is only supported with dynamics, not with integrator '%s'\n", EI(ir->eI));
6422             dd_warning(cr, fplog, buf);
6423         }
6424
6425         return edlbNO;
6426     }
6427
6428     if (!bRecordLoad)
6429     {
6430         dd_warning(cr, fplog, "NOTE: Cycle counting is not supported on this architecture, will not use dynamic load balancing\n");
6431
6432         return edlbNO;
6433     }
6434
6435     if (Flags & MD_REPRODUCIBLE)
6436     {
6437         switch (eDLB)
6438         {
6439             case edlbNO:
6440                 break;
6441             case edlbAUTO:
6442                 dd_warning(cr, fplog, "NOTE: reproducibility requested, will not use dynamic load balancing\n");
6443                 eDLB = edlbNO;
6444                 break;
6445             case edlbYES:
6446                 dd_warning(cr, fplog, "WARNING: reproducibility requested with dynamic load balancing, the simulation will NOT be binary reproducible\n");
6447                 break;
6448             default:
6449                 gmx_fatal(FARGS, "Death horror: undefined case (%d) for load balancing choice", eDLB);
6450                 break;
6451         }
6452     }
6453
6454     return eDLB;
6455 }
6456
6457 static void set_dd_dim(FILE *fplog, gmx_domdec_t *dd)
6458 {
6459     int dim;
6460
6461     dd->ndim = 0;
6462     if (getenv("GMX_DD_ORDER_ZYX") != NULL)
6463     {
6464         /* Decomposition order z,y,x */
6465         if (fplog)
6466         {
6467             fprintf(fplog, "Using domain decomposition order z, y, x\n");
6468         }
6469         for (dim = DIM-1; dim >= 0; dim--)
6470         {
6471             if (dd->nc[dim] > 1)
6472             {
6473                 dd->dim[dd->ndim++] = dim;
6474             }
6475         }
6476     }
6477     else
6478     {
6479         /* Decomposition order x,y,z */
6480         for (dim = 0; dim < DIM; dim++)
6481         {
6482             if (dd->nc[dim] > 1)
6483             {
6484                 dd->dim[dd->ndim++] = dim;
6485             }
6486         }
6487     }
6488 }
6489
6490 static gmx_domdec_comm_t *init_dd_comm()
6491 {
6492     gmx_domdec_comm_t *comm;
6493     int                i;
6494
6495     snew(comm, 1);
6496     snew(comm->cggl_flag, DIM*2);
6497     snew(comm->cgcm_state, DIM*2);
6498     for (i = 0; i < DIM*2; i++)
6499     {
6500         comm->cggl_flag_nalloc[i]  = 0;
6501         comm->cgcm_state_nalloc[i] = 0;
6502     }
6503
6504     comm->nalloc_int = 0;
6505     comm->buf_int    = NULL;
6506
6507     vec_rvec_init(&comm->vbuf);
6508
6509     comm->n_load_have    = 0;
6510     comm->n_load_collect = 0;
6511
6512     for (i = 0; i < ddnatNR-ddnatZONE; i++)
6513     {
6514         comm->sum_nat[i] = 0;
6515     }
6516     comm->ndecomp   = 0;
6517     comm->nload     = 0;
6518     comm->load_step = 0;
6519     comm->load_sum  = 0;
6520     comm->load_max  = 0;
6521     clear_ivec(comm->load_lim);
6522     comm->load_mdf  = 0;
6523     comm->load_pme  = 0;
6524
6525     return comm;
6526 }
6527
6528 gmx_domdec_t *init_domain_decomposition(FILE *fplog, t_commrec *cr,
6529                                         unsigned long Flags,
6530                                         ivec nc,
6531                                         real comm_distance_min, real rconstr,
6532                                         const char *dlb_opt, real dlb_scale,
6533                                         const char *sizex, const char *sizey, const char *sizez,
6534                                         gmx_mtop_t *mtop, t_inputrec *ir,
6535                                         matrix box, rvec *x,
6536                                         gmx_ddbox_t *ddbox,
6537                                         int *npme_x, int *npme_y)
6538 {
6539     gmx_domdec_t      *dd;
6540     gmx_domdec_comm_t *comm;
6541     int                recload;
6542     int                d, i, j;
6543     real               r_2b, r_mb, r_bonded = -1, r_bonded_limit = -1, limit, acs;
6544     gmx_bool           bC;
6545     char               buf[STRLEN];
6546
6547     if (fplog)
6548     {
6549         fprintf(fplog,
6550                 "\nInitializing Domain Decomposition on %d nodes\n", cr->nnodes);
6551     }
6552
6553     snew(dd, 1);
6554
6555     dd->comm = init_dd_comm();
6556     comm     = dd->comm;
6557     snew(comm->cggl_flag, DIM*2);
6558     snew(comm->cgcm_state, DIM*2);
6559
6560     dd->npbcdim   = ePBC2npbcdim(ir->ePBC);
6561     dd->bScrewPBC = (ir->ePBC == epbcSCREW);
6562
6563     dd->bSendRecv2      = dd_nst_env(fplog, "GMX_DD_SENDRECV2", 0);
6564     comm->dlb_scale_lim = dd_nst_env(fplog, "GMX_DLB_MAX", 10);
6565     comm->eFlop         = dd_nst_env(fplog, "GMX_DLB_FLOP", 0);
6566     recload             = dd_nst_env(fplog, "GMX_DD_LOAD", 1);
6567     comm->nstSortCG     = dd_nst_env(fplog, "GMX_DD_SORT", 1);
6568     comm->nstDDDump     = dd_nst_env(fplog, "GMX_DD_DUMP", 0);
6569     comm->nstDDDumpGrid = dd_nst_env(fplog, "GMX_DD_DUMP_GRID", 0);
6570     comm->DD_debug      = dd_nst_env(fplog, "GMX_DD_DEBUG", 0);
6571
6572     dd->pme_recv_f_alloc = 0;
6573     dd->pme_recv_f_buf   = NULL;
6574
6575     if (dd->bSendRecv2 && fplog)
6576     {
6577         fprintf(fplog, "Will use two sequential MPI_Sendrecv calls instead of two simultaneous non-blocking MPI_Irecv and MPI_Isend pairs for constraint and vsite communication\n");
6578     }
6579     if (comm->eFlop)
6580     {
6581         if (fplog)
6582         {
6583             fprintf(fplog, "Will load balance based on FLOP count\n");
6584         }
6585         if (comm->eFlop > 1)
6586         {
6587             srand(1+cr->nodeid);
6588         }
6589         comm->bRecordLoad = TRUE;
6590     }
6591     else
6592     {
6593         comm->bRecordLoad = (wallcycle_have_counter() && recload > 0);
6594
6595     }
6596
6597     comm->eDLB = check_dlb_support(fplog, cr, dlb_opt, comm->bRecordLoad, Flags, ir);
6598
6599     comm->bDynLoadBal = (comm->eDLB == edlbYES);
6600     if (fplog)
6601     {
6602         fprintf(fplog, "Dynamic load balancing: %s\n", edlb_names[comm->eDLB]);
6603     }
6604     dd->bGridJump              = comm->bDynLoadBal;
6605     comm->bPMELoadBalDLBLimits = FALSE;
6606
6607     if (comm->nstSortCG)
6608     {
6609         if (fplog)
6610         {
6611             if (comm->nstSortCG == 1)
6612             {
6613                 fprintf(fplog, "Will sort the charge groups at every domain (re)decomposition\n");
6614             }
6615             else
6616             {
6617                 fprintf(fplog, "Will sort the charge groups every %d steps\n",
6618                         comm->nstSortCG);
6619             }
6620         }
6621         snew(comm->sort, 1);
6622     }
6623     else
6624     {
6625         if (fplog)
6626         {
6627             fprintf(fplog, "Will not sort the charge groups\n");
6628         }
6629     }
6630
6631     comm->bCGs = (ncg_mtop(mtop) < mtop->natoms);
6632
6633     comm->bInterCGBondeds = (ncg_mtop(mtop) > mtop->mols.nr);
6634     if (comm->bInterCGBondeds)
6635     {
6636         comm->bInterCGMultiBody = (multi_body_bondeds_count(mtop) > 0);
6637     }
6638     else
6639     {
6640         comm->bInterCGMultiBody = FALSE;
6641     }
6642
6643     dd->bInterCGcons    = inter_charge_group_constraints(mtop);
6644     dd->bInterCGsettles = inter_charge_group_settles(mtop);
6645
6646     if (ir->rlistlong == 0)
6647     {
6648         /* Set the cut-off to some very large value,
6649          * so we don't need if statements everywhere in the code.
6650          * We use sqrt, since the cut-off is squared in some places.
6651          */
6652         comm->cutoff   = GMX_CUTOFF_INF;
6653     }
6654     else
6655     {
6656         comm->cutoff   = ir->rlistlong;
6657     }
6658     comm->cutoff_mbody = 0;
6659
6660     comm->cellsize_limit = 0;
6661     comm->bBondComm      = FALSE;
6662
6663     if (comm->bInterCGBondeds)
6664     {
6665         if (comm_distance_min > 0)
6666         {
6667             comm->cutoff_mbody = comm_distance_min;
6668             if (Flags & MD_DDBONDCOMM)
6669             {
6670                 comm->bBondComm = (comm->cutoff_mbody > comm->cutoff);
6671             }
6672             else
6673             {
6674                 comm->cutoff = max(comm->cutoff, comm->cutoff_mbody);
6675             }
6676             r_bonded_limit = comm->cutoff_mbody;
6677         }
6678         else if (ir->bPeriodicMols)
6679         {
6680             /* Can not easily determine the required cut-off */
6681             dd_warning(cr, fplog, "NOTE: Periodic molecules are present in this system. Because of this, the domain decomposition algorithm cannot easily determine the minimum cell size that it requires for treating bonded interactions. Instead, domain decomposition will assume that half the non-bonded cut-off will be a suitable lower bound.\n");
6682             comm->cutoff_mbody = comm->cutoff/2;
6683             r_bonded_limit     = comm->cutoff_mbody;
6684         }
6685         else
6686         {
6687             if (MASTER(cr))
6688             {
6689                 dd_bonded_cg_distance(fplog, mtop, ir, x, box,
6690                                       Flags & MD_DDBONDCHECK, &r_2b, &r_mb);
6691             }
6692             gmx_bcast(sizeof(r_2b), &r_2b, cr);
6693             gmx_bcast(sizeof(r_mb), &r_mb, cr);
6694
6695             /* We use an initial margin of 10% for the minimum cell size,
6696              * except when we are just below the non-bonded cut-off.
6697              */
6698             if (Flags & MD_DDBONDCOMM)
6699             {
6700                 if (max(r_2b, r_mb) > comm->cutoff)
6701                 {
6702                     r_bonded        = max(r_2b, r_mb);
6703                     r_bonded_limit  = 1.1*r_bonded;
6704                     comm->bBondComm = TRUE;
6705                 }
6706                 else
6707                 {
6708                     r_bonded       = r_mb;
6709                     r_bonded_limit = min(1.1*r_bonded, comm->cutoff);
6710                 }
6711                 /* We determine cutoff_mbody later */
6712             }
6713             else
6714             {
6715                 /* No special bonded communication,
6716                  * simply increase the DD cut-off.
6717                  */
6718                 r_bonded_limit     = 1.1*max(r_2b, r_mb);
6719                 comm->cutoff_mbody = r_bonded_limit;
6720                 comm->cutoff       = max(comm->cutoff, comm->cutoff_mbody);
6721             }
6722         }
6723         comm->cellsize_limit = max(comm->cellsize_limit, r_bonded_limit);
6724         if (fplog)
6725         {
6726             fprintf(fplog,
6727                     "Minimum cell size due to bonded interactions: %.3f nm\n",
6728                     comm->cellsize_limit);
6729         }
6730     }
6731
6732     if (dd->bInterCGcons && rconstr <= 0)
6733     {
6734         /* There is a cell size limit due to the constraints (P-LINCS) */
6735         rconstr = constr_r_max(fplog, mtop, ir);
6736         if (fplog)
6737         {
6738             fprintf(fplog,
6739                     "Estimated maximum distance required for P-LINCS: %.3f nm\n",
6740                     rconstr);
6741             if (rconstr > comm->cellsize_limit)
6742             {
6743                 fprintf(fplog, "This distance will limit the DD cell size, you can override this with -rcon\n");
6744             }
6745         }
6746     }
6747     else if (rconstr > 0 && fplog)
6748     {
6749         /* Here we do not check for dd->bInterCGcons,
6750          * because one can also set a cell size limit for virtual sites only
6751          * and at this point we don't know yet if there are intercg v-sites.
6752          */
6753         fprintf(fplog,
6754                 "User supplied maximum distance required for P-LINCS: %.3f nm\n",
6755                 rconstr);
6756     }
6757     comm->cellsize_limit = max(comm->cellsize_limit, rconstr);
6758
6759     comm->cgs_gl = gmx_mtop_global_cgs(mtop);
6760
6761     if (nc[XX] > 0)
6762     {
6763         copy_ivec(nc, dd->nc);
6764         set_dd_dim(fplog, dd);
6765         set_ddbox_cr(cr, &dd->nc, ir, box, &comm->cgs_gl, x, ddbox);
6766
6767         if (cr->npmenodes == -1)
6768         {
6769             cr->npmenodes = 0;
6770         }
6771         acs = average_cellsize_min(dd, ddbox);
6772         if (acs < comm->cellsize_limit)
6773         {
6774             if (fplog)
6775             {
6776                 fprintf(fplog, "ERROR: The initial cell size (%f) is smaller than the cell size limit (%f)\n", acs, comm->cellsize_limit);
6777             }
6778             gmx_fatal_collective(FARGS, cr, NULL,
6779                                  "The initial cell size (%f) is smaller than the cell size limit (%f), change options -dd, -rdd or -rcon, see the log file for details",
6780                                  acs, comm->cellsize_limit);
6781         }
6782     }
6783     else
6784     {
6785         set_ddbox_cr(cr, NULL, ir, box, &comm->cgs_gl, x, ddbox);
6786
6787         /* We need to choose the optimal DD grid and possibly PME nodes */
6788         limit = dd_choose_grid(fplog, cr, dd, ir, mtop, box, ddbox,
6789                                comm->eDLB != edlbNO, dlb_scale,
6790                                comm->cellsize_limit, comm->cutoff,
6791                                comm->bInterCGBondeds);
6792
6793         if (dd->nc[XX] == 0)
6794         {
6795             bC = (dd->bInterCGcons && rconstr > r_bonded_limit);
6796             sprintf(buf, "Change the number of nodes or mdrun option %s%s%s",
6797                     !bC ? "-rdd" : "-rcon",
6798                     comm->eDLB != edlbNO ? " or -dds" : "",
6799                     bC ? " or your LINCS settings" : "");
6800
6801             gmx_fatal_collective(FARGS, cr, NULL,
6802                                  "There is no domain decomposition for %d nodes that is compatible with the given box and a minimum cell size of %g nm\n"
6803                                  "%s\n"
6804                                  "Look in the log file for details on the domain decomposition",
6805                                  cr->nnodes-cr->npmenodes, limit, buf);
6806         }
6807         set_dd_dim(fplog, dd);
6808     }
6809
6810     if (fplog)
6811     {
6812         fprintf(fplog,
6813                 "Domain decomposition grid %d x %d x %d, separate PME nodes %d\n",
6814                 dd->nc[XX], dd->nc[YY], dd->nc[ZZ], cr->npmenodes);
6815     }
6816
6817     dd->nnodes = dd->nc[XX]*dd->nc[YY]*dd->nc[ZZ];
6818     if (cr->nnodes - dd->nnodes != cr->npmenodes)
6819     {
6820         gmx_fatal_collective(FARGS, cr, NULL,
6821                              "The size of the domain decomposition grid (%d) does not match the number of nodes (%d). The total number of nodes is %d",
6822                              dd->nnodes, cr->nnodes - cr->npmenodes, cr->nnodes);
6823     }
6824     if (cr->npmenodes > dd->nnodes)
6825     {
6826         gmx_fatal_collective(FARGS, cr, NULL,
6827                              "The number of separate PME nodes (%d) is larger than the number of PP nodes (%d), this is not supported.", cr->npmenodes, dd->nnodes);
6828     }
6829     if (cr->npmenodes > 0)
6830     {
6831         comm->npmenodes = cr->npmenodes;
6832     }
6833     else
6834     {
6835         comm->npmenodes = dd->nnodes;
6836     }
6837
6838     if (EEL_PME(ir->coulombtype))
6839     {
6840         /* The following choices should match those
6841          * in comm_cost_est in domdec_setup.c.
6842          * Note that here the checks have to take into account
6843          * that the decomposition might occur in a different order than xyz
6844          * (for instance through the env.var. GMX_DD_ORDER_ZYX),
6845          * in which case they will not match those in comm_cost_est,
6846          * but since that is mainly for testing purposes that's fine.
6847          */
6848         if (dd->ndim >= 2 && dd->dim[0] == XX && dd->dim[1] == YY &&
6849             comm->npmenodes > dd->nc[XX] && comm->npmenodes % dd->nc[XX] == 0 &&
6850             getenv("GMX_PMEONEDD") == NULL)
6851         {
6852             comm->npmedecompdim = 2;
6853             comm->npmenodes_x   = dd->nc[XX];
6854             comm->npmenodes_y   = comm->npmenodes/comm->npmenodes_x;
6855         }
6856         else
6857         {
6858             /* In case nc is 1 in both x and y we could still choose to
6859              * decompose pme in y instead of x, but we use x for simplicity.
6860              */
6861             comm->npmedecompdim = 1;
6862             if (dd->dim[0] == YY)
6863             {
6864                 comm->npmenodes_x = 1;
6865                 comm->npmenodes_y = comm->npmenodes;
6866             }
6867             else
6868             {
6869                 comm->npmenodes_x = comm->npmenodes;
6870                 comm->npmenodes_y = 1;
6871             }
6872         }
6873         if (fplog)
6874         {
6875             fprintf(fplog, "PME domain decomposition: %d x %d x %d\n",
6876                     comm->npmenodes_x, comm->npmenodes_y, 1);
6877         }
6878     }
6879     else
6880     {
6881         comm->npmedecompdim = 0;
6882         comm->npmenodes_x   = 0;
6883         comm->npmenodes_y   = 0;
6884     }
6885
6886     /* Technically we don't need both of these,
6887      * but it simplifies code not having to recalculate it.
6888      */
6889     *npme_x = comm->npmenodes_x;
6890     *npme_y = comm->npmenodes_y;
6891
6892     snew(comm->slb_frac, DIM);
6893     if (comm->eDLB == edlbNO)
6894     {
6895         comm->slb_frac[XX] = get_slb_frac(fplog, "x", dd->nc[XX], sizex);
6896         comm->slb_frac[YY] = get_slb_frac(fplog, "y", dd->nc[YY], sizey);
6897         comm->slb_frac[ZZ] = get_slb_frac(fplog, "z", dd->nc[ZZ], sizez);
6898     }
6899
6900     if (comm->bInterCGBondeds && comm->cutoff_mbody == 0)
6901     {
6902         if (comm->bBondComm || comm->eDLB != edlbNO)
6903         {
6904             /* Set the bonded communication distance to halfway
6905              * the minimum and the maximum,
6906              * since the extra communication cost is nearly zero.
6907              */
6908             acs                = average_cellsize_min(dd, ddbox);
6909             comm->cutoff_mbody = 0.5*(r_bonded + acs);
6910             if (comm->eDLB != edlbNO)
6911             {
6912                 /* Check if this does not limit the scaling */
6913                 comm->cutoff_mbody = min(comm->cutoff_mbody, dlb_scale*acs);
6914             }
6915             if (!comm->bBondComm)
6916             {
6917                 /* Without bBondComm do not go beyond the n.b. cut-off */
6918                 comm->cutoff_mbody = min(comm->cutoff_mbody, comm->cutoff);
6919                 if (comm->cellsize_limit >= comm->cutoff)
6920                 {
6921                     /* We don't loose a lot of efficieny
6922                      * when increasing it to the n.b. cut-off.
6923                      * It can even be slightly faster, because we need
6924                      * less checks for the communication setup.
6925                      */
6926                     comm->cutoff_mbody = comm->cutoff;
6927                 }
6928             }
6929             /* Check if we did not end up below our original limit */
6930             comm->cutoff_mbody = max(comm->cutoff_mbody, r_bonded_limit);
6931
6932             if (comm->cutoff_mbody > comm->cellsize_limit)
6933             {
6934                 comm->cellsize_limit = comm->cutoff_mbody;
6935             }
6936         }
6937         /* Without DLB and cutoff_mbody<cutoff, cutoff_mbody is dynamic */
6938     }
6939
6940     if (debug)
6941     {
6942         fprintf(debug, "Bonded atom communication beyond the cut-off: %d\n"
6943                 "cellsize limit %f\n",
6944                 comm->bBondComm, comm->cellsize_limit);
6945     }
6946
6947     if (MASTER(cr))
6948     {
6949         check_dd_restrictions(cr, dd, ir, fplog);
6950     }
6951
6952     comm->partition_step = INT_MIN;
6953     dd->ddp_count        = 0;
6954
6955     clear_dd_cycle_counts(dd);
6956
6957     return dd;
6958 }
6959
6960 static void set_dlb_limits(gmx_domdec_t *dd)
6961
6962 {
6963     int d;
6964
6965     for (d = 0; d < dd->ndim; d++)
6966     {
6967         dd->comm->cd[d].np                 = dd->comm->cd[d].np_dlb;
6968         dd->comm->cellsize_min[dd->dim[d]] =
6969             dd->comm->cellsize_min_dlb[dd->dim[d]];
6970     }
6971 }
6972
6973
6974 static void turn_on_dlb(FILE *fplog, t_commrec *cr, gmx_large_int_t step)
6975 {
6976     gmx_domdec_t      *dd;
6977     gmx_domdec_comm_t *comm;
6978     real               cellsize_min;
6979     int                d, nc, i;
6980     char               buf[STRLEN];
6981
6982     dd   = cr->dd;
6983     comm = dd->comm;
6984
6985     if (fplog)
6986     {
6987         fprintf(fplog, "At step %s the performance loss due to force load imbalance is %.1f %%\n", gmx_step_str(step, buf), dd_force_imb_perf_loss(dd)*100);
6988     }
6989
6990     cellsize_min = comm->cellsize_min[dd->dim[0]];
6991     for (d = 1; d < dd->ndim; d++)
6992     {
6993         cellsize_min = min(cellsize_min, comm->cellsize_min[dd->dim[d]]);
6994     }
6995
6996     if (cellsize_min < comm->cellsize_limit*1.05)
6997     {
6998         dd_warning(cr, fplog, "NOTE: the minimum cell size is smaller than 1.05 times the cell size limit, will not turn on dynamic load balancing\n");
6999
7000         /* Change DLB from "auto" to "no". */
7001         comm->eDLB = edlbNO;
7002
7003         return;
7004     }
7005
7006     dd_warning(cr, fplog, "NOTE: Turning on dynamic load balancing\n");
7007     comm->bDynLoadBal = TRUE;
7008     dd->bGridJump     = TRUE;
7009
7010     set_dlb_limits(dd);
7011
7012     /* We can set the required cell size info here,
7013      * so we do not need to communicate this.
7014      * The grid is completely uniform.
7015      */
7016     for (d = 0; d < dd->ndim; d++)
7017     {
7018         if (comm->root[d])
7019         {
7020             comm->load[d].sum_m = comm->load[d].sum;
7021
7022             nc = dd->nc[dd->dim[d]];
7023             for (i = 0; i < nc; i++)
7024             {
7025                 comm->root[d]->cell_f[i]    = i/(real)nc;
7026                 if (d > 0)
7027                 {
7028                     comm->root[d]->cell_f_max0[i] =  i   /(real)nc;
7029                     comm->root[d]->cell_f_min1[i] = (i+1)/(real)nc;
7030                 }
7031             }
7032             comm->root[d]->cell_f[nc] = 1.0;
7033         }
7034     }
7035 }
7036
7037 static char *init_bLocalCG(gmx_mtop_t *mtop)
7038 {
7039     int   ncg, cg;
7040     char *bLocalCG;
7041
7042     ncg = ncg_mtop(mtop);
7043     snew(bLocalCG, ncg);
7044     for (cg = 0; cg < ncg; cg++)
7045     {
7046         bLocalCG[cg] = FALSE;
7047     }
7048
7049     return bLocalCG;
7050 }
7051
7052 void dd_init_bondeds(FILE *fplog,
7053                      gmx_domdec_t *dd, gmx_mtop_t *mtop,
7054                      gmx_vsite_t *vsite,
7055                      t_inputrec *ir, gmx_bool bBCheck, cginfo_mb_t *cginfo_mb)
7056 {
7057     gmx_domdec_comm_t *comm;
7058     gmx_bool           bBondComm;
7059     int                d;
7060
7061     dd_make_reverse_top(fplog, dd, mtop, vsite, ir, bBCheck);
7062
7063     comm = dd->comm;
7064
7065     if (comm->bBondComm)
7066     {
7067         /* Communicate atoms beyond the cut-off for bonded interactions */
7068         comm = dd->comm;
7069
7070         comm->cglink = make_charge_group_links(mtop, dd, cginfo_mb);
7071
7072         comm->bLocalCG = init_bLocalCG(mtop);
7073     }
7074     else
7075     {
7076         /* Only communicate atoms based on cut-off */
7077         comm->cglink   = NULL;
7078         comm->bLocalCG = NULL;
7079     }
7080 }
7081
7082 static void print_dd_settings(FILE *fplog, gmx_domdec_t *dd,
7083                               t_inputrec *ir,
7084                               gmx_bool bDynLoadBal, real dlb_scale,
7085                               gmx_ddbox_t *ddbox)
7086 {
7087     gmx_domdec_comm_t *comm;
7088     int                d;
7089     ivec               np;
7090     real               limit, shrink;
7091     char               buf[64];
7092
7093     if (fplog == NULL)
7094     {
7095         return;
7096     }
7097
7098     comm = dd->comm;
7099
7100     if (bDynLoadBal)
7101     {
7102         fprintf(fplog, "The maximum number of communication pulses is:");
7103         for (d = 0; d < dd->ndim; d++)
7104         {
7105             fprintf(fplog, " %c %d", dim2char(dd->dim[d]), comm->cd[d].np_dlb);
7106         }
7107         fprintf(fplog, "\n");
7108         fprintf(fplog, "The minimum size for domain decomposition cells is %.3f nm\n", comm->cellsize_limit);
7109         fprintf(fplog, "The requested allowed shrink of DD cells (option -dds) is: %.2f\n", dlb_scale);
7110         fprintf(fplog, "The allowed shrink of domain decomposition cells is:");
7111         for (d = 0; d < DIM; d++)
7112         {
7113             if (dd->nc[d] > 1)
7114             {
7115                 if (d >= ddbox->npbcdim && dd->nc[d] == 2)
7116                 {
7117                     shrink = 0;
7118                 }
7119                 else
7120                 {
7121                     shrink =
7122                         comm->cellsize_min_dlb[d]/
7123                         (ddbox->box_size[d]*ddbox->skew_fac[d]/dd->nc[d]);
7124                 }
7125                 fprintf(fplog, " %c %.2f", dim2char(d), shrink);
7126             }
7127         }
7128         fprintf(fplog, "\n");
7129     }
7130     else
7131     {
7132         set_dd_cell_sizes_slb(dd, ddbox, FALSE, np);
7133         fprintf(fplog, "The initial number of communication pulses is:");
7134         for (d = 0; d < dd->ndim; d++)
7135         {
7136             fprintf(fplog, " %c %d", dim2char(dd->dim[d]), np[dd->dim[d]]);
7137         }
7138         fprintf(fplog, "\n");
7139         fprintf(fplog, "The initial domain decomposition cell size is:");
7140         for (d = 0; d < DIM; d++)
7141         {
7142             if (dd->nc[d] > 1)
7143             {
7144                 fprintf(fplog, " %c %.2f nm",
7145                         dim2char(d), dd->comm->cellsize_min[d]);
7146             }
7147         }
7148         fprintf(fplog, "\n\n");
7149     }
7150
7151     if (comm->bInterCGBondeds || dd->vsite_comm || dd->constraint_comm)
7152     {
7153         fprintf(fplog, "The maximum allowed distance for charge groups involved in interactions is:\n");
7154         fprintf(fplog, "%40s  %-7s %6.3f nm\n",
7155                 "non-bonded interactions", "", comm->cutoff);
7156
7157         if (bDynLoadBal)
7158         {
7159             limit = dd->comm->cellsize_limit;
7160         }
7161         else
7162         {
7163             if (dynamic_dd_box(ddbox, ir))
7164             {
7165                 fprintf(fplog, "(the following are initial values, they could change due to box deformation)\n");
7166             }
7167             limit = dd->comm->cellsize_min[XX];
7168             for (d = 1; d < DIM; d++)
7169             {
7170                 limit = min(limit, dd->comm->cellsize_min[d]);
7171             }
7172         }
7173
7174         if (comm->bInterCGBondeds)
7175         {
7176             fprintf(fplog, "%40s  %-7s %6.3f nm\n",
7177                     "two-body bonded interactions", "(-rdd)",
7178                     max(comm->cutoff, comm->cutoff_mbody));
7179             fprintf(fplog, "%40s  %-7s %6.3f nm\n",
7180                     "multi-body bonded interactions", "(-rdd)",
7181                     (comm->bBondComm || dd->bGridJump) ? comm->cutoff_mbody : min(comm->cutoff, limit));
7182         }
7183         if (dd->vsite_comm)
7184         {
7185             fprintf(fplog, "%40s  %-7s %6.3f nm\n",
7186                     "virtual site constructions", "(-rcon)", limit);
7187         }
7188         if (dd->constraint_comm)
7189         {
7190             sprintf(buf, "atoms separated by up to %d constraints",
7191                     1+ir->nProjOrder);
7192             fprintf(fplog, "%40s  %-7s %6.3f nm\n",
7193                     buf, "(-rcon)", limit);
7194         }
7195         fprintf(fplog, "\n");
7196     }
7197
7198     fflush(fplog);
7199 }
7200
7201 static void set_cell_limits_dlb(gmx_domdec_t      *dd,
7202                                 real               dlb_scale,
7203                                 const t_inputrec  *ir,
7204                                 const gmx_ddbox_t *ddbox)
7205 {
7206     gmx_domdec_comm_t *comm;
7207     int                d, dim, npulse, npulse_d_max, npulse_d;
7208     gmx_bool           bNoCutOff;
7209
7210     comm = dd->comm;
7211
7212     bNoCutOff = (ir->rvdw == 0 || ir->rcoulomb == 0);
7213
7214     /* Determine the maximum number of comm. pulses in one dimension */
7215
7216     comm->cellsize_limit = max(comm->cellsize_limit, comm->cutoff_mbody);
7217
7218     /* Determine the maximum required number of grid pulses */
7219     if (comm->cellsize_limit >= comm->cutoff)
7220     {
7221         /* Only a single pulse is required */
7222         npulse = 1;
7223     }
7224     else if (!bNoCutOff && comm->cellsize_limit > 0)
7225     {
7226         /* We round down slightly here to avoid overhead due to the latency
7227          * of extra communication calls when the cut-off
7228          * would be only slightly longer than the cell size.
7229          * Later cellsize_limit is redetermined,
7230          * so we can not miss interactions due to this rounding.
7231          */
7232         npulse = (int)(0.96 + comm->cutoff/comm->cellsize_limit);
7233     }
7234     else
7235     {
7236         /* There is no cell size limit */
7237         npulse = max(dd->nc[XX]-1, max(dd->nc[YY]-1, dd->nc[ZZ]-1));
7238     }
7239
7240     if (!bNoCutOff && npulse > 1)
7241     {
7242         /* See if we can do with less pulses, based on dlb_scale */
7243         npulse_d_max = 0;
7244         for (d = 0; d < dd->ndim; d++)
7245         {
7246             dim      = dd->dim[d];
7247             npulse_d = (int)(1 + dd->nc[dim]*comm->cutoff
7248                              /(ddbox->box_size[dim]*ddbox->skew_fac[dim]*dlb_scale));
7249             npulse_d_max = max(npulse_d_max, npulse_d);
7250         }
7251         npulse = min(npulse, npulse_d_max);
7252     }
7253
7254     /* This env var can override npulse */
7255     d = dd_nst_env(debug, "GMX_DD_NPULSE", 0);
7256     if (d > 0)
7257     {
7258         npulse = d;
7259     }
7260
7261     comm->maxpulse       = 1;
7262     comm->bVacDLBNoLimit = (ir->ePBC == epbcNONE);
7263     for (d = 0; d < dd->ndim; d++)
7264     {
7265         comm->cd[d].np_dlb    = min(npulse, dd->nc[dd->dim[d]]-1);
7266         comm->cd[d].np_nalloc = comm->cd[d].np_dlb;
7267         snew(comm->cd[d].ind, comm->cd[d].np_nalloc);
7268         comm->maxpulse = max(comm->maxpulse, comm->cd[d].np_dlb);
7269         if (comm->cd[d].np_dlb < dd->nc[dd->dim[d]]-1)
7270         {
7271             comm->bVacDLBNoLimit = FALSE;
7272         }
7273     }
7274
7275     /* cellsize_limit is set for LINCS in init_domain_decomposition */
7276     if (!comm->bVacDLBNoLimit)
7277     {
7278         comm->cellsize_limit = max(comm->cellsize_limit,
7279                                    comm->cutoff/comm->maxpulse);
7280     }
7281     comm->cellsize_limit = max(comm->cellsize_limit, comm->cutoff_mbody);
7282     /* Set the minimum cell size for each DD dimension */
7283     for (d = 0; d < dd->ndim; d++)
7284     {
7285         if (comm->bVacDLBNoLimit ||
7286             comm->cd[d].np_dlb*comm->cellsize_limit >= comm->cutoff)
7287         {
7288             comm->cellsize_min_dlb[dd->dim[d]] = comm->cellsize_limit;
7289         }
7290         else
7291         {
7292             comm->cellsize_min_dlb[dd->dim[d]] =
7293                 comm->cutoff/comm->cd[d].np_dlb;
7294         }
7295     }
7296     if (comm->cutoff_mbody <= 0)
7297     {
7298         comm->cutoff_mbody = min(comm->cutoff, comm->cellsize_limit);
7299     }
7300     if (comm->bDynLoadBal)
7301     {
7302         set_dlb_limits(dd);
7303     }
7304 }
7305
7306 gmx_bool dd_bonded_molpbc(gmx_domdec_t *dd, int ePBC)
7307 {
7308     /* If each molecule is a single charge group
7309      * or we use domain decomposition for each periodic dimension,
7310      * we do not need to take pbc into account for the bonded interactions.
7311      */
7312     return (ePBC != epbcNONE && dd->comm->bInterCGBondeds &&
7313             !(dd->nc[XX] > 1 &&
7314               dd->nc[YY] > 1 &&
7315               (dd->nc[ZZ] > 1 || ePBC == epbcXY)));
7316 }
7317
7318 void set_dd_parameters(FILE *fplog, gmx_domdec_t *dd, real dlb_scale,
7319                        t_inputrec *ir, gmx_ddbox_t *ddbox)
7320 {
7321     gmx_domdec_comm_t *comm;
7322     int                natoms_tot;
7323     real               vol_frac;
7324
7325     comm = dd->comm;
7326
7327     /* Initialize the thread data.
7328      * This can not be done in init_domain_decomposition,
7329      * as the numbers of threads is determined later.
7330      */
7331     comm->nth = gmx_omp_nthreads_get(emntDomdec);
7332     if (comm->nth > 1)
7333     {
7334         snew(comm->dth, comm->nth);
7335     }
7336
7337     if (EEL_PME(ir->coulombtype))
7338     {
7339         init_ddpme(dd, &comm->ddpme[0], 0);
7340         if (comm->npmedecompdim >= 2)
7341         {
7342             init_ddpme(dd, &comm->ddpme[1], 1);
7343         }
7344     }
7345     else
7346     {
7347         comm->npmenodes = 0;
7348         if (dd->pme_nodeid >= 0)
7349         {
7350             gmx_fatal_collective(FARGS, NULL, dd,
7351                                  "Can not have separate PME nodes without PME electrostatics");
7352         }
7353     }
7354
7355     if (debug)
7356     {
7357         fprintf(debug, "The DD cut-off is %f\n", comm->cutoff);
7358     }
7359     if (comm->eDLB != edlbNO)
7360     {
7361         set_cell_limits_dlb(dd, dlb_scale, ir, ddbox);
7362     }
7363
7364     print_dd_settings(fplog, dd, ir, comm->bDynLoadBal, dlb_scale, ddbox);
7365     if (comm->eDLB == edlbAUTO)
7366     {
7367         if (fplog)
7368         {
7369             fprintf(fplog, "When dynamic load balancing gets turned on, these settings will change to:\n");
7370         }
7371         print_dd_settings(fplog, dd, ir, TRUE, dlb_scale, ddbox);
7372     }
7373
7374     if (ir->ePBC == epbcNONE)
7375     {
7376         vol_frac = 1 - 1/(double)dd->nnodes;
7377     }
7378     else
7379     {
7380         vol_frac =
7381             (1 + comm_box_frac(dd->nc, comm->cutoff, ddbox))/(double)dd->nnodes;
7382     }
7383     if (debug)
7384     {
7385         fprintf(debug, "Volume fraction for all DD zones: %f\n", vol_frac);
7386     }
7387     natoms_tot = comm->cgs_gl.index[comm->cgs_gl.nr];
7388
7389     dd->ga2la = ga2la_init(natoms_tot, vol_frac*natoms_tot);
7390 }
7391
7392 static gmx_bool test_dd_cutoff(t_commrec *cr,
7393                                t_state *state, t_inputrec *ir,
7394                                real cutoff_req)
7395 {
7396     gmx_domdec_t *dd;
7397     gmx_ddbox_t   ddbox;
7398     int           d, dim, np;
7399     real          inv_cell_size;
7400     int           LocallyLimited;
7401
7402     dd = cr->dd;
7403
7404     set_ddbox(dd, FALSE, cr, ir, state->box,
7405               TRUE, &dd->comm->cgs_gl, state->x, &ddbox);
7406
7407     LocallyLimited = 0;
7408
7409     for (d = 0; d < dd->ndim; d++)
7410     {
7411         dim = dd->dim[d];
7412
7413         inv_cell_size = DD_CELL_MARGIN*dd->nc[dim]/ddbox.box_size[dim];
7414         if (dynamic_dd_box(&ddbox, ir))
7415         {
7416             inv_cell_size *= DD_PRES_SCALE_MARGIN;
7417         }
7418
7419         np = 1 + (int)(cutoff_req*inv_cell_size*ddbox.skew_fac[dim]);
7420
7421         if (dd->comm->eDLB != edlbNO && dim < ddbox.npbcdim &&
7422             dd->comm->cd[d].np_dlb > 0)
7423         {
7424             if (np > dd->comm->cd[d].np_dlb)
7425             {
7426                 return FALSE;
7427             }
7428
7429             /* If a current local cell size is smaller than the requested
7430              * cut-off, we could still fix it, but this gets very complicated.
7431              * Without fixing here, we might actually need more checks.
7432              */
7433             if ((dd->comm->cell_x1[dim] - dd->comm->cell_x0[dim])*ddbox.skew_fac[dim]*dd->comm->cd[d].np_dlb < cutoff_req)
7434             {
7435                 LocallyLimited = 1;
7436             }
7437         }
7438     }
7439
7440     if (dd->comm->eDLB != edlbNO)
7441     {
7442         /* If DLB is not active yet, we don't need to check the grid jumps.
7443          * Actually we shouldn't, because then the grid jump data is not set.
7444          */
7445         if (dd->comm->bDynLoadBal &&
7446             check_grid_jump(0, dd, cutoff_req, &ddbox, FALSE))
7447         {
7448             LocallyLimited = 1;
7449         }
7450
7451         gmx_sumi(1, &LocallyLimited, cr);
7452
7453         if (LocallyLimited > 0)
7454         {
7455             return FALSE;
7456         }
7457     }
7458
7459     return TRUE;
7460 }
7461
7462 gmx_bool change_dd_cutoff(t_commrec *cr, t_state *state, t_inputrec *ir,
7463                           real cutoff_req)
7464 {
7465     gmx_bool bCutoffAllowed;
7466
7467     bCutoffAllowed = test_dd_cutoff(cr, state, ir, cutoff_req);
7468
7469     if (bCutoffAllowed)
7470     {
7471         cr->dd->comm->cutoff = cutoff_req;
7472     }
7473
7474     return bCutoffAllowed;
7475 }
7476
7477 void change_dd_dlb_cutoff_limit(t_commrec *cr)
7478 {
7479     gmx_domdec_comm_t *comm;
7480
7481     comm = cr->dd->comm;
7482
7483     /* Turn on the DLB limiting (might have been on already) */
7484     comm->bPMELoadBalDLBLimits = TRUE;
7485
7486     /* Change the cut-off limit */
7487     comm->PMELoadBal_max_cutoff = comm->cutoff;
7488 }
7489
7490 static void merge_cg_buffers(int ncell,
7491                              gmx_domdec_comm_dim_t *cd, int pulse,
7492                              int  *ncg_cell,
7493                              int  *index_gl, int  *recv_i,
7494                              rvec *cg_cm,    rvec *recv_vr,
7495                              int *cgindex,
7496                              cginfo_mb_t *cginfo_mb, int *cginfo)
7497 {
7498     gmx_domdec_ind_t *ind, *ind_p;
7499     int               p, cell, c, cg, cg0, cg1, cg_gl, nat;
7500     int               shift, shift_at;
7501
7502     ind = &cd->ind[pulse];
7503
7504     /* First correct the already stored data */
7505     shift = ind->nrecv[ncell];
7506     for (cell = ncell-1; cell >= 0; cell--)
7507     {
7508         shift -= ind->nrecv[cell];
7509         if (shift > 0)
7510         {
7511             /* Move the cg's present from previous grid pulses */
7512             cg0                = ncg_cell[ncell+cell];
7513             cg1                = ncg_cell[ncell+cell+1];
7514             cgindex[cg1+shift] = cgindex[cg1];
7515             for (cg = cg1-1; cg >= cg0; cg--)
7516             {
7517                 index_gl[cg+shift] = index_gl[cg];
7518                 copy_rvec(cg_cm[cg], cg_cm[cg+shift]);
7519                 cgindex[cg+shift] = cgindex[cg];
7520                 cginfo[cg+shift]  = cginfo[cg];
7521             }
7522             /* Correct the already stored send indices for the shift */
7523             for (p = 1; p <= pulse; p++)
7524             {
7525                 ind_p = &cd->ind[p];
7526                 cg0   = 0;
7527                 for (c = 0; c < cell; c++)
7528                 {
7529                     cg0 += ind_p->nsend[c];
7530                 }
7531                 cg1 = cg0 + ind_p->nsend[cell];
7532                 for (cg = cg0; cg < cg1; cg++)
7533                 {
7534                     ind_p->index[cg] += shift;
7535                 }
7536             }
7537         }
7538     }
7539
7540     /* Merge in the communicated buffers */
7541     shift    = 0;
7542     shift_at = 0;
7543     cg0      = 0;
7544     for (cell = 0; cell < ncell; cell++)
7545     {
7546         cg1 = ncg_cell[ncell+cell+1] + shift;
7547         if (shift_at > 0)
7548         {
7549             /* Correct the old cg indices */
7550             for (cg = ncg_cell[ncell+cell]; cg < cg1; cg++)
7551             {
7552                 cgindex[cg+1] += shift_at;
7553             }
7554         }
7555         for (cg = 0; cg < ind->nrecv[cell]; cg++)
7556         {
7557             /* Copy this charge group from the buffer */
7558             index_gl[cg1] = recv_i[cg0];
7559             copy_rvec(recv_vr[cg0], cg_cm[cg1]);
7560             /* Add it to the cgindex */
7561             cg_gl          = index_gl[cg1];
7562             cginfo[cg1]    = ddcginfo(cginfo_mb, cg_gl);
7563             nat            = GET_CGINFO_NATOMS(cginfo[cg1]);
7564             cgindex[cg1+1] = cgindex[cg1] + nat;
7565             cg0++;
7566             cg1++;
7567             shift_at += nat;
7568         }
7569         shift                 += ind->nrecv[cell];
7570         ncg_cell[ncell+cell+1] = cg1;
7571     }
7572 }
7573
7574 static void make_cell2at_index(gmx_domdec_comm_dim_t *cd,
7575                                int nzone, int cg0, const int *cgindex)
7576 {
7577     int cg, zone, p;
7578
7579     /* Store the atom block boundaries for easy copying of communication buffers
7580      */
7581     cg = cg0;
7582     for (zone = 0; zone < nzone; zone++)
7583     {
7584         for (p = 0; p < cd->np; p++)
7585         {
7586             cd->ind[p].cell2at0[zone] = cgindex[cg];
7587             cg += cd->ind[p].nrecv[zone];
7588             cd->ind[p].cell2at1[zone] = cgindex[cg];
7589         }
7590     }
7591 }
7592
7593 static gmx_bool missing_link(t_blocka *link, int cg_gl, char *bLocalCG)
7594 {
7595     int      i;
7596     gmx_bool bMiss;
7597
7598     bMiss = FALSE;
7599     for (i = link->index[cg_gl]; i < link->index[cg_gl+1]; i++)
7600     {
7601         if (!bLocalCG[link->a[i]])
7602         {
7603             bMiss = TRUE;
7604         }
7605     }
7606
7607     return bMiss;
7608 }
7609
7610 /* Domain corners for communication, a maximum of 4 i-zones see a j domain */
7611 typedef struct {
7612     real c[DIM][4]; /* the corners for the non-bonded communication */
7613     real cr0;       /* corner for rounding */
7614     real cr1[4];    /* corners for rounding */
7615     real bc[DIM];   /* corners for bounded communication */
7616     real bcr1;      /* corner for rounding for bonded communication */
7617 } dd_corners_t;
7618
7619 /* Determine the corners of the domain(s) we are communicating with */
7620 static void
7621 set_dd_corners(const gmx_domdec_t *dd,
7622                int dim0, int dim1, int dim2,
7623                gmx_bool bDistMB,
7624                dd_corners_t *c)
7625 {
7626     const gmx_domdec_comm_t  *comm;
7627     const gmx_domdec_zones_t *zones;
7628     int i, j;
7629
7630     comm = dd->comm;
7631
7632     zones = &comm->zones;
7633
7634     /* Keep the compiler happy */
7635     c->cr0  = 0;
7636     c->bcr1 = 0;
7637
7638     /* The first dimension is equal for all cells */
7639     c->c[0][0] = comm->cell_x0[dim0];
7640     if (bDistMB)
7641     {
7642         c->bc[0] = c->c[0][0];
7643     }
7644     if (dd->ndim >= 2)
7645     {
7646         dim1 = dd->dim[1];
7647         /* This cell row is only seen from the first row */
7648         c->c[1][0] = comm->cell_x0[dim1];
7649         /* All rows can see this row */
7650         c->c[1][1] = comm->cell_x0[dim1];
7651         if (dd->bGridJump)
7652         {
7653             c->c[1][1] = max(comm->cell_x0[dim1], comm->zone_d1[1].mch0);
7654             if (bDistMB)
7655             {
7656                 /* For the multi-body distance we need the maximum */
7657                 c->bc[1] = max(comm->cell_x0[dim1], comm->zone_d1[1].p1_0);
7658             }
7659         }
7660         /* Set the upper-right corner for rounding */
7661         c->cr0 = comm->cell_x1[dim0];
7662
7663         if (dd->ndim >= 3)
7664         {
7665             dim2 = dd->dim[2];
7666             for (j = 0; j < 4; j++)
7667             {
7668                 c->c[2][j] = comm->cell_x0[dim2];
7669             }
7670             if (dd->bGridJump)
7671             {
7672                 /* Use the maximum of the i-cells that see a j-cell */
7673                 for (i = 0; i < zones->nizone; i++)
7674                 {
7675                     for (j = zones->izone[i].j0; j < zones->izone[i].j1; j++)
7676                     {
7677                         if (j >= 4)
7678                         {
7679                             c->c[2][j-4] =
7680                                 max(c->c[2][j-4],
7681                                     comm->zone_d2[zones->shift[i][dim0]][zones->shift[i][dim1]].mch0);
7682                         }
7683                     }
7684                 }
7685                 if (bDistMB)
7686                 {
7687                     /* For the multi-body distance we need the maximum */
7688                     c->bc[2] = comm->cell_x0[dim2];
7689                     for (i = 0; i < 2; i++)
7690                     {
7691                         for (j = 0; j < 2; j++)
7692                         {
7693                             c->bc[2] = max(c->bc[2], comm->zone_d2[i][j].p1_0);
7694                         }
7695                     }
7696                 }
7697             }
7698
7699             /* Set the upper-right corner for rounding */
7700             /* Cell (0,0,0) and cell (1,0,0) can see cell 4 (0,1,1)
7701              * Only cell (0,0,0) can see cell 7 (1,1,1)
7702              */
7703             c->cr1[0] = comm->cell_x1[dim1];
7704             c->cr1[3] = comm->cell_x1[dim1];
7705             if (dd->bGridJump)
7706             {
7707                 c->cr1[0] = max(comm->cell_x1[dim1], comm->zone_d1[1].mch1);
7708                 if (bDistMB)
7709                 {
7710                     /* For the multi-body distance we need the maximum */
7711                     c->bcr1 = max(comm->cell_x1[dim1], comm->zone_d1[1].p1_1);
7712                 }
7713             }
7714         }
7715     }
7716 }
7717
7718 /* Determine which cg's we need to send in this pulse from this zone */
7719 static void
7720 get_zone_pulse_cgs(gmx_domdec_t *dd,
7721                    int zonei, int zone,
7722                    int cg0, int cg1,
7723                    const int *index_gl,
7724                    const int *cgindex,
7725                    int dim, int dim_ind,
7726                    int dim0, int dim1, int dim2,
7727                    real r_comm2, real r_bcomm2,
7728                    matrix box,
7729                    ivec tric_dist,
7730                    rvec *normal,
7731                    real skew_fac2_d, real skew_fac_01,
7732                    rvec *v_d, rvec *v_0, rvec *v_1,
7733                    const dd_corners_t *c,
7734                    rvec sf2_round,
7735                    gmx_bool bDistBonded,
7736                    gmx_bool bBondComm,
7737                    gmx_bool bDist2B,
7738                    gmx_bool bDistMB,
7739                    rvec *cg_cm,
7740                    int *cginfo,
7741                    gmx_domdec_ind_t *ind,
7742                    int **ibuf, int *ibuf_nalloc,
7743                    vec_rvec_t *vbuf,
7744                    int *nsend_ptr,
7745                    int *nat_ptr,
7746                    int *nsend_z_ptr)
7747 {
7748     gmx_domdec_comm_t *comm;
7749     gmx_bool           bScrew;
7750     gmx_bool           bDistMB_pulse;
7751     int                cg, i;
7752     real               r2, rb2, r, tric_sh;
7753     rvec               rn, rb;
7754     int                dimd;
7755     int                nsend_z, nsend, nat;
7756
7757     comm = dd->comm;
7758
7759     bScrew = (dd->bScrewPBC && dim == XX);
7760
7761     bDistMB_pulse = (bDistMB && bDistBonded);
7762
7763     nsend_z = 0;
7764     nsend   = *nsend_ptr;
7765     nat     = *nat_ptr;
7766
7767     for (cg = cg0; cg < cg1; cg++)
7768     {
7769         r2  = 0;
7770         rb2 = 0;
7771         if (tric_dist[dim_ind] == 0)
7772         {
7773             /* Rectangular direction, easy */
7774             r = cg_cm[cg][dim] - c->c[dim_ind][zone];
7775             if (r > 0)
7776             {
7777                 r2 += r*r;
7778             }
7779             if (bDistMB_pulse)
7780             {
7781                 r = cg_cm[cg][dim] - c->bc[dim_ind];
7782                 if (r > 0)
7783                 {
7784                     rb2 += r*r;
7785                 }
7786             }
7787             /* Rounding gives at most a 16% reduction
7788              * in communicated atoms
7789              */
7790             if (dim_ind >= 1 && (zonei == 1 || zonei == 2))
7791             {
7792                 r = cg_cm[cg][dim0] - c->cr0;
7793                 /* This is the first dimension, so always r >= 0 */
7794                 r2 += r*r;
7795                 if (bDistMB_pulse)
7796                 {
7797                     rb2 += r*r;
7798                 }
7799             }
7800             if (dim_ind == 2 && (zonei == 2 || zonei == 3))
7801             {
7802                 r = cg_cm[cg][dim1] - c->cr1[zone];
7803                 if (r > 0)
7804                 {
7805                     r2 += r*r;
7806                 }
7807                 if (bDistMB_pulse)
7808                 {
7809                     r = cg_cm[cg][dim1] - c->bcr1;
7810                     if (r > 0)
7811                     {
7812                         rb2 += r*r;
7813                     }
7814                 }
7815             }
7816         }
7817         else
7818         {
7819             /* Triclinic direction, more complicated */
7820             clear_rvec(rn);
7821             clear_rvec(rb);
7822             /* Rounding, conservative as the skew_fac multiplication
7823              * will slightly underestimate the distance.
7824              */
7825             if (dim_ind >= 1 && (zonei == 1 || zonei == 2))
7826             {
7827                 rn[dim0] = cg_cm[cg][dim0] - c->cr0;
7828                 for (i = dim0+1; i < DIM; i++)
7829                 {
7830                     rn[dim0] -= cg_cm[cg][i]*v_0[i][dim0];
7831                 }
7832                 r2 = rn[dim0]*rn[dim0]*sf2_round[dim0];
7833                 if (bDistMB_pulse)
7834                 {
7835                     rb[dim0] = rn[dim0];
7836                     rb2      = r2;
7837                 }
7838                 /* Take care that the cell planes along dim0 might not
7839                  * be orthogonal to those along dim1 and dim2.
7840                  */
7841                 for (i = 1; i <= dim_ind; i++)
7842                 {
7843                     dimd = dd->dim[i];
7844                     if (normal[dim0][dimd] > 0)
7845                     {
7846                         rn[dimd] -= rn[dim0]*normal[dim0][dimd];
7847                         if (bDistMB_pulse)
7848                         {
7849                             rb[dimd] -= rb[dim0]*normal[dim0][dimd];
7850                         }
7851                     }
7852                 }
7853             }
7854             if (dim_ind == 2 && (zonei == 2 || zonei == 3))
7855             {
7856                 rn[dim1] += cg_cm[cg][dim1] - c->cr1[zone];
7857                 tric_sh   = 0;
7858                 for (i = dim1+1; i < DIM; i++)
7859                 {
7860                     tric_sh -= cg_cm[cg][i]*v_1[i][dim1];
7861                 }
7862                 rn[dim1] += tric_sh;
7863                 if (rn[dim1] > 0)
7864                 {
7865                     r2 += rn[dim1]*rn[dim1]*sf2_round[dim1];
7866                     /* Take care of coupling of the distances
7867                      * to the planes along dim0 and dim1 through dim2.
7868                      */
7869                     r2 -= rn[dim0]*rn[dim1]*skew_fac_01;
7870                     /* Take care that the cell planes along dim1
7871                      * might not be orthogonal to that along dim2.
7872                      */
7873                     if (normal[dim1][dim2] > 0)
7874                     {
7875                         rn[dim2] -= rn[dim1]*normal[dim1][dim2];
7876                     }
7877                 }
7878                 if (bDistMB_pulse)
7879                 {
7880                     rb[dim1] +=
7881                         cg_cm[cg][dim1] - c->bcr1 + tric_sh;
7882                     if (rb[dim1] > 0)
7883                     {
7884                         rb2 += rb[dim1]*rb[dim1]*sf2_round[dim1];
7885                         /* Take care of coupling of the distances
7886                          * to the planes along dim0 and dim1 through dim2.
7887                          */
7888                         rb2 -= rb[dim0]*rb[dim1]*skew_fac_01;
7889                         /* Take care that the cell planes along dim1
7890                          * might not be orthogonal to that along dim2.
7891                          */
7892                         if (normal[dim1][dim2] > 0)
7893                         {
7894                             rb[dim2] -= rb[dim1]*normal[dim1][dim2];
7895                         }
7896                     }
7897                 }
7898             }
7899             /* The distance along the communication direction */
7900             rn[dim] += cg_cm[cg][dim] - c->c[dim_ind][zone];
7901             tric_sh  = 0;
7902             for (i = dim+1; i < DIM; i++)
7903             {
7904                 tric_sh -= cg_cm[cg][i]*v_d[i][dim];
7905             }
7906             rn[dim] += tric_sh;
7907             if (rn[dim] > 0)
7908             {
7909                 r2 += rn[dim]*rn[dim]*skew_fac2_d;
7910                 /* Take care of coupling of the distances
7911                  * to the planes along dim0 and dim1 through dim2.
7912                  */
7913                 if (dim_ind == 1 && zonei == 1)
7914                 {
7915                     r2 -= rn[dim0]*rn[dim]*skew_fac_01;
7916                 }
7917             }
7918             if (bDistMB_pulse)
7919             {
7920                 clear_rvec(rb);
7921                 rb[dim] += cg_cm[cg][dim] - c->bc[dim_ind] + tric_sh;
7922                 if (rb[dim] > 0)
7923                 {
7924                     rb2 += rb[dim]*rb[dim]*skew_fac2_d;
7925                     /* Take care of coupling of the distances
7926                      * to the planes along dim0 and dim1 through dim2.
7927                      */
7928                     if (dim_ind == 1 && zonei == 1)
7929                     {
7930                         rb2 -= rb[dim0]*rb[dim]*skew_fac_01;
7931                     }
7932                 }
7933             }
7934         }
7935
7936         if (r2 < r_comm2 ||
7937             (bDistBonded &&
7938              ((bDistMB && rb2 < r_bcomm2) ||
7939               (bDist2B && r2  < r_bcomm2)) &&
7940              (!bBondComm ||
7941               (GET_CGINFO_BOND_INTER(cginfo[cg]) &&
7942                missing_link(comm->cglink, index_gl[cg],
7943                             comm->bLocalCG)))))
7944         {
7945             /* Make an index to the local charge groups */
7946             if (nsend+1 > ind->nalloc)
7947             {
7948                 ind->nalloc = over_alloc_large(nsend+1);
7949                 srenew(ind->index, ind->nalloc);
7950             }
7951             if (nsend+1 > *ibuf_nalloc)
7952             {
7953                 *ibuf_nalloc = over_alloc_large(nsend+1);
7954                 srenew(*ibuf, *ibuf_nalloc);
7955             }
7956             ind->index[nsend] = cg;
7957             (*ibuf)[nsend]    = index_gl[cg];
7958             nsend_z++;
7959             vec_rvec_check_alloc(vbuf, nsend+1);
7960
7961             if (dd->ci[dim] == 0)
7962             {
7963                 /* Correct cg_cm for pbc */
7964                 rvec_add(cg_cm[cg], box[dim], vbuf->v[nsend]);
7965                 if (bScrew)
7966                 {
7967                     vbuf->v[nsend][YY] = box[YY][YY] - vbuf->v[nsend][YY];
7968                     vbuf->v[nsend][ZZ] = box[ZZ][ZZ] - vbuf->v[nsend][ZZ];
7969                 }
7970             }
7971             else
7972             {
7973                 copy_rvec(cg_cm[cg], vbuf->v[nsend]);
7974             }
7975             nsend++;
7976             nat += cgindex[cg+1] - cgindex[cg];
7977         }
7978     }
7979
7980     *nsend_ptr   = nsend;
7981     *nat_ptr     = nat;
7982     *nsend_z_ptr = nsend_z;
7983 }
7984
7985 static void setup_dd_communication(gmx_domdec_t *dd,
7986                                    matrix box, gmx_ddbox_t *ddbox,
7987                                    t_forcerec *fr, t_state *state, rvec **f)
7988 {
7989     int                    dim_ind, dim, dim0, dim1, dim2, dimd, p, nat_tot;
7990     int                    nzone, nzone_send, zone, zonei, cg0, cg1;
7991     int                    c, i, j, cg, cg_gl, nrcg;
7992     int                   *zone_cg_range, pos_cg, *index_gl, *cgindex, *recv_i;
7993     gmx_domdec_comm_t     *comm;
7994     gmx_domdec_zones_t    *zones;
7995     gmx_domdec_comm_dim_t *cd;
7996     gmx_domdec_ind_t      *ind;
7997     cginfo_mb_t           *cginfo_mb;
7998     gmx_bool               bBondComm, bDist2B, bDistMB, bDistBonded;
7999     real                   r_mb, r_comm2, r_scomm2, r_bcomm2, r_0, r_1, r2inc, inv_ncg;
8000     dd_corners_t           corners;
8001     ivec                   tric_dist;
8002     rvec                  *cg_cm, *normal, *v_d, *v_0 = NULL, *v_1 = NULL, *recv_vr;
8003     real                   skew_fac2_d, skew_fac_01;
8004     rvec                   sf2_round;
8005     int                    nsend, nat;
8006     int                    th;
8007
8008     if (debug)
8009     {
8010         fprintf(debug, "Setting up DD communication\n");
8011     }
8012
8013     comm  = dd->comm;
8014
8015     switch (fr->cutoff_scheme)
8016     {
8017         case ecutsGROUP:
8018             cg_cm = fr->cg_cm;
8019             break;
8020         case ecutsVERLET:
8021             cg_cm = state->x;
8022             break;
8023         default:
8024             gmx_incons("unimplemented");
8025             cg_cm = NULL;
8026     }
8027
8028     for (dim_ind = 0; dim_ind < dd->ndim; dim_ind++)
8029     {
8030         dim = dd->dim[dim_ind];
8031
8032         /* Check if we need to use triclinic distances */
8033         tric_dist[dim_ind] = 0;
8034         for (i = 0; i <= dim_ind; i++)
8035         {
8036             if (ddbox->tric_dir[dd->dim[i]])
8037             {
8038                 tric_dist[dim_ind] = 1;
8039             }
8040         }
8041     }
8042
8043     bBondComm = comm->bBondComm;
8044
8045     /* Do we need to determine extra distances for multi-body bondeds? */
8046     bDistMB = (comm->bInterCGMultiBody && dd->bGridJump && dd->ndim > 1);
8047
8048     /* Do we need to determine extra distances for only two-body bondeds? */
8049     bDist2B = (bBondComm && !bDistMB);
8050
8051     r_comm2  = sqr(comm->cutoff);
8052     r_bcomm2 = sqr(comm->cutoff_mbody);
8053
8054     if (debug)
8055     {
8056         fprintf(debug, "bBondComm %d, r_bc %f\n", bBondComm, sqrt(r_bcomm2));
8057     }
8058
8059     zones = &comm->zones;
8060
8061     dim0 = dd->dim[0];
8062     dim1 = (dd->ndim >= 2 ? dd->dim[1] : -1);
8063     dim2 = (dd->ndim >= 3 ? dd->dim[2] : -1);
8064
8065     set_dd_corners(dd, dim0, dim1, dim2, bDistMB, &corners);
8066
8067     /* Triclinic stuff */
8068     normal      = ddbox->normal;
8069     skew_fac_01 = 0;
8070     if (dd->ndim >= 2)
8071     {
8072         v_0 = ddbox->v[dim0];
8073         if (ddbox->tric_dir[dim0] && ddbox->tric_dir[dim1])
8074         {
8075             /* Determine the coupling coefficient for the distances
8076              * to the cell planes along dim0 and dim1 through dim2.
8077              * This is required for correct rounding.
8078              */
8079             skew_fac_01 =
8080                 ddbox->v[dim0][dim1+1][dim0]*ddbox->v[dim1][dim1+1][dim1];
8081             if (debug)
8082             {
8083                 fprintf(debug, "\nskew_fac_01 %f\n", skew_fac_01);
8084             }
8085         }
8086     }
8087     if (dd->ndim >= 3)
8088     {
8089         v_1 = ddbox->v[dim1];
8090     }
8091
8092     zone_cg_range = zones->cg_range;
8093     index_gl      = dd->index_gl;
8094     cgindex       = dd->cgindex;
8095     cginfo_mb     = fr->cginfo_mb;
8096
8097     zone_cg_range[0]   = 0;
8098     zone_cg_range[1]   = dd->ncg_home;
8099     comm->zone_ncg1[0] = dd->ncg_home;
8100     pos_cg             = dd->ncg_home;
8101
8102     nat_tot = dd->nat_home;
8103     nzone   = 1;
8104     for (dim_ind = 0; dim_ind < dd->ndim; dim_ind++)
8105     {
8106         dim = dd->dim[dim_ind];
8107         cd  = &comm->cd[dim_ind];
8108
8109         if (dim >= ddbox->npbcdim && dd->ci[dim] == 0)
8110         {
8111             /* No pbc in this dimension, the first node should not comm. */
8112             nzone_send = 0;
8113         }
8114         else
8115         {
8116             nzone_send = nzone;
8117         }
8118
8119         v_d         = ddbox->v[dim];
8120         skew_fac2_d = sqr(ddbox->skew_fac[dim]);
8121
8122         cd->bInPlace = TRUE;
8123         for (p = 0; p < cd->np; p++)
8124         {
8125             /* Only atoms communicated in the first pulse are used
8126              * for multi-body bonded interactions or for bBondComm.
8127              */
8128             bDistBonded = ((bDistMB || bDist2B) && p == 0);
8129
8130             ind   = &cd->ind[p];
8131             nsend = 0;
8132             nat   = 0;
8133             for (zone = 0; zone < nzone_send; zone++)
8134             {
8135                 if (tric_dist[dim_ind] && dim_ind > 0)
8136                 {
8137                     /* Determine slightly more optimized skew_fac's
8138                      * for rounding.
8139                      * This reduces the number of communicated atoms
8140                      * by about 10% for 3D DD of rhombic dodecahedra.
8141                      */
8142                     for (dimd = 0; dimd < dim; dimd++)
8143                     {
8144                         sf2_round[dimd] = 1;
8145                         if (ddbox->tric_dir[dimd])
8146                         {
8147                             for (i = dd->dim[dimd]+1; i < DIM; i++)
8148                             {
8149                                 /* If we are shifted in dimension i
8150                                  * and the cell plane is tilted forward
8151                                  * in dimension i, skip this coupling.
8152                                  */
8153                                 if (!(zones->shift[nzone+zone][i] &&
8154                                       ddbox->v[dimd][i][dimd] >= 0))
8155                                 {
8156                                     sf2_round[dimd] +=
8157                                         sqr(ddbox->v[dimd][i][dimd]);
8158                                 }
8159                             }
8160                             sf2_round[dimd] = 1/sf2_round[dimd];
8161                         }
8162                     }
8163                 }
8164
8165                 zonei = zone_perm[dim_ind][zone];
8166                 if (p == 0)
8167                 {
8168                     /* Here we permutate the zones to obtain a convenient order
8169                      * for neighbor searching
8170                      */
8171                     cg0 = zone_cg_range[zonei];
8172                     cg1 = zone_cg_range[zonei+1];
8173                 }
8174                 else
8175                 {
8176                     /* Look only at the cg's received in the previous grid pulse
8177                      */
8178                     cg1 = zone_cg_range[nzone+zone+1];
8179                     cg0 = cg1 - cd->ind[p-1].nrecv[zone];
8180                 }
8181
8182 #pragma omp parallel for num_threads(comm->nth) schedule(static)
8183                 for (th = 0; th < comm->nth; th++)
8184                 {
8185                     gmx_domdec_ind_t *ind_p;
8186                     int             **ibuf_p, *ibuf_nalloc_p;
8187                     vec_rvec_t       *vbuf_p;
8188                     int              *nsend_p, *nat_p;
8189                     int              *nsend_zone_p;
8190                     int               cg0_th, cg1_th;
8191
8192                     if (th == 0)
8193                     {
8194                         /* Thread 0 writes in the comm buffers */
8195                         ind_p         = ind;
8196                         ibuf_p        = &comm->buf_int;
8197                         ibuf_nalloc_p = &comm->nalloc_int;
8198                         vbuf_p        = &comm->vbuf;
8199                         nsend_p       = &nsend;
8200                         nat_p         = &nat;
8201                         nsend_zone_p  = &ind->nsend[zone];
8202                     }
8203                     else
8204                     {
8205                         /* Other threads write into temp buffers */
8206                         ind_p         = &comm->dth[th].ind;
8207                         ibuf_p        = &comm->dth[th].ibuf;
8208                         ibuf_nalloc_p = &comm->dth[th].ibuf_nalloc;
8209                         vbuf_p        = &comm->dth[th].vbuf;
8210                         nsend_p       = &comm->dth[th].nsend;
8211                         nat_p         = &comm->dth[th].nat;
8212                         nsend_zone_p  = &comm->dth[th].nsend_zone;
8213
8214                         comm->dth[th].nsend      = 0;
8215                         comm->dth[th].nat        = 0;
8216                         comm->dth[th].nsend_zone = 0;
8217                     }
8218
8219                     if (comm->nth == 1)
8220                     {
8221                         cg0_th = cg0;
8222                         cg1_th = cg1;
8223                     }
8224                     else
8225                     {
8226                         cg0_th = cg0 + ((cg1 - cg0)* th   )/comm->nth;
8227                         cg1_th = cg0 + ((cg1 - cg0)*(th+1))/comm->nth;
8228                     }
8229
8230                     /* Get the cg's for this pulse in this zone */
8231                     get_zone_pulse_cgs(dd, zonei, zone, cg0_th, cg1_th,
8232                                        index_gl, cgindex,
8233                                        dim, dim_ind, dim0, dim1, dim2,
8234                                        r_comm2, r_bcomm2,
8235                                        box, tric_dist,
8236                                        normal, skew_fac2_d, skew_fac_01,
8237                                        v_d, v_0, v_1, &corners, sf2_round,
8238                                        bDistBonded, bBondComm,
8239                                        bDist2B, bDistMB,
8240                                        cg_cm, fr->cginfo,
8241                                        ind_p,
8242                                        ibuf_p, ibuf_nalloc_p,
8243                                        vbuf_p,
8244                                        nsend_p, nat_p,
8245                                        nsend_zone_p);
8246                 }
8247
8248                 /* Append data of threads>=1 to the communication buffers */
8249                 for (th = 1; th < comm->nth; th++)
8250                 {
8251                     dd_comm_setup_work_t *dth;
8252                     int                   i, ns1;
8253
8254                     dth = &comm->dth[th];
8255
8256                     ns1 = nsend + dth->nsend_zone;
8257                     if (ns1 > ind->nalloc)
8258                     {
8259                         ind->nalloc = over_alloc_dd(ns1);
8260                         srenew(ind->index, ind->nalloc);
8261                     }
8262                     if (ns1 > comm->nalloc_int)
8263                     {
8264                         comm->nalloc_int = over_alloc_dd(ns1);
8265                         srenew(comm->buf_int, comm->nalloc_int);
8266                     }
8267                     if (ns1 > comm->vbuf.nalloc)
8268                     {
8269                         comm->vbuf.nalloc = over_alloc_dd(ns1);
8270                         srenew(comm->vbuf.v, comm->vbuf.nalloc);
8271                     }
8272
8273                     for (i = 0; i < dth->nsend_zone; i++)
8274                     {
8275                         ind->index[nsend]    = dth->ind.index[i];
8276                         comm->buf_int[nsend] = dth->ibuf[i];
8277                         copy_rvec(dth->vbuf.v[i],
8278                                   comm->vbuf.v[nsend]);
8279                         nsend++;
8280                     }
8281                     nat              += dth->nat;
8282                     ind->nsend[zone] += dth->nsend_zone;
8283                 }
8284             }
8285             /* Clear the counts in case we do not have pbc */
8286             for (zone = nzone_send; zone < nzone; zone++)
8287             {
8288                 ind->nsend[zone] = 0;
8289             }
8290             ind->nsend[nzone]   = nsend;
8291             ind->nsend[nzone+1] = nat;
8292             /* Communicate the number of cg's and atoms to receive */
8293             dd_sendrecv_int(dd, dim_ind, dddirBackward,
8294                             ind->nsend, nzone+2,
8295                             ind->nrecv, nzone+2);
8296
8297             /* The rvec buffer is also required for atom buffers of size nsend
8298              * in dd_move_x and dd_move_f.
8299              */
8300             vec_rvec_check_alloc(&comm->vbuf, ind->nsend[nzone+1]);
8301
8302             if (p > 0)
8303             {
8304                 /* We can receive in place if only the last zone is not empty */
8305                 for (zone = 0; zone < nzone-1; zone++)
8306                 {
8307                     if (ind->nrecv[zone] > 0)
8308                     {
8309                         cd->bInPlace = FALSE;
8310                     }
8311                 }
8312                 if (!cd->bInPlace)
8313                 {
8314                     /* The int buffer is only required here for the cg indices */
8315                     if (ind->nrecv[nzone] > comm->nalloc_int2)
8316                     {
8317                         comm->nalloc_int2 = over_alloc_dd(ind->nrecv[nzone]);
8318                         srenew(comm->buf_int2, comm->nalloc_int2);
8319                     }
8320                     /* The rvec buffer is also required for atom buffers
8321                      * of size nrecv in dd_move_x and dd_move_f.
8322                      */
8323                     i = max(cd->ind[0].nrecv[nzone+1], ind->nrecv[nzone+1]);
8324                     vec_rvec_check_alloc(&comm->vbuf2, i);
8325                 }
8326             }
8327
8328             /* Make space for the global cg indices */
8329             if (pos_cg + ind->nrecv[nzone] > dd->cg_nalloc
8330                 || dd->cg_nalloc == 0)
8331             {
8332                 dd->cg_nalloc = over_alloc_dd(pos_cg + ind->nrecv[nzone]);
8333                 srenew(index_gl, dd->cg_nalloc);
8334                 srenew(cgindex, dd->cg_nalloc+1);
8335             }
8336             /* Communicate the global cg indices */
8337             if (cd->bInPlace)
8338             {
8339                 recv_i = index_gl + pos_cg;
8340             }
8341             else
8342             {
8343                 recv_i = comm->buf_int2;
8344             }
8345             dd_sendrecv_int(dd, dim_ind, dddirBackward,
8346                             comm->buf_int, nsend,
8347                             recv_i,        ind->nrecv[nzone]);
8348
8349             /* Make space for cg_cm */
8350             dd_check_alloc_ncg(fr, state, f, pos_cg + ind->nrecv[nzone]);
8351             if (fr->cutoff_scheme == ecutsGROUP)
8352             {
8353                 cg_cm = fr->cg_cm;
8354             }
8355             else
8356             {
8357                 cg_cm = state->x;
8358             }
8359             /* Communicate cg_cm */
8360             if (cd->bInPlace)
8361             {
8362                 recv_vr = cg_cm + pos_cg;
8363             }
8364             else
8365             {
8366                 recv_vr = comm->vbuf2.v;
8367             }
8368             dd_sendrecv_rvec(dd, dim_ind, dddirBackward,
8369                              comm->vbuf.v, nsend,
8370                              recv_vr,      ind->nrecv[nzone]);
8371
8372             /* Make the charge group index */
8373             if (cd->bInPlace)
8374             {
8375                 zone = (p == 0 ? 0 : nzone - 1);
8376                 while (zone < nzone)
8377                 {
8378                     for (cg = 0; cg < ind->nrecv[zone]; cg++)
8379                     {
8380                         cg_gl              = index_gl[pos_cg];
8381                         fr->cginfo[pos_cg] = ddcginfo(cginfo_mb, cg_gl);
8382                         nrcg               = GET_CGINFO_NATOMS(fr->cginfo[pos_cg]);
8383                         cgindex[pos_cg+1]  = cgindex[pos_cg] + nrcg;
8384                         if (bBondComm)
8385                         {
8386                             /* Update the charge group presence,
8387                              * so we can use it in the next pass of the loop.
8388                              */
8389                             comm->bLocalCG[cg_gl] = TRUE;
8390                         }
8391                         pos_cg++;
8392                     }
8393                     if (p == 0)
8394                     {
8395                         comm->zone_ncg1[nzone+zone] = ind->nrecv[zone];
8396                     }
8397                     zone++;
8398                     zone_cg_range[nzone+zone] = pos_cg;
8399                 }
8400             }
8401             else
8402             {
8403                 /* This part of the code is never executed with bBondComm. */
8404                 merge_cg_buffers(nzone, cd, p, zone_cg_range,
8405                                  index_gl, recv_i, cg_cm, recv_vr,
8406                                  cgindex, fr->cginfo_mb, fr->cginfo);
8407                 pos_cg += ind->nrecv[nzone];
8408             }
8409             nat_tot += ind->nrecv[nzone+1];
8410         }
8411         if (!cd->bInPlace)
8412         {
8413             /* Store the atom block for easy copying of communication buffers */
8414             make_cell2at_index(cd, nzone, zone_cg_range[nzone], cgindex);
8415         }
8416         nzone += nzone;
8417     }
8418     dd->index_gl = index_gl;
8419     dd->cgindex  = cgindex;
8420
8421     dd->ncg_tot          = zone_cg_range[zones->n];
8422     dd->nat_tot          = nat_tot;
8423     comm->nat[ddnatHOME] = dd->nat_home;
8424     for (i = ddnatZONE; i < ddnatNR; i++)
8425     {
8426         comm->nat[i] = dd->nat_tot;
8427     }
8428
8429     if (!bBondComm)
8430     {
8431         /* We don't need to update cginfo, since that was alrady done above.
8432          * So we pass NULL for the forcerec.
8433          */
8434         dd_set_cginfo(dd->index_gl, dd->ncg_home, dd->ncg_tot,
8435                       NULL, comm->bLocalCG);
8436     }
8437
8438     if (debug)
8439     {
8440         fprintf(debug, "Finished setting up DD communication, zones:");
8441         for (c = 0; c < zones->n; c++)
8442         {
8443             fprintf(debug, " %d", zones->cg_range[c+1]-zones->cg_range[c]);
8444         }
8445         fprintf(debug, "\n");
8446     }
8447 }
8448
8449 static void set_cg_boundaries(gmx_domdec_zones_t *zones)
8450 {
8451     int c;
8452
8453     for (c = 0; c < zones->nizone; c++)
8454     {
8455         zones->izone[c].cg1  = zones->cg_range[c+1];
8456         zones->izone[c].jcg0 = zones->cg_range[zones->izone[c].j0];
8457         zones->izone[c].jcg1 = zones->cg_range[zones->izone[c].j1];
8458     }
8459 }
8460
8461 static void set_zones_size(gmx_domdec_t *dd,
8462                            matrix box, const gmx_ddbox_t *ddbox,
8463                            int zone_start, int zone_end)
8464 {
8465     gmx_domdec_comm_t  *comm;
8466     gmx_domdec_zones_t *zones;
8467     gmx_bool            bDistMB;
8468     int                 z, zi, zj0, zj1, d, dim;
8469     real                rcs, rcmbs;
8470     int                 i, j;
8471     real                size_j, add_tric;
8472     real                vol;
8473
8474     comm = dd->comm;
8475
8476     zones = &comm->zones;
8477
8478     /* Do we need to determine extra distances for multi-body bondeds? */
8479     bDistMB = (comm->bInterCGMultiBody && dd->bGridJump && dd->ndim > 1);
8480
8481     for (z = zone_start; z < zone_end; z++)
8482     {
8483         /* Copy cell limits to zone limits.
8484          * Valid for non-DD dims and non-shifted dims.
8485          */
8486         copy_rvec(comm->cell_x0, zones->size[z].x0);
8487         copy_rvec(comm->cell_x1, zones->size[z].x1);
8488     }
8489
8490     for (d = 0; d < dd->ndim; d++)
8491     {
8492         dim = dd->dim[d];
8493
8494         for (z = 0; z < zones->n; z++)
8495         {
8496             /* With a staggered grid we have different sizes
8497              * for non-shifted dimensions.
8498              */
8499             if (dd->bGridJump && zones->shift[z][dim] == 0)
8500             {
8501                 if (d == 1)
8502                 {
8503                     zones->size[z].x0[dim] = comm->zone_d1[zones->shift[z][dd->dim[d-1]]].min0;
8504                     zones->size[z].x1[dim] = comm->zone_d1[zones->shift[z][dd->dim[d-1]]].max1;
8505                 }
8506                 else if (d == 2)
8507                 {
8508                     zones->size[z].x0[dim] = comm->zone_d2[zones->shift[z][dd->dim[d-2]]][zones->shift[z][dd->dim[d-1]]].min0;
8509                     zones->size[z].x1[dim] = comm->zone_d2[zones->shift[z][dd->dim[d-2]]][zones->shift[z][dd->dim[d-1]]].max1;
8510                 }
8511             }
8512         }
8513
8514         rcs   = comm->cutoff;
8515         rcmbs = comm->cutoff_mbody;
8516         if (ddbox->tric_dir[dim])
8517         {
8518             rcs   /= ddbox->skew_fac[dim];
8519             rcmbs /= ddbox->skew_fac[dim];
8520         }
8521
8522         /* Set the lower limit for the shifted zone dimensions */
8523         for (z = zone_start; z < zone_end; z++)
8524         {
8525             if (zones->shift[z][dim] > 0)
8526             {
8527                 dim = dd->dim[d];
8528                 if (!dd->bGridJump || d == 0)
8529                 {
8530                     zones->size[z].x0[dim] = comm->cell_x1[dim];
8531                     zones->size[z].x1[dim] = comm->cell_x1[dim] + rcs;
8532                 }
8533                 else
8534                 {
8535                     /* Here we take the lower limit of the zone from
8536                      * the lowest domain of the zone below.
8537                      */
8538                     if (z < 4)
8539                     {
8540                         zones->size[z].x0[dim] =
8541                             comm->zone_d1[zones->shift[z][dd->dim[d-1]]].min1;
8542                     }
8543                     else
8544                     {
8545                         if (d == 1)
8546                         {
8547                             zones->size[z].x0[dim] =
8548                                 zones->size[zone_perm[2][z-4]].x0[dim];
8549                         }
8550                         else
8551                         {
8552                             zones->size[z].x0[dim] =
8553                                 comm->zone_d2[zones->shift[z][dd->dim[d-2]]][zones->shift[z][dd->dim[d-1]]].min1;
8554                         }
8555                     }
8556                     /* A temporary limit, is updated below */
8557                     zones->size[z].x1[dim] = zones->size[z].x0[dim];
8558
8559                     if (bDistMB)
8560                     {
8561                         for (zi = 0; zi < zones->nizone; zi++)
8562                         {
8563                             if (zones->shift[zi][dim] == 0)
8564                             {
8565                                 /* This takes the whole zone into account.
8566                                  * With multiple pulses this will lead
8567                                  * to a larger zone then strictly necessary.
8568                                  */
8569                                 zones->size[z].x1[dim] = max(zones->size[z].x1[dim],
8570                                                              zones->size[zi].x1[dim]+rcmbs);
8571                             }
8572                         }
8573                     }
8574                 }
8575             }
8576         }
8577
8578         /* Loop over the i-zones to set the upper limit of each
8579          * j-zone they see.
8580          */
8581         for (zi = 0; zi < zones->nizone; zi++)
8582         {
8583             if (zones->shift[zi][dim] == 0)
8584             {
8585                 for (z = zones->izone[zi].j0; z < zones->izone[zi].j1; z++)
8586                 {
8587                     if (zones->shift[z][dim] > 0)
8588                     {
8589                         zones->size[z].x1[dim] = max(zones->size[z].x1[dim],
8590                                                      zones->size[zi].x1[dim]+rcs);
8591                     }
8592                 }
8593             }
8594         }
8595     }
8596
8597     for (z = zone_start; z < zone_end; z++)
8598     {
8599         /* Initialization only required to keep the compiler happy */
8600         rvec corner_min = {0, 0, 0}, corner_max = {0, 0, 0}, corner;
8601         int  nc, c;
8602
8603         /* To determine the bounding box for a zone we need to find
8604          * the extreme corners of 4, 2 or 1 corners.
8605          */
8606         nc = 1 << (ddbox->npbcdim - 1);
8607
8608         for (c = 0; c < nc; c++)
8609         {
8610             /* Set up a zone corner at x=0, ignoring trilinic couplings */
8611             corner[XX] = 0;
8612             if ((c & 1) == 0)
8613             {
8614                 corner[YY] = zones->size[z].x0[YY];
8615             }
8616             else
8617             {
8618                 corner[YY] = zones->size[z].x1[YY];
8619             }
8620             if ((c & 2) == 0)
8621             {
8622                 corner[ZZ] = zones->size[z].x0[ZZ];
8623             }
8624             else
8625             {
8626                 corner[ZZ] = zones->size[z].x1[ZZ];
8627             }
8628             if (dd->ndim == 1 && box[ZZ][YY] != 0)
8629             {
8630                 /* With 1D domain decomposition the cg's are not in
8631                  * the triclinic box, but triclinic x-y and rectangular y-z.
8632                  * Shift y back, so it will later end up at 0.
8633                  */
8634                 corner[YY] -= corner[ZZ]*box[ZZ][YY]/box[ZZ][ZZ];
8635             }
8636             /* Apply the triclinic couplings */
8637             for (i = YY; i < ddbox->npbcdim; i++)
8638             {
8639                 for (j = XX; j < i; j++)
8640                 {
8641                     corner[j] += corner[i]*box[i][j]/box[i][i];
8642                 }
8643             }
8644             if (c == 0)
8645             {
8646                 copy_rvec(corner, corner_min);
8647                 copy_rvec(corner, corner_max);
8648             }
8649             else
8650             {
8651                 for (i = 0; i < DIM; i++)
8652                 {
8653                     corner_min[i] = min(corner_min[i], corner[i]);
8654                     corner_max[i] = max(corner_max[i], corner[i]);
8655                 }
8656             }
8657         }
8658         /* Copy the extreme cornes without offset along x */
8659         for (i = 0; i < DIM; i++)
8660         {
8661             zones->size[z].bb_x0[i] = corner_min[i];
8662             zones->size[z].bb_x1[i] = corner_max[i];
8663         }
8664         /* Add the offset along x */
8665         zones->size[z].bb_x0[XX] += zones->size[z].x0[XX];
8666         zones->size[z].bb_x1[XX] += zones->size[z].x1[XX];
8667     }
8668
8669     if (zone_start == 0)
8670     {
8671         vol = 1;
8672         for (dim = 0; dim < DIM; dim++)
8673         {
8674             vol *= zones->size[0].x1[dim] - zones->size[0].x0[dim];
8675         }
8676         zones->dens_zone0 = (zones->cg_range[1] - zones->cg_range[0])/vol;
8677     }
8678
8679     if (debug)
8680     {
8681         for (z = zone_start; z < zone_end; z++)
8682         {
8683             fprintf(debug, "zone %d    %6.3f - %6.3f  %6.3f - %6.3f  %6.3f - %6.3f\n",
8684                     z,
8685                     zones->size[z].x0[XX], zones->size[z].x1[XX],
8686                     zones->size[z].x0[YY], zones->size[z].x1[YY],
8687                     zones->size[z].x0[ZZ], zones->size[z].x1[ZZ]);
8688             fprintf(debug, "zone %d bb %6.3f - %6.3f  %6.3f - %6.3f  %6.3f - %6.3f\n",
8689                     z,
8690                     zones->size[z].bb_x0[XX], zones->size[z].bb_x1[XX],
8691                     zones->size[z].bb_x0[YY], zones->size[z].bb_x1[YY],
8692                     zones->size[z].bb_x0[ZZ], zones->size[z].bb_x1[ZZ]);
8693         }
8694     }
8695 }
8696
8697 static int comp_cgsort(const void *a, const void *b)
8698 {
8699     int           comp;
8700
8701     gmx_cgsort_t *cga, *cgb;
8702     cga = (gmx_cgsort_t *)a;
8703     cgb = (gmx_cgsort_t *)b;
8704
8705     comp = cga->nsc - cgb->nsc;
8706     if (comp == 0)
8707     {
8708         comp = cga->ind_gl - cgb->ind_gl;
8709     }
8710
8711     return comp;
8712 }
8713
8714 static void order_int_cg(int n, const gmx_cgsort_t *sort,
8715                          int *a, int *buf)
8716 {
8717     int i;
8718
8719     /* Order the data */
8720     for (i = 0; i < n; i++)
8721     {
8722         buf[i] = a[sort[i].ind];
8723     }
8724
8725     /* Copy back to the original array */
8726     for (i = 0; i < n; i++)
8727     {
8728         a[i] = buf[i];
8729     }
8730 }
8731
8732 static void order_vec_cg(int n, const gmx_cgsort_t *sort,
8733                          rvec *v, rvec *buf)
8734 {
8735     int i;
8736
8737     /* Order the data */
8738     for (i = 0; i < n; i++)
8739     {
8740         copy_rvec(v[sort[i].ind], buf[i]);
8741     }
8742
8743     /* Copy back to the original array */
8744     for (i = 0; i < n; i++)
8745     {
8746         copy_rvec(buf[i], v[i]);
8747     }
8748 }
8749
8750 static void order_vec_atom(int ncg, const int *cgindex, const gmx_cgsort_t *sort,
8751                            rvec *v, rvec *buf)
8752 {
8753     int a, atot, cg, cg0, cg1, i;
8754
8755     if (cgindex == NULL)
8756     {
8757         /* Avoid the useless loop of the atoms within a cg */
8758         order_vec_cg(ncg, sort, v, buf);
8759
8760         return;
8761     }
8762
8763     /* Order the data */
8764     a = 0;
8765     for (cg = 0; cg < ncg; cg++)
8766     {
8767         cg0 = cgindex[sort[cg].ind];
8768         cg1 = cgindex[sort[cg].ind+1];
8769         for (i = cg0; i < cg1; i++)
8770         {
8771             copy_rvec(v[i], buf[a]);
8772             a++;
8773         }
8774     }
8775     atot = a;
8776
8777     /* Copy back to the original array */
8778     for (a = 0; a < atot; a++)
8779     {
8780         copy_rvec(buf[a], v[a]);
8781     }
8782 }
8783
8784 static void ordered_sort(int nsort2, gmx_cgsort_t *sort2,
8785                          int nsort_new, gmx_cgsort_t *sort_new,
8786                          gmx_cgsort_t *sort1)
8787 {
8788     int i1, i2, i_new;
8789
8790     /* The new indices are not very ordered, so we qsort them */
8791     qsort_threadsafe(sort_new, nsort_new, sizeof(sort_new[0]), comp_cgsort);
8792
8793     /* sort2 is already ordered, so now we can merge the two arrays */
8794     i1    = 0;
8795     i2    = 0;
8796     i_new = 0;
8797     while (i2 < nsort2 || i_new < nsort_new)
8798     {
8799         if (i2 == nsort2)
8800         {
8801             sort1[i1++] = sort_new[i_new++];
8802         }
8803         else if (i_new == nsort_new)
8804         {
8805             sort1[i1++] = sort2[i2++];
8806         }
8807         else if (sort2[i2].nsc < sort_new[i_new].nsc ||
8808                  (sort2[i2].nsc == sort_new[i_new].nsc &&
8809                   sort2[i2].ind_gl < sort_new[i_new].ind_gl))
8810         {
8811             sort1[i1++] = sort2[i2++];
8812         }
8813         else
8814         {
8815             sort1[i1++] = sort_new[i_new++];
8816         }
8817     }
8818 }
8819
8820 static int dd_sort_order(gmx_domdec_t *dd, t_forcerec *fr, int ncg_home_old)
8821 {
8822     gmx_domdec_sort_t *sort;
8823     gmx_cgsort_t      *cgsort, *sort_i;
8824     int                ncg_new, nsort2, nsort_new, i, *a, moved, *ibuf;
8825     int                sort_last, sort_skip;
8826
8827     sort = dd->comm->sort;
8828
8829     a = fr->ns.grid->cell_index;
8830
8831     moved = NSGRID_SIGNAL_MOVED_FAC*fr->ns.grid->ncells;
8832
8833     if (ncg_home_old >= 0)
8834     {
8835         /* The charge groups that remained in the same ns grid cell
8836          * are completely ordered. So we can sort efficiently by sorting
8837          * the charge groups that did move into the stationary list.
8838          */
8839         ncg_new   = 0;
8840         nsort2    = 0;
8841         nsort_new = 0;
8842         for (i = 0; i < dd->ncg_home; i++)
8843         {
8844             /* Check if this cg did not move to another node */
8845             if (a[i] < moved)
8846             {
8847                 if (i >= ncg_home_old || a[i] != sort->sort[i].nsc)
8848                 {
8849                     /* This cg is new on this node or moved ns grid cell */
8850                     if (nsort_new >= sort->sort_new_nalloc)
8851                     {
8852                         sort->sort_new_nalloc = over_alloc_dd(nsort_new+1);
8853                         srenew(sort->sort_new, sort->sort_new_nalloc);
8854                     }
8855                     sort_i = &(sort->sort_new[nsort_new++]);
8856                 }
8857                 else
8858                 {
8859                     /* This cg did not move */
8860                     sort_i = &(sort->sort2[nsort2++]);
8861                 }
8862                 /* Sort on the ns grid cell indices
8863                  * and the global topology index.
8864                  * index_gl is irrelevant with cell ns,
8865                  * but we set it here anyhow to avoid a conditional.
8866                  */
8867                 sort_i->nsc    = a[i];
8868                 sort_i->ind_gl = dd->index_gl[i];
8869                 sort_i->ind    = i;
8870                 ncg_new++;
8871             }
8872         }
8873         if (debug)
8874         {
8875             fprintf(debug, "ordered sort cgs: stationary %d moved %d\n",
8876                     nsort2, nsort_new);
8877         }
8878         /* Sort efficiently */
8879         ordered_sort(nsort2, sort->sort2, nsort_new, sort->sort_new,
8880                      sort->sort);
8881     }
8882     else
8883     {
8884         cgsort  = sort->sort;
8885         ncg_new = 0;
8886         for (i = 0; i < dd->ncg_home; i++)
8887         {
8888             /* Sort on the ns grid cell indices
8889              * and the global topology index
8890              */
8891             cgsort[i].nsc    = a[i];
8892             cgsort[i].ind_gl = dd->index_gl[i];
8893             cgsort[i].ind    = i;
8894             if (cgsort[i].nsc < moved)
8895             {
8896                 ncg_new++;
8897             }
8898         }
8899         if (debug)
8900         {
8901             fprintf(debug, "qsort cgs: %d new home %d\n", dd->ncg_home, ncg_new);
8902         }
8903         /* Determine the order of the charge groups using qsort */
8904         qsort_threadsafe(cgsort, dd->ncg_home, sizeof(cgsort[0]), comp_cgsort);
8905     }
8906
8907     return ncg_new;
8908 }
8909
8910 static int dd_sort_order_nbnxn(gmx_domdec_t *dd, t_forcerec *fr)
8911 {
8912     gmx_cgsort_t *sort;
8913     int           ncg_new, i, *a, na;
8914
8915     sort = dd->comm->sort->sort;
8916
8917     nbnxn_get_atomorder(fr->nbv->nbs, &a, &na);
8918
8919     ncg_new = 0;
8920     for (i = 0; i < na; i++)
8921     {
8922         if (a[i] >= 0)
8923         {
8924             sort[ncg_new].ind = a[i];
8925             ncg_new++;
8926         }
8927     }
8928
8929     return ncg_new;
8930 }
8931
8932 static void dd_sort_state(gmx_domdec_t *dd, rvec *cgcm, t_forcerec *fr, t_state *state,
8933                           int ncg_home_old)
8934 {
8935     gmx_domdec_sort_t *sort;
8936     gmx_cgsort_t      *cgsort, *sort_i;
8937     int               *cgindex;
8938     int                ncg_new, i, *ibuf, cgsize;
8939     rvec              *vbuf;
8940
8941     sort = dd->comm->sort;
8942
8943     if (dd->ncg_home > sort->sort_nalloc)
8944     {
8945         sort->sort_nalloc = over_alloc_dd(dd->ncg_home);
8946         srenew(sort->sort, sort->sort_nalloc);
8947         srenew(sort->sort2, sort->sort_nalloc);
8948     }
8949     cgsort = sort->sort;
8950
8951     switch (fr->cutoff_scheme)
8952     {
8953         case ecutsGROUP:
8954             ncg_new = dd_sort_order(dd, fr, ncg_home_old);
8955             break;
8956         case ecutsVERLET:
8957             ncg_new = dd_sort_order_nbnxn(dd, fr);
8958             break;
8959         default:
8960             gmx_incons("unimplemented");
8961             ncg_new = 0;
8962     }
8963
8964     /* We alloc with the old size, since cgindex is still old */
8965     vec_rvec_check_alloc(&dd->comm->vbuf, dd->cgindex[dd->ncg_home]);
8966     vbuf = dd->comm->vbuf.v;
8967
8968     if (dd->comm->bCGs)
8969     {
8970         cgindex = dd->cgindex;
8971     }
8972     else
8973     {
8974         cgindex = NULL;
8975     }
8976
8977     /* Remove the charge groups which are no longer at home here */
8978     dd->ncg_home = ncg_new;
8979     if (debug)
8980     {
8981         fprintf(debug, "Set the new home charge group count to %d\n",
8982                 dd->ncg_home);
8983     }
8984
8985     /* Reorder the state */
8986     for (i = 0; i < estNR; i++)
8987     {
8988         if (EST_DISTR(i) && (state->flags & (1<<i)))
8989         {
8990             switch (i)
8991             {
8992                 case estX:
8993                     order_vec_atom(dd->ncg_home, cgindex, cgsort, state->x, vbuf);
8994                     break;
8995                 case estV:
8996                     order_vec_atom(dd->ncg_home, cgindex, cgsort, state->v, vbuf);
8997                     break;
8998                 case estSDX:
8999                     order_vec_atom(dd->ncg_home, cgindex, cgsort, state->sd_X, vbuf);
9000                     break;
9001                 case estCGP:
9002                     order_vec_atom(dd->ncg_home, cgindex, cgsort, state->cg_p, vbuf);
9003                     break;
9004                 case estLD_RNG:
9005                 case estLD_RNGI:
9006                 case estDISRE_INITF:
9007                 case estDISRE_RM3TAV:
9008                 case estORIRE_INITF:
9009                 case estORIRE_DTAV:
9010                     /* No ordering required */
9011                     break;
9012                 default:
9013                     gmx_incons("Unknown state entry encountered in dd_sort_state");
9014                     break;
9015             }
9016         }
9017     }
9018     if (fr->cutoff_scheme == ecutsGROUP)
9019     {
9020         /* Reorder cgcm */
9021         order_vec_cg(dd->ncg_home, cgsort, cgcm, vbuf);
9022     }
9023
9024     if (dd->ncg_home+1 > sort->ibuf_nalloc)
9025     {
9026         sort->ibuf_nalloc = over_alloc_dd(dd->ncg_home+1);
9027         srenew(sort->ibuf, sort->ibuf_nalloc);
9028     }
9029     ibuf = sort->ibuf;
9030     /* Reorder the global cg index */
9031     order_int_cg(dd->ncg_home, cgsort, dd->index_gl, ibuf);
9032     /* Reorder the cginfo */
9033     order_int_cg(dd->ncg_home, cgsort, fr->cginfo, ibuf);
9034     /* Rebuild the local cg index */
9035     if (dd->comm->bCGs)
9036     {
9037         ibuf[0] = 0;
9038         for (i = 0; i < dd->ncg_home; i++)
9039         {
9040             cgsize    = dd->cgindex[cgsort[i].ind+1] - dd->cgindex[cgsort[i].ind];
9041             ibuf[i+1] = ibuf[i] + cgsize;
9042         }
9043         for (i = 0; i < dd->ncg_home+1; i++)
9044         {
9045             dd->cgindex[i] = ibuf[i];
9046         }
9047     }
9048     else
9049     {
9050         for (i = 0; i < dd->ncg_home+1; i++)
9051         {
9052             dd->cgindex[i] = i;
9053         }
9054     }
9055     /* Set the home atom number */
9056     dd->nat_home = dd->cgindex[dd->ncg_home];
9057
9058     if (fr->cutoff_scheme == ecutsVERLET)
9059     {
9060         /* The atoms are now exactly in grid order, update the grid order */
9061         nbnxn_set_atomorder(fr->nbv->nbs);
9062     }
9063     else
9064     {
9065         /* Copy the sorted ns cell indices back to the ns grid struct */
9066         for (i = 0; i < dd->ncg_home; i++)
9067         {
9068             fr->ns.grid->cell_index[i] = cgsort[i].nsc;
9069         }
9070         fr->ns.grid->nr = dd->ncg_home;
9071     }
9072 }
9073
9074 static void add_dd_statistics(gmx_domdec_t *dd)
9075 {
9076     gmx_domdec_comm_t *comm;
9077     int                ddnat;
9078
9079     comm = dd->comm;
9080
9081     for (ddnat = ddnatZONE; ddnat < ddnatNR; ddnat++)
9082     {
9083         comm->sum_nat[ddnat-ddnatZONE] +=
9084             comm->nat[ddnat] - comm->nat[ddnat-1];
9085     }
9086     comm->ndecomp++;
9087 }
9088
9089 void reset_dd_statistics_counters(gmx_domdec_t *dd)
9090 {
9091     gmx_domdec_comm_t *comm;
9092     int                ddnat;
9093
9094     comm = dd->comm;
9095
9096     /* Reset all the statistics and counters for total run counting */
9097     for (ddnat = ddnatZONE; ddnat < ddnatNR; ddnat++)
9098     {
9099         comm->sum_nat[ddnat-ddnatZONE] = 0;
9100     }
9101     comm->ndecomp   = 0;
9102     comm->nload     = 0;
9103     comm->load_step = 0;
9104     comm->load_sum  = 0;
9105     comm->load_max  = 0;
9106     clear_ivec(comm->load_lim);
9107     comm->load_mdf = 0;
9108     comm->load_pme = 0;
9109 }
9110
9111 void print_dd_statistics(t_commrec *cr, t_inputrec *ir, FILE *fplog)
9112 {
9113     gmx_domdec_comm_t *comm;
9114     int                ddnat;
9115     double             av;
9116
9117     comm = cr->dd->comm;
9118
9119     gmx_sumd(ddnatNR-ddnatZONE, comm->sum_nat, cr);
9120
9121     if (fplog == NULL)
9122     {
9123         return;
9124     }
9125
9126     fprintf(fplog, "\n    D O M A I N   D E C O M P O S I T I O N   S T A T I S T I C S\n\n");
9127
9128     for (ddnat = ddnatZONE; ddnat < ddnatNR; ddnat++)
9129     {
9130         av = comm->sum_nat[ddnat-ddnatZONE]/comm->ndecomp;
9131         switch (ddnat)
9132         {
9133             case ddnatZONE:
9134                 fprintf(fplog,
9135                         " av. #atoms communicated per step for force:  %d x %.1f\n",
9136                         2, av);
9137                 break;
9138             case ddnatVSITE:
9139                 if (cr->dd->vsite_comm)
9140                 {
9141                     fprintf(fplog,
9142                             " av. #atoms communicated per step for vsites: %d x %.1f\n",
9143                             (EEL_PME(ir->coulombtype) || ir->coulombtype == eelEWALD) ? 3 : 2,
9144                             av);
9145                 }
9146                 break;
9147             case ddnatCON:
9148                 if (cr->dd->constraint_comm)
9149                 {
9150                     fprintf(fplog,
9151                             " av. #atoms communicated per step for LINCS:  %d x %.1f\n",
9152                             1 + ir->nLincsIter, av);
9153                 }
9154                 break;
9155             default:
9156                 gmx_incons(" Unknown type for DD statistics");
9157         }
9158     }
9159     fprintf(fplog, "\n");
9160
9161     if (comm->bRecordLoad && EI_DYNAMICS(ir->eI))
9162     {
9163         print_dd_load_av(fplog, cr->dd);
9164     }
9165 }
9166
9167 void dd_partition_system(FILE                *fplog,
9168                          gmx_large_int_t      step,
9169                          t_commrec           *cr,
9170                          gmx_bool             bMasterState,
9171                          int                  nstglobalcomm,
9172                          t_state             *state_global,
9173                          gmx_mtop_t          *top_global,
9174                          t_inputrec          *ir,
9175                          t_state             *state_local,
9176                          rvec               **f,
9177                          t_mdatoms           *mdatoms,
9178                          gmx_localtop_t      *top_local,
9179                          t_forcerec          *fr,
9180                          gmx_vsite_t         *vsite,
9181                          gmx_shellfc_t        shellfc,
9182                          gmx_constr_t         constr,
9183                          t_nrnb              *nrnb,
9184                          gmx_wallcycle_t      wcycle,
9185                          gmx_bool             bVerbose)
9186 {
9187     gmx_domdec_t      *dd;
9188     gmx_domdec_comm_t *comm;
9189     gmx_ddbox_t        ddbox = {0};
9190     t_block           *cgs_gl;
9191     gmx_large_int_t    step_pcoupl;
9192     rvec               cell_ns_x0, cell_ns_x1;
9193     int                i, j, n, ncgindex_set, ncg_home_old = -1, ncg_moved, nat_f_novirsum;
9194     gmx_bool           bBoxChanged, bNStGlobalComm, bDoDLB, bCheckDLB, bTurnOnDLB, bLogLoad;
9195     gmx_bool           bRedist, bSortCG, bResortAll;
9196     ivec               ncells_old = {0, 0, 0}, ncells_new = {0, 0, 0}, np;
9197     real               grid_density;
9198     char               sbuf[22];
9199
9200     dd   = cr->dd;
9201     comm = dd->comm;
9202
9203     bBoxChanged = (bMasterState || DEFORM(*ir));
9204     if (ir->epc != epcNO)
9205     {
9206         /* With nstpcouple > 1 pressure coupling happens.
9207          * one step after calculating the pressure.
9208          * Box scaling happens at the end of the MD step,
9209          * after the DD partitioning.
9210          * We therefore have to do DLB in the first partitioning
9211          * after an MD step where P-coupling occured.
9212          * We need to determine the last step in which p-coupling occurred.
9213          * MRS -- need to validate this for vv?
9214          */
9215         n = ir->nstpcouple;
9216         if (n == 1)
9217         {
9218             step_pcoupl = step - 1;
9219         }
9220         else
9221         {
9222             step_pcoupl = ((step - 1)/n)*n + 1;
9223         }
9224         if (step_pcoupl >= comm->partition_step)
9225         {
9226             bBoxChanged = TRUE;
9227         }
9228     }
9229
9230     bNStGlobalComm = (step % nstglobalcomm == 0);
9231
9232     if (!comm->bDynLoadBal)
9233     {
9234         bDoDLB = FALSE;
9235     }
9236     else
9237     {
9238         /* Should we do dynamic load balacing this step?
9239          * Since it requires (possibly expensive) global communication,
9240          * we might want to do DLB less frequently.
9241          */
9242         if (bBoxChanged || ir->epc != epcNO)
9243         {
9244             bDoDLB = bBoxChanged;
9245         }
9246         else
9247         {
9248             bDoDLB = bNStGlobalComm;
9249         }
9250     }
9251
9252     /* Check if we have recorded loads on the nodes */
9253     if (comm->bRecordLoad && dd_load_count(comm))
9254     {
9255         if (comm->eDLB == edlbAUTO && !comm->bDynLoadBal)
9256         {
9257             /* Check if we should use DLB at the second partitioning
9258              * and every 100 partitionings,
9259              * so the extra communication cost is negligible.
9260              */
9261             n         = max(100, nstglobalcomm);
9262             bCheckDLB = (comm->n_load_collect == 0 ||
9263                          comm->n_load_have % n == n-1);
9264         }
9265         else
9266         {
9267             bCheckDLB = FALSE;
9268         }
9269
9270         /* Print load every nstlog, first and last step to the log file */
9271         bLogLoad = ((ir->nstlog > 0 && step % ir->nstlog == 0) ||
9272                     comm->n_load_collect == 0 ||
9273                     (ir->nsteps >= 0 &&
9274                      (step + ir->nstlist > ir->init_step + ir->nsteps)));
9275
9276         /* Avoid extra communication due to verbose screen output
9277          * when nstglobalcomm is set.
9278          */
9279         if (bDoDLB || bLogLoad || bCheckDLB ||
9280             (bVerbose && (ir->nstlist == 0 || nstglobalcomm <= ir->nstlist)))
9281         {
9282             get_load_distribution(dd, wcycle);
9283             if (DDMASTER(dd))
9284             {
9285                 if (bLogLoad)
9286                 {
9287                     dd_print_load(fplog, dd, step-1);
9288                 }
9289                 if (bVerbose)
9290                 {
9291                     dd_print_load_verbose(dd);
9292                 }
9293             }
9294             comm->n_load_collect++;
9295
9296             if (bCheckDLB)
9297             {
9298                 /* Since the timings are node dependent, the master decides */
9299                 if (DDMASTER(dd))
9300                 {
9301                     bTurnOnDLB =
9302                         (dd_force_imb_perf_loss(dd) >= DD_PERF_LOSS);
9303                     if (debug)
9304                     {
9305                         fprintf(debug, "step %s, imb loss %f\n",
9306                                 gmx_step_str(step, sbuf),
9307                                 dd_force_imb_perf_loss(dd));
9308                     }
9309                 }
9310                 dd_bcast(dd, sizeof(bTurnOnDLB), &bTurnOnDLB);
9311                 if (bTurnOnDLB)
9312                 {
9313                     turn_on_dlb(fplog, cr, step);
9314                     bDoDLB = TRUE;
9315                 }
9316             }
9317         }
9318         comm->n_load_have++;
9319     }
9320
9321     cgs_gl = &comm->cgs_gl;
9322
9323     bRedist = FALSE;
9324     if (bMasterState)
9325     {
9326         /* Clear the old state */
9327         clear_dd_indices(dd, 0, 0);
9328         ncgindex_set = 0;
9329
9330         set_ddbox(dd, bMasterState, cr, ir, state_global->box,
9331                   TRUE, cgs_gl, state_global->x, &ddbox);
9332
9333         get_cg_distribution(fplog, step, dd, cgs_gl,
9334                             state_global->box, &ddbox, state_global->x);
9335
9336         dd_distribute_state(dd, cgs_gl,
9337                             state_global, state_local, f);
9338
9339         dd_make_local_cgs(dd, &top_local->cgs);
9340
9341         /* Ensure that we have space for the new distribution */
9342         dd_check_alloc_ncg(fr, state_local, f, dd->ncg_home);
9343
9344         if (fr->cutoff_scheme == ecutsGROUP)
9345         {
9346             calc_cgcm(fplog, 0, dd->ncg_home,
9347                       &top_local->cgs, state_local->x, fr->cg_cm);
9348         }
9349
9350         inc_nrnb(nrnb, eNR_CGCM, dd->nat_home);
9351
9352         dd_set_cginfo(dd->index_gl, 0, dd->ncg_home, fr, comm->bLocalCG);
9353     }
9354     else if (state_local->ddp_count != dd->ddp_count)
9355     {
9356         if (state_local->ddp_count > dd->ddp_count)
9357         {
9358             gmx_fatal(FARGS, "Internal inconsistency state_local->ddp_count (%d) > dd->ddp_count (%d)", state_local->ddp_count, dd->ddp_count);
9359         }
9360
9361         if (state_local->ddp_count_cg_gl != state_local->ddp_count)
9362         {
9363             gmx_fatal(FARGS, "Internal inconsistency state_local->ddp_count_cg_gl (%d) != state_local->ddp_count (%d)", state_local->ddp_count_cg_gl, state_local->ddp_count);
9364         }
9365
9366         /* Clear the old state */
9367         clear_dd_indices(dd, 0, 0);
9368
9369         /* Build the new indices */
9370         rebuild_cgindex(dd, cgs_gl->index, state_local);
9371         make_dd_indices(dd, cgs_gl->index, 0);
9372         ncgindex_set = dd->ncg_home;
9373
9374         if (fr->cutoff_scheme == ecutsGROUP)
9375         {
9376             /* Redetermine the cg COMs */
9377             calc_cgcm(fplog, 0, dd->ncg_home,
9378                       &top_local->cgs, state_local->x, fr->cg_cm);
9379         }
9380
9381         inc_nrnb(nrnb, eNR_CGCM, dd->nat_home);
9382
9383         dd_set_cginfo(dd->index_gl, 0, dd->ncg_home, fr, comm->bLocalCG);
9384
9385         set_ddbox(dd, bMasterState, cr, ir, state_local->box,
9386                   TRUE, &top_local->cgs, state_local->x, &ddbox);
9387
9388         bRedist = comm->bDynLoadBal;
9389     }
9390     else
9391     {
9392         /* We have the full state, only redistribute the cgs */
9393
9394         /* Clear the non-home indices */
9395         clear_dd_indices(dd, dd->ncg_home, dd->nat_home);
9396         ncgindex_set = 0;
9397
9398         /* Avoid global communication for dim's without pbc and -gcom */
9399         if (!bNStGlobalComm)
9400         {
9401             copy_rvec(comm->box0, ddbox.box0    );
9402             copy_rvec(comm->box_size, ddbox.box_size);
9403         }
9404         set_ddbox(dd, bMasterState, cr, ir, state_local->box,
9405                   bNStGlobalComm, &top_local->cgs, state_local->x, &ddbox);
9406
9407         bBoxChanged = TRUE;
9408         bRedist     = TRUE;
9409     }
9410     /* For dim's without pbc and -gcom */
9411     copy_rvec(ddbox.box0, comm->box0    );
9412     copy_rvec(ddbox.box_size, comm->box_size);
9413
9414     set_dd_cell_sizes(dd, &ddbox, dynamic_dd_box(&ddbox, ir), bMasterState, bDoDLB,
9415                       step, wcycle);
9416
9417     if (comm->nstDDDumpGrid > 0 && step % comm->nstDDDumpGrid == 0)
9418     {
9419         write_dd_grid_pdb("dd_grid", step, dd, state_local->box, &ddbox);
9420     }
9421
9422     /* Check if we should sort the charge groups */
9423     if (comm->nstSortCG > 0)
9424     {
9425         bSortCG = (bMasterState ||
9426                    (bRedist && (step % comm->nstSortCG == 0)));
9427     }
9428     else
9429     {
9430         bSortCG = FALSE;
9431     }
9432
9433     ncg_home_old = dd->ncg_home;
9434
9435     ncg_moved = 0;
9436     if (bRedist)
9437     {
9438         wallcycle_sub_start(wcycle, ewcsDD_REDIST);
9439
9440         dd_redistribute_cg(fplog, step, dd, ddbox.tric_dir,
9441                            state_local, f, fr,
9442                            !bSortCG, nrnb, &ncgindex_set, &ncg_moved);
9443
9444         wallcycle_sub_stop(wcycle, ewcsDD_REDIST);
9445     }
9446
9447     get_nsgrid_boundaries(ddbox.nboundeddim, state_local->box,
9448                           dd, &ddbox,
9449                           &comm->cell_x0, &comm->cell_x1,
9450                           dd->ncg_home, fr->cg_cm,
9451                           cell_ns_x0, cell_ns_x1, &grid_density);
9452
9453     if (bBoxChanged)
9454     {
9455         comm_dd_ns_cell_sizes(dd, &ddbox, cell_ns_x0, cell_ns_x1, step);
9456     }
9457
9458     switch (fr->cutoff_scheme)
9459     {
9460         case ecutsGROUP:
9461             copy_ivec(fr->ns.grid->n, ncells_old);
9462             grid_first(fplog, fr->ns.grid, dd, &ddbox,
9463                        state_local->box, cell_ns_x0, cell_ns_x1,
9464                        fr->rlistlong, grid_density);
9465             break;
9466         case ecutsVERLET:
9467             nbnxn_get_ncells(fr->nbv->nbs, &ncells_old[XX], &ncells_old[YY]);
9468             break;
9469         default:
9470             gmx_incons("unimplemented");
9471     }
9472     /* We need to store tric_dir for dd_get_ns_ranges called from ns.c */
9473     copy_ivec(ddbox.tric_dir, comm->tric_dir);
9474
9475     if (bSortCG)
9476     {
9477         wallcycle_sub_start(wcycle, ewcsDD_GRID);
9478
9479         /* Sort the state on charge group position.
9480          * This enables exact restarts from this step.
9481          * It also improves performance by about 15% with larger numbers
9482          * of atoms per node.
9483          */
9484
9485         /* Fill the ns grid with the home cell,
9486          * so we can sort with the indices.
9487          */
9488         set_zones_ncg_home(dd);
9489
9490         switch (fr->cutoff_scheme)
9491         {
9492             case ecutsVERLET:
9493                 set_zones_size(dd, state_local->box, &ddbox, 0, 1);
9494
9495                 nbnxn_put_on_grid(fr->nbv->nbs, fr->ePBC, state_local->box,
9496                                   0,
9497                                   comm->zones.size[0].bb_x0,
9498                                   comm->zones.size[0].bb_x1,
9499                                   0, dd->ncg_home,
9500                                   comm->zones.dens_zone0,
9501                                   fr->cginfo,
9502                                   state_local->x,
9503                                   ncg_moved, bRedist ? comm->moved : NULL,
9504                                   fr->nbv->grp[eintLocal].kernel_type,
9505                                   fr->nbv->grp[eintLocal].nbat);
9506
9507                 nbnxn_get_ncells(fr->nbv->nbs, &ncells_new[XX], &ncells_new[YY]);
9508                 break;
9509             case ecutsGROUP:
9510                 fill_grid(&comm->zones, fr->ns.grid, dd->ncg_home,
9511                           0, dd->ncg_home, fr->cg_cm);
9512
9513                 copy_ivec(fr->ns.grid->n, ncells_new);
9514                 break;
9515             default:
9516                 gmx_incons("unimplemented");
9517         }
9518
9519         bResortAll = bMasterState;
9520
9521         /* Check if we can user the old order and ns grid cell indices
9522          * of the charge groups to sort the charge groups efficiently.
9523          */
9524         if (ncells_new[XX] != ncells_old[XX] ||
9525             ncells_new[YY] != ncells_old[YY] ||
9526             ncells_new[ZZ] != ncells_old[ZZ])
9527         {
9528             bResortAll = TRUE;
9529         }
9530
9531         if (debug)
9532         {
9533             fprintf(debug, "Step %s, sorting the %d home charge groups\n",
9534                     gmx_step_str(step, sbuf), dd->ncg_home);
9535         }
9536         dd_sort_state(dd, fr->cg_cm, fr, state_local,
9537                       bResortAll ? -1 : ncg_home_old);
9538         /* Rebuild all the indices */
9539         ga2la_clear(dd->ga2la);
9540         ncgindex_set = 0;
9541
9542         wallcycle_sub_stop(wcycle, ewcsDD_GRID);
9543     }
9544
9545     wallcycle_sub_start(wcycle, ewcsDD_SETUPCOMM);
9546
9547     /* Setup up the communication and communicate the coordinates */
9548     setup_dd_communication(dd, state_local->box, &ddbox, fr, state_local, f);
9549
9550     /* Set the indices */
9551     make_dd_indices(dd, cgs_gl->index, ncgindex_set);
9552
9553     /* Set the charge group boundaries for neighbor searching */
9554     set_cg_boundaries(&comm->zones);
9555
9556     if (fr->cutoff_scheme == ecutsVERLET)
9557     {
9558         set_zones_size(dd, state_local->box, &ddbox,
9559                        bSortCG ? 1 : 0, comm->zones.n);
9560     }
9561
9562     wallcycle_sub_stop(wcycle, ewcsDD_SETUPCOMM);
9563
9564     /*
9565        write_dd_pdb("dd_home",step,"dump",top_global,cr,
9566                  -1,state_local->x,state_local->box);
9567      */
9568
9569     wallcycle_sub_start(wcycle, ewcsDD_MAKETOP);
9570
9571     /* Extract a local topology from the global topology */
9572     for (i = 0; i < dd->ndim; i++)
9573     {
9574         np[dd->dim[i]] = comm->cd[i].np;
9575     }
9576     dd_make_local_top(dd, &comm->zones, dd->npbcdim, state_local->box,
9577                       comm->cellsize_min, np,
9578                       fr,
9579                       fr->cutoff_scheme == ecutsGROUP ? fr->cg_cm : state_local->x,
9580                       vsite, top_global, top_local);
9581
9582     wallcycle_sub_stop(wcycle, ewcsDD_MAKETOP);
9583
9584     wallcycle_sub_start(wcycle, ewcsDD_MAKECONSTR);
9585
9586     /* Set up the special atom communication */
9587     n = comm->nat[ddnatZONE];
9588     for (i = ddnatZONE+1; i < ddnatNR; i++)
9589     {
9590         switch (i)
9591         {
9592             case ddnatVSITE:
9593                 if (vsite && vsite->n_intercg_vsite)
9594                 {
9595                     n = dd_make_local_vsites(dd, n, top_local->idef.il);
9596                 }
9597                 break;
9598             case ddnatCON:
9599                 if (dd->bInterCGcons || dd->bInterCGsettles)
9600                 {
9601                     /* Only for inter-cg constraints we need special code */
9602                     n = dd_make_local_constraints(dd, n, top_global, fr->cginfo,
9603                                                   constr, ir->nProjOrder,
9604                                                   top_local->idef.il);
9605                 }
9606                 break;
9607             default:
9608                 gmx_incons("Unknown special atom type setup");
9609         }
9610         comm->nat[i] = n;
9611     }
9612
9613     wallcycle_sub_stop(wcycle, ewcsDD_MAKECONSTR);
9614
9615     wallcycle_sub_start(wcycle, ewcsDD_TOPOTHER);
9616
9617     /* Make space for the extra coordinates for virtual site
9618      * or constraint communication.
9619      */
9620     state_local->natoms = comm->nat[ddnatNR-1];
9621     if (state_local->natoms > state_local->nalloc)
9622     {
9623         dd_realloc_state(state_local, f, state_local->natoms);
9624     }
9625
9626     if (fr->bF_NoVirSum)
9627     {
9628         if (vsite && vsite->n_intercg_vsite)
9629         {
9630             nat_f_novirsum = comm->nat[ddnatVSITE];
9631         }
9632         else
9633         {
9634             if (EEL_FULL(ir->coulombtype) && dd->n_intercg_excl > 0)
9635             {
9636                 nat_f_novirsum = dd->nat_tot;
9637             }
9638             else
9639             {
9640                 nat_f_novirsum = dd->nat_home;
9641             }
9642         }
9643     }
9644     else
9645     {
9646         nat_f_novirsum = 0;
9647     }
9648
9649     /* Set the number of atoms required for the force calculation.
9650      * Forces need to be constrained when using a twin-range setup
9651      * or with energy minimization. For simple simulations we could
9652      * avoid some allocation, zeroing and copying, but this is
9653      * probably not worth the complications ande checking.
9654      */
9655     forcerec_set_ranges(fr, dd->ncg_home, dd->ncg_tot,
9656                         dd->nat_tot, comm->nat[ddnatCON], nat_f_novirsum);
9657
9658     /* We make the all mdatoms up to nat_tot_con.
9659      * We could save some work by only setting invmass
9660      * between nat_tot and nat_tot_con.
9661      */
9662     /* This call also sets the new number of home particles to dd->nat_home */
9663     atoms2md(top_global, ir,
9664              comm->nat[ddnatCON], dd->gatindex, 0, dd->nat_home, mdatoms);
9665
9666     /* Now we have the charges we can sort the FE interactions */
9667     dd_sort_local_top(dd, mdatoms, top_local);
9668
9669     if (vsite != NULL)
9670     {
9671         /* Now we have updated mdatoms, we can do the last vsite bookkeeping */
9672         split_vsites_over_threads(top_local->idef.il, mdatoms, FALSE, vsite);
9673     }
9674
9675     if (shellfc)
9676     {
9677         /* Make the local shell stuff, currently no communication is done */
9678         make_local_shells(cr, mdatoms, shellfc);
9679     }
9680
9681     if (ir->implicit_solvent)
9682     {
9683         make_local_gb(cr, fr->born, ir->gb_algorithm);
9684     }
9685
9686     setup_bonded_threading(fr, &top_local->idef);
9687
9688     if (!(cr->duty & DUTY_PME))
9689     {
9690         /* Send the charges to our PME only node */
9691         gmx_pme_send_q(cr, mdatoms->nChargePerturbed,
9692                        mdatoms->chargeA, mdatoms->chargeB,
9693                        dd_pme_maxshift_x(dd), dd_pme_maxshift_y(dd));
9694     }
9695
9696     if (constr)
9697     {
9698         set_constraints(constr, top_local, ir, mdatoms, cr);
9699     }
9700
9701     if (ir->ePull != epullNO)
9702     {
9703         /* Update the local pull groups */
9704         dd_make_local_pull_groups(dd, ir->pull, mdatoms);
9705     }
9706
9707     if (ir->bRot)
9708     {
9709         /* Update the local rotation groups */
9710         dd_make_local_rotation_groups(dd, ir->rot);
9711     }
9712
9713
9714     add_dd_statistics(dd);
9715
9716     /* Make sure we only count the cycles for this DD partitioning */
9717     clear_dd_cycle_counts(dd);
9718
9719     /* Because the order of the atoms might have changed since
9720      * the last vsite construction, we need to communicate the constructing
9721      * atom coordinates again (for spreading the forces this MD step).
9722      */
9723     dd_move_x_vsites(dd, state_local->box, state_local->x);
9724
9725     wallcycle_sub_stop(wcycle, ewcsDD_TOPOTHER);
9726
9727     if (comm->nstDDDump > 0 && step % comm->nstDDDump == 0)
9728     {
9729         dd_move_x(dd, state_local->box, state_local->x);
9730         write_dd_pdb("dd_dump", step, "dump", top_global, cr,
9731                      -1, state_local->x, state_local->box);
9732     }
9733
9734     /* Store the partitioning step */
9735     comm->partition_step = step;
9736
9737     /* Increase the DD partitioning counter */
9738     dd->ddp_count++;
9739     /* The state currently matches this DD partitioning count, store it */
9740     state_local->ddp_count = dd->ddp_count;
9741     if (bMasterState)
9742     {
9743         /* The DD master node knows the complete cg distribution,
9744          * store the count so we can possibly skip the cg info communication.
9745          */
9746         comm->master_cg_ddp_count = (bSortCG ? 0 : dd->ddp_count);
9747     }
9748
9749     if (comm->DD_debug > 0)
9750     {
9751         /* Set the env var GMX_DD_DEBUG if you suspect corrupted indices */
9752         check_index_consistency(dd, top_global->natoms, ncg_mtop(top_global),
9753                                 "after partitioning");
9754     }
9755 }