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