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