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