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