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