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