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