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