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