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