void mk_mshift(FILE *log, t_graph *g, int ePBC, matrix box, const rvec x[]) { static int nerror_tot = 0; int npbcdim; int ng, nnodes, i; int nW, nG, nB; /* Number of Grey, Black, White */ int fW, fG; /* First of each category */ int nerror = 0; g->bScrewPBC = (ePBC == epbcSCREW); if (ePBC == epbcXY) { npbcdim = 2; } else { npbcdim = 3; } GCHECK(g); /* This puts everything in the central box, that is does not move it * at all. If we return without doing this for a system without bonds * (i.e. only settles) all water molecules are moved to the opposite octant */ for (i = g->at0; (i < g->at1); i++) { g->ishift[i][XX] = g->ishift[i][YY] = g->ishift[i][ZZ] = 0; } if (!g->nbound) { return; } nnodes = g->nnodes; if (nnodes > g->negc) { g->negc = nnodes; srenew(g->egc, g->negc); } memset(g->egc, 0, (size_t)(nnodes*sizeof(g->egc[0]))); nW = g->nbound; nG = 0; nB = 0; fW = 0; /* We even have a loop invariant: * nW+nG+nB == g->nbound */ #ifdef DEBUG2 fprintf(log, "Starting W loop\n"); #endif while (nW > 0) { /* Find the first white, this will allways be a larger * number than before, because no nodes are made white * in the loop */ if ((fW = first_colour(fW, egcolWhite, g, g->egc)) == -1) { gmx_fatal(FARGS, "No WHITE nodes found while nW=%d\n", nW); } /* Make the first white node grey */ g->egc[fW] = egcolGrey; nG++; nW--; /* Initial value for the first grey */ fG = fW; #ifdef DEBUG2 fprintf(log, "Starting G loop (nW=%d, nG=%d, nB=%d, total %d)\n", nW, nG, nB, nW+nG+nB); #endif while (nG > 0) { if ((fG = first_colour(fG, egcolGrey, g, g->egc)) == -1) { gmx_fatal(FARGS, "No GREY nodes found while nG=%d\n", nG); } /* Make the first grey node black */ g->egc[fG] = egcolBlack; nB++; nG--; /* Make all the neighbours of this black node grey * and set their periodicity */ ng = mk_grey(g->egc, g, &fG, npbcdim, box, x, &nerror); /* ng is the number of white nodes made grey */ nG += ng; nW -= ng; } } if (nerror > 0) { nerror_tot++; if (nerror_tot <= 100) { fprintf(stderr, "There were %d inconsistent shifts. Check your topology\n", nerror); if (log) { fprintf(log, "There were %d inconsistent shifts. Check your topology\n", nerror); } } if (nerror_tot == 100) { fprintf(stderr, "Will stop reporting inconsistent shifts\n"); if (log) { fprintf(log, "Will stop reporting inconsistent shifts\n"); } } } }
static int mk_sblocks(FILE *fp, t_graph *g, int maxsid, t_sid sid[]) { int ng, nnodes; int nW, nG, nB; /* Number of Grey, Black, White */ int fW, fG; /* First of each category */ egCol *egc = NULL; /* The colour of each node */ int g0, nblock; if (!g->nbound) { return 0; } nblock = 0; nnodes = g->nnodes; snew(egc, nnodes); g0 = g->at_start; nW = g->nbound; nG = 0; nB = 0; fW = 0; /* We even have a loop invariant: * nW+nG+nB == g->nbound */ if (fp) { fprintf(fp, "Walking down the molecule graph to make constraint-blocks\n"); } while (nW > 0) { /* Find the first white, this will allways be a larger * number than before, because no nodes are made white * in the loop */ if ((fW = first_colour(fW, egcolWhite, g, egc)) == -1) { gmx_fatal(FARGS, "No WHITE nodes found while nW=%d\n", nW); } /* Make the first white node grey, and set the block number */ egc[fW] = egcolGrey; range_check(fW+g0, 0, maxsid); sid[fW+g0].sid = nblock++; nG++; nW--; /* Initial value for the first grey */ fG = fW; if (debug) { fprintf(debug, "Starting G loop (nW=%d, nG=%d, nB=%d, total %d)\n", nW, nG, nB, nW+nG+nB); } while (nG > 0) { if ((fG = first_colour(fG, egcolGrey, g, egc)) == -1) { gmx_fatal(FARGS, "No GREY nodes found while nG=%d\n", nG); } /* Make the first grey node black */ egc[fG] = egcolBlack; nB++; nG--; /* Make all the neighbours of this black node grey * and set their block number */ ng = mk_grey(egc, g, &fG, maxsid, sid); /* ng is the number of white nodes made grey */ nG += ng; nW -= ng; } } sfree(egc); if (debug) { fprintf(debug, "Found %d shake blocks\n", nblock); } return nblock; }