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