clang-tidy: more misc+readability
[alexxy/gromacs.git] / src / gromacs / pbcutil / mshift.cpp
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,2015,2016,2017,2018, 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 #include "gmxpre.h"
38
39 #include "mshift.h"
40
41 #include <string.h>
42
43 #include <algorithm>
44
45 #include "gromacs/math/vec.h"
46 #include "gromacs/pbcutil/pbc.h"
47 #include "gromacs/topology/idef.h"
48 #include "gromacs/topology/ifunc.h"
49 #include "gromacs/utility/fatalerror.h"
50 #include "gromacs/utility/smalloc.h"
51
52 /************************************************************
53  *
54  *      S H I F T   U T I L I T I E S
55  *
56  ************************************************************/
57
58
59 /************************************************************
60  *
61  *      G R A P H   G E N E R A T I O N    C O D E
62  *
63  ************************************************************/
64
65 static void add_gbond(t_graph *g, int a0, int a1)
66 {
67     int         i;
68     int         inda0, inda1;
69     gmx_bool    bFound;
70
71     inda0  = a0 - g->at_start;
72     inda1  = a1 - g->at_start;
73     bFound = FALSE;
74     /* Search for a direct edge between a0 and a1.
75      * All egdes are bidirectional, so we only need to search one way.
76      */
77     for (i = 0; (i < g->nedge[inda0] && !bFound); i++)
78     {
79         bFound = (g->edge[inda0][i] == a1);
80     }
81
82     if (!bFound)
83     {
84         g->edge[inda0][g->nedge[inda0]++] = a1;
85         g->edge[inda1][g->nedge[inda1]++] = a0;
86     }
87 }
88
89 static void mk_igraph(t_graph *g, int ftype, const t_ilist *il,
90                       int at_start, int at_end,
91                       const int *part)
92 {
93     t_iatom *ia;
94     int      i, j, np;
95     int      end;
96
97     end = il->nr;
98     ia  = il->iatoms;
99
100     i = 0;
101     while (i < end)
102     {
103         np = interaction_function[ftype].nratoms;
104
105         if (ia[1] >= at_start && ia[1] < at_end)
106         {
107             if (ia[np] >= at_end)
108             {
109                 gmx_fatal(FARGS,
110                           "Molecule in topology has atom numbers below and "
111                           "above natoms (%d).\n"
112                           "You are probably trying to use a trajectory which does "
113                           "not match the first %d atoms of the run input file.\n"
114                           "You can make a matching run input file with gmx convert-tpr.",
115                           at_end, at_end);
116             }
117             if (ftype == F_SETTLE)
118             {
119                 /* Bond all the atoms in the settle */
120                 add_gbond(g, ia[1], ia[2]);
121                 add_gbond(g, ia[1], ia[3]);
122             }
123             else if (part == nullptr)
124             {
125                 /* Simply add this bond */
126                 for (j = 1; j < np; j++)
127                 {
128                     add_gbond(g, ia[j], ia[j+1]);
129                 }
130             }
131             else
132             {
133                 /* Add this bond when it connects two unlinked parts of the graph */
134                 for (j = 1; j < np; j++)
135                 {
136                     if (part[ia[j]] != part[ia[j+1]])
137                     {
138                         add_gbond(g, ia[j], ia[j+1]);
139                     }
140                 }
141             }
142         }
143         ia += np+1;
144         i  += np+1;
145     }
146 }
147
148 gmx_noreturn static void g_error(int line, const char *file)
149 {
150     gmx_fatal(FARGS, "Trying to print nonexistent graph (file %s, line %d)",
151               file, line);
152 }
153 #define GCHECK(g) if ((g) == NULL) g_error(__LINE__, __FILE__)
154
155 void p_graph(FILE *log, const char *title, t_graph *g)
156 {
157     int         i, j;
158     const char *cc[egcolNR] = { "W", "G", "B" };
159
160     GCHECK(g);
161     fprintf(log, "graph:  %s\n", title);
162     fprintf(log, "nnodes: %d\n", g->nnodes);
163     fprintf(log, "nbound: %d\n", g->nbound);
164     fprintf(log, "start:  %d\n", g->at_start);
165     fprintf(log, "end:    %d\n", g->at_end);
166     fprintf(log, " atom shiftx shifty shiftz C nedg    e1    e2 etc.\n");
167     for (i = 0; (i < g->nnodes); i++)
168     {
169         if (g->nedge[i] > 0)
170         {
171             fprintf(log, "%5d%7d%7d%7d %1s%5d", g->at_start+i+1,
172                     g->ishift[g->at_start+i][XX],
173                     g->ishift[g->at_start+i][YY],
174                     g->ishift[g->at_start+i][ZZ],
175                     (g->negc > 0) ? cc[g->egc[i]] : " ",
176                     g->nedge[i]);
177             for (j = 0; (j < g->nedge[i]); j++)
178             {
179                 fprintf(log, " %5d", g->edge[i][j]+1);
180             }
181             fprintf(log, "\n");
182         }
183     }
184     fflush(log);
185 }
186
187 static void calc_1se(t_graph *g, int ftype, const t_ilist *il,
188                      int nbond[], int at_start, int at_end)
189 {
190     int      k, nratoms, end, j;
191     t_iatom *ia, iaa;
192
193     end = il->nr;
194
195     ia = il->iatoms;
196     for (j = 0; (j < end); j += nratoms+1, ia += nratoms+1)
197     {
198         nratoms = interaction_function[ftype].nratoms;
199
200         if (ftype == F_SETTLE)
201         {
202             iaa          = ia[1];
203             if (iaa >= at_start && iaa < at_end)
204             {
205                 nbond[iaa]   += 2;
206                 nbond[ia[2]] += 1;
207                 nbond[ia[3]] += 1;
208                 g->at_start   = std::min(g->at_start, iaa);
209                 g->at_end     = std::max(g->at_end, iaa+2+1);
210             }
211         }
212         else
213         {
214             for (k = 1; (k <= nratoms); k++)
215             {
216                 iaa = ia[k];
217                 if (iaa >= at_start && iaa < at_end)
218                 {
219                     g->at_start = std::min(g->at_start, iaa);
220                     g->at_end   = std::max(g->at_end,  iaa+1);
221                     /* When making the graph we (might) link all atoms in an interaction
222                      * sequentially. Therefore the end atoms add 1 to the count,
223                      * the middle atoms 2.
224                      */
225                     if (k == 1 || k == nratoms)
226                     {
227                         nbond[iaa] += 1;
228                     }
229                     else
230                     {
231                         nbond[iaa] += 2;
232                     }
233                 }
234             }
235         }
236     }
237 }
238
239 static int calc_start_end(FILE *fplog, t_graph *g, const t_ilist il[],
240                           int at_start, int at_end,
241                           int nbond[])
242 {
243     int   i, nnb, nbtot;
244
245     g->at_start = at_end;
246     g->at_end   = 0;
247
248     /* First add all the real bonds: they should determine the molecular
249      * graph.
250      */
251     for (i = 0; (i < F_NRE); i++)
252     {
253         if (interaction_function[i].flags & IF_CHEMBOND)
254         {
255             calc_1se(g, i, &il[i], nbond, at_start, at_end);
256         }
257     }
258     /* Then add all the other interactions in fixed lists, but first
259      * check to see what's there already.
260      */
261     for (i = 0; (i < F_NRE); i++)
262     {
263         if (!(interaction_function[i].flags & IF_CHEMBOND))
264         {
265             calc_1se(g, i, &il[i], nbond, at_start, at_end);
266         }
267     }
268
269     nnb   = 0;
270     nbtot = 0;
271     for (i = g->at_start; (i < g->at_end); i++)
272     {
273         nbtot += nbond[i];
274         nnb    = std::max(nnb, nbond[i]);
275     }
276     if (fplog)
277     {
278         fprintf(fplog, "Max number of connections per atom is %d\n", nnb);
279         fprintf(fplog, "Total number of connections is %d\n", nbtot);
280     }
281     return nbtot;
282 }
283
284
285
286 static void compact_graph(FILE *fplog, t_graph *g)
287 {
288     int      i, j, n, max_nedge;
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 = std::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     int      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                     const 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, nullptr);
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, nullptr);
446             if (bSettle)
447             {
448                 mk_igraph(g, F_SETTLE, &(ilist[F_SETTLE]), at_start, at_end, nullptr);
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  = nullptr;
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                   const 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     GCHECK(g);
490     if (g->nnodes > 0)
491     {
492         sfree(g->nedge);
493         sfree(g->edge[0]);
494         sfree(g->edge);
495         sfree(g->egc);
496     }
497     sfree(g->ishift);
498 }
499
500 /************************************************************
501  *
502  *      S H I F T   C A L C U L A T I O N   C O D E
503  *
504  ************************************************************/
505
506 static void mk_1shift_tric(int npbcdim, const matrix box, const rvec hbox,
507                            const rvec xi, const rvec xj, const int *mi, int *mj)
508 {
509     /* Calculate periodicity for triclinic box... */
510     int  m, d;
511     rvec dx;
512
513     rvec_sub(xi, xj, dx);
514
515     mj[ZZ] = 0;
516     for (m = npbcdim-1; (m >= 0); m--)
517     {
518         /* If dx < hbox, then xj will be reduced by box, so that
519          * xi - xj will be bigger
520          */
521         if (dx[m] < -hbox[m])
522         {
523             mj[m] = mi[m]-1;
524             for (d = m-1; d >= 0; d--)
525             {
526                 dx[d] += box[m][d];
527             }
528         }
529         else if (dx[m] >= hbox[m])
530         {
531             mj[m] = mi[m]+1;
532             for (d = m-1; d >= 0; d--)
533             {
534                 dx[d] -= box[m][d];
535             }
536         }
537         else
538         {
539             mj[m] = mi[m];
540         }
541     }
542 }
543
544 static void mk_1shift(int npbcdim, const rvec hbox, const rvec xi, const rvec xj,
545                       const int *mi, int *mj)
546 {
547     /* Calculate periodicity for rectangular box... */
548     int  m;
549     rvec dx;
550
551     rvec_sub(xi, xj, dx);
552
553     mj[ZZ] = 0;
554     for (m = 0; (m < npbcdim); m++)
555     {
556         /* If dx < hbox, then xj will be reduced by box, so that
557          * xi - xj will be bigger
558          */
559         if (dx[m] < -hbox[m])
560         {
561             mj[m] = mi[m]-1;
562         }
563         else if (dx[m] >= hbox[m])
564         {
565             mj[m] = mi[m]+1;
566         }
567         else
568         {
569             mj[m] = mi[m];
570         }
571     }
572 }
573
574 static void mk_1shift_screw(const matrix box, const rvec hbox,
575                             const rvec xi, const rvec xj, const int *mi, int *mj)
576 {
577     /* Calculate periodicity for rectangular box... */
578     int  signi, m;
579     rvec dx;
580
581     if ((mi[XX] > 0 &&  mi[XX] % 2 == 1) ||
582         (mi[XX] < 0 && -mi[XX] % 2 == 1))
583     {
584         signi = -1;
585     }
586     else
587     {
588         signi =  1;
589     }
590
591     rvec_sub(xi, xj, dx);
592
593     if (dx[XX] < -hbox[XX])
594     {
595         mj[XX] = mi[XX] - 1;
596     }
597     else if (dx[XX] >= hbox[XX])
598     {
599         mj[XX] = mi[XX] + 1;
600     }
601     else
602     {
603         mj[XX] = mi[XX];
604     }
605     if (mj[XX] != mi[XX])
606     {
607         /* Rotate */
608         dx[YY] = xi[YY] - (box[YY][YY] + box[ZZ][YY] - xj[YY]);
609         dx[ZZ] = xi[ZZ] - (box[ZZ][ZZ]               - xj[ZZ]);
610     }
611     for (m = 1; (m < DIM); m++)
612     {
613         /* The signs are taken such that we can first shift x and rotate
614          * and then shift y and z.
615          */
616         if (dx[m] < -hbox[m])
617         {
618             mj[m] = mi[m] - signi;
619         }
620         else if (dx[m] >= hbox[m])
621         {
622             mj[m] = mi[m] + signi;
623         }
624         else
625         {
626             mj[m] = mi[m];
627         }
628     }
629 }
630
631 static int mk_grey(egCol egc[], t_graph *g, int *AtomI,
632                    int npbcdim, const matrix box, const rvec x[], int *nerror)
633 {
634     int          m, j, ng, ai, aj, g0;
635     rvec         dx, hbox;
636     gmx_bool     bTriclinic;
637     ivec         is_aj;
638     t_pbc        pbc;
639
640     for (m = 0; (m < DIM); m++)
641     {
642         hbox[m] = box[m][m]*0.5;
643     }
644     bTriclinic = TRICLINIC(box);
645
646     g0 = g->at_start;
647     ng = 0;
648     ai = g0 + *AtomI;
649
650     /* Loop over all the bonds */
651     for (j = 0; (j < g->nedge[ai-g0]); j++)
652     {
653         aj = g->edge[ai-g0][j];
654         /* If there is a white one, make it grey and set pbc */
655         if (g->bScrewPBC)
656         {
657             mk_1shift_screw(box, hbox, x[ai], x[aj], g->ishift[ai], is_aj);
658         }
659         else if (bTriclinic)
660         {
661             mk_1shift_tric(npbcdim, box, hbox, x[ai], x[aj], g->ishift[ai], is_aj);
662         }
663         else
664         {
665             mk_1shift(npbcdim, hbox, x[ai], x[aj], g->ishift[ai], is_aj);
666         }
667
668         if (egc[aj-g0] == egcolWhite)
669         {
670             if (aj - g0 < *AtomI)
671             {
672                 *AtomI = aj - g0;
673             }
674             egc[aj-g0] = egcolGrey;
675
676             copy_ivec(is_aj, g->ishift[aj]);
677
678             ng++;
679         }
680         else if ((is_aj[XX] != g->ishift[aj][XX]) ||
681                  (is_aj[YY] != g->ishift[aj][YY]) ||
682                  (is_aj[ZZ] != g->ishift[aj][ZZ]))
683         {
684             if (gmx_debug_at)
685             {
686                 set_pbc(&pbc, -1, box);
687                 pbc_dx(&pbc, x[ai], x[aj], dx);
688                 fprintf(debug, "mk_grey: shifts for atom %d due to atom %d\n"
689                         "are (%d,%d,%d), should be (%d,%d,%d)\n"
690                         "dx = (%g,%g,%g)\n",
691                         aj+1, ai+1, is_aj[XX], is_aj[YY], is_aj[ZZ],
692                         g->ishift[aj][XX], g->ishift[aj][YY], g->ishift[aj][ZZ],
693                         dx[XX], dx[YY], dx[ZZ]);
694             }
695             (*nerror)++;
696         }
697     }
698     return ng;
699 }
700
701 static int first_colour(int fC, egCol Col, t_graph *g, const egCol egc[])
702 /* Return the first node with colour Col starting at fC.
703  * return -1 if none found.
704  */
705 {
706     int i;
707
708     for (i = fC; (i < g->nnodes); i++)
709     {
710         if ((g->nedge[i] > 0) && (egc[i] == Col))
711         {
712             return i;
713         }
714     }
715
716     return -1;
717 }
718
719 void mk_mshift(FILE *log, t_graph *g, int ePBC,
720                const matrix box, const 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(const t_graph *g, const matrix box, const 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(const t_graph *g, const 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(const t_graph *g, const matrix box, rvec x[], const 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(const t_graph *g, const 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