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