1 // -*- Mode : c++ -*-
2 //
3 // SUMMARY :
4 // USAGE :
5 // ORG :
6 // AUTHOR : Frederic Hecht
7 // E-MAIL : hecht@ann.jussieu.fr
8 //
9
10 /*
11
12 This file is part of Freefem++
13
14 Freefem++ is free software; you can redistribute it and/or modify
15 it under the terms of the GNU Lesser General Public License as published by
16 the Free Software Foundation; either version 2.1 of the License, or
17 (at your option) any later version.
18
19 Freefem++ is distributed in the hope that it will be useful,
20 but WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 GNU Lesser General Public License for more details.
23
24 You should have received a copy of the GNU Lesser General Public License
25 along with Freefem++; if not, write to the Free Software
26 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
27 */
28
29 #include <cmath>
30 #include <cstdio>
31 #include <cstdlib>
32 #include "vect.h"
33
34 #define mmax(a, b) (a > b ? a : b)
35 #define mmin(a, b) (a < b ? a : b)
36 #define ffalse 0
37 #define ttrue 1
38
39 /* -- translated by f2c (version of 23 May 1992 14:18:33).
40 You must link the resulting object file with the libraries:
41 -lF77 -lI77 -lm -lc (in that order)
42 */
43
44 #define integer long
45 #define logical long
46
47 int gibbs1_(integer* n, integer* record, integer* ptvois);
48 int gibbs2_(integer* n, integer* record, integer* criter);
49 int gibbsa_(integer* n, integer* ptvois, integer* vois, integer* r, integer* m, integer* nv,
50 integer* nx, integer* ny, integer* nn, integer* w1, integer* w2, integer* pfold,
51 integer* pfnew, integer* impre, integer* nfout);
52 int gibbsb_(integer* x, integer* y, integer* n, integer* ptvois, integer* vois, integer* nx,
53 integer* ny, integer* nv, integer* nn, integer* m, integer* wh, integer* wl, integer* r,
54 integer* impre, integer* nfout);
55 int gibbsc_(integer* nz, integer* nv, integer* niveau, integer* n, integer*);
56 int gibbsd_(integer* racine, integer* n, integer* ptvois, integer* vois, integer* nv, integer* r,
57 integer* niveau);
58 int gibbst_(integer* n, integer* p, integer* nv, integer* nn, integer* ptvois, integer* vois,
59 integer* m, integer* r, integer* new_, integer* option, integer* pfnew, integer* impre,
60 integer* nfout);
61
gibbs1_(integer * n,integer * record,integer * ptvois)62 /* Subroutine */ int gibbs1_(integer* n, integer* record, integer* ptvois) {
63 /* System generated locals */
64 integer i__1;
65
66 /* Local variables */
67 static integer crit, i, j, l, r, rec;
68
69 /* -----------------------------------------------------------------------
70 */
71 /* routine appele par gibbs0 */
72 /* -----------------------------------------------------------------------
73 */
74 /* but: trie record (ensemble de n sommet) telle que l'ordre des somm
75 */
76 /* soit croissant (ordre du sommet i est ptvois(i+1)-ptvois(i)) */
77 /* -----------------------------------------------------------------------
78 */
79
80 /* Parameter adjustments */
81 --ptvois;
82 --record;
83
84 /* Function Body */
85 if (*n <= 1) {
86 return 0;
87 }
88 l = *n / 2 + 1;
89 r = *n;
90 L2:
91 if (l <= 1) {
92 goto L20;
93 }
94 --l;
95 rec = record[l];
96 crit = ptvois[record[l] + 1] - ptvois[record[l]];
97 goto L3;
98 L20:
99 rec = record[r];
100 crit = ptvois[record[r] + 1] - ptvois[record[r]];
101 record[r] = record[1];
102 --r;
103 if (r == 1) {
104 goto L999;
105 }
106 L3:
107 j = l;
108 L4:
109 i = j;
110 j <<= 1;
111 if ((i__1 = j - r) < 0) {
112 goto L5;
113 } else if (i__1 == 0) {
114 goto L6;
115 } else {
116 goto L8;
117 }
118 L5:
119 if (ptvois[record[j] + 1] - ptvois[record[j]] <
120 ptvois[record[j + 1] + 1] - ptvois[record[j + 1]]) {
121 ++j;
122 }
123 L6:
124 if (crit >= ptvois[record[j] + 1] - ptvois[record[j]]) {
125 goto L8;
126 }
127 record[i] = record[j];
128 goto L4;
129 L8:
130 record[i] = rec;
131 goto L2;
132 L999:
133 record[1] = rec;
134 return 0;
135 } /* gibbs1_ */
136
gibbs2_(integer * n,integer * record,integer * criter)137 /* Subroutine */ int gibbs2_(integer* n, integer* record, integer* criter) {
138 static integer crit, i, j, l, r, rec;
139
140 /* trie record selon les valeurs de criter(record(.)) croissantes */
141
142 /* Parameter adjustments */
143 --criter;
144 --record;
145
146 /* Function Body */
147 if (*n <= 1) {
148 return 0;
149 }
150 l = *n / 2 + 1;
151 r = *n;
152 L2:
153 if (l <= 1) {
154 goto L20;
155 }
156 --l;
157 rec = record[l];
158 crit = criter[rec];
159 goto L3;
160 L20:
161 rec = record[r];
162 crit = criter[rec];
163 record[r] = record[1];
164 --r;
165 if (r == 1) {
166 goto L999;
167 }
168 L3:
169 j = l;
170 L4:
171 i = j;
172 j <<= 1;
173 if (j - r < 0) {
174 goto L5;
175 } else if (j == r) {
176 goto L6;
177 } else {
178 goto L8;
179 }
180 L5:
181 if (criter[record[j]] < criter[record[j + 1]]) {
182 ++j;
183 }
184 L6:
185 if (crit >= criter[record[j]]) {
186 goto L8;
187 }
188 record[i] = record[j];
189 goto L4;
190 L8:
191 record[i] = rec;
192 goto L2;
193 L999:
194 record[1] = rec;
195 return 0;
196 } /* gibbs2_ */
197
198 /* Subroutine */
gibbsa_(integer * n,integer * ptvois,integer * vois,integer * r,integer * m,integer * nv,integer * nx,integer * ny,integer * nn,integer * w1,integer * w2,integer * pfold,integer * pfnew,integer * impre,integer * nfout)199 int gibbsa_(integer* n, integer* ptvois, integer* vois, integer* r, integer* m, integer* nv,
200 integer* nx, integer* ny, integer* nn, integer* w1, integer* w2, integer* pfold,
201 integer* pfnew, integer* impre, integer* nfout) {
202 /* System generated locals */
203 integer i__1, i__2, i__3, i__4;
204
205 /* Builtin functions */
206 /* Subroutine */ int s_stop( );
207
208 /* Local variables */
209 static integer nbcc, degi, bold, bnew, i, j, k, p, degre, x, y, p1, p2;
210 /* extern Subroutine int gibbs1_();*/
211 static integer pf;
212 /* extern Subroutine int gibbsb_(), gibbsd_(), gibbst_();*/
213 static integer nbpass, niveau, pf1, option, old, new_, opt, new1;
214
215 /* -----------------------------------------------------------------------
216 */
217 /* but: calculer une renumerotation des sommets d'un graphe defini par:
218 */
219 /* par la methode de gibbs */
220 /* -----------------------------------------------------------------------
221 */
222 /* entree */
223 /* -------- */
224 /* n = nb de sommet du graphe */
225 /* les voisins d'un sommet i ont pour numero : */
226 /* ( vois(j) , j=ptvois(i),ptvois(i+1)-1 ) */
227
228 /* impre parametre d'impression */
229 /* nfout numero du fichier pour impression */
230
231 /* sortie */
232 /* ------ */
233 /* r(1:n) tableau donnant la nouvelle numerotation: */
234 /* r(i) = nouveau numero du sommet i */
235 /* pfolf = ancien profile */
236 /* pfnew = nouveau profile */
237
238 /* tableau de travail : */
239 /* -------------------- */
240 /* m(n) */
241 /* nv(0:n+n) */
242 /* nx(n) */
243 /* ny(n) */
244 /* nn(0:n) */
245 /* w1(n) */
246 /* w2(n) */
247
248 /* -----------------------------------------------------------------------
249 */
250 /* programmeur f. hecht le 3/02/1987 */
251 /* -----------------------------------------------------------------------
252 */
253
254 /* tri des voisins d'un sommet du graphe par degre croissant */
255 /* --------------------------------------------------------------- */
256 /* Parameter adjustments */
257 --w2;
258 --w1;
259 --ny;
260 --nx;
261 --m;
262 --r;
263 --vois;
264 --ptvois;
265
266 /* Function Body */
267 p2 = ptvois[1] - 1;
268 i__1 = *n;
269 for (i = 1; i <= i__1; ++i) {
270 p1 = p2 + 1;
271 p2 = ptvois[i + 1] - 1;
272 i__2 = p2 - p1 + 1;
273 gibbs1_(&i__2, &vois[p1], &ptvois[1]);
274 /* if(impre.le.-9) then */
275 /* write (nfout,*) 'les voisin de ',i,'sont: ', (vois(j),j=p1,p
276 2) */
277 /* endif */
278 /* L10: */
279 }
280 i__1 = *n;
281 for (i = 1; i <= i__1; ++i) {
282 r[i] = 0;
283 /* L20: */
284 }
285 /* boucle sur les composante connexe du graphe */
286 new_ = 0;
287 nbcc = 0;
288 L30:
289 if (new_ < *n) {
290 ++nbcc;
291 /* recherche d'une racine y (un sommet non numerote) de degree m
292 ini */
293 y = 0;
294 degre = *n + 1;
295 i__1 = *n;
296 for (i = 1; i <= i__1; ++i) {
297 if (r[i] <= 0) {
298 degi = ptvois[i + 1] - ptvois[i];
299 if (degi < degre) {
300 degre = degi;
301 y = i;
302 }
303 }
304 /* L40: */
305 }
306 if (y == 0) {
307 return -3; /* s_stop("fatal erreur gibbs 2 : pb racine", 33L); */
308 }
309 gibbsd_(&y, n, &ptvois[1], &vois[1], nv, &r[1], &niveau);
310 nbpass = 0;
311 L50:
312 ++nbpass;
313 x = y;
314 p = niveau;
315 k = 0;
316 i__1 = nv[p + 1];
317 for (i = nv[p] + 1; i <= i__1; ++i) {
318 ++k;
319 m[k] = nv[i];
320 /* L60: */
321 }
322 gibbs1_(&k, &m[1], &ptvois[1]);
323 i__1 = k;
324 for (i = 1; i <= i__1; ++i) {
325 y = m[i];
326 gibbsd_(&y, n, &ptvois[1], &vois[1], nv, &r[1], &niveau);
327 if (niveau > p) {
328 goto L50;
329 }
330 /* L70: */
331 }
332 y = m[1];
333 /* if(impre.lt.0) then */
334 /* write(nfout,*) */
335 /* + ' nb de pass pour trouver le pseudo diametre',nbpass */
336 /* + ,' x=',x,',y=',y,' de la composante connexe ',nbcc */
337
338 /* write (nfout,*) ('-',i=1,78) */
339 /* endif */
340 /* optimisation de la descendance de la numerotation */
341 /* ------------------------------------------------- */
342 gibbsb_(&x, &y, n, &ptvois[1], &vois[1], &nx[1], &ny[1], nv, nn, &m[1], &w1[1], &w2[1], &r[1],
343 impre, nfout);
344
345 /* renumerotation de cuthill mac kee avec la meilleur des 4 option
346 s */
347 /* --------------------------------------------------------------
348 --- */
349 pf = 1073741824;
350 option = -2;
351 new1 = new_;
352 for (opt = -2; opt <= 2; ++opt) {
353 new_ = new1;
354 if (opt != 0) {
355 gibbst_(n, &p, nv, nn, &ptvois[1], &vois[1], &m[1], &r[1], &new_, &opt, &pf1, impre, nfout);
356 if (pf1 < pf) {
357 pf = pf1;
358 option = opt;
359 }
360 }
361 /* L80: */
362 }
363 /* if(impre.ne.0) write (nfout,*) ' on a choisi l''option ',
364 */
365 /* + option,', new =',new */
366 new_ = new1;
367 gibbst_(n, &p, nv, nn, &ptvois[1], &vois[1], &m[1], &r[1], &new_, &option, &pf1, impre, nfout);
368 goto L30;
369 }
370 /* if(impre.ne.0) write(nfout,*) */
371 /* + ' nb de composante connexe du graphe =',nbcc */
372 /* calcul du profile */
373 *pfold = 0;
374 *pfnew = 0;
375 bnew = 0;
376 bold = 0;
377 i__1 = *n;
378 for (i = 1; i <= i__1; ++i) {
379 old = i;
380 new_ = r[i];
381 i__2 = ptvois[i + 1] - 1;
382 for (j = ptvois[i]; j <= i__2; ++j) {
383 /* Computing MIN */
384 i__3 = old, i__4 = vois[j];
385 old = mmin(i__3, i__4);
386 /* Computing MIN */
387 i__3 = new_, i__4 = r[vois[j]];
388 new_ = mmin(i__3, i__4);
389 /* L100: */
390 }
391 *pfold = *pfold + i - old + 1;
392 /* Computing MAX */
393 i__2 = bold, i__3 = i - old + 1;
394 bold = mmax(i__2, i__3);
395 *pfnew = *pfnew + r[i] - new_ + 1;
396 /* Computing MAX */
397 i__2 = bnew, i__3 = r[i] - new_ + 1;
398 bnew = mmax(i__2, i__3);
399 /* L110: */
400 }
401 /* if(impre.ne.0) then */
402 /* write(nfout,*)'profile old = ',pfold,', profile new = ',pfnew
403 */
404 /* write(nfout,*)'1/2 bande old = ',bold ,', 1/2 band new = ',bnew
405 */
406 /* endif */
407 return 0;
408 } /* gibbsa_ */
409
gibbsb_(integer * x,integer * y,integer * n,integer * ptvois,integer * vois,integer * nx,integer * ny,integer * nv,integer * nn,integer * m,integer * wh,integer * wl,integer * r,integer * impre,integer * nfout)410 /* Subroutine */ int gibbsb_(integer* x, integer* y, integer* n, integer* ptvois, integer* vois,
411 integer* nx, integer* ny, integer* nv, integer* nn, integer* m,
412 integer* wh, integer* wl, integer* r, integer* impre, integer* nfout) {
413 /* System generated locals */
414 integer i__1, i__2;
415
416 /* Local variables */
417 static flag_;
418 static integer i, j, k, p, s, h0, i1, l0, i2;
419 /* extern Subroutine int gibbs1_(); */
420 static integer lg;
421 /* extern Subroutine int gibbsd_(), gibbsc_();*/
422 static integer niveau, mxcanx, mxcany, nbc;
423
424 /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
425 */
426 /* ......................................................................
427 */
428 /* attention on met la descente optimiser dans r <0 ou nulle */
429 /* .......................................................................
430 */
431 /* Parameter adjustments */
432 --r;
433 --m;
434 --ny;
435 --nx;
436 --vois;
437 --ptvois;
438
439 /* Function Body */
440 gibbsd_(y, n, &ptvois[1], &vois[1], nv, &r[1], &niveau);
441 gibbsc_(&ny[1], nv, &niveau, n, &mxcany);
442 gibbsd_(x, n, &ptvois[1], &vois[1], nv, &r[1], &niveau);
443 p = niveau;
444 gibbsc_(&nx[1], nv, &niveau, n, &mxcanx);
445 flag_ = ffalse;
446 i__1 = *n;
447 for (i = 1; i <= i__1; ++i) {
448 if (nx[i] + ny[i] == p) {
449 r[i] = -nx[i];
450 } else if (nx[i] >= 0) {
451 flag_ = ttrue;
452 r[i] = -1073741824;
453 } else {
454 if (r[i] <= 0) {
455 r[i] = -1073741822;
456 }
457 }
458 /* L20: */
459 }
460 if (flag_) {
461 /* calcul des composantes connexe du graphe sans les sommets de
462 nn */
463 /* ------------------------------------------------------------
464 --- */
465 j = *n;
466 k = 0;
467 nbc = 0;
468 nv[nbc] = j;
469 L30:
470 ++k;
471 if (k <= *n) {
472 if (r[k] == -1073741824) {
473 /* recherche de la fermeture transitive partant de k
474 */
475 ++nbc;
476 i = -1;
477 s = k;
478 L40:
479 ++i;
480 wl[i] = ptvois[s];
481 wh[i] = ptvois[s + 1];
482 ++j;
483 nv[j] = s;
484 r[s] = -1073741823;
485 L50:
486 if (i >= 0) {
487 if (wl[i] < wh[i]) {
488 s = vois[wl[i]];
489 ++wl[i];
490 if (r[s] == -1073741824) {
491 goto L40;
492 }
493 goto L50;
494 }
495 --i;
496 goto L50;
497 }
498 nv[nbc] = j;
499 m[nbc] = nbc;
500 }
501 goto L30;
502 }
503 /* if(impre.lt.0) write(nfout,*) */
504 /* + ' nb de composante connexe du graphe reduit =',nbc */
505
506 /* --------------- fin de construction des composantes connexes------
507 --- */
508 /* nv(0)=n */
509 /* if(impre.le.-10) write(nfout,5555)'nv(0:n+n) = ',(nv(i),i=0,
510 n+n) */
511 gibbs1_(&nbc, &m[1], nv);
512 /* if(impre.le.-10)write(nfout,5555)'trie m =',(m(i),i=1,nbc)
513 */
514 i__1 = p;
515 for (i = 0; i <= i__1; ++i) {
516 nn[i] = 0;
517 /* L60: */
518 }
519 i__1 = *n;
520 for (i = 1; i <= i__1; ++i) {
521 j = -r[i];
522 if (j >= 0 && j <= p) {
523 ++nn[j];
524 }
525 /* L70: */
526 }
527
528 /* boucle sur les composante connexes par ordre croissantes */
529 /* -------------------------------------------------------- */
530 for (k = nbc; k >= 1; --k) {
531 i = m[k];
532 i1 = nv[i - 1] + 1;
533 i2 = nv[i];
534 lg = i2 - i1 + 1;
535 /* if(impre.le.-7) */
536 /* + write(nfout,*) k,' composante ',i,',lg=',lg,',i1,i2
537 =',i1,i2 */
538 /* if(impre.le.-8) */
539 /* + write (nfout,5555)' ',(nv(i),i=i1,i2) */
540 h0 = 0;
541 l0 = 0;
542 i__1 = p;
543 for (j = 0; j <= i__1; ++j) {
544 wh[j] = nn[j];
545 wl[j] = nn[j];
546 /* L90: */
547 }
548 i__1 = i2;
549 for (i = i1; i <= i__1; ++i) {
550 s = nv[i];
551 ++wh[nx[s]];
552 ++wl[p - ny[s]];
553 /* L100: */
554 }
555 i__1 = p;
556 for (j = 0; j <= i__1; ++j) {
557 if (wh[j] != nn[j]) {
558 /* Computing MAX */
559 i__2 = wh[j];
560 h0 = mmax(i__2, h0);
561 }
562 if (wl[j] != nn[j]) {
563 /* Computing MAX */
564 i__2 = wl[j];
565 l0 = mmax(i__2, l0);
566 }
567 /* L110: */
568 }
569 if (h0 < l0 || h0 == l0 && mxcanx <= mxcany) {
570 /* if(impre.le.-2) write(nfout,*) */
571 /* + ' h0 = ',h0,',l0 = ',l0,' ------- XXXX
572 --------' */
573 i__1 = i2;
574 for (i = i1; i <= i__1; ++i) {
575 s = nv[i];
576 r[s] = -nx[s];
577 ++nn[-r[s]];
578 /* L120: */
579 }
580 } else {
581 /* if (impre.le.-2) write(nfout,*) */
582 /* + ' h0 = ',h0,',l0 = ',l0,' ------- YYYY
583 --------' */
584 i__1 = i2;
585 for (i = i1; i <= i__1; ++i) {
586 s = nv[i];
587 r[s] = -p + ny[s];
588 ++nn[-r[s]];
589 /* L130: */
590 }
591 }
592 /* L140: */
593 }
594 }
595 /* on met les nouveaux niveaux de la descendance optimiser dans nn */
596 /* -----------------------------------------------------------------
597 */
598 i__1 = *n;
599 for (i = 1; i <= i__1; ++i) {
600 if (r[i] > 0) {
601 nn[i] = -1;
602 } else if (r[i] == -1073741822) {
603 nn[i] = -2;
604 } else {
605 nn[i] = -r[i];
606 }
607 /* L150: */
608 }
609 /* if(impre.le.-10)write (nfout,5555)' nn(i)=',(nn(i),i=1,n) */
610 /* 5555 format(' -------- ',a,/,5(15x,10(i5)/)) */
611 return 0;
612 } /* gibbsb_ */
613
gibbsc_(integer * nz,integer * nv,integer * niveau,integer * n,integer * mxz)614 /* Subroutine */ int gibbsc_(integer* nz, integer* nv, integer* niveau, integer* n, integer* mxz) {
615 /* System generated locals */
616 integer i__1, i__2, i__3;
617
618 /* Local variables */
619 static integer i, j;
620
621 /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
622 */
623 /* Parameter adjustments */
624 --nz;
625
626 /* Function Body */
627 i__1 = *n;
628 for (i = 1; i <= i__1; ++i) {
629 nz[i] = -1;
630 /* L10: */
631 }
632 *mxz = 0;
633 i__1 = *niveau;
634 for (i = 0; i <= i__1; ++i) {
635 /* Computing MAX */
636 i__2 = *mxz, i__3 = nv[i + 1] - nv[i];
637 *mxz = mmax(i__2, i__3);
638 i__2 = nv[i + 1];
639 for (j = nv[i] + 1; j <= i__2; ++j) {
640 nz[nv[j]] = i;
641 /* L20: */
642 }
643 }
644 return 0;
645 } /* gibbsc_ */
646
gibbsd_(integer * racine,integer * n,integer * ptvois,integer * vois,integer * nv,integer * r,integer * niveau)647 /* Subroutine */ int gibbsd_(integer* racine, integer* n, integer* ptvois, integer* vois,
648 integer* nv, integer* r, integer* niveau) {
649 /* System generated locals */
650 integer i__1, i__2;
651
652 /* Local variables */
653 static integer i, k, s, sv, stk, stk1, stk2;
654
655 /* -----------------------------------------------------------------------
656 */
657 /* but construire la structure des descendant de racine du graphe */
658 /* -----------------------------------------------------------------------
659 */
660 /* sortie : */
661 /* -------- */
662 /* nv est la structure des niveaux */
663 /* les sommets du niveau (i =0,niveau_ sont defini par : */
664 /* (nv(j),j=nv(i),nv(i+1)-1) */
665
666 /* le tableau r(i) n'est modifier que sur les sommets */
667 /* de la composante connexe du graphe contenant la racine */
668
669 /* -----------------------------------------------------------------------
670 */
671
672 /* on demark tout les sommets non remuneroter */
673 /* -------------------------------------------------- */
674 /* Parameter adjustments */
675 --r;
676 --vois;
677 --ptvois;
678
679 /* Function Body */
680 i__1 = *n;
681 for (i = 1; i <= i__1; ++i) {
682 if (r[i] < 0) {
683 r[i] = 0;
684 }
685 /* L10: */
686 }
687
688 /* initialisation */
689
690 stk = *n - 1;
691 nv[0] = stk;
692 stk2 = stk;
693 *niveau = 0;
694 ++stk;
695 nv[stk] = *racine;
696 r[*racine] = -1;
697 L20:
698 if (stk2 < stk) {
699 ++(*niveau);
700 stk1 = stk2 + 1;
701 nv[*niveau] = stk;
702 stk2 = stk;
703 /* print *,' ------- niveau =',niveau,' stk=',stk1,stk2 */
704 i__1 = stk2;
705 for (k = stk1; k <= i__1; ++k) {
706 s = nv[k];
707 /* print *,'----------------- s=',s */
708 i__2 = ptvois[s + 1] - 1;
709 for (i = ptvois[s]; i <= i__2; ++i) {
710 /* pour tout les sommets (sv) voisin */
711 /* d'un sommet (s) du niveau precedent */
712 sv = vois[i];
713 /* print *,' voisin =',sv */
714 /* si le sommet n'est pas marque on le marque et
715 on l'ajout */
716 if (r[sv] == 0) {
717 ++stk;
718 nv[stk] = sv;
719 r[sv] = -1;
720 }
721 /* L30: */
722 }
723 /* L40: */
724 }
725 goto L20;
726 }
727 --(*niveau);
728 /* call pnv(' gibbsd ',n,nv,niveau) */
729 return 0;
730 } /* gibbsd_ */
731
gibbst_(integer * n,integer * p,integer * nv,integer * nn,integer * ptvois,integer * vois,integer * m,integer * r,integer * new_,integer * option,integer * pfnew,integer * impre,integer * nfout)732 /* Subroutine */ int gibbst_(integer* n, integer* p, integer* nv, integer* nn, integer* ptvois,
733 integer* vois, integer* m, integer* r, integer* new_, integer* option,
734 integer* pfnew, integer* impre, integer* nfout) {
735 /* System generated locals */
736 integer i__1, i__2, i__3, i__4, i__5;
737
738 /* Local variables */
739 static integer nbsc, bnew, knew, step, plus, i, j, k, s, debut, i1, i2;
740 /* extern Subroutine int gibbs2_();*/
741 static integer fin;
742
743 /* construction de la stucture de niveau dans nv a partir de nn */
744 /* ------------------------------------------------------------ */
745 /* Parameter adjustments */
746 --r;
747 --m;
748 --vois;
749 --ptvois;
750
751 /* Function Body */
752 nv[0] = *n;
753 i__1 = *p + 1;
754 for (i = 1; i <= i__1; ++i) {
755 nv[i] = 0;
756 /* L150: */
757 }
758 i__1 = *n;
759 for (i = 1; i <= i__1; ++i) {
760 if (nn[i] >= 0) {
761 ++nv[nn[i] + 1];
762 }
763 /* L160: */
764 }
765 i__1 = *p;
766 for (i = 0; i <= i__1; ++i) {
767 nv[i + 1] += nv[i];
768 /* L170: */
769 }
770 i__1 = *n;
771 for (i = 1; i <= i__1; ++i) {
772 if (nn[i] >= 0) {
773 j = nn[i];
774 ++nv[j];
775 nv[nv[j]] = i;
776 }
777 /* L180: */
778 }
779 for (i = *p; i >= 0; --i) {
780 nv[i + 1] = nv[i];
781 /* L190: */
782 }
783 nv[0] = *n;
784 nbsc = nv[*p + 1] - nv[0];
785 /* --- fin de la construction ------------------------------------ */
786 if (*option == -2) {
787 i__1 = *impre - 1;
788 }
789 i__1 = *n;
790 for (i = 1; i <= i__1; ++i) {
791 m[i] = *n * 3 + ptvois[i + 1] - ptvois[i];
792 /* L10: */
793 }
794 if ((((int)*option) == 1) || (((int)*option) == -1)) {
795 debut = 0;
796 fin = *p;
797 step = 1;
798 } else {
799 debut = *p;
800 fin = 0;
801 step = -1;
802 }
803 i__1 = fin;
804 i__2 = step;
805 for (i = debut; i__2 < 0 ? i >= i__1 : i <= i__1; i += i__2) {
806 i1 = nv[i] + 1;
807 i2 = nv[i + 1];
808 i__3 = i2 - i1 + 1;
809 gibbs2_(&i__3, &nv[i1], &m[1]);
810 i__3 = i2;
811 for (j = i1; j <= i__3; ++j) {
812 s = nv[j];
813 i__4 = ptvois[s + 1] - 1;
814 for (k = ptvois[s]; k <= i__4; ++k) {
815 /* Computing MIN */
816 i__5 = m[vois[k]];
817 m[vois[k]] = mmin(i__5, j);
818 /* L20: */
819 }
820 /* L30: */
821 }
822 /* L40: */
823 }
824 if (*option > 0) {
825 knew = *new_;
826 plus = 1;
827 } else {
828 knew = *new_ + nbsc + 1;
829 plus = -1;
830 }
831 *new_ += nbsc;
832 /* if(option.gt.0) then */
833 /* do 60 k = debut , fin , step */
834 /* do 60 j = nv(k+1),nv(k)+1,-1 */
835 /* knew = knew + plus */
836 /* r(nv(j)) = knew */
837 /* 60 continue */
838 /* else */
839 i__2 = fin;
840 i__1 = step;
841 for (k = debut; i__1 < 0 ? k >= i__2 : k <= i__2; k += i__1) {
842 i__3 = nv[k + 1];
843 for (j = nv[k] + 1; j <= i__3; ++j) {
844 knew += plus;
845 r[nv[j]] = knew;
846 /* L70: */
847 }
848 }
849 /* endif */
850 *pfnew = 0;
851 bnew = 0;
852 i__3 = *n;
853 for (i = 1; i <= i__3; ++i) {
854 k = r[i];
855 if (k > 0) {
856 i__1 = ptvois[i + 1] - 1;
857 for (j = ptvois[i]; j <= i__1; ++j) {
858 if (r[vois[j]] > 0) {
859 /* Computing MIN */
860 i__2 = k, i__4 = r[vois[j]];
861 k = mmin(i__2, i__4);
862 }
863 /* L100: */
864 }
865 *pfnew = *pfnew + r[i] - k + 1;
866 /* Computing MAX */
867 i__1 = bnew, i__2 = r[i] - k + 1;
868 bnew = mmax(i__1, i__2);
869 }
870 /* L110: */
871 }
872 /* if(impre.lt.0.or.impre.gt.2) then */
873 /* write(nfout,*) ' option =',option,', profile =',pfnew */
874 /* + ,', 1/2 bande =',bnew,', new=',new,', nbss composante=',nbsc
875 */
876 /* endif */
877 return 0;
878 } /* gibbst_ */
879
880 /* function */
gibbsv(integer * ptvoi,integer * vois,integer * lvois,integer * w,integer * v)881 int Triangles::gibbsv(integer* ptvoi, integer* vois, integer* lvois, integer* w, integer* v) {
882 /* System generated locals */
883 integer i__2;
884
885 /* Local variables */
886 integer i, j, k, T, ss, iii, ptv, ptv1;
887 integer nbss = nbv;
888 /*--- Prepare les donees pour gibbsa en construisant ptvoi, vois, lvois -
889 ------------*/
890 /* in */
891 /* --- nbnt =3 pour des triangles 2D, */
892 /* nbt = nb de triangle */
893 /* nbss = nb de sommets */
894 /* nsea = numeros de 3 sommets de chaque triangle (me) */
895 /* out */
896 /* --- ptvoi, vois, lvois, err */
897 /* tableaux de travail w, v */
898 /*-----------------------------------------------------------------------
899 ----------*/
900 /* Parameter adjustments */
901 --v;
902 --w;
903 --vois;
904 --ptvoi;
905 long nt = nbt - NbOutT;
906 /* Function Body */
907 for (i = 1; i <= nbss; ++i) {
908 w[i] = -1;
909 ptvoi[i] = 0;
910 }
911 ptvoi[nbss + 1] = 0;
912 for (i = 0; i < nt; ++i) {
913 assert(triangles[i].link);
914 for (j = 0; j < 3; ++j) {
915 ss = Number(triangles[i][j]) + 1;
916 ++ptvoi[ss + 1];
917 w[ss] = 0;
918 }
919 }
920
921 for (i = 1; i <= nbss; ++i) ptvoi[i + 1] += ptvoi[i];
922
923 for (i = 0; i < nt; ++i)
924 if (triangles[i].link)
925 for (j = 0; j < 3; ++j) {
926 ss = Number(triangles[i][j]) + 1;
927 ++ptvoi[ss];
928 v[ptvoi[ss]] = i;
929 }
930
931 ptv1 = 0;
932 iii = 1;
933 for (i = 1; i <= nbss; ++i) {
934 ptv = ptv1 + 1;
935 ptv1 = ptvoi[i];
936 ptvoi[i] = iii;
937 i__2 = ptv1;
938 for (j = ptv; j <= i__2; ++j) {
939 T = v[j];
940 for (k = 0; k < 3; ++k) {
941 ss = Number(triangles[T][k]) + 1; /* nsea[k + T * nsea_dim1]; */
942 if (w[ss] != i) {
943 w[ss] = i;
944 if (iii > *lvois) return 2;
945 /* print*,'pas assez de place memoire' */
946
947 vois[iii] = ss;
948 ++iii;
949 }
950 }
951 }
952 }
953 ptvoi[nbss + 1] = iii;
954 *lvois = iii - 1;
955 return 0; /* OK */
956 return 0;
957 } /* gibbsv_ */
958
gibbs()959 int Triangles::gibbs( )
960 /* --------
961 renumber vertices by gibbs method; updates triangle and edge array
962 in: mesh
963 out: mesh
964 auxiliary arrays: ptvois,vois,r,m,nv,nx,ny,nn,w1,w2,f
965 all of size nv+1 except vois (10(nv+1)) and nv (2(nv+1))
966 err = -1 : memory alloc pb; err = -3: fatal erreur gibbs 2 : pb racine
967 */
968 {
969 long nv = nbv;
970 long nt = nbt - NbOutT;
971 long i, j, pfold, pfnew;
972 long* ptvois = NULL;
973 long* vois = NULL;
974 long* nn = NULL;
975 long* r = NULL;
976 long* m = NULL;
977 long* nnv = NULL;
978 long* nx = NULL;
979 long* ny = NULL;
980 long* w1 = NULL;
981 long* w2 = NULL;
982 long nbvoisin = 10 * nv;
983 long printint = 0, iodev = 6;
984 int err = 0;
985 ptvois = new long[nv + 1]; //(long*)calloc((long)(nv + 1) , sizeof(long));
986 nn = new long[3 * nt]; //(long*)calloc(3 * nt ,sizeof(long));
987 vois = new long[nbvoisin + 10]; //(long*)calloc((long)(nbvoisin + 10) , sizeof(long));
988 r = new long[nv + 1]; //(long*)calloc((long)(nv + 1) , sizeof(long));
989 if ((!ptvois) || (!nn) || (!vois) || (!r)) return -1;
990 err = gibbsv(ptvois, vois, &nbvoisin, r, nn);
991 delete[] nn; // free(nn);
992 if (err == 0) {
993 m = new long[nv + 1];
994 nn = new long[nv + 1];
995 nnv = new long[(nv + 1) << 1];
996 nx = new long[nv + 1];
997 ny = new long[nv + 1];
998 w1 = new long[nv + 1];
999 w2 = new long[nv + 1];
1000 long lnv = nv;
1001 err =
1002 gibbsa_(&lnv, ptvois, vois, r, m, nnv, nx, ny, nn, w1, w2, &pfold, &pfnew, &printint, &iodev);
1003 delete[] m;
1004 delete[] nnv;
1005 delete[] nn;
1006 delete[] nx;
1007 delete[] ny;
1008 delete[] w1;
1009 delete[] w2;
1010 }
1011
1012 delete[] vois;
1013 delete[] ptvois;
1014 /*
1015 if (err == 0 && (pfnew <= pfold))
1016 {
1017 A<bVertex> f(nv);
1018 for (i = 0; i < nv; ++i)
1019 { f[i].x = v[i].x;
1020 f[i].y = v[i].y;
1021 f[i].where = v[i].where;
1022 }
1023 for (i = 0; i < nv; ++i)
1024 { v[r[i] - 1].x = f[i].x;
1025 v[r[i] - 1].y = f[i].y;
1026 v[r[i] - 1].where = f[i].where;
1027 }
1028
1029 for (j = 0; j < nt; ++j) // updates triangle array
1030 for (i = 0; i < 3; i++)
1031 t[j].v[i] = &v[r[no(t[j].v[i])] - 1];
1032
1033 for (j = 0; j < ne; ++j) // updates edge array
1034 {
1035 e[j].in = &v[r[no(e[j].in)] - 1];
1036 e[j].out = &v[r[no(e[j].out)] - 1];
1037 }
1038 f.destroy();
1039 if (!NumThinGrid)
1040 { NumThinGrid= new int [nv];
1041 for (i=0;i<nv;i++) NumThinGrid[i]=i;// Same numbering
1042 }
1043 for (i=0;i<nv;i++) NumThinGrid[i]=r[NumThinGrid[i]]-1;
1044
1045 }
1046 */
1047 delete[] r;
1048 return err;
1049 }
1050
1051 /* message d'erreur: *err = 2; print*,'pas assez de place memoire' */
1052