392c68c8e7235f3be173697a22f2c5129b3c4c8e
[alexxy/gromacs.git] / src / gromacs / mdlib / nsgrid.c
1 /*
2  * This file is part of the GROMACS molecular simulation package.
3  *
4  * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
5  * Copyright (c) 2001-2004, The GROMACS development team.
6  * Copyright (c) 2013,2014, by the GROMACS development team, led by
7  * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
8  * and including many others, as listed in the AUTHORS file in the
9  * top-level source directory and at http://www.gromacs.org.
10  *
11  * GROMACS is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU Lesser General Public License
13  * as published by the Free Software Foundation; either version 2.1
14  * of the License, or (at your option) any later version.
15  *
16  * GROMACS is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19  * Lesser General Public License for more details.
20  *
21  * You should have received a copy of the GNU Lesser General Public
22  * License along with GROMACS; if not, see
23  * http://www.gnu.org/licenses, or write to the Free Software Foundation,
24  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA.
25  *
26  * If you want to redistribute modifications to GROMACS, please
27  * consider that scientific software is very special. Version
28  * control is crucial - bugs must be traceable. We will be happy to
29  * consider code for inclusion in the official distribution, but
30  * derived work must not be called official GROMACS. Details are found
31  * in the README & COPYING files - if they are missing, get the
32  * official version at http://www.gromacs.org.
33  *
34  * To help us fund GROMACS development, we humbly ask that you cite
35  * the research papers on the package. Check out http://www.gromacs.org.
36  */
37 /* This file is completely threadsafe - keep it that way! */
38 #include "gmxpre.h"
39
40 #include "config.h"
41
42 #include <stdlib.h>
43
44 #include "gromacs/legacyheaders/typedefs.h"
45 #include "gromacs/legacyheaders/types/commrec.h"
46 #include "gromacs/legacyheaders/macros.h"
47 #include "gromacs/utility/smalloc.h"
48 #include "gromacs/legacyheaders/nsgrid.h"
49 #include "gromacs/utility/fatalerror.h"
50 #include "gromacs/math/vec.h"
51 #include "gromacs/legacyheaders/network.h"
52 #include "gromacs/legacyheaders/domdec.h"
53 #include "gromacs/pbcutil/pbc.h"
54 #include <stdio.h>
55 #include "gromacs/utility/futil.h"
56 #include "gromacs/fileio/pdbio.h"
57
58 /***********************************
59  *         Grid Routines
60  ***********************************/
61
62 const char *range_warn =
63     "Explanation: During neighborsearching, we assign each particle to a grid\n"
64     "based on its coordinates. If your system contains collisions or parameter\n"
65     "errors that give particles very high velocities you might end up with some\n"
66     "coordinates being +-Infinity or NaN (not-a-number). Obviously, we cannot\n"
67     "put these on a grid, so this is usually where we detect those errors.\n"
68     "Make sure your system is properly energy-minimized and that the potential\n"
69     "energy seems reasonable before trying again.";
70
71 static void calc_x_av_stddev(int n, rvec *x, rvec av, rvec stddev)
72 {
73     dvec s1, s2;
74     int  i, d;
75
76     clear_dvec(s1);
77     clear_dvec(s2);
78
79     for (i = 0; i < n; i++)
80     {
81         for (d = 0; d < DIM; d++)
82         {
83             s1[d] += x[i][d];
84             s2[d] += x[i][d]*x[i][d];
85         }
86     }
87
88     dsvmul(1.0/n, s1, s1);
89     dsvmul(1.0/n, s2, s2);
90
91     for (d = 0; d < DIM; d++)
92     {
93         av[d]     = s1[d];
94         stddev[d] = sqrt(s2[d] - s1[d]*s1[d]);
95     }
96 }
97
98 void get_nsgrid_boundaries_vac(real av, real stddev,
99                                real *bound0, real *bound1,
100                                real *bdens0, real *bdens1)
101 {
102     /* Set the grid to 2 times the standard deviation of
103      * the charge group centers in both directions.
104      * For a uniform bounded distribution the width is sqrt(3)*stddev,
105      * so all charge groups fall within the width.
106      * For a sphere stddev is r/sqrt(5): 99.2% falls within the width.
107      * For a Gaussian distribution 98% fall within the width.
108      */
109     *bound0 = av - NSGRID_STDDEV_FAC*stddev;
110     *bound1 = av + NSGRID_STDDEV_FAC*stddev;
111
112     *bdens0 = av - GRID_STDDEV_FAC*stddev;
113     *bdens1 = av + GRID_STDDEV_FAC*stddev;
114 }
115
116 static void dd_box_bounds_to_ns_bounds(real box0, real box_size,
117                                        real *gr0, real *gr1)
118 {
119     real av, stddev;
120
121     /* Redetermine av and stddev from the DD box boundaries */
122     av     = box0 + 0.5*box_size;
123     stddev = 0.5*box_size/GRID_STDDEV_FAC;
124
125     *gr0 = av - NSGRID_STDDEV_FAC*stddev;
126     *gr1 = av + NSGRID_STDDEV_FAC*stddev;
127 }
128
129 void get_nsgrid_boundaries(int nboundeddim, matrix box,
130                            gmx_domdec_t *dd,
131                            gmx_ddbox_t *ddbox, rvec *gr0, rvec *gr1,
132                            int ncg, rvec *cgcm,
133                            rvec grid_x0, rvec grid_x1,
134                            real *grid_density)
135 {
136     rvec av, stddev;
137     real vol, bdens0, bdens1;
138     int  d;
139
140     if (nboundeddim < DIM)
141     {
142         calc_x_av_stddev(ncg, cgcm, av, stddev);
143     }
144
145     vol = 1;
146     for (d = 0; d < DIM; d++)
147     {
148         if (d < nboundeddim)
149         {
150             grid_x0[d] = (gr0 != NULL ? (*gr0)[d] : 0);
151             grid_x1[d] = (gr1 != NULL ? (*gr1)[d] : box[d][d]);
152             vol       *= (grid_x1[d] - grid_x0[d]);
153         }
154         else
155         {
156             if (ddbox == NULL)
157             {
158                 get_nsgrid_boundaries_vac(av[d], stddev[d],
159                                           &grid_x0[d], &grid_x1[d],
160                                           &bdens0, &bdens1);
161             }
162             else
163             {
164                 /* Temporary fix which uses global ddbox boundaries
165                  * for unbounded dimensions.
166                  * Should be replaced by local boundaries, which makes
167                  * the ns grid smaller and does not require global comm.
168                  */
169                 dd_box_bounds_to_ns_bounds(ddbox->box0[d], ddbox->box_size[d],
170                                            &grid_x0[d], &grid_x1[d]);
171                 bdens0 = grid_x0[d];
172                 bdens1 = grid_x1[d];
173             }
174             /* Check for a DD cell not at a lower edge */
175             if (dd != NULL && gr0 != NULL && dd->ci[d] > 0)
176             {
177                 grid_x0[d] = (*gr0)[d];
178                 bdens0     = (*gr0)[d];
179             }
180             /* Check for a DD cell not at a higher edge */
181             if (dd != NULL && gr1 != NULL && dd->ci[d] < dd->nc[d]-1)
182             {
183                 grid_x1[d] = (*gr1)[d];
184                 bdens1     = (*gr1)[d];
185             }
186             vol *= (bdens1 - bdens0);
187         }
188
189         if (debug)
190         {
191             fprintf(debug, "Set grid boundaries dim %d: %f %f\n",
192                     d, grid_x0[d], grid_x1[d]);
193         }
194     }
195
196     *grid_density = ncg/vol;
197 }
198
199 static void set_grid_sizes(matrix box, rvec izones_x0, rvec izones_x1, real rlist,
200                            const gmx_domdec_t *dd, const gmx_ddbox_t *ddbox,
201                            t_grid *grid,
202                            real grid_density)
203 {
204     int      i, j;
205     gmx_bool bDD, bDDRect;
206     rvec     av, stddev;
207     rvec     izones_size;
208     real     inv_r_ideal, size, add_tric, radd;
209
210     for (i = 0; (i < DIM); i++)
211     {
212         if (debug)
213         {
214             fprintf(debug,
215                     "set_grid_sizes, i-zone bounds for dim %d: %6.3f %6.3f\n",
216                     i, izones_x0[i], izones_x1[i]);
217         }
218         izones_size[i] = izones_x1[i] - izones_x0[i];
219     }
220
221     /* Use the ideal number of cg's per cell to set the ideal cell size */
222     inv_r_ideal = pow(grid_density/grid->ncg_ideal, 1.0/3.0);
223     if (rlist > 0 && inv_r_ideal*rlist < 1)
224     {
225         inv_r_ideal = 1/rlist;
226     }
227     if (debug)
228     {
229         fprintf(debug, "CG density %f ideal ns cell size %f\n",
230                 grid_density, 1/inv_r_ideal);
231     }
232
233     clear_rvec(grid->cell_offset);
234     for (i = 0; (i < DIM); i++)
235     {
236         /* Initial settings, for DD might change below */
237         grid->cell_offset[i] = izones_x0[i];
238         size                 = izones_size[i];
239
240         bDD = dd && (dd->nc[i] > 1);
241         if (!bDD)
242         {
243             bDDRect = FALSE;
244         }
245         else
246         {
247             /* With DD grid cell jumps only the first decomposition
248              * direction has uniform DD cell boundaries.
249              */
250             bDDRect = !(ddbox->tric_dir[i] ||
251                         (dd->bGridJump && i != dd->dim[0]));
252
253             radd = rlist;
254             if (i >= ddbox->npbcdim &&
255                 (rlist == 0 ||
256                  izones_x1[i] + radd > ddbox->box0[i] + ddbox->box_size[i]))
257             {
258                 radd = ddbox->box0[i] + ddbox->box_size[i] - izones_x1[i];
259                 if (radd < 0)
260                 {
261                     radd = 0;
262                 }
263             }
264
265             /* With DD we only need a grid of one DD cell size + rlist */
266             if (bDDRect)
267             {
268                 size += radd;
269             }
270             else
271             {
272                 size += radd/ddbox->skew_fac[i];
273             }
274
275             /* Check if the cell boundary in this direction is
276              * perpendicular to the Cartesian axis.
277              */
278             for (j = i+1; j < grid->npbcdim; j++)
279             {
280                 if (box[j][i] != 0)
281                 {
282                     /* Correct the offset for the home cell location */
283                     grid->cell_offset[i] += izones_x0[j]*box[j][i]/box[j][j];
284
285                     /* Correct the offset and size for the off-diagonal
286                      * displacement of opposing DD cell corners.
287                      */
288                     /* Without rouding we would need to add:
289                      * box[j][i]*rlist/(dd->skew_fac[i]*box[j][j])
290                      */
291                     /* Determine the shift for the corners of the triclinic box */
292                     add_tric = izones_size[j]*box[j][i]/box[j][j];
293                     if (dd->ndim == 1 && j == ZZ)
294                     {
295                         /* With 1D domain decomposition the cg's are not in
296                          * the triclinic box, but trilinic x-y and rectangular y-z.
297                          * Therefore we need to add the shift from the trilinic
298                          * corner to the corner at y=0.
299                          */
300                         add_tric += -box[YY][XX]*box[ZZ][YY]/box[YY][YY];
301                     }
302                     if (box[j][i] < 0)
303                     {
304                         grid->cell_offset[i] += add_tric;
305                         size                 -= add_tric;
306                     }
307                     else
308                     {
309                         size += add_tric;
310                     }
311                 }
312             }
313         }
314         if (!bDDRect)
315         {
316             /* No DD or the box is triclinic is this direction:
317              * we will use the normal grid ns that checks all cells
318              * that are within cut-off distance of the i-particle.
319              */
320             grid->n[i] = (int)(size*inv_r_ideal + 0.5);
321             if (grid->n[i] < 2)
322             {
323                 grid->n[i] = 2;
324             }
325             grid->cell_size[i] = size/grid->n[i];
326             grid->ncpddc[i]    = 0;
327         }
328         else
329         {
330             /* We use grid->ncpddc[i] such that all particles
331              * in one ns cell belong to a single DD cell only.
332              * We can then beforehand exclude certain ns grid cells
333              * for non-home i-particles.
334              */
335             grid->ncpddc[i] = (int)(izones_size[i]*inv_r_ideal + 0.5);
336             if (grid->ncpddc[i] < 2)
337             {
338                 grid->ncpddc[i] = 2;
339             }
340             grid->cell_size[i] = izones_size[i]/grid->ncpddc[i];
341             grid->n[i]         = grid->ncpddc[i] + (int)(radd/grid->cell_size[i]) + 1;
342         }
343         if (debug)
344         {
345             fprintf(debug, "grid dim %d size %d x %f: %f - %f\n",
346                     i, grid->n[i], grid->cell_size[i],
347                     grid->cell_offset[i],
348                     grid->cell_offset[i]+grid->n[i]*grid->cell_size[i]);
349         }
350     }
351
352     if (debug)
353     {
354         fprintf(debug, "CG ncg ideal %d, actual density %.1f\n",
355                 grid->ncg_ideal, grid_density*grid->cell_size[XX]*grid->cell_size[YY]*grid->cell_size[ZZ]);
356     }
357 }
358
359 t_grid *init_grid(FILE *fplog, t_forcerec *fr)
360 {
361     int     d, m;
362     char   *ptr;
363     t_grid *grid;
364
365     snew(grid, 1);
366
367     grid->npbcdim = ePBC2npbcdim(fr->ePBC);
368
369     if (fr->ePBC == epbcXY && fr->nwall == 2)
370     {
371         grid->nboundeddim = 3;
372     }
373     else
374     {
375         grid->nboundeddim = grid->npbcdim;
376     }
377
378     if (debug)
379     {
380         fprintf(debug, "The coordinates are bounded in %d dimensions\n",
381                 grid->nboundeddim);
382     }
383
384     /* The ideal number of cg's per ns grid cell seems to be 10 */
385     grid->ncg_ideal = 10;
386     ptr             = getenv("GMX_NSCELL_NCG");
387     if (ptr)
388     {
389         sscanf(ptr, "%d", &grid->ncg_ideal);
390         if (fplog)
391         {
392             fprintf(fplog, "Set ncg_ideal to %d\n", grid->ncg_ideal);
393         }
394         if (grid->ncg_ideal <= 0)
395         {
396             gmx_fatal(FARGS, "The number of cg's per cell should be > 0");
397         }
398     }
399     if (debug)
400     {
401         fprintf(debug, "Set ncg_ideal to %d\n", grid->ncg_ideal);
402     }
403
404     return grid;
405 }
406
407 void done_grid(t_grid *grid)
408 {
409     grid->nr      = 0;
410     clear_ivec(grid->n);
411     grid->ncells  = 0;
412     sfree(grid->cell_index);
413     sfree(grid->a);
414     sfree(grid->index);
415     sfree(grid->nra);
416     grid->cells_nalloc = 0;
417     sfree(grid->dcx2);
418     sfree(grid->dcy2);
419     sfree(grid->dcz2);
420     grid->dc_nalloc = 0;
421
422     if (debug)
423     {
424         fprintf(debug, "Successfully freed memory for grid pointers.");
425     }
426 }
427
428 int xyz2ci_(int nry, int nrz, int x, int y, int z)
429 /* Return the cell index */
430 {
431     return (nry*nrz*x+nrz*y+z);
432 }
433
434 void ci2xyz(t_grid *grid, int i, int *x, int *y, int *z)
435 /* Return x,y and z from the cell index */
436 {
437     int ci;
438
439     range_check_mesg(i, 0, grid->nr, range_warn);
440
441     ci  = grid->cell_index[i];
442     *x  = ci / (grid->n[YY]*grid->n[ZZ]);
443     ci -= (*x)*grid->n[YY]*grid->n[ZZ];
444     *y  = ci / grid->n[ZZ];
445     ci -= (*y)*grid->n[ZZ];
446     *z  = ci;
447 }
448
449 static int ci_not_used(ivec n)
450 {
451     /* Return an improbable value */
452     return xyz2ci(n[YY], n[ZZ], 3*n[XX], 3*n[YY], 3*n[ZZ]);
453 }
454
455 static void set_grid_ncg(t_grid *grid, int ncg)
456 {
457     int nr_old, i;
458
459     grid->nr = ncg;
460     if (grid->nr+1 > grid->nr_alloc)
461     {
462         nr_old         = grid->nr_alloc;
463         grid->nr_alloc = over_alloc_dd(grid->nr) + 1;
464         srenew(grid->cell_index, grid->nr_alloc);
465         for (i = nr_old; i < grid->nr_alloc; i++)
466         {
467             grid->cell_index[i] = 0;
468         }
469         srenew(grid->a, grid->nr_alloc);
470     }
471 }
472
473 void grid_first(FILE *fplog, t_grid *grid,
474                 gmx_domdec_t *dd, const gmx_ddbox_t *ddbox,
475                 matrix box, rvec izones_x0, rvec izones_x1,
476                 real rlistlong, real grid_density)
477 {
478     int    i, m;
479     ivec   cx;
480
481     set_grid_sizes(box, izones_x0, izones_x1, rlistlong, dd, ddbox, grid, grid_density);
482
483     grid->ncells = grid->n[XX]*grid->n[YY]*grid->n[ZZ];
484
485     if (grid->ncells+1 > grid->cells_nalloc)
486     {
487         /* Allocate double the size so we have some headroom */
488         grid->cells_nalloc = 2*grid->ncells;
489         srenew(grid->nra,  grid->cells_nalloc+1);
490         srenew(grid->index, grid->cells_nalloc+1);
491
492         if (fplog)
493         {
494             fprintf(fplog, "Grid: %d x %d x %d cells\n",
495                     grid->n[XX], grid->n[YY], grid->n[ZZ]);
496         }
497     }
498
499     m = max(grid->n[XX], max(grid->n[YY], grid->n[ZZ]));
500     if (m > grid->dc_nalloc)
501     {
502         /* Allocate with double the initial size for box scaling */
503         grid->dc_nalloc = 2*m;
504         srenew(grid->dcx2, grid->dc_nalloc);
505         srenew(grid->dcy2, grid->dc_nalloc);
506         srenew(grid->dcz2, grid->dc_nalloc);
507     }
508
509     grid->nr = 0;
510     for (i = 0; (i < grid->ncells); i++)
511     {
512         grid->nra[i] = 0;
513     }
514 }
515
516 static void calc_bor(int cg0, int cg1, int ncg, int CG0[2], int CG1[2])
517 {
518     if (cg1 > ncg)
519     {
520         CG0[0] = cg0;
521         CG1[0] = ncg;
522         CG0[1] = 0;
523         CG1[1] = cg1-ncg;
524     }
525     else
526     {
527         CG0[0] = cg0;
528         CG1[0] = cg1;
529         CG0[1] = 0;
530         CG1[1] = 0;
531     }
532     if (debug)
533     {
534         int m;
535
536         fprintf(debug, "calc_bor: cg0=%d, cg1=%d, ncg=%d\n", cg0, cg1, ncg);
537         for (m = 0; (m < 2); m++)
538         {
539             fprintf(debug, "CG0[%d]=%d, CG1[%d]=%d\n", m, CG0[m], m, CG1[m]);
540         }
541     }
542
543 }
544
545 void calc_elemnr(t_grid *grid, int cg0, int cg1, int ncg)
546 {
547     int     CG0[2], CG1[2];
548     int    *cell_index = grid->cell_index;
549     int    *nra        = grid->nra;
550     int     i, m, ncells;
551     int     ci, not_used;
552
553     ncells = grid->ncells;
554     if (ncells <= 0)
555     {
556         gmx_fatal(FARGS, "Number of grid cells is zero. Probably the system and box collapsed.\n");
557     }
558
559     not_used = ci_not_used(grid->n);
560
561     calc_bor(cg0, cg1, ncg, CG0, CG1);
562     for (m = 0; (m < 2); m++)
563     {
564         for (i = CG0[m]; (i < CG1[m]); i++)
565         {
566             ci = cell_index[i];
567             if (ci != not_used)
568             {
569                 range_check_mesg(ci, 0, ncells, range_warn);
570                 nra[ci]++;
571             }
572         }
573     }
574 }
575
576 void calc_ptrs(t_grid *grid)
577 {
578     int *index = grid->index;
579     int *nra   = grid->nra;
580     int  ix, iy, iz, ci, nr;
581     int  nnra, ncells;
582
583     ncells = grid->ncells;
584     if (ncells <= 0)
585     {
586         gmx_fatal(FARGS, "Number of grid cells is zero. Probably the system and box collapsed.\n");
587     }
588
589     ci = nr = 0;
590     for (ix = 0; (ix < grid->n[XX]); ix++)
591     {
592         for (iy = 0; (iy < grid->n[YY]); iy++)
593         {
594             for (iz = 0; (iz < grid->n[ZZ]); iz++, ci++)
595             {
596                 range_check_mesg(ci, 0, ncells, range_warn);
597                 index[ci] = nr;
598                 nnra      = nra[ci];
599                 nr       += nnra;
600                 nra[ci]   = 0;
601             }
602         }
603     }
604 }
605
606 void grid_last(t_grid *grid, int cg0, int cg1, int ncg)
607 {
608     int     CG0[2], CG1[2];
609     int     i, m;
610     int     ci, not_used, ind, ncells;
611     int    *cell_index = grid->cell_index;
612     int    *nra        = grid->nra;
613     int    *index      = grid->index;
614     int    *a          = grid->a;
615
616     ncells = grid->ncells;
617     if (ncells <= 0)
618     {
619         gmx_fatal(FARGS, "Number of grid cells is zero. Probably the system and box collapsed.\n");
620     }
621
622     not_used = ci_not_used(grid->n);
623
624     calc_bor(cg0, cg1, ncg, CG0, CG1);
625     for (m = 0; (m < 2); m++)
626     {
627         for (i = CG0[m]; (i < CG1[m]); i++)
628         {
629             ci     = cell_index[i];
630             if (ci != not_used)
631             {
632                 range_check_mesg(ci, 0, ncells, range_warn);
633                 ind    = index[ci]+nra[ci]++;
634                 range_check_mesg(ind, 0, grid->nr, range_warn);
635                 a[ind] = i;
636             }
637         }
638     }
639 }
640
641 void fill_grid(gmx_domdec_zones_t *dd_zones,
642                t_grid *grid, int ncg_tot,
643                int cg0, int cg1, rvec cg_cm[])
644 {
645     int       *cell_index;
646     int        nrx, nry, nrz;
647     rvec       n_box, offset;
648     int        zone, ccg0, ccg1, cg, d, not_used;
649     ivec       shift0, useall, b0, b1, ind;
650     gmx_bool   bUse;
651
652     if (cg0 == -1)
653     {
654         /* We have already filled the grid up to grid->ncg,
655          * continue from there.
656          */
657         cg0 = grid->nr;
658     }
659
660     set_grid_ncg(grid, ncg_tot);
661
662     cell_index = grid->cell_index;
663
664     /* Initiate cell borders */
665     nrx = grid->n[XX];
666     nry = grid->n[YY];
667     nrz = grid->n[ZZ];
668     for (d = 0; d < DIM; d++)
669     {
670         if (grid->cell_size[d] > 0)
671         {
672             n_box[d] = 1/grid->cell_size[d];
673         }
674         else
675         {
676             n_box[d] = 0;
677         }
678     }
679     copy_rvec(grid->cell_offset, offset);
680
681     if (debug)
682     {
683         fprintf(debug, "Filling grid from %d to %d\n", cg0, cg1);
684     }
685
686     debug_gmx();
687     if (dd_zones == NULL)
688     {
689         for (cg = cg0; cg < cg1; cg++)
690         {
691             for (d = 0; d < DIM; d++)
692             {
693                 ind[d] = (cg_cm[cg][d] - offset[d])*n_box[d];
694                 /* With pbc we should be done here.
695                  * Without pbc cg's outside the grid
696                  * should be assigned to the closest grid cell.
697                  */
698                 if (ind[d] < 0)
699                 {
700                     ind[d] = 0;
701                 }
702                 else if (ind[d] >= grid->n[d])
703                 {
704                     ind[d] = grid->n[d] - 1;
705                 }
706             }
707             cell_index[cg] = xyz2ci(nry, nrz, ind[XX], ind[YY], ind[ZZ]);
708         }
709     }
710     else
711     {
712         for (zone = 0; zone < dd_zones->n; zone++)
713         {
714             ccg0 = dd_zones->cg_range[zone];
715             ccg1 = dd_zones->cg_range[zone+1];
716             if (ccg1 <= cg0 || ccg0 >= cg1)
717             {
718                 continue;
719             }
720
721             /* Determine the ns grid cell limits for this DD zone */
722             for (d = 0; d < DIM; d++)
723             {
724                 shift0[d] = dd_zones->shift[zone][d];
725                 useall[d] = (shift0[d] == 0 || d >= grid->npbcdim);
726                 /* Check if we need to do normal or optimized grid assignments.
727                  * Normal is required for dims without DD or triclinic dims.
728                  * DD edge cell on dims without pbc will be automatically
729                  * be correct, since the shift=0 zones with have b0 and b1
730                  * set to the grid boundaries and there are no shift=1 zones.
731                  */
732                 if (grid->ncpddc[d] == 0)
733                 {
734                     b0[d] = 0;
735                     b1[d] = grid->n[d];
736                 }
737                 else
738                 {
739                     if (shift0[d] == 0)
740                     {
741                         b0[d] = 0;
742                         b1[d] = grid->ncpddc[d];
743                     }
744                     else
745                     {
746                         /* shift = 1 */
747                         b0[d] = grid->ncpddc[d];
748                         b1[d] = grid->n[d];
749                     }
750                 }
751             }
752
753             not_used = ci_not_used(grid->n);
754
755             /* Put all the charge groups of this DD zone on the grid */
756             for (cg = ccg0; cg < ccg1; cg++)
757             {
758                 if (cell_index[cg] == -1)
759                 {
760                     /* This cg has moved to another node */
761                     cell_index[cg] = NSGRID_SIGNAL_MOVED_FAC*grid->ncells;
762                     continue;
763                 }
764
765                 bUse = TRUE;
766                 for (d = 0; d < DIM; d++)
767                 {
768                     ind[d] = (cg_cm[cg][d] - offset[d])*n_box[d];
769                     /* Here we have to correct for rounding problems,
770                      * as this cg_cm to cell index operation is not necessarily
771                      * binary identical to the operation for the DD zone assignment
772                      * and therefore a cg could end up in an unused grid cell.
773                      * For dimensions without pbc we need to check
774                      * for cells on the edge if charge groups are beyond
775                      * the grid and if so, store them in the closest cell.
776                      */
777                     if (ind[d] < b0[d])
778                     {
779                         ind[d] = b0[d];
780                     }
781                     else if (ind[d] >= b1[d])
782                     {
783                         if (useall[d])
784                         {
785                             ind[d] = b1[d] - 1;
786                         }
787                         else
788                         {
789                             /* Charge groups in this DD zone further away than the cut-off
790                              * in direction do not participate in non-bonded interactions.
791                              */
792                             bUse = FALSE;
793                         }
794                     }
795                 }
796                 if (cg > grid->nr_alloc)
797                 {
798                     fprintf(stderr, "WARNING: nra_alloc %d cg0 %d cg1 %d cg %d\n",
799                             grid->nr_alloc, cg0, cg1, cg);
800                 }
801                 if (bUse)
802                 {
803                     cell_index[cg] = xyz2ci(nry, nrz, ind[XX], ind[YY], ind[ZZ]);
804                 }
805                 else
806                 {
807                     cell_index[cg] = not_used;
808                 }
809             }
810         }
811     }
812     debug_gmx();
813
814 }
815
816 void check_grid(t_grid *grid)
817 {
818     int ix, iy, iz, ci, cci, nra;
819
820     if (grid->ncells <= 0)
821     {
822         gmx_fatal(FARGS, "Number of grid cells is zero. Probably the system and box collapsed.\n");
823     }
824
825     ci  = 0;
826     cci = 0;
827     for (ix = 0; (ix < grid->n[XX]); ix++)
828     {
829         for (iy = 0; (iy < grid->n[YY]); iy++)
830         {
831             for (iz = 0; (iz < grid->n[ZZ]); iz++, ci++)
832             {
833                 if (ci > 0)
834                 {
835                     nra = grid->index[ci]-grid->index[cci];
836                     if (nra != grid->nra[cci])
837                     {
838                         gmx_fatal(FARGS, "nra=%d, grid->nra=%d, cci=%d",
839                                   nra, grid->nra[cci], cci);
840                     }
841                 }
842                 cci = xyz2ci(grid->n[YY], grid->n[ZZ], ix, iy, iz);
843                 range_check_mesg(cci, 0, grid->ncells, range_warn);
844
845                 if (cci != ci)
846                 {
847                     gmx_fatal(FARGS, "ci = %d, cci = %d", ci, cci);
848                 }
849             }
850         }
851     }
852 }
853
854 void print_grid(FILE *log, t_grid *grid)
855 {
856     int i, nra, index;
857     int ix, iy, iz, ci;
858
859     fprintf(log, "nr:        %d\n", grid->nr);
860     fprintf(log, "nrx:       %d\n", grid->n[XX]);
861     fprintf(log, "nry:       %d\n", grid->n[YY]);
862     fprintf(log, "nrz:       %d\n", grid->n[ZZ]);
863     fprintf(log, "ncg_ideal: %d\n", grid->ncg_ideal);
864     fprintf(log, "    i  cell_index\n");
865     for (i = 0; (i < grid->nr); i++)
866     {
867         fprintf(log, "%5d  %5d\n", i, grid->cell_index[i]);
868     }
869     fprintf(log, "cells\n");
870     fprintf(log, " ix iy iz   nr  index  cgs...\n");
871     ci = 0;
872     for (ix = 0; (ix < grid->n[XX]); ix++)
873     {
874         for (iy = 0; (iy < grid->n[YY]); iy++)
875         {
876             for (iz = 0; (iz < grid->n[ZZ]); iz++, ci++)
877             {
878                 index = grid->index[ci];
879                 nra   = grid->nra[ci];
880                 fprintf(log, "%3d%3d%3d%5d%5d", ix, iy, iz, nra, index);
881                 for (i = 0; (i < nra); i++)
882                 {
883                     fprintf(log, "%5d", grid->a[index+i]);
884                 }
885                 fprintf(log, "\n");
886             }
887         }
888     }
889     fflush(log);
890 }