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