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