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