Version bumps after new release
[alexxy/gromacs.git] / src / gromacs / gmxlib / mshift.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 #ifdef HAVE_CONFIG_H
38 #include <config.h>
39 #endif
40
41 #include <string.h>
42 #include "gromacs/utility/smalloc.h"
43 #include "gmx_fatal.h"
44 #include "macros.h"
45 #include "vec.h"
46 #include "gromacs/fileio/futil.h"
47 #include "mshift.h"
48 #include "main.h"
49 #include "pbc.h"
50
51 /************************************************************
52  *
53  *      S H I F T   U T I L I T I E S
54  *
55  ************************************************************/
56
57
58 /************************************************************
59  *
60  *      G R A P H   G E N E R A T I O N    C O D E
61  *
62  ************************************************************/
63
64 static void add_gbond(t_graph *g, atom_id a0, atom_id a1)
65 {
66     int         i;
67     atom_id     inda0, inda1;
68     gmx_bool    bFound;
69
70     inda0  = a0 - g->at_start;
71     inda1  = a1 - g->at_start;
72     bFound = FALSE;
73     /* Search for a direct edge between a0 and a1.
74      * All egdes are bidirectional, so we only need to search one way.
75      */
76     for (i = 0; (i < g->nedge[inda0] && !bFound); i++)
77     {
78         bFound = (g->edge[inda0][i] == a1);
79     }
80
81     if (!bFound)
82     {
83         g->edge[inda0][g->nedge[inda0]++] = a1;
84         g->edge[inda1][g->nedge[inda1]++] = a0;
85     }
86 }
87
88 static void mk_igraph(t_graph *g, int ftype, t_ilist *il,
89                       int at_start, int at_end,
90                       int *part)
91 {
92     t_iatom *ia;
93     int      i, j, np;
94     int      end;
95
96     end = il->nr;
97     ia  = il->iatoms;
98
99     i = 0;
100     while (i < end)
101     {
102         np = interaction_function[ftype].nratoms;
103
104         if (ia[1] >= at_start && ia[1] < at_end)
105         {
106             if (ia[np] >= at_end)
107             {
108                 gmx_fatal(FARGS,
109                           "Molecule in topology has atom numbers below and "
110                           "above natoms (%d).\n"
111                           "You are probably trying to use a trajectory which does "
112                           "not match the first %d atoms of the run input file.\n"
113                           "You can make a matching run input file with gmx convert-tpr.",
114                           at_end, at_end);
115             }
116             if (ftype == F_SETTLE)
117             {
118                 /* Bond all the atoms in the settle */
119                 add_gbond(g, ia[1], ia[2]);
120                 add_gbond(g, ia[1], ia[3]);
121             }
122             else if (part == NULL)
123             {
124                 /* Simply add this bond */
125                 for (j = 1; j < np; j++)
126                 {
127                     add_gbond(g, ia[j], ia[j+1]);
128                 }
129             }
130             else
131             {
132                 /* Add this bond when it connects two unlinked parts of the graph */
133                 for (j = 1; j < np; j++)
134                 {
135                     if (part[ia[j]] != part[ia[j+1]])
136                     {
137                         add_gbond(g, ia[j], ia[j+1]);
138                     }
139                 }
140             }
141         }
142         ia += np+1;
143         i  += np+1;
144     }
145 }
146
147 GMX_ATTRIBUTE_NORETURN static void g_error(int line, const char *file)
148 {
149     gmx_fatal(FARGS, "Tring to print non existant graph (file %s, line %d)",
150               file, line);
151 }
152 #define GCHECK(g) if (g == NULL) g_error(__LINE__, __FILE__)
153
154 void p_graph(FILE *log, const char *title, t_graph *g)
155 {
156     int         i, j;
157     const char *cc[egcolNR] = { "W", "G", "B" };
158
159     GCHECK(g);
160     fprintf(log, "graph:  %s\n", title);
161     fprintf(log, "nnodes: %d\n", g->nnodes);
162     fprintf(log, "nbound: %d\n", g->nbound);
163     fprintf(log, "start:  %d\n", g->at_start);
164     fprintf(log, "end:    %d\n", g->at_end);
165     fprintf(log, " atom shiftx shifty shiftz C nedg    e1    e2 etc.\n");
166     for (i = 0; (i < g->nnodes); i++)
167     {
168         if (g->nedge[i] > 0)
169         {
170             fprintf(log, "%5d%7d%7d%7d %1s%5d", g->at_start+i+1,
171                     g->ishift[g->at_start+i][XX],
172                     g->ishift[g->at_start+i][YY],
173                     g->ishift[g->at_start+i][ZZ],
174                     (g->negc > 0) ? cc[g->egc[i]] : " ",
175                     g->nedge[i]);
176             for (j = 0; (j < g->nedge[i]); j++)
177             {
178                 fprintf(log, " %5u", g->edge[i][j]+1);
179             }
180             fprintf(log, "\n");
181         }
182     }
183     fflush(log);
184 }
185
186 static void calc_1se(t_graph *g, int ftype, t_ilist *il,
187                      int nbond[], int at_start, int at_end)
188 {
189     int      k, nratoms, end, j;
190     t_iatom *ia, iaa;
191
192     end = il->nr;
193
194     ia = il->iatoms;
195     for (j = 0; (j < end); j += nratoms+1, ia += nratoms+1)
196     {
197         nratoms = interaction_function[ftype].nratoms;
198
199         if (ftype == F_SETTLE)
200         {
201             iaa          = ia[1];
202             if (iaa >= at_start && iaa < at_end)
203             {
204                 nbond[iaa]   += 2;
205                 nbond[ia[2]] += 1;
206                 nbond[ia[3]] += 1;
207                 g->at_start   = min(g->at_start, iaa);
208                 g->at_end     = max(g->at_end, iaa+2+1);
209             }
210         }
211         else
212         {
213             for (k = 1; (k <= nratoms); k++)
214             {
215                 iaa = ia[k];
216                 if (iaa >= at_start && iaa < at_end)
217                 {
218                     g->at_start = min(g->at_start, iaa);
219                     g->at_end   = max(g->at_end,  iaa+1);
220                     /* When making the graph we (might) link all atoms in an interaction
221                      * sequentially. Therefore the end atoms add 1 to the count,
222                      * the middle atoms 2.
223                      */
224                     if (k == 1 || k == nratoms)
225                     {
226                         nbond[iaa] += 1;
227                     }
228                     else
229                     {
230                         nbond[iaa] += 2;
231                     }
232                 }
233             }
234         }
235     }
236 }
237
238 static int calc_start_end(FILE *fplog, t_graph *g, t_ilist il[],
239                           int at_start, int at_end,
240                           int nbond[])
241 {
242     int   i, nnb, nbtot;
243
244     g->at_start = at_end;
245     g->at_end   = 0;
246
247     /* First add all the real bonds: they should determine the molecular
248      * graph.
249      */
250     for (i = 0; (i < F_NRE); i++)
251     {
252         if (interaction_function[i].flags & IF_CHEMBOND)
253         {
254             calc_1se(g, i, &il[i], nbond, at_start, at_end);
255         }
256     }
257     /* Then add all the other interactions in fixed lists, but first
258      * check to see what's there already.
259      */
260     for (i = 0; (i < F_NRE); i++)
261     {
262         if (!(interaction_function[i].flags & IF_CHEMBOND))
263         {
264             calc_1se(g, i, &il[i], nbond, at_start, at_end);
265         }
266     }
267
268     nnb   = 0;
269     nbtot = 0;
270     for (i = g->at_start; (i < g->at_end); i++)
271     {
272         nbtot += nbond[i];
273         nnb    = max(nnb, nbond[i]);
274     }
275     if (fplog)
276     {
277         fprintf(fplog, "Max number of connections per atom is %d\n", nnb);
278         fprintf(fplog, "Total number of connections is %d\n", nbtot);
279     }
280     return nbtot;
281 }
282
283
284
285 static void compact_graph(FILE *fplog, t_graph *g)
286 {
287     int      i, j, n, max_nedge;
288     atom_id *e;
289
290     max_nedge = 0;
291     n         = 0;
292     for (i = 0; i < g->nnodes; i++)
293     {
294         for (j = 0; j < g->nedge[i]; j++)
295         {
296             g->edge[0][n++] = g->edge[i][j];
297         }
298         max_nedge = max(max_nedge, g->nedge[i]);
299     }
300     srenew(g->edge[0], n);
301     /* set pointers after srenew because edge[0] might move */
302     for (i = 1; i < g->nnodes; i++)
303     {
304         g->edge[i] = g->edge[i-1] + g->nedge[i-1];
305     }
306
307     if (fplog)
308     {
309         fprintf(fplog, "Max number of graph edges per atom is %d\n",
310                 max_nedge);
311         fprintf(fplog, "Total number of graph edges is %d\n", n);
312     }
313 }
314
315 static gmx_bool determine_graph_parts(t_graph *g, int *part)
316 {
317     int      i, e;
318     int      nchanged;
319     atom_id  at_i, *at_i2;
320     gmx_bool bMultiPart;
321
322     /* Initialize the part array with all entries different */
323     for (at_i = g->at_start; at_i < g->at_end; at_i++)
324     {
325         part[at_i] = at_i;
326     }
327
328     /* Loop over the graph until the part array is fixed */
329     do
330     {
331         bMultiPart = FALSE;
332         nchanged   = 0;
333         for (i = 0; (i < g->nnodes); i++)
334         {
335             at_i  = g->at_start + i;
336             at_i2 = g->edge[i];
337             for (e = 0; e < g->nedge[i]; e++)
338             {
339                 /* Set part for both nodes to the minimum */
340                 if (part[at_i2[e]] > part[at_i])
341                 {
342                     part[at_i2[e]] = part[at_i];
343                     nchanged++;
344                 }
345                 else if (part[at_i2[e]] < part[at_i])
346                 {
347                     part[at_i] = part[at_i2[e]];
348                     nchanged++;
349                 }
350             }
351             if (part[at_i] != part[g->at_start])
352             {
353                 bMultiPart = TRUE;
354             }
355         }
356         if (debug)
357         {
358             fprintf(debug, "graph part[] nchanged=%d, bMultiPart=%d\n",
359                     nchanged, bMultiPart);
360         }
361     }
362     while (nchanged > 0);
363
364     return bMultiPart;
365 }
366
367 void mk_graph_ilist(FILE *fplog,
368                     t_ilist *ilist, int at_start, int at_end,
369                     gmx_bool bShakeOnly, gmx_bool bSettle,
370                     t_graph *g)
371 {
372     int        *nbond;
373     int         i, nbtot;
374     gmx_bool    bMultiPart;
375
376     /* The naming is somewhat confusing, but we need g->at0 and g->at1
377      * for shifthing coordinates to a new array (not in place) when
378      * some atoms are not connected by the graph, which runs from
379      * g->at_start (>= g->at0) to g->at_end (<= g->at1).
380      */
381     g->at0 = at_start;
382     g->at1 = at_end;
383
384     snew(nbond, at_end);
385     nbtot = calc_start_end(fplog, g, ilist, at_start, at_end, nbond);
386
387     if (g->at_start >= g->at_end)
388     {
389         g->at_start = at_start;
390         g->at_end   = at_end;
391         g->nnodes   = 0;
392         g->nbound   = 0;
393     }
394     else
395     {
396         g->nnodes = g->at_end - g->at_start;
397         snew(g->nedge, g->nnodes);
398         snew(g->edge, g->nnodes);
399         /* Allocate a single array and set pointers into it */
400         snew(g->edge[0], nbtot);
401         for (i = 1; (i < g->nnodes); i++)
402         {
403             g->edge[i] = g->edge[i-1] + nbond[g->at_start+i-1];
404         }
405
406         if (!bShakeOnly)
407         {
408             /* First add all the real bonds: they should determine the molecular
409              * graph.
410              */
411             for (i = 0; (i < F_NRE); i++)
412             {
413                 if (interaction_function[i].flags & IF_CHEMBOND)
414                 {
415                     mk_igraph(g, i, &(ilist[i]), at_start, at_end, NULL);
416                 }
417             }
418
419             /* Determine of which separated parts the IF_CHEMBOND graph consists.
420              * Store the parts in the nbond array.
421              */
422             bMultiPart = determine_graph_parts(g, nbond);
423
424             if (bMultiPart)
425             {
426                 /* Then add all the other interactions in fixed lists,
427                  * but only when they connect parts of the graph
428                  * that are not connected through IF_CHEMBOND interactions.
429                  */
430                 for (i = 0; (i < F_NRE); i++)
431                 {
432                     if (!(interaction_function[i].flags & IF_CHEMBOND))
433                     {
434                         mk_igraph(g, i, &(ilist[i]), at_start, at_end, nbond);
435                     }
436                 }
437             }
438
439             /* Removed all the unused space from the edge array */
440             compact_graph(fplog, g);
441         }
442         else
443         {
444             /* This is a special thing used in splitter.c to generate shake-blocks */
445             mk_igraph(g, F_CONSTR, &(ilist[F_CONSTR]), at_start, at_end, NULL);
446             if (bSettle)
447             {
448                 mk_igraph(g, F_SETTLE, &(ilist[F_SETTLE]), at_start, at_end, NULL);
449             }
450         }
451         g->nbound = 0;
452         for (i = 0; (i < g->nnodes); i++)
453         {
454             if (g->nedge[i] > 0)
455             {
456                 g->nbound++;
457             }
458         }
459     }
460
461     g->negc = 0;
462     g->egc  = NULL;
463
464     sfree(nbond);
465
466     snew(g->ishift, g->at1);
467
468     if (gmx_debug_at)
469     {
470         p_graph(debug, "graph", g);
471     }
472 }
473
474 t_graph *mk_graph(FILE *fplog,
475                   t_idef *idef, int at_start, int at_end,
476                   gmx_bool bShakeOnly, gmx_bool bSettle)
477 {
478     t_graph *g;
479
480     snew(g, 1);
481
482     mk_graph_ilist(fplog, idef->il, at_start, at_end, bShakeOnly, bSettle, g);
483
484     return g;
485 }
486
487 void done_graph(t_graph *g)
488 {
489     int i;
490
491     GCHECK(g);
492     if (g->nnodes > 0)
493     {
494         sfree(g->nedge);
495         sfree(g->edge[0]);
496         sfree(g->edge);
497         sfree(g->egc);
498     }
499     sfree(g->ishift);
500 }
501
502 /************************************************************
503  *
504  *      S H I F T   C A L C U L A T I O N   C O D E
505  *
506  ************************************************************/
507
508 static void mk_1shift_tric(int npbcdim, matrix box, rvec hbox,
509                            rvec xi, rvec xj, int *mi, int *mj)
510 {
511     /* Calculate periodicity for triclinic box... */
512     int  m, d;
513     rvec dx;
514
515     rvec_sub(xi, xj, dx);
516
517     mj[ZZ] = 0;
518     for (m = npbcdim-1; (m >= 0); m--)
519     {
520         /* If dx < hbox, then xj will be reduced by box, so that
521          * xi - xj will be bigger
522          */
523         if (dx[m] < -hbox[m])
524         {
525             mj[m] = mi[m]-1;
526             for (d = m-1; d >= 0; d--)
527             {
528                 dx[d] += box[m][d];
529             }
530         }
531         else if (dx[m] >= hbox[m])
532         {
533             mj[m] = mi[m]+1;
534             for (d = m-1; d >= 0; d--)
535             {
536                 dx[d] -= box[m][d];
537             }
538         }
539         else
540         {
541             mj[m] = mi[m];
542         }
543     }
544 }
545
546 static void mk_1shift(int npbcdim, rvec hbox, rvec xi, rvec xj, int *mi, int *mj)
547 {
548     /* Calculate periodicity for rectangular box... */
549     int  m;
550     rvec dx;
551
552     rvec_sub(xi, xj, dx);
553
554     mj[ZZ] = 0;
555     for (m = 0; (m < npbcdim); m++)
556     {
557         /* If dx < hbox, then xj will be reduced by box, so that
558          * xi - xj will be bigger
559          */
560         if (dx[m] < -hbox[m])
561         {
562             mj[m] = mi[m]-1;
563         }
564         else if (dx[m] >= hbox[m])
565         {
566             mj[m] = mi[m]+1;
567         }
568         else
569         {
570             mj[m] = mi[m];
571         }
572     }
573 }
574
575 static void mk_1shift_screw(matrix box, rvec hbox,
576                             rvec xi, rvec xj, int *mi, int *mj)
577 {
578     /* Calculate periodicity for rectangular box... */
579     int  signi, m;
580     rvec dx;
581
582     if ((mi[XX] > 0 &&  mi[XX] % 2 == 1) ||
583         (mi[XX] < 0 && -mi[XX] % 2 == 1))
584     {
585         signi = -1;
586     }
587     else
588     {
589         signi =  1;
590     }
591
592     rvec_sub(xi, xj, dx);
593
594     if (dx[XX] < -hbox[XX])
595     {
596         mj[XX] = mi[XX] - 1;
597     }
598     else if (dx[XX] >= hbox[XX])
599     {
600         mj[XX] = mi[XX] + 1;
601     }
602     else
603     {
604         mj[XX] = mi[XX];
605     }
606     if (mj[XX] != mi[XX])
607     {
608         /* Rotate */
609         dx[YY] = xi[YY] - (box[YY][YY] + box[ZZ][YY] - xj[YY]);
610         dx[ZZ] = xi[ZZ] - (box[ZZ][ZZ]               - xj[ZZ]);
611     }
612     for (m = 1; (m < DIM); m++)
613     {
614         /* The signs are taken such that we can first shift x and rotate
615          * and then shift y and z.
616          */
617         if (dx[m] < -hbox[m])
618         {
619             mj[m] = mi[m] - signi;
620         }
621         else if (dx[m] >= hbox[m])
622         {
623             mj[m] = mi[m] + signi;
624         }
625         else
626         {
627             mj[m] = mi[m];
628         }
629     }
630 }
631
632 static int mk_grey(egCol egc[], t_graph *g, int *AtomI,
633                    int npbcdim, matrix box, rvec x[], int *nerror)
634 {
635     int          m, j, ng, ai, aj, g0;
636     rvec         dx, hbox;
637     gmx_bool     bTriclinic;
638     ivec         is_aj;
639     t_pbc        pbc;
640
641     for (m = 0; (m < DIM); m++)
642     {
643         hbox[m] = box[m][m]*0.5;
644     }
645     bTriclinic = TRICLINIC(box);
646
647     g0 = g->at_start;
648     ng = 0;
649     ai = g0 + *AtomI;
650
651     /* Loop over all the bonds */
652     for (j = 0; (j < g->nedge[ai-g0]); j++)
653     {
654         aj = g->edge[ai-g0][j];
655         /* If there is a white one, make it grey and set pbc */
656         if (g->bScrewPBC)
657         {
658             mk_1shift_screw(box, hbox, x[ai], x[aj], g->ishift[ai], is_aj);
659         }
660         else if (bTriclinic)
661         {
662             mk_1shift_tric(npbcdim, box, hbox, x[ai], x[aj], g->ishift[ai], is_aj);
663         }
664         else
665         {
666             mk_1shift(npbcdim, hbox, x[ai], x[aj], g->ishift[ai], is_aj);
667         }
668
669         if (egc[aj-g0] == egcolWhite)
670         {
671             if (aj - g0 < *AtomI)
672             {
673                 *AtomI = aj - g0;
674             }
675             egc[aj-g0] = egcolGrey;
676
677             copy_ivec(is_aj, g->ishift[aj]);
678
679             ng++;
680         }
681         else if ((is_aj[XX] != g->ishift[aj][XX]) ||
682                  (is_aj[YY] != g->ishift[aj][YY]) ||
683                  (is_aj[ZZ] != g->ishift[aj][ZZ]))
684         {
685             if (gmx_debug_at)
686             {
687                 set_pbc(&pbc, -1, box);
688                 pbc_dx(&pbc, x[ai], x[aj], dx);
689                 fprintf(debug, "mk_grey: shifts for atom %d due to atom %d\n"
690                         "are (%d,%d,%d), should be (%d,%d,%d)\n"
691                         "dx = (%g,%g,%g)\n",
692                         aj+1, ai+1, is_aj[XX], is_aj[YY], is_aj[ZZ],
693                         g->ishift[aj][XX], g->ishift[aj][YY], g->ishift[aj][ZZ],
694                         dx[XX], dx[YY], dx[ZZ]);
695             }
696             (*nerror)++;
697         }
698     }
699     return ng;
700 }
701
702 static int first_colour(int fC, egCol Col, t_graph *g, egCol egc[])
703 /* Return the first node with colour Col starting at fC.
704  * return -1 if none found.
705  */
706 {
707     int i;
708
709     for (i = fC; (i < g->nnodes); i++)
710     {
711         if ((g->nedge[i] > 0) && (egc[i] == Col))
712         {
713             return i;
714         }
715     }
716
717     return -1;
718 }
719
720 void mk_mshift(FILE *log, t_graph *g, int ePBC, matrix box, rvec x[])
721 {
722     static int nerror_tot = 0;
723     int        npbcdim;
724     int        ng, nnodes, i;
725     int        nW, nG, nB; /* Number of Grey, Black, White      */
726     int        fW, fG;     /* First of each category    */
727     int        nerror = 0;
728
729     g->bScrewPBC = (ePBC == epbcSCREW);
730
731     if (ePBC == epbcXY)
732     {
733         npbcdim = 2;
734     }
735     else
736     {
737         npbcdim = 3;
738     }
739
740     GCHECK(g);
741     /* This puts everything in the central box, that is does not move it
742      * at all. If we return without doing this for a system without bonds
743      * (i.e. only settles) all water molecules are moved to the opposite octant
744      */
745     for (i = g->at0; (i < g->at1); i++)
746     {
747         g->ishift[i][XX] = g->ishift[i][YY] = g->ishift[i][ZZ] = 0;
748     }
749
750     if (!g->nbound)
751     {
752         return;
753     }
754
755     nnodes = g->nnodes;
756     if (nnodes > g->negc)
757     {
758         g->negc = nnodes;
759         srenew(g->egc, g->negc);
760     }
761     memset(g->egc, 0, (size_t)(nnodes*sizeof(g->egc[0])));
762
763     nW = g->nbound;
764     nG = 0;
765     nB = 0;
766
767     fW = 0;
768
769     /* We even have a loop invariant:
770      * nW+nG+nB == g->nbound
771      */
772 #ifdef DEBUG2
773     fprintf(log, "Starting W loop\n");
774 #endif
775     while (nW > 0)
776     {
777         /* Find the first white, this will allways be a larger
778          * number than before, because no nodes are made white
779          * in the loop
780          */
781         if ((fW = first_colour(fW, egcolWhite, g, g->egc)) == -1)
782         {
783             gmx_fatal(FARGS, "No WHITE nodes found while nW=%d\n", nW);
784         }
785
786         /* Make the first white node grey */
787         g->egc[fW] = egcolGrey;
788         nG++;
789         nW--;
790
791         /* Initial value for the first grey */
792         fG = fW;
793 #ifdef DEBUG2
794         fprintf(log, "Starting G loop (nW=%d, nG=%d, nB=%d, total %d)\n",
795                 nW, nG, nB, nW+nG+nB);
796 #endif
797         while (nG > 0)
798         {
799             if ((fG = first_colour(fG, egcolGrey, g, g->egc)) == -1)
800             {
801                 gmx_fatal(FARGS, "No GREY nodes found while nG=%d\n", nG);
802             }
803
804             /* Make the first grey node black */
805             g->egc[fG] = egcolBlack;
806             nB++;
807             nG--;
808
809             /* Make all the neighbours of this black node grey
810              * and set their periodicity
811              */
812             ng = mk_grey(g->egc, g, &fG, npbcdim, box, x, &nerror);
813             /* ng is the number of white nodes made grey */
814             nG += ng;
815             nW -= ng;
816         }
817     }
818     if (nerror > 0)
819     {
820         nerror_tot++;
821         if (nerror_tot <= 100)
822         {
823             fprintf(stderr, "There were %d inconsistent shifts. Check your topology\n",
824                     nerror);
825             if (log)
826             {
827                 fprintf(log, "There were %d inconsistent shifts. Check your topology\n",
828                         nerror);
829             }
830         }
831         if (nerror_tot == 100)
832         {
833             fprintf(stderr, "Will stop reporting inconsistent shifts\n");
834             if (log)
835             {
836                 fprintf(log, "Will stop reporting inconsistent shifts\n");
837             }
838         }
839     }
840 }
841
842 /************************************************************
843  *
844  *      A C T U A L   S H I F T   C O D E
845  *
846  ************************************************************/
847
848 void shift_x(t_graph *g, matrix box, rvec x[], rvec x_s[])
849 {
850     ivec    *is;
851     int      g0, g1;
852     int      j, tx, ty, tz;
853
854     GCHECK(g);
855     g0 = g->at_start;
856     g1 = g->at_end;
857     is = g->ishift;
858
859     for (j = g->at0; j < g0; j++)
860     {
861         copy_rvec(x[j], x_s[j]);
862     }
863
864     if (g->bScrewPBC)
865     {
866         for (j = g0; (j < g1); j++)
867         {
868             tx = is[j][XX];
869             ty = is[j][YY];
870             tz = is[j][ZZ];
871
872             if ((tx > 0 && tx % 2 == 1) ||
873                 (tx < 0 && -tx %2 == 1))
874             {
875                 x_s[j][XX] = x[j][XX] + tx*box[XX][XX];
876                 x_s[j][YY] = box[YY][YY] + box[ZZ][YY] - x[j][YY];
877                 x_s[j][ZZ] = box[ZZ][ZZ]               - x[j][ZZ];
878             }
879             else
880             {
881                 x_s[j][XX] = x[j][XX];
882             }
883             x_s[j][YY] = x[j][YY] + ty*box[YY][YY] + tz*box[ZZ][YY];
884             x_s[j][ZZ] = x[j][ZZ] + tz*box[ZZ][ZZ];
885         }
886     }
887     else if (TRICLINIC(box))
888     {
889         for (j = g0; (j < g1); j++)
890         {
891             tx = is[j][XX];
892             ty = is[j][YY];
893             tz = is[j][ZZ];
894
895             x_s[j][XX] = x[j][XX]+tx*box[XX][XX]+ty*box[YY][XX]+tz*box[ZZ][XX];
896             x_s[j][YY] = x[j][YY]+ty*box[YY][YY]+tz*box[ZZ][YY];
897             x_s[j][ZZ] = x[j][ZZ]+tz*box[ZZ][ZZ];
898         }
899     }
900     else
901     {
902         for (j = g0; (j < g1); j++)
903         {
904             tx = is[j][XX];
905             ty = is[j][YY];
906             tz = is[j][ZZ];
907
908             x_s[j][XX] = x[j][XX]+tx*box[XX][XX];
909             x_s[j][YY] = x[j][YY]+ty*box[YY][YY];
910             x_s[j][ZZ] = x[j][ZZ]+tz*box[ZZ][ZZ];
911         }
912     }
913
914     for (j = g1; j < g->at1; j++)
915     {
916         copy_rvec(x[j], x_s[j]);
917     }
918 }
919
920 void shift_self(t_graph *g, matrix box, rvec x[])
921 {
922     ivec    *is;
923     int      g0, g1;
924     int      j, tx, ty, tz;
925
926     if (g->bScrewPBC)
927     {
928         gmx_incons("screw pbc not implemented for shift_self");
929     }
930
931     g0 = g->at_start;
932     g1 = g->at_end;
933     is = g->ishift;
934
935 #ifdef DEBUG
936     fprintf(stderr, "Shifting atoms %d to %d\n", g0, g0+gn);
937 #endif
938     if (TRICLINIC(box))
939     {
940         for (j = g0; (j < g1); j++)
941         {
942             tx = is[j][XX];
943             ty = is[j][YY];
944             tz = is[j][ZZ];
945
946             x[j][XX] = x[j][XX]+tx*box[XX][XX]+ty*box[YY][XX]+tz*box[ZZ][XX];
947             x[j][YY] = x[j][YY]+ty*box[YY][YY]+tz*box[ZZ][YY];
948             x[j][ZZ] = x[j][ZZ]+tz*box[ZZ][ZZ];
949         }
950     }
951     else
952     {
953         for (j = g0; (j < g1); j++)
954         {
955             tx = is[j][XX];
956             ty = is[j][YY];
957             tz = is[j][ZZ];
958
959             x[j][XX] = x[j][XX]+tx*box[XX][XX];
960             x[j][YY] = x[j][YY]+ty*box[YY][YY];
961             x[j][ZZ] = x[j][ZZ]+tz*box[ZZ][ZZ];
962         }
963     }
964 }
965
966 void unshift_x(t_graph *g, matrix box, rvec x[], rvec x_s[])
967 {
968     ivec    *is;
969     int      g0, g1;
970     int      j, tx, ty, tz;
971
972     if (g->bScrewPBC)
973     {
974         gmx_incons("screw pbc not implemented (yet) for unshift_x");
975     }
976
977     g0 = g->at_start;
978     g1 = g->at_end;
979     is = g->ishift;
980
981     for (j = g->at0; j < g0; j++)
982     {
983         copy_rvec(x_s[j], x[j]);
984     }
985
986     if (TRICLINIC(box))
987     {
988         for (j = g0; (j < g1); j++)
989         {
990             tx = is[j][XX];
991             ty = is[j][YY];
992             tz = is[j][ZZ];
993
994             x[j][XX] = x_s[j][XX]-tx*box[XX][XX]-ty*box[YY][XX]-tz*box[ZZ][XX];
995             x[j][YY] = x_s[j][YY]-ty*box[YY][YY]-tz*box[ZZ][YY];
996             x[j][ZZ] = x_s[j][ZZ]-tz*box[ZZ][ZZ];
997         }
998     }
999     else
1000     {
1001         for (j = g0; (j < g1); j++)
1002         {
1003             tx = is[j][XX];
1004             ty = is[j][YY];
1005             tz = is[j][ZZ];
1006
1007             x[j][XX] = x_s[j][XX]-tx*box[XX][XX];
1008             x[j][YY] = x_s[j][YY]-ty*box[YY][YY];
1009             x[j][ZZ] = x_s[j][ZZ]-tz*box[ZZ][ZZ];
1010         }
1011     }
1012
1013     for (j = g1; j < g->at1; j++)
1014     {
1015         copy_rvec(x_s[j], x[j]);
1016     }
1017 }
1018
1019 void unshift_self(t_graph *g, matrix box, rvec x[])
1020 {
1021     ivec *is;
1022     int   g0, g1;
1023     int   j, tx, ty, tz;
1024
1025     if (g->bScrewPBC)
1026     {
1027         gmx_incons("screw pbc not implemented for unshift_self");
1028     }
1029
1030     g0 = g->at_start;
1031     g1 = g->at_end;
1032     is = g->ishift;
1033
1034     if (TRICLINIC(box))
1035     {
1036         for (j = g0; (j < g1); j++)
1037         {
1038             tx = is[j][XX];
1039             ty = is[j][YY];
1040             tz = is[j][ZZ];
1041
1042             x[j][XX] = x[j][XX]-tx*box[XX][XX]-ty*box[YY][XX]-tz*box[ZZ][XX];
1043             x[j][YY] = x[j][YY]-ty*box[YY][YY]-tz*box[ZZ][YY];
1044             x[j][ZZ] = x[j][ZZ]-tz*box[ZZ][ZZ];
1045         }
1046     }
1047     else
1048     {
1049         for (j = g0; (j < g1); j++)
1050         {
1051             tx = is[j][XX];
1052             ty = is[j][YY];
1053             tz = is[j][ZZ];
1054
1055             x[j][XX] = x[j][XX]-tx*box[XX][XX];
1056             x[j][YY] = x[j][YY]-ty*box[YY][YY];
1057             x[j][ZZ] = x[j][ZZ]-tz*box[ZZ][ZZ];
1058         }
1059     }
1060 }
1061 #undef GCHECK