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