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