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