File: | gromacs/gmxlib/splitter.c |
Location: | line 417, column 5 |
Description: | Value stored to 'nsid' is never read |
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 | #include "splitter.h" |
38 | |
39 | #ifdef HAVE_CONFIG_H1 |
40 | #include <config.h> |
41 | #endif |
42 | |
43 | #include <assert.h> |
44 | #include <stdlib.h> |
45 | #include <string.h> |
46 | |
47 | #include "macros.h" |
48 | #include "mshift.h" |
49 | |
50 | #include "gromacs/utility/fatalerror.h" |
51 | #include "gromacs/utility/smalloc.h" |
52 | |
53 | typedef struct { |
54 | int atom, sid; |
55 | } t_sid; |
56 | |
57 | static int sid_comp(const void *a, const void *b) |
58 | { |
59 | t_sid *sa, *sb; |
60 | int dd; |
61 | |
62 | sa = (t_sid *)a; |
63 | sb = (t_sid *)b; |
64 | |
65 | dd = sa->sid-sb->sid; |
66 | if (dd == 0) |
67 | { |
68 | return (sa->atom-sb->atom); |
69 | } |
70 | else |
71 | { |
72 | return dd; |
73 | } |
74 | } |
75 | |
76 | static int mk_grey(egCol egc[], t_graph *g, int *AtomI, |
77 | int maxsid, t_sid sid[]) |
78 | { |
79 | int j, ng, ai, aj, g0; |
80 | |
81 | ng = 0; |
82 | ai = *AtomI; |
83 | |
84 | g0 = g->at_start; |
85 | /* Loop over all the bonds */ |
86 | for (j = 0; (j < g->nedge[ai]); j++) |
87 | { |
88 | aj = g->edge[ai][j]-g0; |
89 | /* If there is a white one, make it gray and set pbc */ |
90 | if (egc[aj] == egcolWhite) |
91 | { |
92 | if (aj < *AtomI) |
93 | { |
94 | *AtomI = aj; |
95 | } |
96 | egc[aj] = egcolGrey; |
97 | |
98 | /* Check whether this one has been set before... */ |
99 | range_check(aj+g0, 0, maxsid)_range_check(aj+g0, 0, maxsid, ((void*)0),"aj+g0", "/home/alexxy/Develop/gromacs/src/gromacs/gmxlib/splitter.c" , 99); |
100 | range_check(ai+g0, 0, maxsid)_range_check(ai+g0, 0, maxsid, ((void*)0),"ai+g0", "/home/alexxy/Develop/gromacs/src/gromacs/gmxlib/splitter.c" , 100); |
101 | if (sid[aj+g0].sid != -1) |
102 | { |
103 | gmx_fatal(FARGS0, "/home/alexxy/Develop/gromacs/src/gromacs/gmxlib/splitter.c" , 103, "sid[%d]=%d, sid[%d]=%d, file %s, line %d", |
104 | ai, sid[ai+g0].sid, aj, sid[aj+g0].sid, __FILE__"/home/alexxy/Develop/gromacs/src/gromacs/gmxlib/splitter.c", __LINE__104); |
105 | } |
106 | else |
107 | { |
108 | sid[aj+g0].sid = sid[ai+g0].sid; |
109 | sid[aj+g0].atom = aj+g0; |
110 | } |
111 | ng++; |
112 | } |
113 | } |
114 | return ng; |
115 | } |
116 | |
117 | static int first_colour(int fC, egCol Col, t_graph *g, egCol egc[]) |
118 | /* Return the first node with colour Col starting at fC. |
119 | * return -1 if none found. |
120 | */ |
121 | { |
122 | int i; |
123 | |
124 | for (i = fC; (i < g->nnodes); i++) |
125 | { |
126 | if ((g->nedge[i] > 0) && (egc[i] == Col)) |
127 | { |
128 | return i; |
129 | } |
130 | } |
131 | |
132 | return -1; |
133 | } |
134 | |
135 | static int mk_sblocks(FILE *fp, t_graph *g, int maxsid, t_sid sid[]) |
136 | { |
137 | int ng, nnodes; |
138 | int nW, nG, nB; /* Number of Grey, Black, White */ |
139 | int fW, fG; /* First of each category */ |
140 | egCol *egc = NULL((void*)0); /* The colour of each node */ |
141 | int g0, nblock; |
142 | |
143 | if (!g->nbound) |
144 | { |
145 | return 0; |
146 | } |
147 | |
148 | nblock = 0; |
149 | |
150 | nnodes = g->nnodes; |
151 | snew(egc, nnodes)(egc) = save_calloc("egc", "/home/alexxy/Develop/gromacs/src/gromacs/gmxlib/splitter.c" , 151, (nnodes), sizeof(*(egc))); |
152 | |
153 | g0 = g->at_start; |
154 | nW = g->nbound; |
155 | nG = 0; |
156 | nB = 0; |
157 | |
158 | fW = 0; |
159 | |
160 | /* We even have a loop invariant: |
161 | * nW+nG+nB == g->nbound |
162 | */ |
163 | |
164 | if (fp) |
165 | { |
166 | fprintf(fp, "Walking down the molecule graph to make constraint-blocks\n"); |
167 | } |
168 | |
169 | while (nW > 0) |
170 | { |
171 | /* Find the first white, this will allways be a larger |
172 | * number than before, because no nodes are made white |
173 | * in the loop |
174 | */ |
175 | if ((fW = first_colour(fW, egcolWhite, g, egc)) == -1) |
176 | { |
177 | gmx_fatal(FARGS0, "/home/alexxy/Develop/gromacs/src/gromacs/gmxlib/splitter.c" , 177, "No WHITE nodes found while nW=%d\n", nW); |
178 | } |
179 | |
180 | /* Make the first white node grey, and set the block number */ |
181 | egc[fW] = egcolGrey; |
182 | range_check(fW+g0, 0, maxsid)_range_check(fW+g0, 0, maxsid, ((void*)0),"fW+g0", "/home/alexxy/Develop/gromacs/src/gromacs/gmxlib/splitter.c" , 182); |
183 | sid[fW+g0].sid = nblock++; |
184 | nG++; |
185 | nW--; |
186 | |
187 | /* Initial value for the first grey */ |
188 | fG = fW; |
189 | |
190 | if (debug) |
191 | { |
192 | fprintf(debug, "Starting G loop (nW=%d, nG=%d, nB=%d, total %d)\n", |
193 | nW, nG, nB, nW+nG+nB); |
194 | } |
195 | |
196 | while (nG > 0) |
197 | { |
198 | if ((fG = first_colour(fG, egcolGrey, g, egc)) == -1) |
199 | { |
200 | gmx_fatal(FARGS0, "/home/alexxy/Develop/gromacs/src/gromacs/gmxlib/splitter.c" , 200, "No GREY nodes found while nG=%d\n", nG); |
201 | } |
202 | |
203 | /* Make the first grey node black */ |
204 | egc[fG] = egcolBlack; |
205 | nB++; |
206 | nG--; |
207 | |
208 | /* Make all the neighbours of this black node grey |
209 | * and set their block number |
210 | */ |
211 | ng = mk_grey(egc, g, &fG, maxsid, sid); |
212 | /* ng is the number of white nodes made grey */ |
213 | nG += ng; |
214 | nW -= ng; |
215 | } |
216 | } |
217 | sfree(egc)save_free("egc", "/home/alexxy/Develop/gromacs/src/gromacs/gmxlib/splitter.c" , 217, (egc)); |
218 | |
219 | if (debug) |
220 | { |
221 | fprintf(debug, "Found %d shake blocks\n", nblock); |
222 | } |
223 | |
224 | return nblock; |
225 | } |
226 | |
227 | |
228 | typedef struct { |
229 | int first, last, sid; |
230 | } t_merge_sid; |
231 | |
232 | static int ms_comp(const void *a, const void *b) |
233 | { |
234 | t_merge_sid *ma = (t_merge_sid *)a; |
235 | t_merge_sid *mb = (t_merge_sid *)b; |
236 | int d; |
237 | |
238 | d = ma->first-mb->first; |
239 | if (d == 0) |
240 | { |
241 | return ma->last-mb->last; |
242 | } |
243 | else |
244 | { |
245 | return d; |
246 | } |
247 | } |
248 | |
249 | static int merge_sid(int at_start, int at_end, int nsid, t_sid sid[], |
250 | t_blocka *sblock) |
251 | { |
252 | int i, j, k, n, isid, ndel; |
253 | t_merge_sid *ms; |
254 | int nChanged; |
255 | |
256 | /* We try to remdy the following problem: |
257 | * Atom: 1 2 3 4 5 6 7 8 9 10 |
258 | * Sid: 0 -1 1 0 -1 1 1 1 1 1 |
259 | */ |
260 | |
261 | /* Determine first and last atom in each shake ID */ |
262 | snew(ms, nsid)(ms) = save_calloc("ms", "/home/alexxy/Develop/gromacs/src/gromacs/gmxlib/splitter.c" , 262, (nsid), sizeof(*(ms))); |
263 | |
264 | for (k = 0; (k < nsid); k++) |
265 | { |
266 | ms[k].first = at_end+1; |
267 | ms[k].last = -1; |
268 | ms[k].sid = k; |
269 | } |
270 | for (i = at_start; (i < at_end); i++) |
271 | { |
272 | isid = sid[i].sid; |
273 | range_check(isid, -1, nsid)_range_check(isid, -1, nsid, ((void*)0),"isid", "/home/alexxy/Develop/gromacs/src/gromacs/gmxlib/splitter.c" , 273); |
274 | if (isid >= 0) |
275 | { |
276 | ms[isid].first = min(ms[isid].first, sid[i].atom)(((ms[isid].first) < (sid[i].atom)) ? (ms[isid].first) : ( sid[i].atom) ); |
277 | ms[isid].last = max(ms[isid].last, sid[i].atom)(((ms[isid].last) > (sid[i].atom)) ? (ms[isid].last) : (sid [i].atom) ); |
278 | } |
279 | } |
280 | qsort(ms, nsid, sizeof(ms[0]), ms_comp); |
281 | |
282 | /* Now merge the overlapping ones */ |
283 | ndel = 0; |
284 | for (k = 0; (k < nsid); ) |
285 | { |
286 | for (j = k+1; (j < nsid); ) |
287 | { |
288 | if (ms[j].first <= ms[k].last) |
289 | { |
290 | ms[k].last = max(ms[k].last, ms[j].last)(((ms[k].last) > (ms[j].last)) ? (ms[k].last) : (ms[j].last ) ); |
291 | ms[k].first = min(ms[k].first, ms[j].first)(((ms[k].first) < (ms[j].first)) ? (ms[k].first) : (ms[j]. first) ); |
292 | ms[j].sid = -1; |
293 | ndel++; |
294 | j++; |
295 | } |
296 | else |
297 | { |
298 | k = j; |
299 | j = k+1; |
300 | } |
301 | } |
302 | if (j == nsid) |
303 | { |
304 | k++; |
305 | } |
306 | } |
307 | for (k = 0; (k < nsid); k++) |
308 | { |
309 | while ((k < nsid-1) && (ms[k].sid == -1)) |
310 | { |
311 | for (j = k+1; (j < nsid); j++) |
312 | { |
313 | memcpy(&(ms[j-1]), &(ms[j]), sizeof(ms[0])); |
314 | } |
315 | nsid--; |
316 | } |
317 | } |
318 | |
319 | for (k = at_start; (k < at_end); k++) |
320 | { |
321 | sid[k].atom = k; |
322 | sid[k].sid = -1; |
323 | } |
324 | sblock->nr = nsid; |
325 | sblock->nalloc_index = sblock->nr+1; |
326 | snew(sblock->index, sblock->nalloc_index)(sblock->index) = save_calloc("sblock->index", "/home/alexxy/Develop/gromacs/src/gromacs/gmxlib/splitter.c" , 326, (sblock->nalloc_index), sizeof(*(sblock->index)) ); |
327 | sblock->nra = at_end - at_start; |
328 | sblock->nalloc_a = sblock->nra; |
329 | snew(sblock->a, sblock->nalloc_a)(sblock->a) = save_calloc("sblock->a", "/home/alexxy/Develop/gromacs/src/gromacs/gmxlib/splitter.c" , 329, (sblock->nalloc_a), sizeof(*(sblock->a))); |
330 | sblock->index[0] = 0; |
331 | for (k = n = 0; (k < nsid); k++) |
332 | { |
333 | sblock->index[k+1] = sblock->index[k] + ms[k].last - ms[k].first+1; |
334 | for (j = ms[k].first; (j <= ms[k].last); j++) |
335 | { |
336 | range_check(n, 0, sblock->nra)_range_check(n, 0, sblock->nra, ((void*)0),"n", "/home/alexxy/Develop/gromacs/src/gromacs/gmxlib/splitter.c" , 336); |
337 | sblock->a[n++] = j; |
338 | range_check(j, 0, at_end)_range_check(j, 0, at_end, ((void*)0),"j", "/home/alexxy/Develop/gromacs/src/gromacs/gmxlib/splitter.c" , 338); |
339 | if (sid[j].sid == -1) |
340 | { |
341 | sid[j].sid = k; |
342 | } |
343 | else |
344 | { |
345 | fprintf(stderrstderr, "Double sids (%d, %d) for atom %d\n", sid[j].sid, k, j); |
346 | } |
347 | } |
348 | } |
349 | assert(k == nsid)((void) (0)); |
350 | /* Removed 2007-09-04 |
351 | sblock->index[k+1] = natoms; |
352 | for(k=0; (k<natoms); k++) |
353 | if (sid[k].sid == -1) |
354 | sblock->a[n++] = k; |
355 | assert(n == natoms); |
356 | */ |
357 | sblock->nra = n; |
358 | assert(sblock->index[k] == sblock->nra)((void) (0)); |
359 | sfree(ms)save_free("ms", "/home/alexxy/Develop/gromacs/src/gromacs/gmxlib/splitter.c" , 359, (ms)); |
360 | |
361 | return nsid; |
362 | } |
363 | |
364 | void gen_sblocks(FILE *fp, int at_start, int at_end, |
365 | t_idef *idef, t_blocka *sblock, |
366 | gmx_bool bSettle) |
367 | { |
368 | t_graph *g; |
369 | int i, i0, j, k, istart, n; |
370 | t_sid *sid; |
371 | int isid, nsid; |
372 | |
373 | g = mk_graph(NULL((void*)0), idef, at_start, at_end, TRUE1, bSettle); |
374 | if (debug) |
375 | { |
376 | p_graph(debug, "Graaf Dracula", g); |
377 | } |
378 | snew(sid, at_end)(sid) = save_calloc("sid", "/home/alexxy/Develop/gromacs/src/gromacs/gmxlib/splitter.c" , 378, (at_end), sizeof(*(sid))); |
379 | for (i = at_start; (i < at_end); i++) |
380 | { |
381 | sid[i].atom = i; |
382 | sid[i].sid = -1; |
383 | } |
384 | nsid = mk_sblocks(fp, g, at_end, sid); |
385 | |
386 | if (!nsid) |
387 | { |
388 | return; |
389 | } |
390 | |
391 | /* Now sort the shake blocks... */ |
392 | qsort(sid+at_start, at_end-at_start, (size_t)sizeof(sid[0]), sid_comp); |
393 | |
394 | if (debug) |
395 | { |
396 | fprintf(debug, "Sorted shake block\n"); |
397 | for (i = at_start; (i < at_end); i++) |
398 | { |
399 | fprintf(debug, "sid[%5d] = atom:%5d sid:%5d\n", i, sid[i].atom, sid[i].sid); |
400 | } |
401 | } |
402 | /* Now check how many are NOT -1, i.e. how many have to be shaken */ |
403 | for (i0 = at_start; (i0 < at_end); i0++) |
404 | { |
405 | if (sid[i0].sid > -1) |
406 | { |
407 | break; |
408 | } |
409 | } |
410 | |
411 | /* Now we have the sids that have to be shaken. We'll check the min and |
412 | * max atom numbers and this determines the shake block. DvdS 2007-07-19. |
413 | * For the purpose of making boundaries all atoms in between need to be |
414 | * part of the shake block too. There may be cases where blocks overlap |
415 | * and they will have to be merged. |
416 | */ |
417 | nsid = merge_sid(at_start, at_end, nsid, sid, sblock); |
Value stored to 'nsid' is never read | |
418 | /* Now sort the shake blocks again... */ |
419 | /*qsort(sid,natoms,(size_t)sizeof(sid[0]),sid_comp);*/ |
420 | |
421 | /* Fill the sblock struct */ |
422 | /* sblock->nr = nsid; |
423 | sblock->nra = natoms; |
424 | srenew(sblock->a,sblock->nra); |
425 | srenew(sblock->index,sblock->nr+1); |
426 | |
427 | i = i0; |
428 | isid = sid[i].sid; |
429 | n = k = 0; |
430 | sblock->index[n++]=k; |
431 | while (i < natoms) { |
432 | istart = sid[i].atom; |
433 | while ((i<natoms-1) && (sid[i+1].sid == isid)) |
434 | i++;*/ |
435 | /* After while: we found a new block, or are thru with the atoms */ |
436 | /* for(j=istart; (j<=sid[i].atom); j++,k++) |
437 | sblock->a[k]=j; |
438 | sblock->index[n] = k; |
439 | if (i < natoms-1) |
440 | n++; |
441 | if (n > nsid) |
442 | gmx_fatal(FARGS,"Death Horror: nsid = %d, n= %d",nsid,n); |
443 | i++; |
444 | isid = sid[i].sid; |
445 | } |
446 | */ |
447 | sfree(sid)save_free("sid", "/home/alexxy/Develop/gromacs/src/gromacs/gmxlib/splitter.c" , 447, (sid)); |
448 | /* Due to unknown reason this free generates a problem sometimes */ |
449 | done_graph(g); |
450 | sfree(g)save_free("g", "/home/alexxy/Develop/gromacs/src/gromacs/gmxlib/splitter.c" , 450, (g)); |
451 | if (debug) |
452 | { |
453 | fprintf(debug, "Done gen_sblocks\n"); |
454 | } |
455 | } |