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