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