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