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