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