C     *****************************************************************
C     Delos  est  un  mailleur  automatique "surfacique" qui genere une
C     triangulation  pour  la  simulation    et/ou   la  visualisation.
C
C     Licence et conditions d'utilisation de Delos.
C
C     Copyright (C) 1994-2005 ARMINES/Ecole des Mines de Paris
C
C     Ce programme est un logiciel libre ; vous pouvez  le redistribuer 
C     et/ou le modifier  conformement  aux  dispositions de la  Licence 
C     Publique Generale GNU, telle  que  publiee par  la  Free Software
C     Fondation ; version 2  de  la licence, ou  encore (a votre choix)
C     toute version ulterieure.
C
C     Ce  programme  est distribue dans l'esport qu'il sera utile, mais
C     SANS  AUCUNE  GARANTIE  ; sans  meme  la  garantie  implicite  de 
C     COMMERCIALISATION  ou  D'ADAPTATION  A UN OBJET PARTICULIER. Pour
C     plus  de  detail, voir  la  Licence  Publique  Generale  GNU
C
C     Vous  devez  avoir recu  un exemplaire  de  la  Licence  Publique 
C     Generale en meme temps que ce programme ; si ce n'est pas le cas,
C     ecrivez a la Free Software Fondation Inc.,675 Mass Ave,Cambridge, 
C     MA 02139, Etats-Unis.
C
C     Ce logiciel est telechargeable a l'adresse :
C
C                 http://www.ensmp.fr/~stab/delos
C
C     vous trouverez egalement, sur ce site, un mode d'emploi complet et
C     des informations supplementaires.
C
C     *****************************************************************
C     ***************************************************************
C     MODULE  : CG (CALCUL GEOMETRIQUE) 
C     FICHIER : CG_DISTANCE.F
C     OBJET   : CALCULS ELEMENTAIRES DE DISTANCES
C               A UN POINT, UN AXE. PROJECTIONS.
C     FONCT.  :
C
C        DIPOOB: DISTANCE D'UN POINT A UN OBJET
C        DIMONO: VERIFIE QUE LA DISTANCE A L'OBJET 
C                EST UNE FONCTION MONOTONE SUR L'OBJET.
C
C     FONCT. LOCALES  :
C        DISPAX : DISTANCE D'UN POINT A UN AXE
C        DISPP  : DISTANCE ENTRE 2 POINTS
C        DISPPL : DISTANCE ENTRE UN POINT ET UN PLAN
C        PRPOAX : PROJECTION D'UN POINT SUR UN AXE (LOCAL)
C        PRPOPN : PROJECTION D'UN POINT SUR UN PLAN (LOCAL)
C        PRJSEG : Abscisse du (projete) point XS sur le segment X1,X2 (LOCAL)
C        PRPOOB : PROJECTION D'UN POINT A UN OBJET (LOCAL)
C        DIMOSG : interface entre DIMONO et  DIMOSG2 (LOCAL)
C        DIMOSG2 : points sur la droite XP1,XP2 ou la distance au seg S1,S2 "change" (LOCAL)
C
C     AUTEUR   : O. STAB
C     DATE     : 03.95 / 06.95
C     TESTS    : 07.95
C     MODIFICATIONS :
C      AUTEUR, DATE, OBJET : O.STAB, 27.10.97 BUG_40 DANS DISPSG !
C      AUTEUR, DATE, OBJET : O.STAB, 19.04.01 BUG    DANS DISPAX !
C      AUTEUR, DATE, OBJET : O.STAB, 31.01.05 ajout DIMOSG, DIMOSG2 
C                            (concentration sur un segment)
C      AUTEUR, DATE, OBJET : O.STAB, 13.09.06 BUG dans DIMOSG2 
C      AUTEUR, DATE, OBJET : O.STAB  28.06.2010 : reprise sur ERREUR dans DIMOSG2 
C     ***************************************************************
C
C
      FUNCTION DISPP(IDIMC,XP1,XP2)
C     ***************************************************************
C     OBJET  DISPP : DISTANCE D'UN POINT A UN POINT (LOCAL)
C     ***************************************************************
      REAL DISPP
      INTEGER IDIMC
      REAL    XP1(*),XP2(*)
C
      REAL V12(3)
      COMMON /CGEPSI/ XYZHUG,XYZMIN,XYZEPS
      REAL  XYZHUG,XYZMIN,XYZEPS
C
      EXTERNAL SCALVE
      REAL     SCALVE
C
      CALL DIFFVE(XP2,XP1,IDIMC,V12)
      DISPP = SCALVE(V12,V12,IDIMC)
      DISPP = SQRT(DISPP)
      IF((DISPP.LT.XYZEPS).AND.(DISPP.GT.-XYZEPS))DISPP = 0.0
      END
C
C
      FUNCTION DISPAX(IDIMC,XP1,XPA,VAX)
C     ***************************************************************
C     OBJET  DISPAX : DISTANCE D'UN POINT A UN AXE (LOCAL)
C     XPA : UN POINT DE L'AXE
C     VAX : LE VECTEUR DIRECTEUR DE L'AXE (NORME)
C     ***************************************************************
      REAL DISPAX
      INTEGER IDIMC
      REAL    XP1(*),XPA(*),VAX(*)
C
      REAL V12(3),VPRV(3)
      COMMON /CGEPSI/ XYZHUG,XYZMIN,XYZEPS
      REAL  XYZHUG,XYZMIN,XYZEPS
C
      EXTERNAL SCALVE
      REAL     SCALVE
C
      CALL DIFFVE(XPA,XP1,IDIMC,V12)
      CALL VECTVE(V12,VAX,IDIMC,VPRV)
      DISPAX = ABS(VPRV(1))
C     --- modif 19.04.2001 : BUG, on prenait la racine meme en 2D
      IF( IDIMC .EQ. 3 )THEN
        DISPAX = SCALVE(VPRV,VPRV,IDIMC)
        DISPAX = SQRT(DISPAX)
      ENDIF
      IF((DISPAX.LT.XYZEPS).AND.(DISPAX.GT.-XYZEPS))DISPAX = 0.0
      END
C
C
      FUNCTION DISPSG(IDIMC,XP1,XPO,XPE)
C     ***************************************************************
C     OBJET DISPSG DISTANCE D'UN POINT A UN SEGMENT DE DROITE
C     XPO : LE POINT ORIGINE DU SEGMENT
C     XPE : LE POINT EXTREMITE DU SEGMENT
C     ***************************************************************
      REAL DISPSG
      INTEGER IDIMC
      REAL    XP1(*),XPO(*),XPE(*)
C
      REAL VO1(3),VOE(3),VPRJ(3),DO1,DOE
      COMMON /CGEPSI/ XYZHUG,XYZMIN,XYZEPS
      REAL  XYZHUG,XYZMIN,XYZEPS
C
      EXTERNAL SCALVE
      REAL     SCALVE
C
      CALL DIFFVE( XP1,XPO,IDIMC,VO1)
      CALL DIFFVE( XPE,XPO,IDIMC,VOE)
      DO1 = SCALVE(VO1,VOE,IDIMC)
      DOE = SCALVE(VOE,VOE,IDIMC)
      IF(DO1.LE.(XYZEPS*DOE))THEN
C     --- LE POINT LE PLUS PROCHE EST XPO ---
        DISPSG = SCALVE(VO1,VO1,IDIMC)
      ELSE
      IF(DO1.GE.((1.-XYZEPS)*DOE))THEN
C     --- LE POINT LE PLUS PROCHE EST XPE ---
        CALL DIFFVE( XPE,XP1,IDIMC,VO1)
        DISPSG = SCALVE(VO1,VO1,IDIMC)
        ELSE
C       --- LE PROJETE EST SUR LE SEGMENT --- 
          CALL VECTVE(VO1,VOE,IDIMC,VPRJ)
C     ---- BUG_33.B : O.STAB, 17.10.97 : ERREUR SUR HP AVEC OPTION (+T) ----
          IF(IDIMC.EQ.2)THEN
C            DISPSG = SQRT( VPRJ(1)*VPRJ(1) ) BUG_40, 27.10.97 O.STAB
            DISPSG = VPRJ(1)*VPRJ(1) 
          ELSE
            DISPSG = SCALVE(VPRJ,VPRJ,IDIMC)
          ENDIF
          DISPSG = DISPSG / DOE                
        ENDIF
      ENDIF
C
      IF( DISPSG. LT. (XYZEPS**2) )THEN
          DISPSG = 0.0
      ELSE
          DISPSG = SQRT(DISPSG)
      ENDIF
  999 END
C
C
      FUNCTION DISPPL(IDIMC,XP1,XPP,VNP)
C     ***************************************************************
C     OBJET DISPPL : DISTANCE D'UN POINT A UN PLAN (LOCAL)
C     XPP : UN POINT DU PLAN
C     VNP : LE VECTEUR NORMAL AU PLAN (NORME)
C     ***************************************************************
      REAL DISPPL
      INTEGER IDIMC
      REAL    XP1(*),XPP(*),VNP(*)
C
      REAL V12(3)
      COMMON /CGEPSI/ XYZHUG,XYZMIN,XYZEPS
      REAL  XYZHUG,XYZMIN,XYZEPS
C
      EXTERNAL SCALVE
      REAL    SCALVE
C
      CALL DIFFVE( XPP,XP1,IDIMC,V12)
      DISPPL = SCALVE(V12,VNP,IDIMC)
      IF((DISPPL.LT.XYZEPS**2))THEN
        DISPPL = 0.0
      ELSE
        DISPPL = SQRT(DISPPL)
      ENDIF
      END
C
      SUBROUTINE DIPOOB(IDIMC,XP,ITYPE,ROBJET,D,IERR)
C     ***************************************************************
C     OBJET DIPOOB :   DISTANCE D'UN POINT A UN OBJET
C     EN ENTREE :
C         IDIMC: DIMENSION DE L'ESPACE
C         XP   : COORDONNEES DU POINT DONT ON CHERCHE LA DISTANCE
C         ITYPE: TYPE DE L'OBJET (1 = POINT, 2 = AXE, 3 = SEGMENT)
C         ROBJET : DEFINITION DE LA GEOMETRIE DE L'OBJET
C     EN SORTIE :
C         D    : LA DISTANCE A L'OBJET
C     ***************************************************************
      INTEGER IDIMC,ITYPE,IERR
      REAL    XP(*),ROBJET(*),D
C
      EXTERNAL DISPP,DISPAX,DISPPL,XNORVE,DIFFVE,MUSCVE,
     >         DISPSG
      REAL    DISPP,DISPAX,DISPPL,XNORVE,DISPSG
      REAL    VAX(3), XNORM
      COMMON /CGEPSI/ XYZHUG,XYZMIN,XYZEPS
      REAL  XYZHUG,XYZMIN,XYZEPS
C
      IERR = -1
      GOTO (10,20,30,40) ITYPE
       GO TO 888
C        --- POINT ------------
   10    IF( IDIMC .LT. 1 )GOTO 888
         D = DISPP(IDIMC,XP,ROBJET)
         IERR = 0
         GO TO 999
C        --- AXE -----------
   20    IF( IDIMC .LT. 2 )GOTO 888
         CALL DIFFVE(ROBJET(IDIMC+1),ROBJET,IDIMC,VAX)
         XNORM = XNORVE(VAX,IDIMC)
         IF( XNORM .LE. XYZMIN )GOTO 888
         XNORM = 1.0 / XNORM
         CALL MUSCVE(VAX,XNORM,IDIMC,VAX)
         D = DISPAX(IDIMC,XP,ROBJET,VAX)
         IERR = 0
         GO TO 999
C        --- SEGMENT DE DROITE -------------
   30    IF( IDIMC .LT. 2 )GOTO 888
C         PRINT *,'EN TEST'
         D = DISPSG(IDIMC,XP,ROBJET,ROBJET(IDIMC+1))
         IERR = 0
         GO TO 999
C        --- PLAN -------------
   40    IF( IDIMC .LT. 3 )GOTO 888
C         PRINT *,'A FAIRE'
         IERR = -3
C         D = DISPPL(IDIMC,XP,ROBJET,VAX)
C         IERR = 0
         GO TO 999
  888 IF( IERR .NE. 0 )CALL DSERRE(1,IERR,'CG','DANS DIPOOB')
  999 END
C
C
      SUBROUTINE PRPOAX(IDIMC,XP1,XPA,VAX,XPRJ)
C     ***************************************************************
C     OBJET PRPOAX : PROJECTION D'UN POINT SUR UN AXE (LOCAL)
C     XPA : UN POINT DE L'AXE
C     VAX : LE VECTEUR DIRECTEUR DE L'AXE (NORME)
C     ***************************************************************
      INTEGER IDIMC
      REAL     XP1(*),XPA(*),VAX(*),XPRJ(*)
C
      REAL    V12(3),VPRJ(3),XDPA
      COMMON /CGEPSI/ XYZHUG,XYZMIN,XYZEPS
      REAL  XYZHUG,XYZMIN,XYZEPS
C
      EXTERNAL SCALVE
      REAL    SCALVE
C
      CALL DIFFVE( XPA,XP1,IDIMC,V12)
      XDPA = SCALVE(V12,VAX,IDIMC)
      IF((XDPA.LT.XYZEPS).AND.(XDPA.GT.-XYZEPS))XDPA = 0.0
      CALL MUSCVE( VAX, XDPA, IDIMC, VPRJ )
      CALL DIFFVE( VPRJ, XPA, IDIMC, XPRJ )
      END
C
C
      SUBROUTINE PRPOPN(IDIMC,XP1,XPP,VNP,XPRJ)
C     ***************************************************************
C     OBJET PRPOPN : PROJECTION D'UN POINT SUR UN PLAN (LOCAL)
C     XPP : UN POINT DU PLAN
C     VNP : LE VECTEUR NORMAL AU PLAN (NORME)
C     ***************************************************************
      INTEGER IDIMC
      REAL    XP1(*),XPP(*),VNP(*),XPRJ(*)
C
      REAL V12(3),VPN12(3),VPRJ(3)
C
      EXTERNAL NULLVE
      INTEGER  NULLVE
C
      IF( IDIMC .LT. 3 )THEN
        CALL COPIVE(XP1,IDIMC,XPRJ)
        GO TO 999
      ENDIF
C     --- PROJECTION SUR LE PLAN ---
      CALL DIFFVE(XP1,XPP,IDIMC,V12)
      CALL VECTVE(V12,VNP,IDIMC,VPN12)
      IF(NULLVE(VPN12,IDIMC).NE.1)THEN
        CALL VECTVE(VNP,VPN12,IDIMC,VPRJ)
        CALL SOMMVE(XPP,VPRJ,IDIMC,XPRJ)
      ELSE
        CALL COPIVE(XPP,IDIMC,XPRJ)
      ENDIF
C
  999 END
C
C
      SUBROUTINE PRJSEG(XS,X1,X2,IDIMC,XSA)
C     *****************************************************
C     OBJET PRJSEG : Abscisse du (projete) point XS sur le segment X1,X2 (LOCAL)
C	  XSA : abscisse du point XS sur le segment X1,X2 
C     *****************************************************
      REAL    XS(*),X1(*),X2(*)
      INTEGER IDIMC
      REAL    XSA
C	
      EXTERNAL SCALVE
      REAL X12(3),XSC(3),SCALVE,X12N
C
      CALL DIFFVE(XS,X1,IDIMC,XSC)
      CALL DIFFVE(X2,X1,IDIMC,X12)
      XSA   = SCALVE(X12,XSC,IDIMC)
      X12N  = SCALVE(X12,X12,IDIMC)
      XSA  = XSA / X12N
 9999 END
C
C
      SUBROUTINE PRPOOB(IDIMC,XP,ITYPE,ROBJET,XPRJ,IERR)
C     ***************************************************************
C     OBJET  PRPOOB :  PROJECTION D'UN POINT A UN OBJET (LOCAL)
C     EN ENTREE :
C         IDIMC: DIMENSION DE L'ESPACE
C         XP   : COORDONNEES DU POINT DONT ON CHERCHE LA DISTANCE
C         ITYPE: TYPE DE L'OBJET (1 = POINT, 2 = AXE, 3 = PLAN)
C         ROBJET : DEFINITION DE LA GEOMETRIE DE L'OBJET
C     EN SORTIE :
C         D    : LA DISTANCE A L'OBJET
C     ***************************************************************
      INTEGER IDIMC,ITYPE,IERR
      REAL    XP(*),ROBJET(*),XPRJ(*)
C
      IERR = -1
      GOTO (10,20,30) ITYPE
        GO TO 999
C       --- POINT ------------
   10   IF( IDIMC .LT. 1 )GOTO 999
        CALL COPIVE(XP,IDIMC,XPRJ)
        IERR = 0
        GO TO 999
C       --- AXE -----------
   20   IF( IDIMC .LT. 2 )GOTO 999
        CALL PRPOAX(IDIMC,XP,ROBJET,ROBJET(IDIMC),XPRJ)
        IERR = 0
        GO TO 999
C       --- PLAN -------------
   30   IF( IDIMC .LT. 3 )GOTO 999
        CALL PRPOPN(IDIMC,XP,ROBJET,ROBJET(IDIMC),XPRJ)
        IERR = 0
        GO TO 999
  999 END
C
C
      SUBROUTINE DIMONO(XP1,XP2,IDIMC,ITYPO,ROBJET,
     >                       XPNUL,MONO,IERR)
C     ****************************************************************
C     OBJET DIMONO :  DISTANCE A L'OBJET MOMOTONE SUR LE SEGMENT ?
C     EN ENTREE :
C         XP1,XP2 : EXTREMITES DU SEGMENT
C         IDIMC   : DIMENSION DE L'ESPACE
C         ---------------------
C         ITYPO   : TYPE DE L'OBJET (de concentration)
C         ROBJET  : LA DEFINITION GEOMETRIQUE DE L'OBJET
C     EN SORTIE :
C         MONO    : 0 SI MONOTONE 
C                   > 0 nombre de points dans XPNUL
C         XPNUL   : COORDONNEES des POINTS sur XP1,XP2
C     anciennement : modif O.Stab 19.01.2005
C         MONO    : 1 SI MONOTONE 0 SINON
C         XPNUL   : COORDONNEES DU POINT OU LA DERIVEE S'ANNULE
C     ****************************************************************
      REAL     XP1(*),XP2(*)
      INTEGER  IDIMC,ITYPO
      REAL     ROBJET(*),XPNUL(*)
      INTEGER  MONO,IERR
C
      COMMON /CGEPSI/ XYZHUG,XYZMIN,XYZEPS
      REAL  XYZHUG,XYZMIN,XYZEPS
      REAL     PO(3),OE(3),XL,DROITE(3)
      EXTERNAL DIFFVE,SOMMVE,MUSCVE
      INTEGER  INTER, INDRSE
      EXTERNAL INDRSE
C
      IERR = 0
      MONO = 0
      GOTO( 10,60,120,180 ) ITYPO
        IERR = -1
        GOTO 888
C          ======================
C       --- L'OBJET EST UN POINT --- ITYPO=1
C          ======================
   10   CALL DIFFVE(XP1,ROBJET,IDIMC,PO)
        CALL DIFFVE(XP2,XP1,IDIMC,OE)
C       --- CAS 1D, 2D, 3D ---
        GOTO (20,30,40) IDIMC
          IERR = -1
          GOTO 888
   20     XL = OE(1)
          IF(( XL.GE.-XYZMIN ).AND.( XL.LE.XYZMIN ))THEN
             IERR = -1
             GOTO 888
          ENDIF
          XL = -PO(1) / XL
          GOTO 50
   30     XL = (OE(1)**2+OE(2)**2)
          IF(( XL.GE.-XYZMIN ).AND.( XL.LE.XYZMIN ))THEN
             IERR = -1
             GOTO 888
          ENDIF
          XL = -(PO(1)*OE(1)+PO(2)*OE(2))/ XL
          GOTO 50
   40     XL = (OE(1)**2+OE(2)**2+OE(3)**2)
          IF(( XL.GE.-XYZMIN ).AND.( XL.LE.XYZMIN ))THEN
             IERR = -1
             GOTO 888
          ENDIF
          XL=-(PO(1)*OE(1)+PO(2)*OE(2)+PO(3)*OE(3))/XL
          GOTO 50
C
   50   IF((XL.GE.(1.-XYZEPS)).OR.(XL.LE.XYZEPS))GOTO 999
C        PRINT *,' NON MONOTONE EN : ',XL
        MONO = 1
        CALL MUSCVE(OE,XL,IDIMC,OE)        
        CALL SOMMVE(XP1,OE,IDIMC,XPNUL)       
        GOTO 999
C          ========================
C       --- L'OBJET EST UNE DROITE --- ITYPO=2
C          ========================
C       --- CAS 1D, 2D, 3D ---
   60   GOTO (70,80,90) IDIMC
   70     IERR = -1
          GOTO 888
C         --- INTERSECTION D'UNE DROITE ET D'UN SEGMENT --- 
   80     CALL DR2PO(ROBJET,ROBJET(IDIMC+1),DROITE,IERR)
          IF( IERR.NE. 0 )GOTO 888
          INTER = INDRSE(XP1,XP2,DROITE,0,XPNUL,IERR)
          IF( IERR .NE. 0 )GOTO 888
          IF( INTER .EQ. 1 )MONO = 1
          GOTO 100
C         --- DISTANCE MINI. ENTRE UNE DROITE ET UN SEGMENT --- 
   90     IERR = -3
C          PRINT *,'A FAIRE'
          GOTO 888
  100     GOTO 999
C          ========================
C       --- L'OBJET EST UN SEGMENT --- ITYPO=3
C          ========================
  120   GOTO (130,140,150) IDIMC
  130     IERR=-1
          GOTO 888
C         --- DIST. MINI. ENTRE 2 SEGMENTS ---
C
C         PB : IL PEUT Y AVOIR 2 MINIMUMS PAR EXEMPLE
C              DANS LE CAS DE 2 SEGMENT PARALLELES OU
C              L'UN EST INCLUS DANS L'AUTRE.
C
C         --- DIST. MINI. ENTRE 2 SEGMENTS ---
  140     CONTINUE
          CALL  DIMOSG(XP1,XP2,IDIMC,ROBJET,ROBJET(IDIMC+1),
     >                       XPNUL,MONO,IERR)
C          IF( IERR .NE. 0 )GOTO 888
C          PRINT *,'CAS DU SEGMENT EN TEST !!!!'
          GOTO 888    
  150     IERR = -3
C          PRINT *,'A FAIRE'
          IERR = -3
          GOTO 888    
C          ========================
C       --- L'OBJET EST UN PLAN    ---
C          ========================
  180   IF( IDIMC.NE.3 )IERR = -1
C       --- INTERSECTION D'UN PLAN AVEC UN SEGMENT ---
C        PRINT *,'A FAIRE'
        IERR = -3
        GOTO 888    
C
  888 IF( IERR .NE. 0 )CALL DSERRE(1,IERR,'CG','DANS DIMONO')
  999 END
C
C
C
      SUBROUTINE DIMOSG(XP1,XP2,IDIMC,S1,S2,
     >                       XPNUL,MONO,IERR)
C     ****************************************************************
C     OBJET DIMOSG : interface entre DIMONO et  DIMOSG2 (LOCAL)
C     ****************************************************************
      REAL    XP1(*),XP2(*),S1(*),S2(*)
      INTEGER IDIMC
      REAL    XPNUL(*)
      INTEGER MONO,IERR
C
      REAL    XPPP(3),XPSEG(4*3),V12(3)
      INTEGER I,NBS,ICASE
C
      CALL DIMOSG2(XP1,XP2,IDIMC,S1,S2,
     >            XPPP,XPSEG,NBS,ICASE,IERR)
      IF( IERR .NE. 0 )GOTO 888
      MONO =0
C     --- monotone
      IF(ICASE.EQ.0)GOTO 9999
C
      CALL DIFFVE(XP2,XP1,IDIMC,V12)
C     --- il n'y a pas de plus proche voisin pour ICASE=4
      IF(ICASE.NE.4)THEN
         MONO = MONO+1
         CALL MUSCVE(V12,XPPP,IDIMC,XPNUL((MONO-1)*IDIMC+1))
         CALL SOMMVE(XP1,XPNUL,IDIMC,XPNUL((MONO-1)*IDIMC+1))
       ENDIF
       DO 142 I=1,NBS
         MONO=MONO+1
         CALL MUSCVE(V12,XPSEG(I),IDIMC,XPNUL((MONO-1)*IDIMC+1))
         CALL SOMMVE(XP1,XPNUL((MONO-1)*IDIMC+1),IDIMC,
     >               XPNUL((MONO-1)*IDIMC+1))
  142 CONTINUE
  888 IF( IERR .NE. 0 )CALL DSERRE(1,IERR,'DIMOSG','APPEL DIMOSG2 ')
 9999 END

C
      SUBROUTINE DIMOSG2(XP1,XP2,IDIMC,S1,S2,
     >                       XPPP,XSEG,NBS,ICASE,IERR)
C     ****************************************************************
C     OBJET DIMOSG2 : points sur la droite XP1,XP2 ou la distance au seg S1,S2 "change" (LOCAL)
C
C     EN ENTREE :
C      XP1,XP2 : le segment a tester
C      S1,S2   : le segment "site" (concentration)
C     EN SORTIE :
C        XPNODE(NBNODE) : abscisse des points de redecoupage
C                du segment XP1,XP2
C        ICASE : 0 = monotone sur le segment XP1,XP2
C                1 = intersection du segment S1,S2 avec le segment XP1,XP2
C                2 = S1 est le point le plus proche de XP1,XP2
C                3 = S2 est le point le plus proche de XP1,XP2
C                4 = segment // a la droite (ou confondu)
C                5 = segment perpendiculaire 
C
C     REMARQUE : ne fonctionne qu'en 2D pour l'instant !!!???
C     ****************************************************************
      REAL    XP1(*),XP2(*),S1(*),S2(*)
      INTEGER IDIMC
      REAL    XPPP,XSEG(*)
      INTEGER NBS,ICASE,IERR
C
      REAL    APS1,APS2,AIS1,AIS2,AISMIN,AISMAX,APS12
      REAL    SP1(2),SP2(2),XIS1(2),XIS2(2),XS12(2)
      INTEGER INTER
C
C      COMMON /CGEPSI/ XYZHUG,XYZMIN,XYZEPS,XYZHU2,XYZMI2
C      REAL  XYZHUG,XYZMIN,XYZEPS,XYZHU2,XYZMI2
      COMMON /CGEPSI/ XYZHUG,XYZMIN,XYZEPS
      REAL  XYZHUG,XYZMIN,XYZEPS
C
      ICASE = -1
      IERR = 0
      NBS = 0
      IF( IDIMC.NE.2 )THEN
	  IERR = -3
	  GOTO 9999
      ENDIF
C     1. calcul de PS1,PS2
C     --------------------
C     PS1,PS2 <-projete de S1 et S2 sur XP1,XP2
      CALL PRJSEG(S1,XP1,XP2,IDIMC,APS1)
      CALL PRJSEG(S2,XP1,XP2,IDIMC,APS2)
C     si PS1=PS2 les segments sont perpendiculaires
C      IF( ABS(APS1-APS2).LT.XYZEPS)THEN
C     BUG 13.09.06  O.STAB
C      .00000096  > 1.1920929e-07 et intersection pas detecte INDRDR !!!
C     FINALEMENT : comme APS1 sans unite = (PS1-XP1)/(XP2-XP1)
C     BUG 28.06.2010 : reprise sur ERREUR 
C     on suppose segments perpendiculaires si INDRDR ne detecte pas d'intersection
C     TODO pour etre coherent avec INDRDR : ABS(S1SP2 n XP1XP2) < XYZEPS
C     ABS(APS1-APS2).LT.XYZEPS*norm(S1S2)
      IF( ABS(APS1-APS2).LT.0.0001)THEN
        GOTO 100
      ENDIF
C
C     2. calcul de IS1,IS2
C     --------------------
C     IS1,IS2 <-intersection (Perpen en S1 avec XP1,XP2)
C     si PS1 = S1 (S1 est sur le segment XP1,XP2) IS1=PS1=S1
C     SP2 est le point tel que :
C     S1,SP2 est le segment passant par S1 et perpendiculaire a S1,S2
      SP2(1) = S2(2)-S1(2)+S1(1)
      SP2(2) = S1(1)-S2(1)+S1(2)
      CALL INDRDR(S1,SP2,XP1,XP2,IDIMC,XIS1,INTER)
      IF(INTER.NE.1)THEN
C     --- reprise sur le bug : si perpendiculaire
        IF(INTER.EQ.0)THEN
          GOTO 100
        ENDIF
C     --- il y a un bug !!!
        CALL INDRDR(S1,SP2,XP1,XP2,IDIMC,XIS1,INTER)
        IERR = -1
        GOTO 9999
        ENDIF
      CALL PRJSEG(XIS1,XP1,XP2,IDIMC,AIS1)
C     ---idem PS2
C     S2,SP1 est le segment passant par S2 et perpendiculaire a S1,S2
      SP1(1) = S2(2)-S1(2)+S2(1)
      SP1(2) = S1(1)-S2(1)+S2(2)
      CALL INDRDR(S2,SP1,XP1,XP2,IDIMC,XIS2,INTER)
      IF(INTER.NE.1)THEN
C     --- reprise sur le bug : si perpendiculaire
        IF(INTER.EQ.0)THEN
          GOTO 100
        GOTO 9999
        ENDIF
C     --- il y a un bug !!!
        CALL INDRDR(S2,SP1,XP1,XP2,IDIMC,XIS2,INTER)
        IERR = -1
        GOTO 9999
      ENDIF
      CALL PRJSEG(XIS2,XP1,XP2,IDIMC,AIS2)
C     --- XPNODE <-stocker IS1, IS2
      NBS = 0
      IF((AIS1.GT.XYZEPS).AND.(AIS1.LT.1+XYZEPS))THEN
          NBS = NBS+1
          XSEG(NBS)= AIS1
      ENDIF
      IF((AIS2.GT.XYZEPS).AND.(AIS2.LT.1+XYZEPS))THEN
          NBS = NBS+1
          XSEG(NBS)= AIS2
      ENDIF
C
C     3b. stockage de PS1, PS2
C     -------------------------
C     --- si IS1=PS1 et IS2=PS2 les segments sont //
      IF((ABS(AIS1-APS1).LT.XYZEPS).AND.(ABS(AIS2-APS2).LT.XYZEPS))THEN
C       les vecteurs sont // 
        ICASE = 4
	GOTO 9999      
      ENDIF
      ICASE = 0
      AISMIN =MIN(AIS1,AIS2)
      AISMAX =MAX(AIS1,AIS2)
C     --- si PS1 hors [IS1,IS2] XPNODE <-stocker PS1
C     PS1 est le point le plus proche de la droite XP1,XP2
      IF((APS1.LT.AISMIN).OR.(APS1.GT.AISMAX))THEN
        IF((APS1.GT.XYZEPS).AND.(APS1.LT.1+XYZEPS))THEN
          XPPP = APS1
          ICASE = 2
        ENDIF
      ENDIF
C     PS2 est le point le plus proche de la droite XP1,XP2
      IF((APS2.LT.AISMIN).OR.(APS2.GT.AISMAX))THEN
        IF((APS2.GT.XYZEPS).AND.(APS2.LT.1+XYZEPS))THEN
          XPPP = APS2
          ICASE = 3
        ENDIF
      ENDIF
C
C     4. calcul de IX12
C     --------------------
C     XS12 <-intersection (XP1,XP2) avec (S1,S2)
C     si XS12 dans [PS1,PS2] XPNODE <-stocker XS12
      CALL INDRDR(S1,S2,XP1,XP2,IDIMC,XS12,INTER)
      CALL PRJSEG(XS12,XP1,XP2,IDIMC,APS12)
      IF((APS12.GT.AISMIN).AND.(APS12.LT.AISMAX))THEN
        IF((APS12.GT.XYZEPS).AND.(APS12.LT.1+XYZEPS))THEN
          XPPP = APS12
          ICASE = 1
        ENDIF
      ENDIF
      GOTO 9999
C
  100 CONTINUE
C     --------- SEGMENTS PERPENDICULAIRES : XP1,XP2 et S1,S2 ----------
C     si PS1=PS2 les segments sont perpendiculaires
C     --- point "d'intersection" : IX12=PS1=PS2
        XPPP   = (APS1+APS2)/2.0
        ICASE = 5
C        IF((XPPP.LT.XYZEPS).OR.(XPPP.GT.1+XYZEPS))ICASE=0
C        --- doutes : pourquoi les tests pas interieur tous les 2 ???
        IF((XPPP.LT.XYZEPS).OR.(XPPP.GT.1+XYZEPS))ICASE=0
C
 9999 END
C






C     *****************************************************************
C     MODULE  : CG (CALCUL GEOMETRIQUE)
C     FICHIER : CG_DROITE.F
C     OBJET   : GEOMETRIE 2D - CALCULS SUR LES DROITES 
C     FONCT.  :
C           DR2PO  : CALCULE LA DROITE PASSANT PAR LES 2 POINTS
C           INDRDR : intersection de 2 droites
C
C     FONCT. LOCALES  :
C           PVDROI : CALCULE UN POINT ET LE VECTEUR DE LA DROITE  (LOCAL)
C           INDRSE : INTERSECTION D'UNE DROITE ET D'UN SEGMENT  (LOCAL)
C
C     AUTEUR  : O. STAB
C     DATE    : 06.95
C     TESTS   : 07.95
C     MODIFICATIONS :
C      AUTEUR, DATE, OBJET : O.STAB, 16.04.97, BUG_19 DANS PVDROI
C                            IL FAUT TESTER ABS(DROITE(3))
C      AUTEUR, DATE, OBJET : O.STAB, 31.01.05 ajout INDRDR
C
C
C     *****************************************************************
C
C
      SUBROUTINE PVDROI( DROITE, XPOINT,VDIR, IERR )
C     *****************************************************************
C     OBJET PVDROI : CALCULE UN POINT ET LE VECTEUR DE LA DROITE 2D (LOCAL)
C     EN ENTREE :
C        DROITE : EQUATION DE LA DROITE AX+BY+C = 0
C     EN SORTIE :
C        XPOINT : UN POINT DE LA DROITE
C        VDIR   : LE VECTEUR DIRECTEUR DE LA DROITE
C        IERR   : 0 SI OK, -1 SI "DROITE" N'EST PAS CORRECTE
C     *****************************************************************
      REAL      DROITE(3),XPOINT(2),VDIR(2)
      INTEGER   IERR
C
      COMMON /CGEPSI/ XYZHUG,XYZMIN,XYZEPS
      REAL  XYZHUG,XYZMIN,XYZEPS
C
      IERR = 0
C     ---- BUG_19, O.STAB, 16.04.97 : AJOUT DE ABS --- 
      IF((DROITE(1).GT.XYZEPS*ABS(DROITE(3))).OR.
     >   (DROITE(1).LT.-XYZEPS*ABS(DROITE(3))))THEN
        XPOINT(1) = - DROITE(3) / DROITE(1)
        XPOINT(2) = 0.0
      ELSE
        IF((DROITE(2).GT.XYZEPS*ABS(DROITE(3))).OR.
     >     (DROITE(2).LT.-XYZEPS*ABS(DROITE(3))))THEN
          XPOINT(1) = 0.0
          XPOINT(2) = - DROITE(3) / DROITE(2)
        ELSE
          IERR = -1
        ENDIF
      ENDIF 
      VDIR(1) = -DROITE(2)
      VDIR(2) =  DROITE(1)     
  999 END
C
C      INTEGER FUNCTION INDRSE(XP1,XP2,DROITE,ITEST,XPI,IERR)
      FUNCTION INDRSE(XP1,XP2,DROITE,ITEST,XPI,IERR)
C     *****************************************************************
C     OBJET INDRSE : INTERSECTION D'UNE DROITE ET D'UN SEGMENT 2D
C     EN ENTREE :
C        XP1    : L'ORIGINE DU SEGMENT
C        XP2    : L'EXTREMITE DU SEGMENT
C        DROITE : L'EQUATION DE LA DROITE
C        ITEST   : SI ITEST=1 ON NE CALCULE PAS LA POSITION DU POINT
C     EN SORTIE : RENVOI 1 SI INTERSECTION 0 SINON
C        XPI    : POSITION DU POINT D'INTERSECTION (SI ITEST=1)
C        IERR   : 0 SI OK, -1 SI "DROITE" N'EST PAS CORRECTE
C     *****************************************************************
      INTEGER   INDRSE
      REAL      XP1(2),XP2(2),XPI(2)
      REAL      DROITE(3)
      INTEGER   ITEST,IERR
C
      COMMON /CGEPSI/ XYZHUG,XYZMIN,XYZEPS
      REAL  XYZHUG,XYZMIN,XYZEPS
      REAL      S1,S2
      REAL      XPD(2),V12(2),V23(2),V2S(2),VDIR(2),X,SCALVE
      EXTERNAL  SCALVE
C        ========================
C     --- TEST DE L'INTERSECTION ---
C        ========================
      S1 = DROITE(1)*XP1(1)+DROITE(2)*XP1(2)+DROITE(3)
      S2 = DROITE(1)*XP2(1)+DROITE(2)*XP2(2)+DROITE(3)
      IF(((S1.LE.-XYZEPS).AND.(S2.GE.XYZEPS)).OR.
     >   ((S2.LE.-XYZEPS).AND.(S1.GE.XYZEPS)))THEN
          INDRSE = 1
          IF(ITEST.EQ.1)GOTO 999
C            ================================
C         --- CALCUL DU POINT D'INTERSECTION ---
C            ================================
C         --- L'INTERSECTION EST EN XP1 ---
          IF((S1.LE.XYZEPS).AND.(S1.GE.-XYZEPS ))THEN
             CALL COPIVE(XP1,2,XPI)
             GOTO 999
          ENDIF
C         --- L'INTERSECTION EST EN XP2 ---
          IF((S2.LE.XYZEPS).AND.(S2.GE.-XYZEPS ))THEN
             CALL COPIVE(XP2,2,XPI)
             GOTO 999
          ENDIF          
C         --- L'INTERSECTION N'EST PAS A UNE EXTREMITE ---
          CALL PVDROI( DROITE, XPD, VDIR, IERR )   
          IF( IERR .NE. 0 )GOTO 999       
          CALL DIFFVE( XP1,XPD,2,V12 )
          CALL DIFFVE( XPD,XP2,2,V23 )
          CALL VECTVE( V12,V23,2,V2S )
          X = V2S(1) / ( S1 - S2 )
          IF((X.LE.XYZEPS).AND.(X.GE.-XYZEPS))THEN
C           --- XP1,XP2 ET XPD SONT ALIGNES ---
            CALL COPIVE(XPD,2,XPI)
          ELSE
            CALL MUSCVE( VDIR, -X, 2, VDIR )
            CALL SOMMVE( XPD, VDIR, 2, XPI )
          ENDIF
C          PRINT *,'INTERSECTION =',XPI(1),XPI(2)
      ELSE
          INDRSE = 0        
      ENDIF
  999 END
C 
      SUBROUTINE DR2PO( XP1,XP2, DROITE, IERR )
C     *****************************************************************
C     OBJET DR2PO : CALCULE LA DROITE PASSANT PAR LES 2 POINTS 2D
C     EN ENTREE:
C        XP1, XP2 : LES 2 POINTS DE LA DROITE
C     EN SORTIE
C        DROITE   : LES COEFFICIENTS A,B,C DE L'EQUATION DE LA DROITE 
C                   AX+BY+C = 0
C        IERR     : -1 SI XP1 ET XP2 SONT CONFONDUS, 0 SI OK
C     *****************************************************************
      REAL      XP1(2),XP2(2),DROITE(3)
      INTEGER   IERR
C
      COMMON /CGEPSI/ XYZHUG,XYZMIN,XYZEPS
      REAL  XYZHUG,XYZMIN,XYZEPS
      REAL   XDENO
C 
      IERR = 0
      XDENO = XP2(1) - XP1(1)     
      IF((XDENO.LE.XYZEPS).AND.(XDENO.GE. -XYZEPS))THEN
        XDENO = XP2(2) - XP1(2)
        IF((XDENO.LE.XYZEPS).AND.(XDENO.GE. -XYZEPS))THEN
          IERR = -1
          GOTO 999
        ENDIF
        DROITE(1) = 1.0
        DROITE(2) = 0.0
        DROITE(3) = - XP1(1)
      ELSE
        DROITE(1) = (XP1(2) - XP2(2)) / XDENO
        DROITE(2) = 1.0
        DROITE(3) = - XP1(2) - (XP1(1) * DROITE(1))
      ENDIF
  999 END
C
C
      SUBROUTINE INDRDR(S1,S2,X1,X2,IDIMC,XS,INTER)
C     *****************************************************
C     OBJET INDRDR : intersection de 2 droites
C	SORTIE :
C	   INTER : < 0 une erreur
C                  0 pas d'intersection // ou confondus
C			 1 intersection
C			 2 confondu (a faire)
C     *****************************************************
      REAL    X1(*),X2(*),S1(*),S2(*)
      INTEGER IDIMC
      REAL    XS(*)
      INTEGER INTER	
C
      REAL A(2),B(2),C(2),SDET,S12(2),X12(2)
      COMMON /CGEPSI/ XYZHUG,XYZMIN,XYZEPS,XYZHU2,XYZMI2
      REAL  XYZHUG,XYZMIN,XYZEPS,XYZHU2,XYZMI2
C
      IF(IDIMC.NE.2)THEN
        INTER =-3
        GOTO 9999
      ENDIF
      CALL DIFFVE(S2,S1,IDIMC,S12)
      CALL DIFFVE(X2,X1,IDIMC,X12)
      CALL VECTVE(X12,S12,IDIMC,SDET)
C     il faudrait normaliser !!?  OS.28.06.2010 A FAIRE. ?!..
      IF( ABS(SDET).LT.XYZEPS )THEN
C       les vecteurs sont // <=> DET=0 
        INTER = 0
        GOTO 9999
      ENDIF
      INTER = 1
      SDET = 1.0/SDET
      CALL VECTVE(S12,S1,IDIMC,C(1))
      CALL VECTVE(X12,X1,IDIMC,C(2))
      A(1) = S12(2)
      A(2) = X12(2)
      B(1) = -S12(1)
      B(2) = -X12(1)
      CALL VECTVE(C,B,IDIMC,XS(1))
      CALL VECTVE(A,C,IDIMC,XS(2))
      CALL MUSCVE(XS,SDET,IDIMC,XS)
 9999 END
C
C     ***************************************************************
C     MODULE  : CG (CALCUL GEOMETRIQUE)
C     FICHIER : CG_EPSI.F
C     OBJET   : GESTION DE L'EPSILON
C
C     FONCT.  :  
C     ICGEPS: INITIALISE LES CONSTANTES GEOMETRIQUES DU COMMON CGEPSI
C
C     AUTEUR   : O. STAB
C     DATE     : 01.96 / 05.96
C     TESTS    :  
C     MODIFICATIONS :
C      AUTEUR, DATE, OBJET :
C
C
C     ***************************************************************
C
C
      SUBROUTINE ICGEPS
C     **********************************************************************
C     OBJET : INITIALISE LES CONSTANTES GEOMETRIQUES DU COMMON CGEPSI
C
C     REMARQUE  :
C       L'INITIALISATION DES CONSTANTES EST REALISE PAR PROCEDURE
C       PLUTOT QUE PAR UN BLOCK DATA POUR DES RAISONS DE PORTABILITE.
C       ICGEPS DOIT ETRE APPELEE AU DEBUT DE CHAQUE PROGRAMME
C     **********************************************************************
C
C     LES VALEURS :
C     -------------
C     HUGEX : VALEUR POSITIVE MAXIMUM POUR UNE DONNEE DE TYPE X
C             LA VALEUR NEGATIVE MINIMUM EST -HUGEX
C     MINX : VALEUR POSITIVE MINIMUM POUR "   "   "
C             LA VALEUR NEGATIVE MAXIMUM EST -MINX
C     EPSIX : PLUS GRANDE VALEUR NEGLIGEABLE DEVANT 1
C   
C
C     LES TYPES :
C     -----------
C     XYZ : LE TYPE COORDONNEE (REAL*4)
C  
C     LES MACHINES :
C     --------------
C     HP700 / IRIX  : 
C     POUR LES REAL*4
C        HUGEF, MINF, EPSIF = 3.402823 E+38, 
C                             1.175495 E-38, 
C                             1.19209290 E-07
C
C     POUR LES REAL*8 OU DOUBLE PRECISION
C        HUGED, MIND, EPSID = 1.7976931348623157E+308 ,
C                             2.2250738585072014E-308, 
C                             2.2204460492503131E-16
C     POUR SUN / IBM :
C     MAXDOUBLE	1.797693134862315708E+308
C     MAXFLOAT	((FLOAT)3.40282346638528860E+38)
C     MINDOUBLE	4.94065645841246544E-324
C     MINFLOAT	((FLOAT)1.40129846432481707E-45) 
C
      COMMON /CGEPSI/ XYZHUG,XYZMIN,XYZEPS,XYZHU2,XYZMI2
C
      REAL  XYZHUG,XYZMIN,XYZEPS,XYZHU2,XYZMI2
C
      XYZHUG = 3.402823E+38 
      XYZMIN = 1.175495E-38 
      XYZHU2 = 1.E+19 
      XYZMI2 = 1.E-19 
      XYZEPS = 1.19209290E-07
C
      END
C
C     *****************************************************************
C     MODULE  : CG (CALCUL GEOMETRIQUE)
C     FICHIER : CG_INTER2D.F
C     OBJET   : INTERSECTION D'UNE DROITE AVEC UN POLYGONE SIMPLE 
C
C     FONCT.  : 
C       INDRPO : INTERSECTION D'UN POLYGONE SIMPLE AVEC UNE DROITE
C
C     AUTEUR  : O. STAB
C     DATE    : 03.95
C     MODIFICATIONS :
C      AUTEUR, DATE, OBJET :
C
C
C     *****************************************************************
C 
      SUBROUTINE INDRPO(X,Y,NBN,DROITE,PZERO,NBA,IARET,NBS,SOM)
C     *****************************************************************
C     OBJET : INTERSECTION D'UN POLYGONE SIMPLE AVEC UNE DROITE
C     EN ENTREE :
C        X,Y   : TABLEAU DES COORDONNEES DES POINTS DU POLYGONE
C        NBN   : NOMBRE DE POINT DU POLYGONE
C        DROITE: EQUATION DE LA DROITE
C        PZERO : PRECISION DU CALCUL
C     EN SORTIE:
C        IARET  : INDICES DES ARETES DU POLY QU'INTERSECTE DROITE
C        NBA   : NOMBRE "   "    "      "    "
C        SOM   : INDICES DES SOMMETS DU POLY QU'INTERSECTE DROITE
C        NBS   : NOMBRE "   "    "      "    "
C     *****************************************************************
      INTEGER   NBN,NBA,NBS,IARET(*),SOM(*)
      REAL      X(*),Y(*),PZERO
      REAL      DROITE(3)
C
      REAL      S
      INTEGER   K,K2,ISD
C
       NBS = 0
       NBA = 0
       S = DROITE(1)*X(1)+DROITE(2)*Y(1)+DROITE(3)
C        --- TEST DU PREMIER SOMMET ---
       IF((S.LT.PZERO).AND.(S.GT.-PZERO))THEN
         NBS = NBS + 1
         SOM(NBS) = 1
         ISD = 0
       ELSE
         IF( S.GT.PZERO )THEN
           ISD = 1
         ELSE
           ISD = -1
         ENDIF
       ENDIF
C      --- TEST DES ARETES ---
       DO 20 K=1,NBN
         K2 = MOD(K,NBN)+1
         S = DROITE(1)*X(K2)+DROITE(2)*Y(K2)+DROITE(3)
C        --- LE SOMMET K+1 EST SUR LA DROITE ---
         IF((S.LT.PZERO).AND.(S.GT.-PZERO))THEN
           NBS = NBS + 1
           SOM(NBS) = K2
           ISD = 0
         ELSE
C        --- ON ETAIT SUR LA DROITE ---
           IF( ISD.EQ.0 )THEN
            IF( S.GT.PZERO )THEN
              ISD = 1
            ELSE
              ISD = -1
            ENDIF
           ELSE
C        ---- ON ETAIT PAS SUR LA DROITE 
C        ---- ET ON CHANGE DE COTE ---
            IF((S*ISD).LT.-PZERO)THEN
              ISD = -ISD
              NBA=NBA+1
              IARET(NBA)=K
            ENDIF
           ENDIF
         ENDIF
         IF(K.NE.0)S=DROITE(1)*X(K)+DROITE(2)*Y(K)+DROITE(3)
   20 CONTINUE
  999 END
C 
C     *****************************************************************
C     MODULE  : CG (CALCUL GEOMETRIQUE)
C     FICHIER : CG_POLYGON.F
C     OBJET   : CALCULS GEOMETRIQUES ELEMENTAIRES SUR LES POLYGONES
C               D'UN MAILLAGE
C     FONCT.  : 
C          G2SFPL : CALCULE LA SURFACE D'UN POLYGONE EN 2D
C          G2ORPL : RENVOI L'ORIENTATION D'UN POLYGONE EN 2D 
C
C     AUTEUR  : O. STAB  
C     DATE    : 12.97
C     TESTS   : 
C     MODIFICATIONS :
C      AUTEUR, DATE, OBJET :
C
C
C     *****************************************************************
C
C
      SUBROUTINE G2SFPL(IPOINT, NBPOIN, COORD, SURFPL)
C     *****************************************************************
C     OBJET G2SFPL : CALCULE LA SURFACE D'UN POLYGONE EN 2D
C     EN ENTREE :
C       IPOINT  : INDICE DES POINTS (DANS COORD)
C       NBPOIN  : NOMBRE DE POINTS 
C       COORD   : COORDONNEES DES NOEUDS
C     EN SORTIE :
C       SURFPL  : SURFACE DU POLYGONE 
C     REMARQUE  : POSITIF POUR LE SENS TRIGO, NEGATIF POUR LE SENS INVERSE
C     *****************************************************************
      INTEGER IPOINT(*),NBPOIN
      REAL    COORD(*)
      REAL    SURFPL
C
      INTEGER I,IORIG
      REAL    XP0,YP0,XP1,YP1,XP2,YP2,YMIN
C
      SURFPL = 0.0
      IF( NBPOIN.LE.0 ) GOTO 9999
C     --- POUR PLUS DE FIABILITE ET EVITER LES OVERFLOW
C         ON PREND LE PREMIER POINT COMME ORIGINE DU REPERE D'INTEGRATION ---
C      XP0 = COORD(((IT(1)-1)*2)+1)
      YMIN = COORD(IPOINT(1)*2  )
      IORIG = 1
      DO 10 I=2,NBPOIN
        IF( COORD(IPOINT(I)*2  ).LT.YMIN )THEN
          IORIG = I
          YMIN = COORD(IPOINT(I)*2  )
        ENDIF
   10 CONTINUE
      XP0 = COORD(IPOINT(IORIG)*2-1)
      YP0 = COORD(IPOINT(IORIG)*2  )
      XP2 = COORD(IPOINT(1)*2-1) - XP0
      YP2 = COORD(IPOINT(1)*2  ) - YP0
      DO 100 I=1,(NBPOIN-1)
        XP1 = XP2 
        YP1 = YP2 
C        XP2 = COORD(((IT(I+1)-1)*2+1)- XP0
        XP2 = COORD(IPOINT(I+1)*2-1) - XP0
        YP2 = COORD(IPOINT(I+1)*2  ) - YP0
C       ---- POUR UN SEGMENT DE DROITE ----
        SURFPL = SURFPL + YP2*XP2 - YP2*XP1 + YP1*XP2 - YP1*XP1
  100   CONTINUE
C       ---- ON FERME ---
        XP1 = XP2 
        YP1 = YP2 
        XP2 = COORD(IPOINT(1)*2-1) - XP0
        YP2 = COORD(IPOINT(1)*2  ) - YP0
        SURFPL = SURFPL + YP2*XP2 - YP2*XP1 + YP1*XP2 - YP1*XP1
        SURFPL = -0.5 * SURFPL
 9999   END
C
C
      FUNCTION G2ORPL(IPOINT, NBPOIN, COORD, ZERO)
C     *****************************************************************
C     OBJET G2ORPL : RENVOI L'ORIENTATION D'UN POLYGONE EN 2D 
C     EN ENTREE :
C       IPOINT  : INDICE DES POINTS (DANS COORD)
C       NBPOIN  : NOMBRE DE POINTS 
C       COORD   : COORDONNEES DES NOEUDS
C       ZERO    : SURFACE CONSIDEREE COMME NULLE
C     EN SORTIE :
C       SURFPL  : SURFACE DU POLYGONE
C     *****************************************************************
      INTEGER G2ORPL
      INTEGER IPOINT(*),NBPOIN
      REAL    COORD(*),ZERO
C
      REAL SURFPL
C
      CALL G2SFPL(IPOINT, NBPOIN, COORD, SURFPL)
      IF(SURFPL.GT.ZERO)THEN
      G2ORPL = 1
      ELSE      
        IF(SURFPL.GT.ZERO)THEN
          G2ORPL = -1
        ELSE
          G2ORPL = 0
        ENDIF
      ENDIF
 9999  END
C
C     *****************************************************************
C     MODULE  : CG (CALCUL GEOMETRIQUE) 
C     FICHIER : CG_SUITE.F
C     OBJET   : CALCULS SUR LES SUITES
C     FONCT.  :
C
C        SU2PO     : CALCUL DE LA SUITE ENTRE 2 POINTS
C        SCSUSE     : CALCUL EN 2 POINTS LA VALEUR DE LA SUITE 
C        SUPTSU      : GENERE LES POINTS D'UNE SUITE
C        SCSUPO    : VALEUR D'UNE SUITE EN UN POINT
C        POSUM : GENERE LES POINTS D'UNE SUITE AVEC CALAGE
C        POSUNM : GENERE LES POINTS D'UNE SUITE NON MONOTONE (OBSOLET)
C        POSUNM2 :  GENERE LES POINTS D'UNE SUITE NON MONOTONE (2005)
C        LISUPO     : REGULARISE LA POSITION D'UN POINT ENTRE 2 AUTRES
C
C     FONCT LOCALES  :
C        ------- PROGRESSION GEOMETRIQUE -------
C        SUG2PO  : CALCUL DE LA SUITE GEOMETRIQUE ENTRE 2 POINTS
C        SCSUGS  : CALCUL EN 2 POINTS LA VALEUR DE LA SUITE GEOMETRIQUE 
C        POSUG   : GENERE LES POINTS D'UNE SUITE GEOMETRIQUE
C        ------- PROGRESSION ARITHMETIQUE -------
C        SUA2PO  : CALCUL DE LA SUITE ARITHMETIQUE ENTRE 2 POINTS
C        SCSUAS  : CALCUL EN 2 POINTS LA VALEUR DE LA SUITE ARITHMETIQUE 
C        POSUA   : GENERE LES POINTS D'UNE SUITE ARITHMETIQUE
C
C     AUTEUR  : O. STAB
C     DATE    : 03.95 / 06.95
C     TESTS   : 07.95
C     MODIFICATIONS :
C      AUTEUR, DATE, OBJET : STAB, 02.09.98, BUG NUMERIQUE DANS SUG2PO
C      AUTEUR, DATE, OBJET : STAB, 31.01.05, ajout POSUNM2 (remplace POSUNM)
C      AUTEUR, DATE, OBJET : STAB, 18.08.06 : SUG2PO 
C                            erreur de FORMULE dans le calcul de la suite !!!!!!!!!
C                            R = ( XD - X0 ) / ( XD - XN )
C      AUTEUR, DATE, OBJET : STAB, 07.09.06 : SCSUPO
C                            calcul de la taille discrete (paliers) pour  
C                            les suites geometriques plutot que lineaire !!!
C     *****************************************************************
C
C                           =========================
C     ---------------------- PROGRESSION GEOMETRIQUE ------------------
C                           =========================
C
      SUBROUTINE SUG2PO(XD,X0,XN,N,R,IERR)
C     *****************************************************************
C     OBJET SUG2PO: CALCUL DE LA SUITE GEOMETRIQUE ENTRE 2 POINTS (LOCAL)
C     EN ENTREE :
C          XD   : LA LONGUEUR DU SEGMENT
C          X0   : LA TAILLE SOUHAITE A L'ORIGINE 
C          XN   : LA TAILLE SOUHAITE A L'EXTREMITE
C     EN SORTIE :
C          R    : LA RAISON DE LA SUITE GEOMETRIQUE
C          N    : LE NOMBRE DE NOEUDS
C          IERR: -1 SI ERREUR DANS LES DONNEES D'ENTREE
C     *****************************************************************
      REAL      XD,X0,XN
      INTEGER   N,IERR
      REAL      R
C
      COMMON /CGEPSI/ XYZHUG,XYZMIN,XYZEPS
      REAL  XYZHUG,XYZMIN,XYZEPS
      REAL  XNBN
C
      IERR = 0
C      IF((XN.LE.XYZEPS).OR.(X0.LE.XYZEPS))THEN
C     MODIF 980902 : 
      IF((XN.LE.XYZMIN).OR.(X0.LE.XYZMIN))THEN
       IERR = -1
       CALL DSERRE(1,IERR,'CG',
     >             'DANS SUG2PO : TAILLE SOUHAITEE NEGATIVE OU NULLE')
       GO TO 999
      ENDIF
      IF(XD.LT.XYZMIN)THEN
       R = 1.
       N = 0
       GO TO 999
      ENDIF
C
C      IF( ABS(X0 - XN)  .LE. (X0+XN)*ZERO )THEN
C      IF( ABS((LOG(XD + XN)-LOG(XD + X0))).LE.XYZMIN )THEN
C     BUG NUMERIQUE 980902 :  le log applati TROP l'erreur
C
C      R = ( XD + XN ) / ( XD + X0 )
C     BUG 18.08.06 : erreur de FORMULE dans le calcul de la suite !!!!!!!!!
      IF( XN.EQ.XD )THEN
        N=0
        R=1.
        GOTO 999
      ENDIF
      R = ( XD - X0 ) / ( XD - XN )
      IF( (ABS( R - 1.)  .LE. XYZEPS ).OR.
     >    (ABS(X0 - XN)  .LE. (X0+XN)*XYZEPS ) )THEN
       XNBN = (2. * XD / (X0 + XN) ) - 1.
      ELSE
C       XNBN = ((LOG(XN) - LOG(X0)) / (LOG(XD + XN)-LOG(XD + X0)))
C     >    - 2.  
C     MODIF 980902 : 
C       XNBN = LOG(XN / X0) / LOG((XD + XN)/(XD + X0))   - 2.  
C       XNBN = LOG(XN / X0) / LOG(R)   - 2.  
C     BUG 18.08.06 : erreur de FORMULE dans le calcul de la suite !!!!!!!!!
       XNBN = LOG(XN / X0) / LOG(R)  
      ENDIF 
C      PRINT *,'ERREUR DE TRONCATURE :',N,XNBN
C      N = NINT(XNBN)
C     MODIF 18.08.06 => NON
      N = NINT(XNBN)
C
  999 END
C
      SUBROUTINE SCSUGS(XD,N,R,X0,XN,IERR)
C     *****************************************************************
C     OBJET  SCSUGS : CALCUL EN 2 POINTS LA VALEUR DE LA SUITE GEOMETRIQUE (LOCAL) 
C     EN ENTREE :
C          XD   : LA LONGUEUR DU SEGMENT
C          R    : LA RAISON DE LA SUITE GEOMETRIQUE
C          N    : LE NOMBRE DE NOEUDS
C     EN SORTIE :
C          X0   : LA TAILLE SOUHAITE A L'ORIGINE 
C          XN   : LA TAILLE SOUHAITE A L'EXTREMITE
C          IERR: -1 SI ERREUR DANS LES DONNEES D'ENTREE
C     *****************************************************************
      REAL      XD,X0,XN
      INTEGER   N,IERR
      REAL      R
C
      COMMON /CGEPSI/ XYZHUG,XYZMIN,XYZEPS
      REAL  XYZHUG,XYZMIN,XYZEPS
C
      IERR = 0
      IF(R.LE.XYZEPS)THEN
       IERR = -1
       CALL DSERRE(1,IERR,'CG',
     >             'DANS SCSUGS : RAISON NEGATIVE OU NULLE')
       GO TO 999
      ENDIF
      IF(XD.LE.XYZEPS)THEN
       IERR = -1
       CALL DSERRE(1,IERR,'CG',
     >         'DANS SCSUGS : LONGUEUR DU SEGMENT NEGATIVE OU NULLE')
       GO TO 999
      ENDIF
      IF(N.LE.0)THEN
       IERR = -1
       CALL DSERRE(1,IERR,'CG',
     >             'DANS SCSUGS : NOMBRE DE NOEUDS NEGATIF OU NUL')
       GO TO 999
      ENDIF
C
      IF( ABS(1.-R) .LE. XYZEPS )THEN
        X0 = XD / (N + 1)
        XN = X0
      ELSE
        X0 = XD * (1-R) / (R * (1-R**(N+1)))
C        PRINT *,' D = ', XD
C        PRINT *,' D = ', (X0 * R * (1-R**(N+1))/(1-R))
C        PRINT *,' -   ', XD - (X0 * R * (1-R**(N+1))/(1-R))
        XN = R**(N+2) * X0
      ENDIF 
C
  999 END
C
      SUBROUTINE POSUG(X1,V1,IDIMC,T,N,R,XYZPT,IERR)
C     *****************************************************************
C      OBJET POSUG : GENERE LES POINTS D'UNE SUITE GEOMETRIQUE (LOCAL)
C      EN ENTREE :
C           X1    : LE POINT ORIGINE
C           V1    : LE VECTEUR X2-X1
C         IDIMC   : LA DIMENSION DE L'ESPACE
C            T    : VALEUR INITIALE DE LA SUITE (EN X1)
C            N    : NOMBRE DE SEGMENT APRES DECOUPAGE
C                   SI N = 1 ALORS XYZPT() = X1 + V1
C            R    : RAISON DE LA SUITE GEOMETRIQUE
C      EN SORTIE :
C         XYZPT   : COORDONNEES DES POINTS CALCULES
C         IERR    : -1 SI ERREUR DANS LES DONNEES D'ENTREE
C     *****************************************************************
       REAL       X1(*),V1(*),T,R,XYZPT(*)
       INTEGER    IDIMC,N,IERR
C
       INTEGER I,J
       REAL    RI
C
      COMMON /CGEPSI/ XYZHUG,XYZMIN,XYZEPS
      REAL  XYZHUG,XYZMIN,XYZEPS
      REAL  COEF
C
       IF( N.LE.0 )THEN
         IERR = -1
       CALL DSERRE(1,IERR,'CG',
     >             'DANS POSUG : NOMBRE DE NOEUDS NEGATIF OU NUL')         
         GO TO 999
       ENDIF
       IERR = 0
C
       IF(((1.-R).LE.XYZEPS).AND.((1.-R).GE.-XYZEPS))THEN
        DO 20 I=1,N
          COEF = I * T
          DO 10 J=1,IDIMC
            XYZPT((I-1)*IDIMC+J) = X1(J) + COEF * V1(J)
   10     CONTINUE
   20   CONTINUE
      ELSE
        RI = 1.0
        DO 50 I=1,N
          RI = RI * R
          COEF = R * T * (1-RI) / (1-R)
          DO 40 J=1,IDIMC
            XYZPT((I-1)*IDIMC+J) = X1(J) + COEF * V1(J)
   40     CONTINUE
   50   CONTINUE
      ENDIF
C
  999 END
C                           ==========================
C     ---------------------- PROGRESSION ARITHMETIQUE -----------------
C                           ==========================
C
      SUBROUTINE SUA2PO(XD,X0,XN,N,R,IERR)
C     *****************************************************************
C     OBJET SUA2PO : CALCUL DE LA SUITE ARITHMETIQUE ENTRE 2 POINTS (LOCAL)
C     EN ENTREE :
C          XD   : LA LONGUEUR DU SEGMENT
C          X0   : LA TAILLE SOUHAITE A L'ORIGINE 
C          XN   : LA TAILLE SOUHAITE A L'EXTREMITE
C     EN SORTIE :
C          R    : LA RAISON DE LA SUITE ARITHMETIQUE
C          N    : LE NOMBRE DE NOEUDS
C          IERR: -1 SI ERREUR DANS LES DONNEES D'ENTREE
C     *****************************************************************
      REAL      XD,X0,XN
      INTEGER   N,IERR
      REAL      R
C
      COMMON /CGEPSI/ XYZHUG,XYZMIN,XYZEPS
      REAL  XYZHUG,XYZMIN,XYZEPS
      REAL  XNBN
C
      IERR = 0
      IF((XN.LE.XYZEPS).OR.(X0.LE.XYZEPS))THEN
       IERR = -1
       CALL DSERRE(1,IERR,'CG',
     >             'DANS SUG2PO : TAILLE SOUHAITEE NEGATIVE OU NULLE')
       GO TO 999
      ENDIF
      IF(XD.LT.XYZMIN)THEN
       R = 1.
       N = 0
       GO TO 999
      ENDIF
C
      XNBN = (2. * XD / (X0 + XN) ) - 1.
      N = NINT(XNBN)
      R = 2. * XD * ( XN - X0 ) / ((N+1)*(N+2)*(XN + X0))
C      PRINT *,'ERREUR DE TRONCATURE :',N,XNBN
C
  999 END
C
      SUBROUTINE SCSUAS(XD,N,R,X0,XN,IERR)
C     *****************************************************************
C     OBJET SCSUAS : CALCUL EN 2 POINTS LA VALEUR DE LA SUITE ARITHMETIQUE (LOCAL)  
C     EN ENTREE :
C          XD   : LA LONGUEUR DU SEGMENT
C          R    : LA RAISON DE LA SUITE ARITHMETIQUE 
C          N    : LE NOMBRE DE NOEUDS
C     EN SORTIE :
C          X0   : LA TAILLE SOUHAITE A L'ORIGINE 
C          XN   : LA TAILLE SOUHAITE A L'EXTREMITE
C          IERR: -1 SI ERREUR DANS LES DONNEES D'ENTREE
C     *****************************************************************
      REAL      XD,X0,XN
      INTEGER   N,IERR
      REAL      R
C
      IERR = 0
      IF(N.LE.0)THEN
       IERR = -1
       GO TO 999
      ENDIF
C
C      PRINT *,' XD = ',XD,' = ',((N+1)*(X0+R*(N+2)/2))
      X0 = (XD/(N+1))  - R*(N+2)/2
      XN = X0 + (N+2)*R
C
  999 END
C
      SUBROUTINE POSUA(X1,V1,IDIMC,T,N,R,XYZPT,IERR)
C     *****************************************************************
C      OBJET POSUA :  GENERE LES POINTS D'UNE SUITE ARITHMETIQUE (LOCAL)
C      EN ENTREE :
C           X1    : LE POINT ORIGINE
C           V1    : LE VECTEUR X2-X1
C         IDIMC   : LA DIMENSION DE L'ESPACE
C            T    : VALEUR INITIALE DE LA SUITE (EN X1)
C            N    : NOMBRE DE SEGMENT APRES DECOUPAGE
C                   SI N = 1 ALORS XYZPT() = X1 + V1
C            R    : RAISON DE LA SUITE ARITHMETIQUE 
C      EN SORTIE :
C         XYZPT   : COORDONNEES DES POINTS CALCULES
C         IERR    : -1 SI ERREUR DANS LES DONNEES D'ENTREE
C     *****************************************************************
       REAL       X1(*),V1(*),T,R,XYZPT(*)
       INTEGER    IDIMC,N,IERR
C
       INTEGER I,J
       REAL    COEF
C
      IF( N.LE.0 )THEN
         IERR = -1
         GO TO 999
      ENDIF
      IERR = 0
C
      DO 20 I=1,N
         COEF = I * (T + ((I+1) * R) / 2.)
         DO 10 J=1,IDIMC
            XYZPT((I-1)*IDIMC+J) = X1(J) + COEF * V1(J)
   10    CONTINUE
   20 CONTINUE
C
  999 END
C                           ==========================
C     ---------------------- PROGRESSION (CAS GENERAL) ----------------
C                           ==========================
C
C

      SUBROUTINE SCSUSE(ITYPE,XD,N,R,X0,XN,IERR)
C     *****************************************************************
C     OBJET SCSUSE : CALCUL EN 2 POINTS LA VALEUR DE LA SUITE 
C     EN ENTREE :
C         ITYPE : TYPE DE LA SUITE
C               (1=GEOMETRIQUE,2=ARITHMETIQUE,3=HARMONIQUE)
C          XD   : LA LONGUEUR DU SEGMENT
C          R    : LA RAISON DE LA SUITE GEOMETRIQUE
C          N    : LE NOMBRE DE NOEUDS
C     EN SORTIE :
C          X0   : LA TAILLE SOUHAITE A L'ORIGINE 
C          XN   : LA TAILLE SOUHAITE A L'EXTREMITE
C          IERR: -1 SI ERREUR DANS LES DONNEES D'ENTREE
C     *****************************************************************
      INTEGER   ITYPE
      REAL      XD,X0,XN
      INTEGER   N,IERR
      REAL      R
C
       GOTO (10,20,30) ITYPE
         IERR = -1
         GO TO 999
C        --- SUITE GEOMETRIQUE ------------
   10    CALL SCSUGS(XD,N,R,X0,XN,IERR)
         GO TO 999
C        --- SUITE ARITHMETIQUE -----------
   20    CALL SCSUAS(XD,N,R,X0,XN,IERR)
         GO TO 999
C        --- SUITE HARMONIQUE -------------
   30    IERR = -4
C         PRINT *, ' A FAIRE '
         GO TO 999 
  999 END
C
      SUBROUTINE SU2PO(ITYPE,XD,X0,XN,N,R,IERR)
C     *****************************************************************
C     OBJET  SU2PO : CALCUL DE LA SUITE ENTRE 2 POINTS
C     EN ENTREE :
C         ITYPE : TYPE DE LA SUITE
C               (1=GEOMETRIQUE,2=ARITHMETIQUE,3=HARMONIQUE)
C          XD   : LA LONGUEUR DU SEGMENT
C          X0   : LA TAILLE SOUHAITE A L'ORIGINE
C          XN   : LA TAILLE SOUHAITE A L'EXTREMITE
C      EN SORTIE :
C           R     : LA RAISON DE LA SUITE GEOMETRIQUE
C           N     : LE NOMBRE DE NOEUDS
C           IERR: -1 SI ERREUR DANS LES DONNEES D'ENTREE
C     *****************************************************************
       INTEGER    ITYPE
       REAL       XD,X0,XN
       INTEGER    N,IERR
       REAL       R
C
       GOTO (10,20,30) ITYPE
         IERR = -1
         GO TO 999
C        --- SUITE GEOMETRIQUE ------------
   10    CALL SUG2PO(XD,X0,XN,N,R,IERR)
         GO TO 999
C        --- SUITE ARITHMETIQUE -----------
   20    CALL SUA2PO(XD,X0,XN,N,R,IERR)
         GO TO 999
C        --- SUITE HARMONIQUE -------------
   30    IERR = -4
C         PRINT *, ' A FAIRE '
         GO TO 999 
  999 END
C
C
      SUBROUTINE SUPTSU(X1,V1,IDIMC,ITYPE,T,N,R,XYZPT,IERR)
C     *****************************************************************
C      OBJET SUPTSU :  GENERE LES POINTS D'UNE SUITE
C      EN ENTREE :
C           X1    : LE POINT ORIGINE
C           V1    : LE VECTEUR DIRECT
C         IDIMC   : LA DIMENSION DE L'ESPACE
C            T    : VALEUR INITIALE
C            N    : NOMBRE DE SEGMENT APRES DECOUPAGE
C                   SI N = 1 ALORS XYZPT() = X1 + V1
C            R    : RAISON DE LA SUITE GEOMETRIQUE
C      EN SORTIE :
C         XYZPT   : COORDONNEES DES POINTS CALCULES
C         IERR    : -1 SI ERREUR DANS LES DONNEES D'ENTREE
C     *****************************************************************
      REAL       X1(*),V1(*),R,T,XYZPT(*)
      INTEGER    ITYPE,IDIMC,N,IERR
C
      GOTO (10,20,30) ITYPE
         IERR = -1
         GO TO 999
C        --- SUITE GEOMETRIQUE ------------
   10    CALL POSUG(X1,V1,IDIMC,T,N,R,XYZPT,IERR)
         GO TO 999
C        --- SUITE ARITHMETIQUE -----------
   20    CALL POSUA(X1,V1,IDIMC,T,N,R,XYZPT,IERR)
         GO TO 999
C        --- SUITE HARMONIQUE -------------
   30    IERR = -4
C         PRINT *, ' A FAIRE '
         GO TO 999
  999 END
C
C
      SUBROUTINE SCSUPO(ITYPE,TSP,RSG,D,VSD)
C     *****************************************************************
C     OBJET SCSUPO : VALEUR D'UNE SUITE EN UN POINT
C     EN ENTREE :
C         ITYPE  : TYPE DE LA SUITE
C                  (1=GEOMETRIQUE,2=ARITHMETIQUE,3=HARMONIQUE)
C         TSP    : LA TAILLE SOUHAITE AU POINT
C         RSG    : RAISON DE LA SUITE GEOMETRIQUE
C         D      : ABCISSE OU ON CHERCHE LA VALEUR DE LA SUITE
C      EN SORTIE :
C         VSD    : LA VALEUR DE LA SUITE A L'ABCISSE D
C     *****************************************************************
      INTEGER ITYPE
      REAL    D,TSP,RSG,VSD
C
      COMMON /CGEPSI/ XYZHUG,XYZMIN,XYZEPS
      REAL  XYZHUG,XYZMIN,XYZEPS
      INTEGER N
      REAL    VSC,A
      GOTO (10,20,30) ITYPE
         VSD = 0.0
         GO TO 999
C        --- SUITE GEOMETRIQUE ------------
C        D'OU CA SORT ?   10    VSD = (D*(RSG-1.)+TSP) / RSG
C   10    VSD = TSP - D*(1.- RSG)
   10    VSC = TSP + D*(RSG -1.)
C        remplace le 07.09.2006 par OS :
         IF( RSG.EQ.1 )THEN
           VSD = TSP
         ELSE
           A= (D/TSP)*(RSG-1)+1
           N = ( (LOG((D/TSP)*(RSG-1)+1)/LOG(RSG)) -XYZEPS)
           VSD = TSP * RSG**N
C           write (*,*) 'VSD= ',VSD,' VSC= ',VSC
         ENDIF
         GO TO 999
C        --- SUITE ARITHMETIQUE -----------
   20    VSD = RSG**2 + (8. * D + 4. * TSP)*RSG + 4.*TSP**2
         IF( VSD .LT. 0.0 )GOTO 999   
         VSD = (RSG + SQRT( VSD ))/2.
C         PRINT *, ' VSD ',VSD
         GO TO 999
C        --- SUITE HARMONIQUE -------------
   30    VSD = 0.0
C         PRINT *, ' A FAIRE '
         GO TO 999
  999 END
C
C
      SUBROUTINE POSUM(XP1,XP2,IDIMC,TS1,TS2,ITYPS,
     >                    XPI,NPIMAX,NBPI,IERR)
C     *****************************************************************
C      OBJET POSUM : GENERE LES POINTS D'UNE SUITE AVEC CALAGE
C      EN ENTREE :
C           XP1   : LE POINT ORIGINE
C           XP2   : LE POINT EXTREMITE
C         IDIMC   : LA DIMENSION DE L'ESPACE
C           TS1   : TAILLE SOUHAITE EN XP1
C           TS2   : TAILLE SOUHAITE EN XP2
C         ITYPS   : TYPE DE LA SUITE
C       NPIMAX   : NOMBRE MAXIMUM DE POINTS GENERES
C      EN SORTIE :
C           XPI   : COORDONNEES DES POINTS CALCULES
C          NBPI   : NOMBRE DE POINTS GENERES
C           TS1   : TAILLE REALISE EN XP1
C           TS2   : TAILLE REALISE EN XP2
C          IERR   :  0 SI OK
C                   -1 SI ERREUR DANS LES DONNEES D'ENTREE
C                   -2 SI XYZPT TROP PETIT
C     *****************************************************************
      REAL       XP1(*),XP2(*),TS1,TS2,XPI(*)
      INTEGER    ITYPS,NBPI,NPIMAX,IDIMC,IERR
C
      REAL     RSGCAL,V1(3),S12
      REAL     XNORVE
C      INTEGER  ITRACE
      EXTERNAL DIFFVE,DIPOOB,XNORVE
      EXTERNAL SU2PO,SUPTSU
C
      IERR = 0
C     --- CALCUL DE LA SUITE ------------------------------------
      CALL DIFFVE(XP2,XP1,IDIMC,V1)
      S12 = XNORVE(V1,IDIMC)
      CALL SU2PO(ITYPS,S12,TS1,TS2,NBPI,RSGCAL,IERR)
      IF( IERR .NE. 0 )GOTO 888
      IF( NBPI .LE. 0 )THEN
        NBPI = 0
        GOTO 999
      ENDIF
C     --- RECALALGE DES VALEURS TS1, TS2 ---      
      CALL SCSUSE(ITYPS,S12,NBPI,RSGCAL,TS1,TS2,IERR)
      IF( IERR .NE. 0 )GOTO 888
C
C     --- POUR LE DEBUG :
C
C      ITRACE = 0
C      IF(ITRACE.NE.0)PRINT *,'(T1,T2,NB,R)',TS1,TS2,NBPI,RSGCAL
C      CALL DEBSUSYM(ITYPS,S12,TS1,TS2,ITRACE,0.0,IERR) 
C      IF( IERR.NE. 0 )THEN
C       PRINT *,'ERREUR DANS DEDSUSYM'
C        GOTO 999
C      ENDIF     
C     --- FIN DEBUG -----
C
      IF( NBPI .GT. NPIMAX )THEN
        IERR = -2
        CALL DSERRE(1,IERR,'CG','DANS POSUM : TROP DE POINTS')
        GO TO 999
      ENDIF
      S12 = 1 / S12
      CALL MUSCVE(V1,S12,IDIMC,V1)
      CALL SUPTSU(XP1,V1,IDIMC,ITYPS,TS1,NBPI,RSGCAL,XPI,IERR)
C
  888 IF( IERR .NE. 0 )CALL DSERRE(1,IERR,'CG','DANS POSUM')
  999 END
C
      SUBROUTINE POSUNM(XP1,XPNUL,XP2,IDIMC,TS1,TSNUL,TS2,ITYPS,
     >                      XPI,NPIMAX,NBPI,IERR)
C     *****************************************************************
C      OBJET POSUNM : GENERE LES POINTS D'UNE SUITE NON MONOTONE
C                 AVEC CALAGE
C      EN ENTREE :
C           XP1   : LE POINT ORIGINE
C         XPNUL   : UN POINT SUR LE SEGMENT
C           XP2   : LE POINT EXTREMITE
C         IDIMC   : LA DIMENSION DE L'ESPACE
C           TS1   : TAILLE SOUHAITE EN XP1
C         TSNUL   : TAILLE SOUHAITE EN XPNUL
C           TS2   : TAILLE SOUHAITE EN XP2
C         ITYPS   : TYPE DE LA SUITE
C       NPIMAX   : NOMBRE MAXIMUM DE POINTS GENERES
C      EN SORTIE :
C           XPI   : COORDONNEES DES POINTS CALCULES
C          NBPI   : NOMBRE DE POINTS GENERES
C           TS1   : TAILLE REALISE EN XP1
C         TSNUL   : TAILLE REALISE EN XPNUL
C           TS2   : TAILLE REALISE EN XP2
C          IERR   :  0 SI OK
C                   -1 SI ERREUR DANS LES DONNEES D'ENTREE
C                   -2 SI XYZPT TROP PETIT
C     *****************************************************************
      REAL       XP1(*),XPNUL(*),XP2(*),TS1,TSNUL,TS2,XPI(*)
      INTEGER    ITYPS,NBPI,NPIMAX,IDIMC,IERR
C
      REAL     RSGCAL,V1(3),S12,S22,TSNUL2
      INTEGER  NBPI1,NBPI2,NIMAX2
      REAL     XNORVE
      EXTERNAL DIFFVE,XNORVE
      EXTERNAL SU2PO,SUPTSU
C
C
      IERR = 0
C         ----------------------------------
C     --- CALCUL DE LA SUITE SUR XP1, XPNUL ---------
C         ----------------------------------
      CALL DIFFVE(XPNUL,XP1,IDIMC,V1)
      S12 = XNORVE(V1,IDIMC)
C      WRITE(*,*) 'S12 = ',S12
      CALL SU2PO(ITYPS,S12,TSNUL,TS1,NBPI1,RSGCAL,IERR)
      IF( IERR .NE. 0 )GOTO 888
C         ----------------------------------
C     --- CALCUL DE LA SUITE SUR XPNUL, XP2 ---------
C         ----------------------------------
      CALL DIFFVE(XP2,XPNUL,IDIMC,V1)
      S22 = XNORVE(V1,IDIMC)
C      WRITE(*,*) 'S22 = ',S22
      CALL SU2PO(ITYPS,S22,TS1,TSNUL,NBPI2,RSGCAL,IERR)
C      ---- ???? ERREUR :  TSNUL,TS2,
C
      IF( IERR .NE. 0 )GOTO 888
      IF(( NBPI1 .GE. 0 ).AND.( NBPI2 .GE. 0 ))THEN
C           -------------------------------------
C       --- ON DECOUPE LE SEGMENT EN 2 INTERVALS ---  
C           -------------------------------------
        IF( (NBPI1+NBPI2+1) .GT. NPIMAX )THEN
          IERR = -2
          CALL DSERRE(1,IERR,'CG','DANS POSUNM : TROP DE POINTS')
          GO TO 999
        ENDIF
C       --- PREMIER INTERVAL ---
        NBPI = 0
        TSNUL2 = TSNUL
        CALL POSUM(XP1,XPNUL,IDIMC,TS1,TSNUL2,ITYPS,
     >                XPI,NPIMAX,NBPI,IERR)
        IF( IERR .NE. 0 )GOTO 888
C       --- BUG 7 ----
C       NE COPIER XPNUL QUE SI XP1-XPNUL ET XP2-XPNUL
C       SONT COMPATIBLE AVEC TSNUL
C
        IF(( S12.GE. TSNUL ).AND.( S22.GE.TSNUL ))THEN
          NBPI1 = NBPI+1
          CALL COPIVE(XPNUL,IDIMC,XPI((NBPI1-1)*IDIMC+1))
        ENDIF
C
C       --- DEUXIEME INTERVAL ---
        NBPI = 0
        NIMAX2 = NPIMAX - NBPI1 
        CALL POSUM(XPNUL,XP2,IDIMC,TSNUL,TS2,ITYPS,
     >                XPI(NBPI1*IDIMC+1),NIMAX2,NBPI,IERR)
        NBPI = NBPI + NBPI1
      ELSE
        IF(( NBPI1.LT. 0 ).AND.( NBPI2.LT. 0 ))THEN
C            ---------------------------
C         --- L'INTERVAL EST TROP PETIT ---
C            ---------------------------
          NBPI = 0
        ELSE
C            ------------------------------------
C         --- XP1 OU XP2 EST CONFONDU AVEC XPNUL ---
C            ------------------------------------
        CALL POSUM(XP1,XP2,IDIMC,TS1,TS2,ITYPS,
     >                XPI,NPIMAX,NBPI,IERR)
        ENDIF
      ENDIF
C
  888 IF( IERR .NE. 0 )CALL DSERRE(1,IERR,'CG','DANS POSUNM')
  999 END
C
C
C
      SUBROUTINE POSUNM2(XP1,XPNUL,NBX,XP2,IDIMC,TS1,TSNUL,TS2,ITYPS,
     >                      XPI,NPIMAX,NBPI,IERR)
C     *****************************************************************
C      OBJET POSUNM2 :  GENERE LES POINTS D'UNE SUITE NON MONOTONE
C                 AVEC CALAGE
C      EN ENTREE :
C           XP1   : LE POINT ORIGINE
C           XPNUL(NBX*IDIMC) : COORDONNEES DES NBX POINTS SUR LE SEGMENT
C           XP2   : LE POINT EXTREMITE
C         IDIMC   : LA DIMENSION DE L'ESPACE
C           TS1   : TAILLE SOUHAITE EN XP1
C         TSNUL   : TAILLE SOUHAITE AUX POINTS DE XPNUL
C           TS2   : TAILLE SOUHAITE EN XP2
C         ITYPS   : TYPE DE LA SUITE
C       NPIMAX   : NOMBRE MAXIMUM DE POINTS GENERES
C
C      EN SORTIE :
C           XPI   : COORDONNEES DES POINTS CALCULES
C          NBPI   : NOMBRE DE POINTS GENERES
C           TS1   : TAILLE REALISE EN XP1
C         TSNUL   : TAILLE REALISE AUX POINTS DE XPNUL
C           TS2   : TAILLE REALISE EN XP2
C          IERR   :  0 SI OK
C                   -1 SI ERREUR DANS LES DONNEES D'ENTREE
C                   -2 SI XYZPT TROP PETIT
C     *****************************************************************
      REAL       XP1(*),XPNUL(*),XP2(*),TS1,TSNUL(*),TS2,XPI(*)
      INTEGER    NBX,ITYPS,NBPI,NPIMAX,IDIMC,IERR
C
      REAL     RSGCAL,V1(3),V2(3),XV1,XV2,S12,S22
      REAL     XPS(3*6),TSXPS(6)
      INTEGER  NBS,I,J,II
      INTEGER  NBPI1,NBPI2,NIMAX2
      REAL     XNORVE,SCALVE
      EXTERNAL XNORVE,SCALVE
C
      COMMON /CGEPSI/ XYZHUG,XYZMIN,XYZEPS,XYZHU2,XYZMI2
      REAL  XYZHUG,XYZMIN,XYZEPS,XYZHU2,XYZMI2
C
      IERR = 0
C     ---- 1. decoupage du segment XP1,XP2 par les XPNUL ----
C         -----------------------------------------------
      CALL COPIVE(XP1,IDIMC,XPS)
      CALL COPIVE(XP2,IDIMC,XPS(IDIMC+1))
      TSXPS(1) = TS1
      TSXPS(2) = TS2
      NBS = 2
C     --- on ajoute les points sur le segment XP1,XP2
      DO 100 I=1,NBX
        J=1
   10   CONTINUE
C       --- situer XPNUL sur le segment
        CALL DIFFVE(XPNUL((I-1)*IDIMC+1),XPS((J-1)*IDIMC+1),IDIMC,V1)
        CALL DIFFVE(XPS(J*IDIMC+1)      ,XPS((J-1)*IDIMC+1),IDIMC,V2)
        XV1  = SCALVE(V2,V1,IDIMC)
        XV2  = SCALVE(V2,V2,IDIMC)
        IF(XV1.LT.-XYZEPS*XV2)GOTO 901
        IF( XV1.GT.XV2*(1.+XYZEPS) )THEN
          J=J+1
          IF(J.LT.NBS)GOTO 10
        ENDIF
        IF(J.GT.NBS)GOTO 901
C       --- XPS(J) < XPNUL(I) < XPS(J+1) ---
        S12 = XNORVE(V1,IDIMC)
        CALL SU2PO(ITYPS,S12,TSNUL(I),TSXPS(J),NBPI1,RSGCAL,IERR)
        IF( IERR .NE. 0 )GOTO 902
        CALL DIFFVE(XPS(J*IDIMC+1),XPNUL((I-1)*IDIMC+1),IDIMC,V1)
        S22 = XNORVE(V1,IDIMC)
        CALL SU2PO(ITYPS,S22,TSXPS(J+1),TSNUL(I),NBPI2,RSGCAL,IERR)
        IF( IERR .NE. 0 )GOTO 902
        IF(( NBPI1 .GT. 0 ).AND.( NBPI2 .GT. 0 ))THEN
C       --- on ajoute XPNUL au decoupage du segment
          DO 50 II=NBS,J+1,-1
            CALL COPIVE(XPS((II-1)*IDIMC+1),IDIMC,XPS(II*IDIMC+1))
            TSXPS(II+1) = TSXPS(II) 
   50     CONTINUE
          CALL COPIVE(XPNUL((I-1)*IDIMC+1),IDIMC,XPS(J*IDIMC+1))
          TSXPS(J+1) = TSNUL(I) 
          NBS=NBS+1
        ENDIF
  100 CONTINUE
C
C     ---- 2. generation des points sur les segments ----
C         -----------------------------------------------
C      WRITE (*,*) 'segment : ',(XP1(II),II=1,IDIMC),' a ',
C     >                         (XP2(II),II=1,IDIMC)
      NBPI = 0
      DO 200 J=1,NBS-1
C        WRITE (*,*) 'intervalle : ',J,' ',(XPS(J*IDIMC+II),II=1,IDIMC)
        NIMAX2 = NPIMAX - NBPI
        NBPI1 = 0
        CALL POSUM(XPS((J-1)*IDIMC+1),XPS(J*IDIMC+1),IDIMC,
     >             TSXPS(J), TSXPS(J+1), ITYPS,
     >             XPI(NBPI*IDIMC+1),NIMAX2,NBPI1,IERR)
        IF( IERR.NE.0 )GOTO 903
        NBPI = NBPI + NBPI1
        IF(J.NE.NBS-1)THEN
          NBPI = NBPI+1
          CALL COPIVE(XPS(J*IDIMC+1),IDIMC,XPI((NBPI-1)*IDIMC+1))
        ENDIF
  200 CONTINUE
C
      GOTO 9999
  901 CONTINUE
      IERR = -1
      CALL DSERRE(1,IERR,'POSUNM2','POINT XPNUL HORS SEGMENT')
      GO TO 9999
  902 CONTINUE
      IERR = -1
      CALL DSERRE(1,IERR,'POSUNM2','APPEL SU2PO ?')
      GO TO 9999
  903 CONTINUE
      IERR = -1
      CALL DSERRE(1,IERR,'POSUNM2','APPEL POSUM')
      GO TO 9999
C
 9999 END
C
C
C
      SUBROUTINE LISUPO(XP1,XP2,XP3,IDIMC,ITYPS,RSG,XP2N,DEPLAC,IERR)
C     *****************************************************************
C     OBJET LISUPO :  REGULARISE LA POSITION DE XP2 ENTRE XP1 ET XP3
C     EN ENTREE :
C         XP2     : LA POSITION A REGULARISER
C         XP1,XP3 : L'INTERVAL CONTENANT XP2
C         IDIMC   : DIMENSION DE L'ESPACE
C         ITYPS   : TYPE DE LA SUITE
C         RSG     : RAISON DE LA SUITE
C     EN SORTIE :
C         XP2N    : NOUVELLE POSITION DE XP2
C         DEPLAC  : NORME DU DEPLACEMENT RELATIF
C         IERR    : -1 SI ERREUR 0 SI OK
C     *****************************************************************
      INTEGER IDIMC,ITYPS,IERR
      REAL    XP1(*),XP2(*),XP3(*),RSG
      REAL    XP2N(*),DEPLAC
C
      REAL     V(3),D,D12,D23,COEF, XNORVE,ZERO
      PARAMETER (ZERO = 1.E-10)
      EXTERNAL XNORVE
C
      IERR = 0
      IF( RSG .LE. ZERO )THEN
        IERR = -1
        CALL DSERRE(1,IERR,'LISUPO','RAISON NEGATIVE OU NULLE')
        GOTO 9999
      ENDIF
      DEPLAC = 0.0
      CALL COPIVE(XP2,IDIMC,XP2N)
      CALL DIFFVE(XP2,XP1,IDIMC,V )
      D12 = XNORVE(V,IDIMC)
      CALL DIFFVE(XP3,XP2,IDIMC,V )
      D23 = XNORVE(V,IDIMC)
      IF( D23 .LE. ZERO )THEN
        IERR = -1
        CALL DSERRE(1,IERR,'LISUPO','SEGMENT NUL')
        GOTO 9999
      ENDIF
      D = 1. / D23
      CALL MUSCVE(V,D,IDIMC, V)
      GOTO(10,20) ITYPS
      IERR = -1
      CALL DSERRE(1,IERR,'LISUPO','TYPE DE SUITE INCONNU')
      GOTO 9999
C     --- SUITE GEOMETRIQUE ---
   10 IF(((D12/D23).LT.RSG).AND.((D23/D12).LT.RSG))GOTO 9999
      IF( D12.GT.D23 )THEN
        COEF =  ( RSG*D23 - D12 ) / ( RSG + 1.0 )
      ELSE
        COEF =  ( -RSG*D12 + D23 ) / ( RSG + 1.0 )
      ENDIF
      GOTO 30
C     --- SUITE ARITHMETIQUE ---
   20 IF(((D12-D23).LT.RSG).AND.((D23-D12).LT.RSG))GOTO 9999
      COEF = ( RSG + D23 - D12 ) * 0.5
      GOTO 30
C
   30 CALL MUSCVE(V,COEF,IDIMC,V)
      CALL SOMMVE(XP2,V,IDIMC,XP2N)
      DEPLAC = 2. * COEF / (D12 + D23)
      IF( DEPLAC .LT. 0.0 )DEPLAC = -DEPLAC
C      PRINT *,' DEPLACEMENT RELATIF =',DEPLAC
C
 9999 END
C

C     *****************************************************************
C     MODULE  : CG (CALCUL GEOMETRIQUE)
C     FICHIER : CG_TRIANGLE.F
C     OBJET   : CALCUL DE LA QUALITE D'UN TRIANGLE 2D
C     FONCT.  : 
C     OBJET TRRIL  : RENVOI RI / L DU TRIANGLE 2D
C     OBJET TRLL   : CALCUL L'ARETE MIN. ET L'ARETE MAX. DU TRIANGLE 2D
C     OBJET TRLL2  : CALCUL L'ARETE MIN. ET L'ARETE MAX. DU TRIANGLE
C     OBJET TRLSL2 : RAPPORT MIN/MAX DES LONGUEURS DES ARETES 
C     OBJET TRLAG2 : SINUS MINIMUM DES ANGLES DU TRIANGLE
C     OBJET TRLRC2 : LMAX / RAYON DU CERCLE CIRC. AU TRIANGLE
C     OBJET TRSURF : RENVOI LA SURFACE DU TRIANGLE
C     OBJET TRNORM : RENVOI LA NORMALE ET LA SURFACE DU TRIANGLE
C     OBJET TRRIL2 : RENVOI RI / L DU TRIANGLE
C     OBJET TRAGSO : RENVOI L'ANGLE AU SOMMET D'UN TRIANGLE
C
C     AUTEUR  : O. STAB
C     DATE    : 03.95
C     MODIFICATIONS :
C      AUTEUR, DATE, OBJET : STAB, 12.97, DE NOMBREUX AJOUTS
C      AUTEUR, DATE, OBJET : STAB, 02.03, AJOUTS AGSICO,TRAGSO
C
C     *****************************************************************
C
      SUBROUTINE AGSICO(VASIN,VACOS,ANGLE)
C     *****************************************************************
C     OBJET AGSICO : RENVOI LA VALEUR DE L'ANGLE (EN DEGREES [0.360])
C                    ATTENTION : PAS D'ORIENTATION = FABS(ANGLE)
C     *****************************************************************
      REAL VASIN,VACOS
      REAL ANGLE
C
      REAL VAPI,RAD2DG
C
      VAPI = 3.14159265
      RAD2DG = 180.0 / VAPI
C     ---- ASIN -> [-Pi/2,Pi/2] ----
      ANGLE = ASIN( VASIN ) 
      IF( VACOS.LT.0.0)ANGLE = VAPI - ANGLE    
      ANGLE = ANGLE * RAD2DG
      IF( ANGLE.LT.0 ) ANGLE = -ANGLE
 9999 END
C
      FUNCTION TRAGSO(XP1,XP2,XP3,IDIMC)
C     *****************************************************************
C     OBJET TRAGSO : RENVOI L'ANGLE AU SOMMET D'UN TRIANGLE
C                    L'ANGLE ENTRE LES ARETES  XP1XP2-XP1XP3 
C
C     EN ENTREE : XP1, XP2, XP3 : LES COORDONNEES DES 3 POINTS
C     EN SORTIE : SINUS DE L'ANGLE DU TRIANGLE EN XP1
C     REMARQUE  : A1 = ARCSIN( 2*S / L12 * L13 )   
C     *****************************************************************
      REAL TRAGSO
      REAL XP1(*),XP2(*),XP3(*)
      INTEGER IDIMC
C
      REAL     V12(3),V13(3),L12,L13,XPROD,SURF,PRSCAL,PRVECT
      REAL     COSANG,SINANG,ANGLE
      EXTERNAL SCALVE,XNORVE
      REAL     SCALVE,XNORVE
C
      CALL DIFFVE(XP2,XP1,IDIMC,V12)
      L12 = XNORVE(V12,IDIMC)
      XPROD = L12
C      CALL DIFFVE(XP1,XP3,IDIMC,V13)
      CALL DIFFVE(XP3,XP1,IDIMC,V13)
      L13 = XNORVE(V13,IDIMC)
      XPROD = XPROD * L13
      CALL VECTVE(V12,V13,IDIMC,PRVECT)
      PRSCAL = SCALVE(V12,V13,IDIMC)
      SURF = 0.5 * PRVECT
      SINANG = PRVECT / XPROD
      COSANG = PRSCAL / XPROD
      CALL AGSICO(SINANG,COSANG,ANGLE)
      TRAGSO = ANGLE       
 9999 END
C
C
      FUNCTION TRRIL(P1,P2,P3)
C     *****************************************************************
C     OBJET TRRIL : RENVOI RI / L DU TRIANGLE 2D
C      RI = LE RAYON DU CERCLE INSCRIT 
C      L  = L'ARETE LA PLUS LONGUE. 
C
C     EN ENTREE :
C       P1, P2, P3 : LES COORDONNEES DES 3 POINTS
C
C     FORMULE :
C      RIL = SURFACE / (DEMI PERIMETRE * ARETE LA PLUS LONGUE)
C     *****************************************************************
      REAL TRRIL
      REAL P1(*),P2(*),P3(*)
C
      REAL        COEF3
C     --- COEF3 = SQRT(3)/2 ------------
C      DATA COEF3/.86602540378443864676/
C     --- COEF3 = SQRT(3) ------------
      REAL       XV(3),YV(3),S,P,D,DMAX
      INTEGER    I
C
      COEF3 = 1.73205080756887729352
      TRRIL = 0.0
      XV(1) = P2(1) - P1(1) 
      YV(1) = P2(2) - P1(2) 
      XV(2) = P3(1) - P2(1) 
      YV(2) = P3(2) - P2(2) 
      XV(3) = P1(1) - P3(1) 
      YV(3) = P1(2) - P3(2) 
      S = (XV(1) *  YV(2)) - ( XV(2) * YV(1) )   
      IF( S.LT.0.0 )GOTO 999
      P = 0.0
      DMAX = 0.0
      DO 10 I=1,3
        D = XV(I)**2 + YV(I)**2
        D = SQRT(D)
        IF( D .GT. DMAX )DMAX = D
        P = P + D
   10 CONTINUE 
      TRRIL = ((2. * COEF3 * S) / ( P * DMAX ))    
  999 END
C
      SUBROUTINE TRLL(XP1,XP2,XP3,DMIN,DMAX)
C     *****************************************************************
C     OBJET TRLL : CALCUL L'ARETE MIN. ET L'ARETE MAX. DU TRIANGLE 2D
C
C     EN ENTREE :
C       XP1, XP2, XP3 : LES COORDONNEES DES 3 POINTS
C
C     EN SORTIE :
C       DMIN : LONGUEUR DE L'ARETE LA PLUS COURTE
C       DMAX : LONGUEUR DE L'ARETE LA PLUS LONGUE
C     *****************************************************************
      REAL XP1(*),XP2(*),XP3(*),DMIN,DMAX
C
      REAL     V(3),D
      EXTERNAL XNORVE
      REAL     XNORVE
      INTEGER IDIMC
C
      IDIMC = 2
      CALL DIFFVE(XP2,XP1,IDIMC,V)
      DMIN = XNORVE(V,IDIMC)
      DMAX = DMIN
      CALL DIFFVE(XP3,XP2,IDIMC,V)
      D = XNORVE(V,IDIMC)
      DMIN = MIN( D, DMIN )
      DMAX = MAX( D, DMAX )
      CALL DIFFVE(XP1,XP3,IDIMC,V)
      D = XNORVE(V,IDIMC) 
      DMIN = MIN( D, DMIN )
      DMAX = MAX( D, DMAX )
  999 END
C
C
      SUBROUTINE TRLL2(XP1,XP2,XP3,IDIMC,XLMIN,XLMAX)
C     *****************************************************************
C     OBJET TRLL2 : CALCUL L'ARETE MIN. ET L'ARETE MAX. DU TRIANGLE
C
C     EN ENTREE :
C       XP1, XP2, XP3 : LES COORDONNEES DES 3 POINTS
C
C     EN SORTIE :
C       XLMIN : LONGUEUR DE L'ARETE LA PLUS COURTE
C       XLMAX : LONGUEUR DE L'ARETE LA PLUS LONGUE
C     *****************************************************************
      REAL XP1(*),XP2(*),XP3(*),XLMIN,XLMAX
      INTEGER IDIMC
C
      REAL     V(3),D
      EXTERNAL XNORVE
      REAL     XNORVE
C
      CALL DIFFVE(XP2,XP1,IDIMC,V)
      XLMIN = XNORVE(V,IDIMC)
      XLMAX = XLMIN
      CALL DIFFVE(XP3,XP2,IDIMC,V)
      D = XNORVE(V,IDIMC)
      XLMIN = MIN( D, XLMIN )
      XLMAX = MAX( D, XLMAX )
      CALL DIFFVE(XP1,XP3,IDIMC,V)
      D = XNORVE(V,IDIMC) 
      XLMIN = MIN( D, XLMIN )
      XLMAX = MAX( D, XLMAX )
  999 END
C
C
      FUNCTION TRLMIN(XP1,XP2,XP3,IDIMC)
C     *****************************************************************
C     OBJET TRLL2 : CALCUL L'ARETE MIN DU TRIANGLE
C
C     EN ENTREE :
C       XP1, XP2, XP3 : LES COORDONNEES DES 3 POINTS
C
C     EN SORTIE :
C       XLMIN : LONGUEUR DE L'ARETE LA PLUS COURTE
C     *****************************************************************
      REAL TRLMIN
      REAL XP1(*),XP2(*),XP3(*)
      INTEGER IDIMC
C
      REAL     V(3),D,XLMIN
      EXTERNAL XNORVE
      REAL     XNORVE
C
      CALL DIFFVE(XP2,XP1,IDIMC,V)
      XLMIN = XNORVE(V,IDIMC)
      CALL DIFFVE(XP3,XP2,IDIMC,V)
      D = XNORVE(V,IDIMC)
      XLMIN = MIN( D, XLMIN )
      CALL DIFFVE(XP1,XP3,IDIMC,V)
      D = XNORVE(V,IDIMC) 
      XLMIN = MIN( D, XLMIN )
      TRLMIN = XLMIN
  999 END
C
C
      FUNCTION TRLSL2(XP1,XP2,XP3,IDIMC)
C     *****************************************************************
C     OBJET TRLSL2 : RAPPORT MIN/MAX DES LONGUEURS DES ARETES 
C
C     EN ENTREE :
C       XP1, XP2, XP3 : LES COORDONNEES DES 3 POINTS
C
C     EN SORTIE :
C     *****************************************************************
      REAL TRLSL2
      REAL XP1(*),XP2(*),XP3(*)
      INTEGER IDIMC
C
      REAL     V(3),D,XLMIN,XLMAX
      EXTERNAL XNORVE
      REAL     XNORVE
C
      CALL DIFFVE(XP2,XP1,IDIMC,V)
      XLMIN = XNORVE(V,IDIMC)
      XLMAX = XLMIN
      CALL DIFFVE(XP3,XP2,IDIMC,V)
      D = XNORVE(V,IDIMC)
      XLMIN = MIN( D, XLMIN )
      XLMAX = MAX( D, XLMAX )
      CALL DIFFVE(XP1,XP3,IDIMC,V)
      D = XNORVE(V,IDIMC) 
      XLMIN = MIN( D, XLMIN )
      XLMAX = MAX( D, XLMAX )
      TRLSL2 = XLMIN / XLMAX
 9999 END
C
C
      FUNCTION TRLAG2(XP1,XP2,XP3,IDIMC)
C     *****************************************************************
C     OBJET TRLAG2 : SINUS MINIMUM DES ANGLES DU TRIANGLE
C
C     EN ENTREE :
C       XP1, XP2, XP3 : LES COORDONNEES DES 3 POINTS
C
C     EN SORTIE :
C     REMARQUE  : TETA = ARCSIN( 2*S*LMIN / A*B*C )
C                 ( ON A AUSSI : TETA = ARCSIN( LMIN / RC ) )
C     *****************************************************************
      REAL TRLAG2
      REAL XP1(*),XP2(*),XP3(*)
      INTEGER IDIMC
C
C
      REAL     V12(3),V23(3),V(3),D,XLMIN,XPROD,SURF
      EXTERNAL XNORVE
      REAL     XNORVE
C
      CALL DIFFVE(XP2,XP1,IDIMC,V12)
      XLMIN = XNORVE(V12,IDIMC)
      XPROD = XLMIN
      CALL DIFFVE(XP3,XP2,IDIMC,V23)
      D = XNORVE(V23,IDIMC)
      XPROD = XPROD * D
      XLMIN = MIN( D, XLMIN )
      CALL DIFFVE(XP1,XP3,IDIMC,V)
      D = XNORVE(V,IDIMC) 
      XPROD = XPROD * D
      XLMIN = MIN( D, XLMIN )
C
      CALL VECTVE(V12,V23,IDIMC,V)
      IF( IDIMC.EQ.3 )THEN
        SURF = 0.5 * XNORVE(V,IDIMC)
      ELSE
        SURF = 0.5 * V(1)
      ENDIF
      TRLAG2 = (2.0 * XLMIN * SURF) / XPROD
C
 9999 END
C
C
      FUNCTION TRLRC2(P1,P2,P3,IDIMC)
C     *****************************************************************
C     OBJET TRLRC2 : LMAX / RAYON DU CERCLE CIRC. AU TRIANGLE
C
C     EN ENTREE :
C       P1, P2, P3 : LES COORDONNEES DES 3 POINTS
C
C     FORMULE :
C      TTLRC = 0.5 * L/RC 
C      RC    = ABC / 4S
C     *****************************************************************
      REAL    TRLRC2
      REAL    P1(*),P2(*),P3(*)
      INTEGER IDIMC
C
      REAL     XLMAX,RSC,V(3),V12(3),V23(3),D,S
      EXTERNAL NULLVE,XNORVE
      INTEGER  NULLVE
      REAL     XNORVE
C
      TRLRC2 = 0.0
      XLMAX   = 0.0
      RSC    = 1.0
      CALL DIFFVE(P2,P1,IDIMC,V12)
      D = XNORVE(V12,IDIMC) 
      XLMAX = MAX(D,XLMAX)
      RSC = D * RSC

      CALL DIFFVE(P3,P2,IDIMC,V23)
      D = XNORVE(V23,IDIMC) 
      XLMAX = MAX(D,XLMAX)
      RSC = D * RSC

      CALL DIFFVE(P1,P3,IDIMC,V)
      D = XNORVE(V,IDIMC) 
      XLMAX = MAX(D,XLMAX)
      RSC = D * RSC

      CALL VECTVE(V12,V23,IDIMC,V)
      IF( IDIMC.EQ.3 )THEN
        S = 0.5 * XNORVE(V,IDIMC)
      ELSE
        S = 0.5 * V(1)
      ENDIF
C      PRINT *,'SURFACE = ',S

      IF( NULLVE(RSC,1).EQ.1 )GOTO 9999
      TRLRC2 = 2.0 * S * XLMAX / RSC
C      PRINT *,' LRC = ',TRLRC2 
 9999 END
C
C
      FUNCTION TRCIRC(P1,P2,P3,IDIMC)
C     *****************************************************************
C     OBJET TRCIRC : RAYON DU CERCLE CIRCONSCRIT AU TRIANGLE
C
C     EN ENTREE :
C       P1, P2, P3 : LES COORDONNEES DES 3 POINTS
C
C     FORMULE :
C      RC    = ABC / 4S
C     *****************************************************************
      REAL    TRCIRC
      REAL    P1(*),P2(*),P3(*)
      INTEGER IDIMC
C
      REAL     RSC,V(3),V12(3),V23(3),D,S
      EXTERNAL NULLVE,XNORVE
      INTEGER  NULLVE
      REAL     XNORVE
C
      TRCIRC = 0.0
      RSC    = 1.0
      CALL DIFFVE(P2,P1,IDIMC,V12)
      D = XNORVE(V12,IDIMC) 
      RSC = D * RSC
      CALL DIFFVE(P3,P2,IDIMC,V23)
      D = XNORVE(V23,IDIMC) 
      RSC = D * RSC
      CALL DIFFVE(P1,P3,IDIMC,V)
      D = XNORVE(V,IDIMC) 
      RSC = D * RSC

      CALL VECTVE(V12,V23,IDIMC,V)
      IF( IDIMC.EQ.3 )THEN
        S = 0.5 * XNORVE(V,IDIMC)
      ELSE
        S = 0.5 * V(1)
      ENDIF
C      PRINT *,'SURFACE = ', S
      IF( NULLVE(RSC,1).EQ.1 )GOTO 9999
      TRCIRC = RSC / (4. * S)
 9999 END
C
C
      FUNCTION TRSURF(P1,P2,P3,IDIMC)
C     *****************************************************************
C     OBJET TRSURF : RENVOI LA SURFACE DU TRIANGLE
C
C     EN ENTREE :
C       P1, P2, P3 : LES COORDONNEES DES 3 POINTS
C
C     FORMULE :
C      SURFACE = 0.5 * || V12 ^ V23  ||
C     *****************************************************************
      REAL TRSURF
      INTEGER IDIMC
      REAL P1(*),P2(*),P3(*)
C
      REAL      V(3,3),v123(3),UNDEMI
      EXTERNAL  XNORVE
      REAL      XNORVE
C
      UNDEMI = 0.5
      CALL DIFFVE(P2,P1,IDIMC,V(1,1))
      CALL DIFFVE(P3,P2,IDIMC,V(1,2))
      CALL VECTVE(V(1,1),V(1,2),IDIMC,V123)
C     ---- BUG_33.A : O.STAB, 17.10.97 : ERREUR SUR HP AVEC OPTION (+T) ----
      IF( IDIMC.EQ. 2 )THEN
        TRSURF = UNDEMI * SQRT(V123(1)*V123(1))
      ELSE
        TRSURF = UNDEMI * XNORVE(V123,IDIMC)
      ENDIF
C
 9999 END
C
C
      SUBROUTINE TRNORM(P1,P2,P3,IDIMC,SURF,XNORM,IERR)
C     *****************************************************************
C     OBJET TRNORM : RENVOI LA NORMALE ET LA SURFACE DU TRIANGLE
C
C     EN ENTREE :
C       P1, P2, P3 : LES COORDONNEES DES 3 POINTS
C
C     FORMULE :
C      SURF  = 0.5 * || V12 ^ V23  ||
C      XNORM = V12 ^ V23 / (2*SURF)
C     *****************************************************************
      INTEGER IDIMC
      REAL    P1(*),P2(*),P3(*)
      REAL    SURF,XNORM(*)
      INTEGER IERR
C
      REAL      V(3,2),X
      EXTERNAL  XNORVE,NULLVE
      REAL      XNORVE
      INTEGER   NULLVE
C
      CALL DIFFVE(P2,P1,IDIMC,V(1,1))
      CALL DIFFVE(P3,P2,IDIMC,V(1,2))
      CALL VECTVE(V(1,1),V(1,2),IDIMC,XNORM)
      SURF =  XNORVE(XNORM,IDIMC)
      IF( NULLVE( SURF, 1 ).EQ.1 )THEN
        IERR = -1
        SURF = 0.0
        GOTO 9999
      ENDIF
      X = 1.0 / SURF
      SURF = 0.5 * SURF
      CALL MUSCVE( XNORM,X,IDIMC,XNORM )
      IERR = 0
C
 9999 END
C
C
      FUNCTION TRRIL2(P1,P2,P3,IDIMC)
C     *****************************************************************
C     OBJET TRRIL2 : RENVOI RI / L DU TRIANGLE
C      RI = LE RAYON DU CERCLE INSCRIT 
C      L  = L'ARETE LA PLUS LONGUE. 
C
C     EN ENTREE :
C       P1, P2, P3 : LES COORDONNEES DES 3 POINTS
C
C     FORMULE :
C      RIL = SQRT(3) * SURFACE / (DEMI PERIMETRE * ARETE LA PLUS LONGUE)
C     *****************************************************************
      REAL TRRIL2
      INTEGER IDIMC
      REAL P1(*),P2(*),P3(*)
C
      REAL        COEF3
      EXTERNAL    TRRIL
      REAL        TRRIL      
      REAL       V(3,3),v123(3),S,P,D,XLMAX,UNDEMI
      INTEGER    I
      INTEGER   NULLVE
      EXTERNAL  XNORVE,NULLVE
      REAL      XNORVE
C
      IF( IDIMC.EQ. 2 )THEN
        TRRIL2 = TRRIL(P1,P2,P3)
        GOTO 999
      ENDIF
      UNDEMI = 0.5
C     --- COEF3 = SQRT(3) ------------
      COEF3  = 1.73205080756887729352
      TRRIL2 = 0.0
      CALL DIFFVE(P2,P1,IDIMC,V(1,1))
      CALL DIFFVE(P3,P2,IDIMC,V(1,2))
      CALL DIFFVE(P1,P3,IDIMC,V(1,3))
      CALL VECTVE(V(1,1),V(1,2),IDIMC,V123)
      S = UNDEMI * XNORVE(V123,IDIMC)
      IF( NULLVE(S,1).EQ. 1)GOTO 999
C      IF( S.LT.0.0 )GOTO 999
      P = 0.0
      XLMAX = 0.0
      DO 10 I=1,3
        D = XNORVE(V(1,I),IDIMC)
        IF( D .GT. XLMAX )XLMAX = D
        P = P + D
   10 CONTINUE 
      TRRIL2 = ((4. * COEF3 * S) / ( P * XLMAX ))    
  999 END
C
C     *****************************************************************
C     MODULE  : CG (CALCUL GEOMETRIQUE)
C     FICHIER : cg_volume.F
C     OBJET   : CALCUL DU VOLUME D'UN POLYEDRE (TRIANGULATION)
C     FONCT.  : 
C
C     AUTEUR  : O. STAB
C     DATE    : 04.07
C     MODIFICATIONS :
C      AUTEUR, DATE, OBJET :
C
C     *****************************************************************
C
      FUNCTION PRMIXT(P1,P2,P3,P4)
C     *****************************************************************
C     OBJET PRMXT : PRODUIT MIXTE
C
C     EN ENTREE :
C       P1, P2, P3, P4 : LES COORDONNEES DES 4 POINTS
C
C     FORMULE :
C      PRODUIT MIXTE
C     *****************************************************************
      REAL PRMIXT
      REAL P1(*),P2(*),P3(*),P4(*)
C
      REAL     V12(3),V13(3),V14(3),V123(3)
      INTEGER  IDIMC
      EXTERNAL SCALVE
      REAL     SCALVE
C
      IDIMC = 3
      CALL DIFFVE(P2,P1,IDIMC,V12)
      CALL DIFFVE(P3,P2,IDIMC,V13)
      CALL VECTVE(V12,V13,IDIMC,V123)
      CALL DIFFVE(P4,P3,IDIMC,V14)
      PRMIXT = SCALVE(V123,V14,IDIMC)
 9999 END
C
      FUNCTION TRIVOL(P1,P2,P3,K)
C     *****************************************************************
C     OBJET TRIVOL : RENVOI LE VOLUME ELEMENTAIRE ENTRE LE TRIANGLE ET LE PLAN
C
C     EN ENTREE :
C       P1, P2, P3 : LES COORDONNEES DES 3 POINTS
C       K : 3 plan XOY, 2 plan XOZ, 1 plan YOZ 
C
C     FORMULE :
C      TRIVO = VOLUME( 2 TETRAEDRE + PRISME )
C     *****************************************************************
      REAL TRIVOL
      REAL P1(*),P2(*),P3(*)
      INTEGER K
C
      EXTERNAL PRMIXT
      REAL     PRMIXT
      INTEGER IKI,I
      REAL VKV,P1B(3),P2B(3),P3B(3),P10(3),VOLT1,VOLT2,VOP,UNSIX
      UNSIX = .16666666666666666666
C     recherche du point minimisant Xk
      IKI = 1
      VKV = P1(K)
      IF( P2(K).LT.VKV )THEN
        IKI=2
        VKV=P2(K)
      ENDIF
      IF( P3(K).LT.VKV )THEN
        IKI=3
        VKV=P3(K)
      ENDIF
C     copie des points de la base
      DO 5 I=1,3
        P10(I)=P1(I)
        P1B(I)=P1(I)
        P2B(I)=P2(I)
        P3B(I)=P3(I)
    5 CONTINUE
      P10(K)= 0.0
      P1B(K)=VKV
      P2B(K)=VKV
      P3B(K)=VKV
      GOTO(10,20,30) IKI
   10 CONTINUE
      VOLT1 = UNSIX*PRMIXT(P1B,P2B,P3B,P2)
      VOLT2 = UNSIX*PRMIXT(P1B,P2 ,P3B,P3)
      GOTO 100
   20 CONTINUE
      VOLT1 = UNSIX*PRMIXT(P1B,P2B,P3B,P3)
      VOLT2 = UNSIX*PRMIXT(P3 ,P1B,P2B,P1)
      GOTO 100
   30 CONTINUE
      VOLT1 = UNSIX*PRMIXT(P1B,P2B,P3B,P1)
      VOLT2 = UNSIX*PRMIXT(P1 ,P2B,P3B,P2)
      GOTO 100
  100 CONTINUE
      VOP = PRMIXT(P1B,P2B,P3B,P10)      
C      WRITE(*,*) 'VOL   = ',VOP 
C      WRITE(*,*) 'VOLT1 = ',VOLT1
C      WRITE(*,*) 'VOLT2 = ',VOLT2
      TRIVOL = VOP + VOLT1+VOLT2
 9999 END
C     *****************************************************************
C     MODULE  : CG (CALCUL GEOMETRIQUE)
C     FICHIER : CG_MLT.F
C     OBJET   : SPHERE EN 3D
C     FONCT.  : 
C     OBJET SPTTUT : SPHERE CIRCONSCRITE A UN TETRAEDRE
C     OBJET SL33UT : SYSTEME LINEAIRE AX=B  (3x3)
C     OBJET MIXTUT : SYSTEME LINEAIRE AX=B  (3x3) ET DETERMINANT
C     OBJET SLDTUT : A.(B^C) = PRODUIT MIXTE (DETERMINANT DE 3 COLONNES)
C     OBJET VECTUT : C=A^B  PRODUIT VECTORIEL
C     OBJET SCALUT : PRODUIT SCALAIRE 
C
C     AUTEUR  : S.M.TIJANI
C     DATE    : 03.95 / 04.97
C     MODIFICATIONS :
C      AUTEUR, DATE, OBJET : O.STAB, 95, MISE A LA NORME
C
C     REMARQUE : A FAIRE = OPTIMISATION IN-LINE DANS SPTTUT 
C                ET EVITER LES DOUBLONS VECT SCAL... 
C                METTRE UN PRODUIT MIXTE DANS CG_VECTORIEL ?
C     *****************************************************************
C
C
      SUBROUTINE SPTTUT(N,X,CC)
C     *************************************************************
C     OBJET SPTTUT : SPHERE CIRCONSCRITE A UN TETRAEDRE
C     EN ENTREE: 
C            N : TABLEAU DES 4 NOEUDS DU TETRAEDRE
C            X : COORDONNEES DES NOEUDS (2 DIMENSIONS !)
C
C     EN SORTIE: 
C           CC : TABLEAU DE LA SPHERE
C                CC(1:3) VECTEUR DIAMETRE (PARTANT DE N(4))
C                CC(4)   DIAMETRE AU CARRE 
C     *************************************************************
C      DIMENSION N(4),X(3,1),CC(4)
      INTEGER N(4)
      REAL    X(3,1)
      REAL    CC(4)
C
C     N(4) EST PRIS COMME REFERENCE
C
C      COMMON /INFXMLT/ ZERO,GRAN
      REAL    A(3,3),B(3),Y(3)
      INTEGER K,I,IER
      EXTERNAL SCALUT
      REAL     SCALUT
C
      DO 20 K=1,3
      DO 10 I=1,3
      Y(I)=X(I,N(K))-X(I,N(4))
   10 A(K,I)=Y(I)
   20 B(K)=SCALUT(Y,Y,3)
      CALL SL33UT(IER,A,B,CC)
      IF(IER.EQ.0) THEN
        CC(4)=CC(1)**2+CC(2)**2+CC(3)**2
        RETURN
      ENDIF
      DO 30 I=1,4
   30 CC(I)=0.
      RETURN
      END
C
C
      SUBROUTINE SL33UT(IER,A,B,X)
C     *************************************************************
C     OBJET SL33UT : SYSTEME LINEAIRE AX=B  (3x3)
C     EN ENTREE: 
C            A : PREMIER MEMBRE DU SYSTEME
C            B : SECOND MEMBRE DU SYSTEME
C
C     EN SORTIE: 
C          IER : IER = 0 OK, IER = 1 DETERMINANT NUL
C            X : RESULTAT DU SYSTEME
C     *************************************************************
C      DIMENSION A(3,3),B(3),X(3)
      INTEGER IER
      REAL    A(3,3),B(3),X(3)
C
      REAL    D,ZERO
C
      ZERO=1.E-30
      CALL MIXTUT(A,B,X,D)
      IER=0
      IF(ABS(D).LE.ZERO) IER=1
      RETURN
      END
C
      SUBROUTINE MIXTUT(A,B,X,D)
C     *************************************************************
C     OBJET MIXTUT : SYSTEME LINEAIRE AX=B  (3x3) ET DETERMINANT
C     EN ENTREE: 
C            A : PREMIER MEMBRE DU SYSTEME
C            B : SECOND MEMBRE DU SYSTEME
C     EN SORTIE: 
C            D : DETERMINANT DU SYSTEME
C            X : RESULTAT DU SYSTEME
C                SI D N'EST PAS NUL
C     REMARQUE :
C     IL EST POSSIBLE DE FAIRE L'APPEL COMME SUIT :
C     CALL STROI(A,B,B,D), B EST LE SECOND MEMBRE A L'ENTREE ET
C     LA SOLUTION A LA SORTIE.
C     *************************************************************
C      DIMENSION A(3,3),B(3),X(3),D
      REAL    A(3,3),B(3),X(3),D
C
      REAL V(3),X1,X2,X3   
      EXTERNAL SCALUT,SLDTUT
      REAL     SCALUT,SLDTUT
C
      CALL VECTUT(A(1,2),A(1,3),V)
      D=SCALUT(A,V,3)
      IF(D.EQ.0.) RETURN
      X1=SCALUT(B,V,3)/D
      X2=SLDTUT(B,A(1,3),A)/D
      X3=SLDTUT(B,A,A(1,2))/D
      X(1)=X1
      X(2)=X2
      X(3)=X3
      RETURN
      END
C
C
      FUNCTION SLDTUT(A,B,C)
C     *************************************************************
C     OBJET SLDTUT : A.(B^C) = PRODUIT MIXTE (DETERMINANT DE 3 COLONNES)
C     EN ENTREE: 
C            A,B,C : LES 3 VECTEURS
C     EN SORTIE: RENVOI A.(B^C)
C     **********************************************
C      DIMENSION A(3),B(3),C(3),V(3)
      REAL SLDTUT
      REAL A(3),B(3),C(3)
C
      REAL V(3)
      EXTERNAL SCALUT
      REAL     SCALUT
C
      CALL VECTUT(B,C,V)
      SLDTUT=SCALUT(A,V,3)
      RETURN
      END
C
C
      SUBROUTINE VECTUT(A,B,C)
C     *************************************************************
C     OBJET VECTUT : C=A^B  PRODUIT VECTORIEL
C     EN ENTREE: 
C            A,B : LES 2 VECTEURS
C     EN SORTIE: 
C              C : C=A^B
C     **********************************************
      REAL A(3),B(3),C(3)
C
      C(1)=A(2)*B(3)-A(3)*B(2)
      C(2)=A(3)*B(1)-A(1)*B(3)
      C(3)=A(1)*B(2)-A(2)*B(1)
      RETURN
      END
C
      FUNCTION SCALUT(X,Y,N)
C     **********************************************
C     OBJET SCALUT : PRODUIT SCALAIRE 
C     EN ENTREE: 
C            X,Y : LES 2 VECTEURS
C              N : LE NOMBRE DE COORDONNEES
C     EN SORTIE: RENVOI X(1)*Y(1) + X(2)*Y(2) + ... + X(N)*Y(N)
C     **********************************************
C      DIMENSION X(1),Y(1)
      REAL SCALUT
      REAL X(*),Y(*)
      INTEGER N
C
      INTEGER I
C
      SCALUT=0.
      IF(N.LE.0) RETURN
      DO 10 I=1,N
   10 SCALUT=SCALUT+X(I)*Y(I)
      RETURN
      END
C
C     *****************************************************************
C     MODULE  : CG (CALCUL GEOMETRIQUE)
C     FICHIER : CG_TETRA.F
C     OBJET   : CALCUL DE LA QUALITE D'UN TETRAEDRE 
C               ET D'UN TRIANGLE EN 3D
C     FONCT.  : 
C     OBJET TTRSC : RAYON DE LA SPHERE CIRC. AU TETRA
C     OBJET TTLRC : LMAX / RAYON DE LA SPHERE CIRC. AU TETRA
C     OBJET TTD2SC : DIAM. AU 2 DE LA SPHERE CIRC. AU TETRA
C     OBJET TTVO : RENVOI LE VOLUME DU TETRAEDRE
C     OBJET TTSF4 : RENVOI LA SURFACE D'UNE DES 4 FACES DU TETRA
C     OBJET TTRIL : RENVOI RI / L POUR LE TETRAEDRE 
C     OBJET TTLSL : RENVOI LMIN / LMAX POUR LE TETRAEDRE 
C     OBJET TTLMIN : CALCUL L'ARETE MIN. DU TETRAEDRE
C     OBJET TTLMAX : CALCUL L'ARETE MAX. DU TETRAEDRE
C     OBJET GARMXM : CALCULE LE BARYCENTRE D'UN SIMPLEXE
C     OBJET TRPOOP : CALCUL LE POINT OPTIMUM (FORME TETRA 1,2,3,P )
C     AUTEUR  : O. STAB
C     DATE    : 03.95
C     MODIFICATIONS :
C      AUTEUR, DATE, OBJET :
C
C
C     *****************************************************************
C
      FUNCTION TTRSC(P1,P2,P3,P4)
C     *****************************************************************
C     OBJET TTRSC : RAYON DE LA SPHERE CIRC. AU TETRA
C
C     EN ENTREE :
C       P1, P2, P3, P4 : LES COORDONNEES DES 4 POINTS
C
C     FORMULE :
C      RC =  
C     *****************************************************************
      REAL TTRSC
      REAL P1(*),P2(*),P3(*),P4(*)
C
      REAL     DIAM2
      REAL     TTD2SC
      INTEGER  NULLVE
      EXTERNAL TTD2SC,NULLVE
C
      DIAM2 = TTD2SC(P1,P2,P3,P4)
      TTRSC = 0.0
      IF( NULLVE(DIAM2,1).NE.1 )TTRSC = SQRT(DIAM2) / 2.0
 9999 END
C
C
      FUNCTION TTLRC(P1,P2,P3,P4)
C     *****************************************************************
C     OBJET TTLRC : LMAX / RAYON DE LA SPHERE CIRC. AU TETRA
C
C     EN ENTREE :
C       P1, P2, P3, P4 : LES COORDONNEES DES 4 POINTS
C
C     FORMULE :
C      TTLRC = (2/3)SQRT(6) * L/RC 
C     *****************************************************************
      REAL TTLRC
      REAL P1(*),P2(*),P3(*),P4(*)
C
      REAL     XLMAX,RSC,UNDEMI
      EXTERNAL TTRSC,TTLMAX,NULLVE
      REAL     TTRSC,TTLMAX
      INTEGER  NULLVE
C
      UNDEMI = 0.5
      TTLRC = 0.0
      RSC = TTRSC(P1,P2,P3,P4)
      IF( NULLVE(RSC,1).EQ.1 )GOTO 9999
C
      XLMAX  = TTLMAX(P1,P2,P3,P4)
      TTLRC = UNDEMI * XLMAX / RSC
 9999 END
C
C
      FUNCTION TTD2SC(P1,P2,P3,P4)
C     *****************************************************************
C     OBJET TTD2SC : DIAM. AU 2 DE LA SPHERE CIRC. AU TETRA
C
C     EN ENTREE :
C       P1, P2, P3, P4 : LES COORDONNEES DES 4 POINTS
C
C     FORMULE :
C      RC =  A FAIRE
C     *****************************************************************
      REAL TTD2SC
      REAL P1(*),P2(*),P3(*),P4(*)
C
      REAL      V(3,3),VI(3,3),B(3),CC(4)
      INTEGER   I,K,IERR,IDIMC
      EXTERNAL  XNORVE,SCALVE
      REAL      XNORVE,SCALVE
C
C      DO 20 K=1,3
C        DO 10 I=1,3
C          Y(I)=X(I,N(K))-X(I,N(4))
C          A(K,I)=Y(I)
C   10   CONTINUE
C
C        B(K)=SCALXUTL(Y,Y,3)
C   20 CONTINUE
C      CALL SYS3XTET(IER,A,B,CC)
C
      IDIMC = 3
      CALL DIFFVE(P1,P4,IDIMC,V(1,1))
      CALL DIFFVE(P2,P4,IDIMC,V(1,2))
      CALL DIFFVE(P3,P4,IDIMC,V(1,3))
C
      DO 10 I=1,3
        B(I)=SCALVE(V(1,I),V(1,I),3)
        DO 5 K=1,3
          VI(K,I) = V(I,K)
    5   CONTINUE
   10 CONTINUE

      CALL SL33UT(IERR,VI,B,CC)
      IF(IERR.EQ.0) THEN
        CC(4) = CC(1)**2+CC(2)**2+CC(3)**2
      ELSE
        CC(4) = 0
      ENDIF
C      PRINT*,' DIAM2 = ',CC(4) 
      TTD2SC = CC(4)
 9999 END
C
      FUNCTION TTVO(P1,P2,P3,P4)
C     *****************************************************************
C     OBJET TTVO : RENVOI LE VOLUME DU TETRAEDRE
C
C     EN ENTREE :
C       P1, P2, P3, P4 : LES COORDONNEES DES 4 POINTS
C
C     FORMULE :
C      TTVO = 1/6 PRODUIT MIXTE
C             POSITIF SI LES FACES SONT ORIENTEES VERS L'INTERIEUR
C     *****************************************************************
      REAL TTVO
      REAL P1(*),P2(*),P3(*),P4(*)
C
      REAL     V12(3),V13(3),V14(3),V123(3),UNSIX
      INTEGER  IDIMC
      EXTERNAL SCALVE
      REAL     SCALVE
C
      UNSIX = .16666666666666666666
      IDIMC = 3
      CALL DIFFVE(P2,P1,IDIMC,V12)
      CALL DIFFVE(P3,P2,IDIMC,V13)
      CALL VECTVE(V12,V13,IDIMC,V123)
      CALL DIFFVE(P4,P3,IDIMC,V14)
      TTVO = UNSIX * SCALVE(V123,V14,IDIMC)
C
 9999 END
C
C
      FUNCTION TTSF4(IDF,P1,P2,P3,P4)
C     *****************************************************************
C     OBJET TTSF4 : RENVOI LA SURFACE D'UNE DES 4 FACES DU TETRA
C
C     EN ENTREE :
C       IDF : INDICE DE LA FACE
C            1 = (P1,P2,P3), 2 = (P1,P2,P4)
C            3 = (P2,P3,P4), 4 = (P3,P1,P4)
C
C       P1, P2, P3, P4 : LES COORDONNEES DES 4 POINTS
C
C     FORMULE :
C      TTSF = 1/2 NORME(PRODUIT VECTORIEL)
C     *****************************************************************
      REAL    TTSF4
      REAL    P1(*),P2(*),P3(*),P4(*)
      INTEGER IDF
C
      REAL    V12(3),V13(3),V123(3),UNDEMI
      INTEGER IDIMC
      EXTERNAL XNORVE
      REAL     XNORVE
C
      UNDEMI = 0.5
      IDIMC = 3
      GOTO (10,20,30,40) IDF
      TTSF4 = -1.0
      GOTO 9999
C     ---- FACE (P1,P2,P3) -------
   10 CALL DIFFVE(P2,P1,IDIMC,V12)
      CALL DIFFVE(P3,P1,IDIMC,V13)
      GOTO 50
C     ---- FACE (P1,P2,P4) -------
   20 CALL DIFFVE(P2,P1,IDIMC,V12)
      CALL DIFFVE(P4,P1,IDIMC,V13)
      GOTO 50
C     ---- FACE (P2,P3,P4) -------
   30 CALL DIFFVE(P3,P2,IDIMC,V12)
      CALL DIFFVE(P4,P2,IDIMC,V13)
      GOTO 50
C     ---- FACE (P3,P1,P4) -------
   40 CALL DIFFVE(P1,P3,IDIMC,V12)
      CALL DIFFVE(P4,P3,IDIMC,V13)
      GOTO 50
   50 CALL VECTVE(V12,V13,IDIMC,V123)
      TTSF4 = UNDEMI * XNORVE(V123,IDIMC)
C
 9999 END
C
C
C
      FUNCTION TTRIL(P1,P2,P3,P4)
C     *****************************************************************
C     OBJET TTRIL : RENVOI RI / L POUR LE TETRAEDRE 
C
C     EN ENTREE :
C
C       P1, P2, P3, P4 : LES COORDONNEES DES 4 POINTS
C
C     FORMULE : RIL = VOL / SOMME DES SURFACES DES FACES
C     *****************************************************************
      REAL    TTRIL
      REAL    P1(*),P2(*),P3(*),P4(*)
C
      REAL     SURF, VOL, XLMAX, SQ24M3
      INTEGER  IDIMC,I
      EXTERNAL TTSF4,TTVO,TTLMAX
      REAL     TTSF4,TTVO,TTLMAX
C
      IDIMC = 3
      SURF = 0.0
      SQ24M3 = 14.69693845669906858917
      DO 10 I=1,4
        SURF = TTSF4(I,P1,P2,P3,P4) + SURF
   10 CONTINUE
C
      VOL   = TTVO(P1,P2,P3,P4) 
      XLMAX  = TTLMAX(P1,P2,P3,P4)
      TTRIL = SQ24M3 * VOL / ( SURF * XLMAX )
C
 9999 END
C
C
C
C
C
      FUNCTION TTLSL(P1,P2,P3,P4)
C     *****************************************************************
C     OBJET TTLSL : RENVOI LMIN / LMAX POUR LE TETRAEDRE 
C
C     EN ENTREE :
C
C       P1, P2, P3, P4 : LES COORDONNEES DES 4 POINTS
C
C     FORMULE : 
C     *****************************************************************
      REAL    TTLSL
      REAL    P1(*),P2(*),P3(*),P4(*)
C
      REAL     XLMIN,XLMAX
      EXTERNAL TTLMAX,TTLMIN,NULLVE
      REAL     TTLMAX,TTLMIN
      INTEGER  NULLVE
C
      XLMAX  = TTLMAX(P1,P2,P3,P4)
      XLMIN  = TTLMIN(P1,P2,P3,P4)
      TTLSL = 0.0
      IF( NULLVE(XLMAX,1).EQ. 1)GOTO 9999
      TTLSL = XLMIN / XLMAX
C
 9999 END
C
C
      FUNCTION TTLMIN(XP1,XP2,XP3,XP4)
C     *****************************************************************
C     OBJET TTLMIN : CALCUL L'ARETE MIN. DU TETRAEDRE
C
C     EN ENTREE :
C       XP1, XP2, XP3, XP4 : LES COORDONNEES DES 4 POINTS
C
C     EN SORTIE : LONGUEUR DE L'ARETE LA PLUS COURTE
C     *****************************************************************
      REAL TTLMIN
      REAL XP1(*),XP2(*),XP3(*),XP4(*)
C
      REAL     V(3),D
      EXTERNAL XNORVE
      REAL     XNORVE
      INTEGER  IDIMC
C
C     ---- LES ARETES DE LA BASE ----
C
      IDIMC = 3
      CALL DIFFVE(XP2,XP1,IDIMC,V)
      TTLMIN = XNORVE(V,IDIMC)
      CALL DIFFVE(XP3,XP2,IDIMC,V)
      D = XNORVE(V,IDIMC)
      TTLMIN = MIN( D, TTLMIN )
      CALL DIFFVE(XP1,XP3,IDIMC,V)
      D = XNORVE(V,IDIMC) 
      TTLMIN = MIN( D, TTLMIN )
C
C     ---- LES ARETES VERS P4 ----
C
      CALL DIFFVE(XP4,XP1,IDIMC,V)
      D = XNORVE(V,IDIMC)
      TTLMIN = MIN( D, TTLMIN )
      CALL DIFFVE(XP4,XP2,IDIMC,V)
      D = XNORVE(V,IDIMC)
      TTLMIN = MIN( D, TTLMIN )
      CALL DIFFVE(XP4,XP3,IDIMC,V)
      D = XNORVE(V,IDIMC) 
      TTLMIN = MIN( D, TTLMIN )
C
 9999 END
C
C
      FUNCTION TTLMAX(XP1,XP2,XP3,XP4)
C     *****************************************************************
C     OBJET TTLMAX : CALCUL L'ARETE MAX. DU TETRAEDRE
C
C     EN ENTREE :
C       XP1, XP2, XP3, XP4 : LES COORDONNEES DES 4 POINTS
C
C     EN SORTIE : LONGUEUR DE L'ARETE LA PLUS LONGUE
C     *****************************************************************
      REAL    TTLMAX
      REAL XP1(*),XP2(*),XP3(*),XP4(*)
C
      REAL     V(3),D
      EXTERNAL XNORVE
      REAL     XNORVE
      INTEGER  IDIMC
C
C     ---- LES ARETES DE LA BASE ----
C
      IDIMC = 3
      CALL DIFFVE(XP2,XP1,IDIMC,V)
      TTLMAX = XNORVE(V,IDIMC)
      CALL DIFFVE(XP3,XP2,IDIMC,V)
      D = XNORVE(V,IDIMC)
      TTLMAX = MAX( D, TTLMAX )
      CALL DIFFVE(XP1,XP3,IDIMC,V)
      D = XNORVE(V,IDIMC) 
      TTLMAX = MAX( D, TTLMAX )
C
C     ---- LES ARETES VERS P4 ----
C
      CALL DIFFVE(XP4,XP1,IDIMC,V)
      D = XNORVE(V,IDIMC)
      TTLMAX = MAX( D, TTLMAX )
      CALL DIFFVE(XP4,XP2,IDIMC,V)
      D = XNORVE(V,IDIMC)
      TTLMAX = MAX( D, TTLMAX )
      CALL DIFFVE(XP4,XP3,IDIMC,V)
      D = XNORVE(V,IDIMC) 
      TTLMAX = MAX( D, TTLMAX )            
C
 9999 END
C
C      
      SUBROUTINE GARMXM(IT, NBN, COORD, IDIMC, 
     >                  XLMIN,IMIN,XLMAX,IMAX, IERR)
C     *****************************************************************
C     OBJET GARMXM : CALCULE LE BARYCENTRE D'UN SIMPLEXE
C     EN ENTREE :
C       IT      : NUMERO DES NOEUDS DE L'ELEMENT
C       N       : NOMBRE DE NOEUDS DE L'ELEMENT
C       C       : COORDONNEES DES NOEUDS
C       IDIMC   : DIMENSION DE L'ESPACE
C     EN SORTIE :
C       XLMIN, XLMAX : LONGUEUR MINI ET MAXI DES ARETES DE L'ELEMENT
C       IMIN, IMAX : INDICE RELATIF DE L'ARETE LA PLUS COURTE (LONGUE) 
C       IERR    : 0 SI OK, -1 SI LES DONNEES SONT ERRONEES
C     *****************************************************************
      INTEGER IT(*),NBN,IDIMC,IERR
      REAL    COORD(*),XLMIN,XLMAX
      INTEGER IMIN,IMAX
C
      INTEGER I,J
      REAL    X(3),XM(3)
C
      IERR = 0
      GOTO (10,20,30,30) NBN
C      --- SOMMET ---
   10 IERR = -1
      GOTO 9999
C
C     --- ARETE ---
C        =======
   20 IMIN = 1
      IMAX = 1
      XLMIN = 0.0
      DO 25 J=1,IDIMC
          X(J)         = COORD(((IT(2)-1)*IDIMC)+J) 
     >                 - COORD(((IT(1)-1)*IDIMC)+J)
          XLMIN = XLMIN + X(J)*X(J)
   25 CONTINUE
      XLMIN = SQRT(XLMIN)
      XLMAX = XLMIN
      GOTO 9999 
C
C     --- TRIANGLES ET TETRAEDRES ----
C        ==========================
   30 DO 40 J=1,IDIMC
          X(1)           = COORD(((IT(2)-1)*IDIMC)+J) 
     >                   - COORD(((IT(1)-1)*IDIMC)+J)
          XM(1) = XM(1) + X(1) * X(1)
          X(2)           = COORD(((IT(3)-1)*IDIMC)+J) 
     >                   - COORD(((IT(2)-1)*IDIMC)+J)
          XM(2) = XM(2) + X(2) * X(2)
          X(3)           = COORD(((IT(1)-1)*IDIMC)+J) 
     >                   - COORD(((IT(3)-1)*IDIMC)+J)
          XM(3) = XM(3) + X(3) * X(3)
   40   CONTINUE
C
      XLMIN = XM(1)
      XLMAX = XM(1)
      IMIN = 1 
      IMAX = 1
      DO 50 I=2,3
        IF( XLMAX .LT. X(I) )THEN
          XLMAX = X(I)
          IMAX = I
        ENDIF
        IF( XLMIN .GT. X(I) )THEN
          XLMIN = X(I)
          IMIN = I
        ENDIF
   50 CONTINUE
      IF( NBN.EQ. 3)GOTO 9999
C
C     --- TETRAEDRES SEULEMENT  ----
C        ==========================
      DO 60 J=1,IDIMC
          X(1)           = COORD(((IT(4)-1)*IDIMC)+J) 
     >                   - COORD(((IT(1)-1)*IDIMC)+J)
          XM(1) = XM(1) + X(1) * X(1)
          X(2)           = COORD(((IT(4)-1)*IDIMC)+J) 
     >                   - COORD(((IT(2)-1)*IDIMC)+J)
          XM(2) = XM(2) + X(2) * X(2)
          X(3)           = COORD(((IT(4)-1)*IDIMC)+J) 
     >                   - COORD(((IT(3)-1)*IDIMC)+J)
          XM(3) = XM(3) + X(3) * X(3)
   60   CONTINUE
      DO 70 I=1,3
        IF( XLMAX .LT. X(I) )THEN
          XLMAX = X(I)
          IMAX = I+3
        ENDIF
        IF( XLMIN .GT. X(I) )THEN
          XLMIN = X(I)
          IMIN = I+3
        ENDIF
   70 CONTINUE
C   
 9999 END    
      
C
      SUBROUTINE TRPOOP(XP1,XP2,XP3,BARYTR,NORMTR,POINTR,IERR)
C     *****************************************************************
C     OBJET TRPOOP : CALCUL LE POINT OPTIMUM (FORME TETRA 1,2,3,P )
C
C     EN ENTREE :
C       XP1, XP2, XP3 : LES COORDONNEES DES 3 POINTS (ORIENTES)
C
C     EN SORTIE :
C       BARYTR: BARYCENTRE DU TRIANGLE
C       NORMTR: NORMALE AU TRIANGLE
C       POINTR: COORDONNEES DU POINT OPTIMUM
C       IERR  : 0 SI OK, -1 SI XP1,XP2,XP3 ALIGNES
C
C     REMARQUES :
C       POINTR = HAUTEUR * NORMALE AU BARYCENTRE
C       HAUTEUR= PERIMETRE / 3
C     *****************************************************************
      REAL    XP1(*),XP2(*),XP3(*)
      REAL    BARYTR(*),NORMTR(*),POINTR(*)
      INTEGER IERR
C
      REAL     D,UNS3,UNSD,PERIM,COEF,V(3),V12(3),V23(3)
      EXTERNAL XNORVE,NULLVE
      REAL     XNORVE
      INTEGER  NULLVE
      INTEGER  IDIMC,I
C
      UNS3  = 1.0 / 3.0
      IDIMC = 3
C
C     ---- PERIMETRE ----
C
      PERIM = 0.0
C
      CALL DIFFVE(XP2,XP1,IDIMC,V)
      D = XNORVE(V,IDIMC)
      IF( NULLVE(D,1).EQ.1 )THEN
        IERR = -1
        CALL DSERRE(1,IERR,'TROOP','POINTS 1 ET 2 CONFONDUS')
        GOTO 9999
      ENDIF
      PERIM = PERIM + D
      UNSD = 1.0 / D
      CALL MUSCVE(V,UNSD,IDIMC,V12)
C
      CALL DIFFVE(XP3,XP2,IDIMC,V)
      D = XNORVE(V,IDIMC)
      IF( NULLVE(D,1).EQ.1 )THEN
        IERR = -1
        CALL DSERRE(1,IERR,'TROOP','POINTS 2 ET 3 CONFONDUS')
        GOTO 9999
      ENDIF
      PERIM = PERIM + D
      UNSD = 1.0 / D
      CALL MUSCVE(V,UNSD,IDIMC,V23)
C
      CALL DIFFVE(XP3,XP1,IDIMC,V)
      IF( NULLVE(D,1).EQ.1 )THEN
        IERR = -1
        CALL DSERRE(1,IERR,'TROOP','POINTS 3 ET 1 CONFONDUS')
        GOTO 9999
      ENDIF
      D = XNORVE(V,IDIMC)
      PERIM = PERIM + D
      
C      PRINT *,'PERIMETRE = ',PERIM
C
C     ---- NORMALE ----
C
      CALL VECTVE(V12,V23,IDIMC,NORMTR)
C     --- POUR PLUS DE SECURITE ---
      D = XNORVE(NORMTR,IDIMC)
      IF( NULLVE(D,1).EQ.1 )THEN
        IERR = -1
        CALL DSERRE(1,IERR,'TROOP','3 POINTS ALIGNES')
        GOTO 9999
      ENDIF
      COEF = 1.0 / D
      CALL MUSCVE(NORMTR,COEF,IDIMC,NORMTR)
C
C      PRINT *,'NORMALE = ',(NORMTR(I),I=1,3)
C
C     ---- BARYCENTRE ----
C
      CALL SOMMVE(XP2,XP1,IDIMC,BARYTR)
      CALL SOMMVE(BARYTR,XP3,IDIMC,BARYTR)
      CALL MUSCVE(BARYTR,UNS3,IDIMC,BARYTR)
C
C      PRINT *,'BARYCENTRE = ',(BARYTR(I),I=1,3)
C
C     ---- POINT OPTIMUM ----
C
      COEF = PERIM / 3.0
      CALL MUSCVE(NORMTR,COEF,IDIMC,POINTR)
      CALL SOMMVE(BARYTR,POINTR,IDIMC,POINTR)
      IERR = 0
C
C      PRINT *,'POINT = ',(POINTR(I),I=1,3)
C
 9999 END
C
      

C     *****************************************************************
C     MODULE  : CG (CALCULS GEOMETRIQUES)
C     FICHIER : GG_SIMPLEXE.F
C     OBJET   : CALCULS GEOMETRIQUES ELEMENTAIRES SUR LES SIMPLEXES
C     FONCT.  : 
C     CGTASX : CALCULE LA TAILLE D'UN SIMPLEXE 
C     CGORSX: RENVOI L'ORIENTATION D'UN SIMPLEXE (SIGNE VOLUME) 
C
C     AUTEUR  : O. STAB  
C     DATE    : 12.97
C     TESTS   : 
C     MODIFICATIONS :
C      AUTEUR, DATE, OBJET :
C
C
C     *****************************************************************
C
      SUBROUTINE CGTASX(IPOINT, NBPOIN, COORD, TAILLE, IERR )
C     *****************************************************************
C     OBJET CGTASX : CALCULE LA TAILLE D'UN SIMPLEXE 
C     EN ENTREE :
C       IPOINT  : NUMERO DES SOMMETS DU SIMPLEXE
C       NBPOIN  : NOMBRE DE SOMMET DU SIMPLEXE 
C       COORD   : COORDONNEES DES NOEUDS
C     EN SORTIE :
C       TAILLE  : LONGUEUR D'UN SEGMENT EN 1D
C                 SURFACE D'UN TRIANGLE EN 2D 
C                 VOLUME D'UN TETRAEDRE EN 3D
C       IERR    : 0 SI OK, -1 SI LES DONNEES SONT ERRONEES
C     *****************************************************************
      INTEGER IPOINT(*),NBPOIN
      REAL    COORD(*)
      REAL    TAILLE
      INTEGER IERR
C
      INTEGER I,J,IDIMC
      REAL    X(12),VX,VY,VZ 
C
      TAILLE = 0.0
      IF((NBPOIN.GT.4).OR.(NBPOIN.LT.1))THEN
         IERR = -3
         GOTO 9999
      ENDIF
      IERR = 0
      IDIMC = NBPOIN-1
      IF(NBPOIN.EQ.1)GOTO 9999
      DO 10 I=1,(NBPOIN-1)
        DO 20 J=1,IDIMC
          X((I-1)*IDIMC+J) = COORD(((IPOINT(I+1)-1)*IDIMC)+J) 
     >                    - COORD(((IPOINT(I)-1)*IDIMC)+J)
   20   CONTINUE
   10 CONTINUE 
      IF( IDIMC .EQ. 3 )THEN 
        VX = (X(2) * X(6)) - (X(5) * X(3))
        VY = (X(3) * X(4)) - (X(6) * X(1))
        VZ = (X(1) * X(5)) - (X(4) * X(2))
      ENDIF
C
      GOTO (100,200,300) IDIMC
C     UN POINT
      GOTO 9999
C     LONGUEUR DU SEGMENT
  100 TAILLE = X(1)
      GOTO 9999
C     SURFACE DU TRIANGLE
  200 TAILLE = 0.5 *((X(1) * X(4)) - (X(2) * X(3)))
      GOTO 9999
C     VOLUME DU TETRAEDRE
  300 CONTINUE
      VX = (X(2) * X(6)) - (X(5) * X(3))
      VY = (X(3) * X(4)) - (X(6) * X(1))
      VZ = (X(1) * X(5)) - (X(4) * X(2))
      TAILLE = ((VX * X(7)) + (VY * X(8)) + (VZ * X(9))) / 6.
      GOTO 9999
C
 9999 END
C
      FUNCTION CGORSX(IPOINT, NBPOIN, COORD, ZERO, IERR )
C     *****************************************************************
C     OBJET CGORSX: RENVOI L'ORIENTATION D'UN SIMPLEXE (SIGNE VOLUME) 
C     EN ENTREE :
C       IPOINT  : NUMERO DES SOMMETS DU SIMPLEXE
C       NBPOIN  : NOMBRE DE SOMMET DU SIMPLEXE
C       COORD   : COORDONNEES DES NOEUDS
C       ZERO    : LONGUEUR,SURFACE,VOLUME CONSIDEREE COMME NUL
C     EN SORTIE :
C       IERR    : 0 SI OK, -1 SI LES DONNEES SONT ERRONEES
C     *****************************************************************
      INTEGER CGORSX
      INTEGER IPOINT(*),NBPOIN
      REAL    COORD(*),ZERO
      INTEGER IERR
C
      REAL TAILLE
C
      CALL CGTASX(IPOINT, NBPOIN, COORD, TAILLE, IERR )
      IF( TAILLE .GT. ZERO )THEN
        CGORSX = 1
      ELSE
        IF( TAILLE .LT. -ZERO )THEN
          CGORSX = -1
        ELSE
          CGORSX = 0
        ENDIF
      ENDIF
 9999 END
C
C     *****************************************************************
C     MODULE  : CG (CALCUL GEOMETRIQUE)
C     FICHIER : CG_QUAD.F
C     OBJET   : CALCUL DE LA QUALITE D'UN QUADRANGLE 
C     FONCT.  : 
C        Q4LL : CALCUL L'ARETE MIN. ET L'ARETE MAX.
C
C     AUTEUR  : O. STAB
C     DATE    : 03.95
C     MODIFICATIONS :
C      AUTEUR, DATE, OBJET : O.STAB, 10.97, AJOUT DANS V.2.0.0
C
C
C     *****************************************************************
C
C
      SUBROUTINE Q4LL(XP1,XP2,XP3,XP4,IDIMC,DMIN,DMAX)
C     *****************************************************************
C     OBJET Q4LL : CALCUL L'ARETE MIN. ET L'ARETE MAX.
C
C     EN ENTREE :
C       XP1, XP2, XP3 : LES COORDONNEES DES 3 POINTS
C
C     EN SORTIE :
C       DMIN : LONGUEUR DE L'ARETE LA PLUS COURTE
C       DMAX : LONGUEUR DE L'ARETE LA PLUS LONGUE
C     *****************************************************************
      REAL    XP1(*),XP2(*),XP3(*),XP4(*),DMIN,DMAX
      INTEGER IDIMC
C
      REAL     V(3),D
      EXTERNAL XNORVE
      REAL     XNORVE
C
      CALL DIFFVE(XP2,XP1,IDIMC,V)
      DMIN = XNORVE(V,IDIMC)
      DMAX = DMIN
      CALL DIFFVE(XP3,XP2,IDIMC,V)
      D = XNORVE(V,IDIMC)
      DMIN = MIN( D, DMIN )
      DMAX = MAX( D, DMAX )
      CALL DIFFVE(XP4,XP3,IDIMC,V)
      D = XNORVE(V,IDIMC) 
      DMIN = MIN( D, DMIN )
      DMAX = MAX( D, DMAX )
      CALL DIFFVE(XP1,XP4,IDIMC,V)
      D = XNORVE(V,IDIMC) 
      DMIN = MIN( D, DMIN )
      DMAX = MAX( D, DMAX )
  999 END
C
C
      FUNCTION Q4SURF(P1,P2,P3,P4,IDIMC)
C     *****************************************************************
C     OBJET Q4SURF : RENVOI LA SURFACE DU QUADRANGLE (A REVOIR)
C
C     EN ENTREE :
C       P1, P2, P3, P4 : LES COORDONNEES DES 3 POINTS
C
C     FORMULE :
C      SURFACE = SOMME DES SURFACES DES 2 TRIANGLES !
C     *****************************************************************
      REAL Q4SURF
      INTEGER IDIMC
      REAL P1(*),P2(*),P3(*),P4(*)
C
C
      REAL      V(3,3),V123(3),UNDEMI,TRSURF
      EXTERNAL  XNORVE
      REAL      XNORVE
C
C     ---- PREMIER TRIANGLE ---
C
      UNDEMI = 0.5
      CALL DIFFVE(P2,P1,IDIMC,V(1,1))
      CALL DIFFVE(P3,P2,IDIMC,V(1,2))
      CALL VECTVE(V(1,1),V(1,2),IDIMC,V123)
      IF( IDIMC.EQ. 2 )THEN
        TRSURF = UNDEMI * SQRT(V123(1)*V123(1))
      ELSE
        TRSURF = UNDEMI * XNORVE(V123,IDIMC)
      ENDIF
C
C     ---- SECOND TRIANGLE ---
C
      CALL DIFFVE(P4,P3,IDIMC,V(1,1))
      CALL DIFFVE(P1,P4,IDIMC,V(1,2))
      CALL VECTVE(V(1,1),V(1,2),IDIMC,V123)
      IF( IDIMC.EQ. 2 )THEN
        Q4SURF = TRSURF + UNDEMI * SQRT(V123(1)*V123(1))
      ELSE
        Q4SURF = TRSURF + UNDEMI * XNORVE(V123,IDIMC)
      ENDIF

C
 9999 END










C     ***************************************************************
C     MODULE  : CG (CALCUL GEOMETRIQUE)
C     FICHIER : CG_VECTORIEL.F
C     OBJET   : CALCULS ELEMENTAIRES SUR LES VECTEURS
C
C     FONCT.  :
C        COPIVE    : COPIE UN VECTEUR DANS UN AUTRE
C        SCALVE    : PRODUIT SCALAIRE
C        VECTVE    : PRODUIT VECTORIEL
C        XNORVE    : RENVOI LA NORME D'UN VECTEUR
C        NULLVE    : RENVOI 1 SI LE VECTEUR EST NUL
C        DIFFVE    : FAIT LA DIFFERENCE ENTRE 2 VECTEURS
C        SOMMVE    : FAIT LA SOMME DE 2 VECTEURS
C        MUSCVE    : MULTIPLICATION D'UN VECTEUR PAR UN SCALAIRE
C
C     AUTEUR   : O. STAB
C     DATE     : 03.95 / 06.95
C     TESTS    : 07.95
C     MODIFICATIONS :
C      AUTEUR, DATE, OBJET :
C
C
C     ***************************************************************
C     A INCLURE DANS LES PROCEDURES UTILISANT LE PACKAGE
C
C      EXTERNAL SCALVE,XNORVE,NULLVE
C      REAL     SCALVE,XNORVE
C      INTEGER  NULLVE
C
C     ***************************************************************
C
      SUBROUTINE COPIVE(V1,IDIMC,V2)
C     ***************************************************************
C     COPIE UN VECTEUR DANS UN AUTRE : V2 <- V1
C     ***************************************************************
      INTEGER IDIMC
      REAL    V1(*),V2(*)
C
      INTEGER I
C
      IF(IDIMC.LE.0) RETURN
      DO 10 I=1,IDIMC
        V2(I) = V1(I)
   10 CONTINUE
      END
C
      FUNCTION SCALVE(V1,V2,IDIMC)
C     ***************************************************************
C     PRODUIT SCALAIRE
C     SCALVE = V1(1)*V2(1) + V1(2)*V2(2) + ... + V1(N)'V2(N)
C     ***************************************************************
      REAL SCALVE
      INTEGER IDIMC
      REAL    V1(*),V2(*)
C
      INTEGER I
C
      SCALVE = 0.
      IF(IDIMC.LE.0) RETURN
      DO 10 I=1,IDIMC
        SCALVE  = SCALVE  + V1(I)*V2(I)
   10 CONTINUE
      END
C
      FUNCTION XNORVE(V1,IDIMC)
C     ***************************************************************
C     NORME D'UN VECTEUR
C     ***************************************************************
      REAL XNORVE
      INTEGER IDIMC
      REAL    V1(*)
C
      COMMON /CGEPSI/ XYZHUG,XYZMIN,XYZEPS,XYZHU2,XYZMI2
      REAL  XYZHUG,XYZMIN,XYZEPS,XYZHU2,XYZMI2
      INTEGER I
C
      XNORVE = 0.
      IF(IDIMC.LE.0) RETURN
C      XNORVE  = SCALVE(V1,V1,IDIMC)
C      MODIF O.STAB, REMPLACE A CAUSE DE L'UNDERFLOW LE 05.12.97 PAR :
      DO 10 I=1,IDIMC
C        IF(( V1(I).GT. XYZEPS ).OR.(V1(I).LT.-XYZEPS))THEN
        IF(( V1(I).GT. XYZMI2 ).OR.(V1(I).LT.-XYZMI2))THEN
          XNORVE  = XNORVE  + V1(I)*V1(I)
        ENDIF
   10 CONTINUE
C      IF( XNORVE .LT. XYZEPS*XYZEPS )THEN
      IF( XNORVE .LT. XYZMI2 )THEN
        XNORVE = 0.0 
      ELSE
        XNORVE = SQRT( XNORVE )
      ENDIF
      END
C
      SUBROUTINE DIFFVE(V1,V2,IDIMC,V12)
C     ***************************************************************
C     FAIT LA DIFFERENCE ENTRE 2 VECTEURS V12 = V1 - V2
C     ***************************************************************
      INTEGER IDIMC
      REAL    V1(*),V2(*),V12(*)
C
      INTEGER I
C
      IF(IDIMC.LE.0) RETURN
      DO 10 I=1,IDIMC
        V12(I) = V1(I) - V2(I)
   10 CONTINUE
      END
C
      SUBROUTINE SOMMVE(V1,V2,IDIMC,V12)
C     ***************************************************************
C     FAIT LA SOMME ENTRE 2 VECTEURS V12 = V1 + V2
C     ***************************************************************
      INTEGER IDIMC
      REAL    V1(*),V2(*),V12(*)
C
      INTEGER I
C
      IF(IDIMC.LE.0) RETURN
      DO 10 I=1,IDIMC
        V12(I) = V1(I) + V2(I)
   10 CONTINUE
      END
C
      SUBROUTINE MUSCVE(V1,SCAL,IDIMC,VSL)
C     ***************************************************************
C     MULTIPLIE UN VECTEUR PAR UN SCALAIRE VSL = SCAL * V1
C     ***************************************************************
      INTEGER IDIMC
      REAL    V1(*),SCAL,VSL(*)
C
      INTEGER I
C
      IF(IDIMC.LE.0) RETURN
      DO 10 I=1,IDIMC
       VSL(I) = SCAL * V1(I)
   10 CONTINUE
      END
C
      SUBROUTINE VECTVE(V1,V2,IDIMC,PRV)
C     ***************************************************************
C     CALCUL LE PRODUIT VECTORIEL
C     MODIF 09.02.1999 O.STAB : SUPPRESSION DES MISE A ZERO !!!
C     ***************************************************************
      INTEGER IDIMC
      REAL    V1(*),V2(*),PRV(*)
C
C      COMMON /CGEPSI/ XYZHUG,XYZMIN,XYZEPS
C      REAL  XYZHUG,XYZMIN,XYZEPS
C
       GOTO (10,20,30) IDIMC
         GOTO 999
   10    PRV(1) = V1(1) * V2(1)
C         IF((PRV(1).LT.XYZEPS ).AND.( PRV(1).GT.-XYZEPS))PRV(1) = 0.0
         GOTO 999
   20    PRV(1) = V1(1) * V2(2) - V1(2) * V2(1)
C         IF((PRV(1).LT.XYZEPS ).AND.( PRV(1).GT.-XYZEPS))PRV(1) = 0.0
         GOTO 999
   30    PRV(1) = V1(2) * V2(3) - V1(3) * V2(2)
C         IF((PRV(1).LT.XYZEPS ).AND.( PRV(1).GT.-XYZEPS))PRV(1) = 0.0
         PRV(2) = V1(3) * V2(1) - V1(1) * V2(3)
C         IF((PRV(2).LT.XYZEPS ).AND.( PRV(2).GT.-XYZEPS))PRV(2) = 0.0
         PRV(3) = V1(1) * V2(2) - V1(2) * V2(1)
C         IF((PRV(3).LT.XYZEPS ).AND.( PRV(3).GT.-XYZEPS))PRV(3) = 0.0
  999 END
C
      FUNCTION NULLVE(V,IDIMC)
C     ***************************************************************
C     RENVOI 1 SI LE VECTEUR EST NUL, O SI NON NUL
C     ***************************************************************
      INTEGER NULLVE
      INTEGER IDIMC
      REAL    V(*)
C
      INTEGER I
      COMMON /CGEPSI/ XYZHUG,XYZMIN,XYZEPS
      REAL  XYZHUG,XYZMIN,XYZEPS
C
      NULLVE = 0
      IF(IDIMC.LE.0) RETURN
      DO 10 I=1,IDIMC
        IF(( V(I) .GT. XYZEPS ).OR.( V(I) .LT. -XYZEPS ))RETURN
   10 CONTINUE
      NULLVE = 1
      END
C     *****************************************************************
C     MODULE  : CG (CALCUL GEOMETRIQUE)
C     FICHIER : CG_PLAN.F
C     OBJET   : GEOMETRIE 3D - CALCULS SUR LES PLANS 
C     FONCT.  :
C     OBJET M33DPN : 3 VECTEURS ORTHONORMES REPERE DU PLAN (NORMALE=3)
C     OBJET VEDUPN : UN VECTEUR DU PLAN
C     OBJET PODUPN : UN POINT DU PLAN
C     OBJET PNVEPO  : CALCULE L'EQUATION DU PLAN (3D)
C     OBJET POPLDR  : CALCULE LE POINT D'INTERSECTION D'UN PLAN ET D'UNE DROITE
C     OBJET POVEPN  : CALCULE UN POINT ET LA NORMALE DU PLAN 
C     OBJET INPNDR  : INTERSECTION D'UN PLAN ET D'UNE DROITE
C     OBJET  PL3PO  : CALCULE LE PLAN PASSANT PAR LES 3 POINTS
C     OBJET  PLMCAR : CALCULE LE PLAN DES MOINDRES CARRES DE N POINTS
C     OBJET PRONUL : CALCUL LA VALEUR PROPRE NULLE DE LA MATRICE S.
C     OBJET RPPNCR : PASSAGE DANS LE REPERE DU PLAN DES MOINDRES CARRES
C
C     AUTEUR  : O. STAB
C     DATE    : 97 
C     TESTS   :  
C     MODIFICATIONS :
C      AUTEUR, DATE, OBJET : 
C
C     REMARQUES : PN EST L'ABREVIATION DE PLAN, PL CELLE DE POLYGONE !
C     *****************************************************************
C
      SUBROUTINE M33DPN(XPLAN,XVEC1,XVEC2,XVEC3,IERR)
C     *****************************************************************
C     OBJET M33DPN : 3 VECTEURS ORTHONORMES REPERE DU PLAN (NORMALE=3)
C     EN ENTREE :  XPLAN  : EQUATION DU PLAN AX+BY+CZ+D = 0
C     EN SORTIE :  XMAT44 : MATRICE HOMOGENE DU PLAN
C        IERR   : 0 SI OK, -1 SI "PLAN" N'EST PAS CORRECT
C     *****************************************************************
      REAL      XPLAN(4)
      REAL      XVEC1(3),XVEC2(3),XVEC3(3)
      INTEGER   IERR
C
      COMMON /CGEPSI/ XYZHUG,XYZMIN,XYZEPS
      REAL  XYZHUG,XYZMIN,XYZEPS
C
      INTEGER  IDIMC
      REAL     XN
      REAL     XNORVE,SCALVE
      EXTERNAL XNORVE,SCALVE
C
      IDIMC = 3
      CALL VEDUPN( XPLAN, XVEC1, IERR )
      IF( IERR.NE.0 )THEN
        CALL DSERRE(1,IERR,'M33DPN','APPEL VEDUPN')
        GOTO 9999
      ENDIF
      XN = XNORVE(XVEC1,IDIMC)
      IF( XN.LT.XYZMIN )THEN
        IERR = -1
        CALL DSERRE(1,IERR,'M33DPN ','PLAN NUL !!!')
        GOTO 9999
      ENDIF
      XN = 1.0 / XN
      CALL MUSCVE( XVEC1,XN,IDIMC,XVEC1 )
C
      CALL VECTVE( XPLAN,XVEC1,IDIMC,XVEC2 )
      XN = XNORVE( XVEC2,IDIMC )
      IF( XN.LT.XYZMIN )THEN
        IERR = -1
        CALL DSERRE(1,IERR,'M33DPN ','BUG !!!')
        GOTO 9999
      ENDIF
      XN = 1.0 / XN
      CALL MUSCVE( XVEC2,XN,IDIMC,XVEC2 )
      CALL COPIVE( XPLAN,IDIMC,XVEC3 )
C
      IERR = 0       
C
 9999 END
C
C
      SUBROUTINE VEDUPN( XPLAN, XVECTE, IERR )
C     *****************************************************************
C     OBJET VEDUPN : UN VECTEUR DU PLAN
C     EN ENTREE :  XPLAN  : EQUATION DU PLAN AX+BY+CZ+D = 0
C     EN SORTIE :  XVECTE : UN VECTEUR DU PLAN
C        IERR   : 0 SI OK, -1 SI "PLAN" N'EST PAS CORRECT
C     *****************************************************************
      REAL      XPLAN(4)
      REAL      XVECTE(3)
      INTEGER   IERR
C
      COMMON /CGEPSI/ XYZHUG,XYZMIN,XYZEPS
      REAL  XYZHUG,XYZMIN,XYZEPS
C
      INTEGER  ICHOIX,I
      REAL     XNORVE,SCALVE
      EXTERNAL XNORVE,SCALVE
C
      ICHOIX = 1
      DO 5 I=1,3
      IF((XPLAN(I).LE.XYZMIN).AND.(XPLAN(I).GE.-XYZMIN))ICHOIX = I
    5 CONTINUE
      IERR = 0
C
      GOTO(10,20,30) ICHOIX
   10 CONTINUE
      XVECTE(1) =  0.0
      XVECTE(2) =  XPLAN(3)
      XVECTE(3) = -XPLAN(2)
      GOTO 9999
   20 CONTINUE
      XVECTE(1) = -XPLAN(3)
      XVECTE(2) =  0.0
      XVECTE(3) =  XPLAN(1)
      GOTO 9999
   30 CONTINUE
      XVECTE(1) =  XPLAN(2)
      XVECTE(2) = -XPLAN(1)
      XVECTE(3) =  0.0
      GOTO 9999
C
 9999 END
C
C
      SUBROUTINE PODUPN( XPLAN, XPOINT, IERR )
C     *****************************************************************
C     OBJET PODUPN : UN POINT DU PLAN
C     EN ENTREE :  XPLAN  : EQUATION DU PLAN AX+BY+CZ+D = 0
C     EN SORTIE :  XPOINT : UN POINT DU PLAN
C        IERR   : 0 SI OK, -1 SI "PLAN" N'EST PAS CORRECT
C     *****************************************************************
      REAL      XPLAN(4)
      REAL      XPOINT(3)
      INTEGER   IERR
C
      COMMON /CGEPSI/ XYZHUG,XYZMIN,XYZEPS
      REAL  XYZHUG,XYZMIN,XYZEPS
C
      INTEGER IPLMAX,I
      REAL    XPLMAX
C
      IERR = -1
      XPOINT(1) = 0.0
      XPOINT(2) = 0.0
      XPOINT(3) = 0.0
      IF((XPLAN(4).LE.XYZMIN).AND.(XPLAN(4).GE.-XYZMIN))THEN
        IERR = 0
        GOTO 9999
      ENDIF
C
      XPLMAX = 0.0
      IPLMAX = 0
      DO 10 I=1,3
        IF(ABS(XPLAN(I)).GT.XPLMAX)THEN
          IPLMAX = I
          XPLMAX = ABS(XPLAN(I))
        ENDIF
  10  CONTINUE
C
      IF( IPLMAX.EQ.0 )THEN
        IERR = -1
        CALL DSERRE(1,IERR,'PODUPN',' PLAN NUL ')
        GOTO 9999
      ENDIF
C     ----
      XPOINT(IPLMAX) = - XPLAN(4) / XPLAN(IPLMAX)
      IERR = 0
C
 9999 END
C
C
      SUBROUTINE PNVEPO( XPOINT,VEDIR,XPLAN, IERR )
C     *****************************************************************
C     OBJET PNVEPO  : CALCULE L'EQUATION DU PLAN (3D)
C     EN ENTREE :
C        XPOINT : UN POINT DU PLAN
C        VEDIR  : LE VECTEUR NORMAL AU PLAN
C     EN SORTIE :
C        XPLAN : EQUATION DU PLAN AX+BY+CZ+D = 0
C        IERR   : 0 SI OK, -1 SI "PLAN" N'EST PAS CORRECT
C     *****************************************************************
      REAL      XPOINT(3),VEDIR(3)
      REAL      XPLAN(4)
      INTEGER   IERR
C
      COMMON /CGEPSI/ XYZHUG,XYZMIN,XYZEPS
      REAL  XYZHUG,XYZMIN,XYZEPS
C
      REAL     XNORVE,SCALVE
      EXTERNAL XNORVE,SCALVE
C
      INTEGER IDIMC
      REAL    SNODIR
C
      IDIMC = 3
C     --- NORMALE AU PLAN ---
      SNODIR = XNORVE(VEDIR,IDIMC)
      IF( SNODIR.LT.XYZEPS )THEN
        IERR = -1
        GOTO 9999
      ENDIF
      SNODIR= 1.0 / SNODIR
      CALL MUSCVE(VEDIR,SNODIR,IDIMC,XPLAN)
C     --- CALCUL DU POINT ---
      XPLAN(4) = - SCALVE(XPLAN,XPOINT,IDIMC)
C      PRINT *,'PNVEPO : PLAN = ',XPLAN(1),' * X + ',
C     >                           XPLAN(2),' * Y + ',
C     >                           XPLAN(3),' * Z + ',
C     >                           XPLAN(4)
C
 9999 END
C
C
      SUBROUTINE POPLDR( XPLAN, XPOIDR,VDIRDR, ABCDR, IERR )
C     *****************************************************************
C     OBJET POPLDR  : CALCULE LE POINT D'INTERSECTION D'UN PLAN ET D'UNE DROITE
C     EN ENTREE :
C        XPLAN  : EQUATION DU PLAN AX+BY+CZ+D = 0
C        XPOIDR : UN POINT DE LA DROITE
C        VDIRDR : LE VECTEUR DIRECTEUR DE LA DROITE
C     EN SORTIE :
C        ABCDR  : L'ABSCISSE SUR LA DROITE CORRESPONDANT A L'INTERSECTION
C        IERR   : 0 SI OK, -1 SI PAS D'INTERSECTION
C     *****************************************************************
      REAL      XPLAN(4),XPOIDR(3),VDIRDR(3)
      REAL      ABCDR
      INTEGER   IERR
C
      COMMON /CGEPSI/ XYZHUG,XYZMIN,XYZEPS
      REAL  XYZHUG,XYZMIN,XYZEPS
C
      REAL     SCALVE
      EXTERNAL SCALVE
C
      INTEGER IDIMC
      REAL    XDENOM,XNUMER
C
      IDIMC = 3
      XDENOM = SCALVE(XPLAN,VDIRDR,IDIMC)
      IF((XDENOM.LT. XYZEPS).AND.(XDENOM.GT.-XYZEPS))THEN
        IERR = -1
        GOTO 9999
      ENDIF
      XNUMER = SCALVE(XPLAN,XPOIDR,IDIMC) + XPLAN(4)
      ABCDR = XNUMER / XDENOM
      IERR = 0      
C
 9999 END
C
      SUBROUTINE POVEPN( XPLAN, XPOINT,VDIR, IERR )
C     *****************************************************************
C     OBJET POVEPN  : CALCULE UN POINT ET LA NORMALE DU PLAN 
C     EN ENTREE :
C        XPLAN : EQUATION DU PLAN AX+BY+CZ+D = 0
C     EN SORTIE :
C        XPOINT : UN POINT DU PLAN
C        VDIR   : LE VECTEUR NORMAL AU PLAN
C        IERR   : 0 SI OK, -1 SI "PLAN" N'EST PAS CORRECT
C     *****************************************************************
      REAL      XPLAN(3),XPOINT(2),VDIR(2)
      INTEGER   IERR
C
      INTEGER IDIMC
      IDIMC = 3
C     --- NORMALE AU PLAN ---
      CALL COPIVE(XPLAN,IDIMC,VDIR)
C     --- CALCUL DU POINT ---
      CALL PODUPN(XPLAN,XPOINT,IERR)   
 9999 END
C
      FUNCTION INPNDR(XPOINT,VDIR,XPLAN,ITEST,XPI,IERR)
C     *****************************************************************
C     OBJET INPNDR  : INTERSECTION D'UN PLAN ET D'UNE DROITE
C     EN ENTREE :
C        XPOINT    : UN POINT DE LA DROITE
C        VDIR      : LE VECTEUR DIRECTEUR DE LA DROITE
C        XPLAN     : L'EQUATION DU PLAN : AX+BY+CZ+D = 0
C        ITEST     : SI ITEST=1 ON NE CALCULE PAS LA POSITION DU POINT
C     EN SORTIE : RENVOI 1 SI INTERSECTION 0 SINON
C        XPI    : POSITION DU POINT D'INTERSECTION (SI ITEST=0)
C        IERR   : 0 TOUJOURS OK
C     *****************************************************************
      INTEGER   INPNDR
      REAL      XPOINT(3),VDIR(3),XPLAN(4)
      INTEGER   ITEST,IERR
      REAL      XPI(3)
C
      COMMON /CGEPSI/ XYZHUG,XYZMIN,XYZEPS
      REAL  XYZHUG,XYZMIN,XYZEPS
C
      INTEGER   I
      REAL      ALPHA,XDENO,SCALVE
      EXTERNAL  SCALVE
C
      IERR = 0
C        ========================
C     --- TEST DE L'INTERSECTION ---
C        ========================
      XDENO = SCALVE(XPLAN,VDIR,3)
      IF((XDENO.GT.-XYZEPS).AND.(XDENO.LT.XYZEPS))THEN
C       ---- LE VECTEUR EST DANS LE PLAN ----
        INPNDR = 0
        GOTO 9999
      ENDIF          
      INPNDR = 1
      IF(ITEST.EQ.1)GOTO 9999
C        ================================
C     --- CALCUL DU POINT D'INTERSECTION ---
C        ================================
      ALPHA = (SCALVE(XPLAN,XPOINT,3) + XPLAN(4))
C      PRINT *,'VDIR =',(VDIR(I),I=1,3)
C      PRINT *,'ALPHA =',ALPHA
C      PRINT *,'XDENO =',XDENO
      ALPHA = -ALPHA / XDENO
C      ALPHA = (SCALVE(XPLAN,XPOINT,3) + XPLAN(4)) / XDENO
C      PRINT *,'ALPHA =',ALPHA
      CALL MUSCVE( VDIR, ALPHA, 3, XPI )
C      PRINT *,'XPI =',(XPI(I),I=1,3)
C      PRINT *,'XPOINT =',(XPOINT(I),I=1,3)
      CALL SOMMVE( XPI, XPOINT, 3, XPI )
C      PRINT *,'INTERSECTION PLAN =',XPI(1),XPI(2),XPI(3)
C
 9999 END
C 
      SUBROUTINE PL3PO_NEW( XP1,XP2,XP3, XPLAN, IERR )
C     *****************************************************************
C     OBJET  PL3PO_NEW   : CALCULE LE PLAN PASSANT PAR LES 3 POINTS
C     EN ENTREE:
C        XP1, XP2, XP3 : LES 3 POINTS DU PLAN
C     EN SORTIE
C        XPLAN   : LES COEFFICIENTS A,B,C,D DE L'EQUATION DU PLAN 
C                   AX+BY+CZ+D = 0
C        IERR     : -1 SI XP1 ET XP2 SONT CONFONDUS, 
C                      SI XP1,XP2 ET XP3 ALIGNES,
C                    0 SINON
C     *****************************************************************
      REAL      XP1(3),XP2(3),XP3(3),XPLAN(4)
      INTEGER   IERR
C
      COMMON /CGEPSI/ XYZHUG,XYZMIN,XYZEPS
      REAL  XYZHUG,XYZMIN,XYZEPS,XN,XNO
      REAL SCALVE
      EXTERNAL SCALVE
C
      REAL    COORD(9),XPLANO(4)
      INTEGER IPOINT(3),IDIMC,NPOINT,I,IND1,IND2
C
      CALL PL3PO( XP1,XP2,XP3, XPLANO, IERR )
      IERR = 0
C
      IDIMC = 3
      CALL COPIVE(XP1,IDIMC,COORD)
      CALL COPIVE(XP2,IDIMC,COORD(4))
      CALL COPIVE(XP3,IDIMC,COORD(7))
      NPOINT = 3
      DO 10 I=1,NPOINT
         IPOINT(I) = I
   10 CONTINUE
C
      IND1 = 0
      IND2 = 0
      CALL PLMCAR(IPOINT,NPOINT,IND1,IND2,COORD,IDIMC,XPLAN,IERR)
C
C     ---- POUR LE TEST ----
C
      DO 100 I=1,NPOINT
        XN  = SCALVE(XPLAN,COORD((I-1)*IDIMC+1),IDIMC) + XPLAN(4)
        XNO = SCALVE(XPLANO,COORD((I-1)*IDIMC+1),IDIMC) + XPLANO(4)
        IF((XN.GT.XNO).OR.(XN.LT. -XNO))THEN
           PRINT *,'PL3PO OLDM = ',XNO,' NEW = ',XN
        ELSE
        IF((XNO.GT.XN).OR.(XNO.LT. -XN))THEN
           PRINT *,'PL3PO OLD = ',XNO,' NEWM = ',XN
        ELSE
           PRINT *,'PL3PO IDEM OLD = ',XNO,' NEW = ',XN
        ENDIF
        ENDIF
 100  CONTINUE
C
      PRINT *,'PL3PO : ',(XPLANO(I)-XPLAN(I),I=1,4)
C
 9999 END
C 
      SUBROUTINE PL3PO( XP1,XP2,XP3, XPLAN, IERR )
C     *****************************************************************
C     OBJET  PL3PO   : CALCULE LE PLAN PASSANT PAR LES 3 POINTS
C     EN ENTREE:
C        XP1, XP2, XP3 : LES 3 POINTS DU PLAN
C     EN SORTIE
C        XPLAN   : LES COEFFICIENTS A,B,C,D DE L'EQUATION DU PLAN 
C                   AX+BY+CZ+D = 0
C        IERR     : -1 SI XP1 ET XP2 SONT CONFONDUS, 
C                      SI XP1,XP2 ET XP3 ALIGNES,
C                    0 SINON
C     *****************************************************************
      REAL      XP1(3),XP2(3),XP3(3),XPLAN(4)
      INTEGER   IERR
C
      COMMON /CGEPSI/ XYZHUG,XYZMIN,XYZEPS
      REAL  XYZHUG,XYZMIN,XYZEPS
C
      REAL     XN,V12(3),V23(3),XP(3),ZERO
      REAL     XNORVE,SCALVE
      EXTERNAL XNORVE,SCALVE
      INTEGER  IDIMC,I
      PARAMETER ( ZERO = 1.E-3 )
C 
      IDIMC = 3
      CALL DIFFVE(XP1,XP2,IDIMC,V12)
      CALL DIFFVE(XP2,XP3,IDIMC,V23)
      CALL VECTVE(V12,V23,IDIMC,XPLAN)
      XN = XNORVE(XPLAN,IDIMC)
      IF((XN.LE.XYZEPS).AND.(XN.GE. -XYZEPS))THEN
        IERR = -1
        CALL DSERRE(1,IERR,'PL3PO','POINTS ALIGNES ?')
        GOTO 9999
      ENDIF
      XN = 1.0 / XN
      IERR = 0
      CALL MUSCVE(XPLAN,XN,IDIMC,XPLAN)
      DO 10 I=1,IDIMC
        XP(I) = (XP1(I) + XP2(I) + XP3(I) ) / 3.0
   10 CONTINUE
      XPLAN(4) = - SCALVE(XPLAN,XP,IDIMC)
C
C     ---- POUR LE TEST ----
C
      XN = SCALVE(XPLAN,XP1,IDIMC) + XPLAN(4)
      IF((XN.GT.ZERO).OR.(XN.LT.-ZERO))THEN
C        PRINT *,'IL Y A UNE ERREUR DANS PL3PO XP1 '
C        PRINT *,'XPLAN = ',(XPLAN(I),I=1,4)
C        PRINT *,'XP1 = ',(XP1(I),I=1,3)
C        PRINT *,'XPLAN * XP1 = ',XN
        IERR = -1
      ENDIF
      XN = SCALVE(XPLAN,XP2,IDIMC) + XPLAN(4)
      IF((XN.GT.ZERO).OR.(XN.LT. -ZERO))THEN
C        PRINT *,'IL Y A UNE ERREUR DANS PL3PO XP2 '
C        PRINT *,'XPLAN = ',(XPLAN(I),I=1,4)
C        PRINT *,'XP2 = ',(XP2(I),I=1,3)
C        PRINT *,'XPLAN * XP2 = ',XN
        IERR = -1
      ENDIF
      XN = SCALVE(XPLAN,XP3,IDIMC) + XPLAN(4)
      IF((XN.GT.ZERO).OR.(XN.LT. -ZERO))THEN
C        PRINT *,'IL Y A UNE ERREUR DANS PL3PO XP3 '
C        PRINT *,'XPLAN = ',(XPLAN(I),I=1,4)
C        PRINT *,'XP3 = ',(XP3(I),I=1,3)
C        PRINT *,'XPLAN * XP3 = ',XN
        IERR = -1
      ENDIF
      IF(IERR.NE.0)CALL DSERRE(1,IERR,'PL3PO','CALCUL ERRONE')
 9999 END
C
C 
      SUBROUTINE PLMCAR(IPOINT,NPOINT,IND1,IND2,COORD,IDIMC,XPLAN,IERR)
C     *****************************************************************
C     OBJET  PLMCAR : CALCULE LE PLAN DES MOINDRES CARRES DE N POINTS
C     EN ENTREE:
C        ---- DEFINITION DES POINTS A TRAITER ----
C        IPOINT    : TABLEAU DES INDICES DES POINTS DANS COORD
C        NPOINT    : NOMBRE DE POINTS
C     OU
C        IND1,IND2 : INDICE DU PREMIER ET DERNIER POINT A TRAITER
C
C        COORD  : COORDONNEES DES POINTS
C
C     EN SORTIE
C        XPLAN   : LES COEFFICIENTS A,B,C,D DE L'EQUATION DU PLAN 
C                   AX+BY+CZ+D = 0
C        IERR     : -1 SI SOLUTION PAS UNIQUE
C                    0 SINON
C     AUTEUR : SIDI-MOHAMED TIJANI
C     *****************************************************************
      INTEGER NPOINT,IPOINT(*),IND1,IND2
      REAL    COORD(*)
      INTEGER IDIMC
      REAL    XPLAN(*)
      INTEGER IERR
C
      REAL G(3),S(3,3),C
      INTEGER I,J,L,NBPOI
C
      NBPOI = NPOINT
      IF( NBPOI.LE.0 )NBPOI = IND2 - IND1 + 1
      IF( NBPOI.LT.3 )THEN
        IERR = -1
        CALL DSERRE(1,IERR,'PLMCAR',' IL FAUT 3 POINTS OU +')
        GOTO 9999
      ENDIF
      IF( IDIMC.NE.3 )THEN
        IERR = -1
        CALL DSERRE(1,IERR,'PLMCAR',' 3D SEULEMENT')
        GOTO 9999
      ENDIF
      C = 0.
C
C     ---- AVEC LA LISTE DE POINTS ----
      IF( NPOINT.GT.0 )THEN
      DO 30 I=1,IDIMC
        G(I) = 0.
        DO 10 L=1,NPOINT
          G(I)=G(I)+COORD((IPOINT(L)-1)*IDIMC+I)
   10   CONTINUE
        G(I)=G(I)/NPOINT
        DO 20 L=1,NPOINT
          C=MAX(C,ABS(G(I)-COORD((IPOINT(L)-1)*IDIMC+I)))
   20   CONTINUE
   30 CONTINUE
C
      DO 60 I=1,IDIMC
        DO 50 J=1,I
          S(I,J)=0.
          DO 40 L=1,NPOINT
            S(I,J) = S(I,J) +
     >              ((COORD((IPOINT(L)-1)*IDIMC+I)-G(I))/C) *
     >              ((COORD((IPOINT(L)-1)*IDIMC+J)-G(J))/C)
   40     CONTINUE
          S(I,J)=S(I,J)/NPOINT
          S(J,I)=S(I,J)
   50   CONTINUE
   60 CONTINUE
      ELSE
C     ---- IDEM MAIS AVEC L'INTERVALLE ----
      DO 130 I=1,IDIMC
        G(I) = 0.
        DO 110 L=IND1,IND2
          G(I)=G(I)+COORD((L-1)*IDIMC+I)
  110   CONTINUE
        G(I)=G(I)/NBPOI
        DO 120 L=IND1,IND2
          C=MAX(C,ABS(G(I)-COORD((L-1)*IDIMC+I)))
  120   CONTINUE
  130 CONTINUE
C
      DO 160 I=1,IDIMC
        DO 150 J=1,I
          S(I,J)=0.
          DO 140 L=IND1,IND2
            S(I,J) = S(I,J) +
     >              ((COORD((L-1)*IDIMC+I)-G(I))/C) *
     >              ((COORD((L-1)*IDIMC+J)-G(J))/C)
  140     CONTINUE
          S(I,J)=S(I,J)/NBPOI
          S(J,I)=S(I,J)
  150   CONTINUE
  160 CONTINUE
      ENDIF
C
      CALL PRONUL(S,XPLAN)
      XPLAN(4)=-(XPLAN(1)*G(1)+XPLAN(2)*G(2)+XPLAN(3)*G(3))
C
      IERR = 0
 9999 END
C
      SUBROUTINE PRONUL(S,A)
C     *****************************************************************
C     OBJET PRONUL : CALCUL LA VALEUR PROPRE NULLE DE LA MATRICE S.
C     DONNEE   : S(3,3) EST UNE MATRICE SYMETRIQUE POSITIVE/NEGATIVE
C                (C.A.D. : VALEURS PROPRES DE MEME SIGNE).
C     RESULTAT : A(3) EST UN VECTEUR NORME ASSOCIE A
C                LA VALEUR PROPRE NULLE DE LA MATRICE S.
C
C     AUTEUR : SIDI-MOHAMED TIJANI
C     *****************************************************************
      REAL S(3,3)
      REAL A(3)
C
      REAL D,DIV,DELTA,ADELTA,B
      INTEGER N(3),L,I,J,K
      DATA N /2,3,1/
C
      D=0.
      L=0
      DO 10 I=1,3
        J=N(I)
        K=N(J)
        DELTA=S(J,J)*S(K,K)-S(J,K)**2
        ADELTA=ABS(DELTA)
        IF(ADELTA.LE.D) GOTO 10
        L=I
        D=ADELTA
        DIV=DELTA
   10 CONTINUE
      IF(D.GT.0.) GOTO 30
      D=0.
      L=0
      DO 20 I=1,3
        A(I)=0.
        DELTA=ABS(S(I,I))
        IF(DELTA.LE.D) GOTO 20
        L=I
        D=DELTA
   20 CONTINUE
      IF(D.LE.0.) THEN
        A(1)=1.
        RETURN
      ENDIF
      IF(L.EQ.1) THEN
        A(1)=-S(3,1)/S(1,1)
        A(3)=1.
        GOTO 40
      ENDIF
      IF(L.EQ.3) THEN
        A(1)=1.
        A(3)=-S(1,3)/S(3,3)
        GOTO 40
      ENDIF
      A(1)=1.
      A(3)=1.
      A(2)=(-S(1,2)-S(3,2))/S(2,2)
   30 J=N(L)
      K=N(J)
      A(L)=DIV
      A(J)=S(L,K)*S(J,K)-S(K,K)*S(L,J)
      A(K)=S(J,K)*S(L,J)-S(J,J)*S(L,K)
   40 B=SQRT(A(1)*A(1)+A(2)*A(2)+A(3)*A(3))
      IF(B.NE.0.) THEN
        A(1)=A(1)/B
        A(2)=A(2)/B
        A(3)=A(3)/B
      ENDIF
      RETURN
      END
C
C
      SUBROUTINE RPPNCR(IPOINT,NPOINT,IND1,IND2,
     >                  COORD,IDIMC,
     >                  ITVL,ITVMAX,RTVL,IRTMAX,
     >                  O,XMATT,COORD2,IDIMC2,IERR)
C     *****************************************************************
C     OBJET RPPNCR : PASSAGE DANS LE REPERE DU PLAN DES MOINDRES CARRES
C     EN ENTREE :
C      ----- UNE LISTE DE POINTS OU UN INTERVAL -----
C      IPOINT : LA LISTE DES POINTS A TRAITER
C      NPOINT : NOMBRE DE POINTS DANS LA LISTE
C      IND1,IND2 : INDICE DU PREMIER POINT, ET DU DERNIER
C
C     EN SORTIE : 
C      COORD2 : NOUVELLES COORDONNEES (SI IDIMC2 > 0)
C               EST REMPLI DE 1 A NBPOINT (OU IND2-IND1+1)
C           O : NOUVELLE ORIGINE
C        MATT : MATRICE 3x3 DE PASSAGE DANS LE NOUVEAU REPERE
C     *****************************************************************
      INTEGER IPOINT(*),NPOINT,IND1,IND2
      REAL    COORD(*)
      INTEGER IDIMC,ITVL(*),ITVMAX,IRTMAX
      REAL    RTVL(*)
      REAL    O(3),XMATT(3,3),COORD2(*)
      INTEGER IDIMC2,IERR
C
      REAL     SCALVE
      EXTERNAL SCALVE
      REAL    XPLAN(4),YMATT(3,3),XPOINT(3),XLGCOL
      INTEGER I,II,J,K,NBNUN,NBPOI
      REAL    ZERO
      PARAMETER (ZERO=1.E-7)
C
      CALL PLMCAR(IPOINT,NPOINT,IND1,IND2,COORD,IDIMC,XPLAN,IERR)
      IF( IERR.NE.0 )THEN
        CALL DSERRE(1,IERR,'RPPNCR','APPEL PLMCAR')
        GOTO 9999
      ENDIF
C     --- MODIF : 09.09.99 O.STAB POUR EVITER L'UNDERFLOW SUR SUN DANS M33INV
C     C'est pas grave si on ne projete pas dans le plan exact !!!
C     A TESTER ET PASSER ZERO EN COMMON !!!!
      DO 5 I=1,4
        IF((XPLAN(I).LT.ZERO).AND.(XPLAN(I).GT.-ZERO))XPLAN(I) = 0.0
    5 CONTINUE
C
      CALL M33DPN(XPLAN,YMATT(1,1),YMATT(1,2),YMATT(1,3),IERR)
      IF( IERR.NE.0 )THEN
        CALL DSERRE(1,IERR,'RPPNCR','APPEL M33DPN')
        GOTO 9999
      ENDIF
C
      CALL M33INV(YMATT,XMATT,IERR)
      IF( IERR.NE. 0 )THEN
        CALL DSERRE(1,IERR,'RPPNCR','APPEL M33INV')
        GOTO 9999
      ENDIF
C
      CALL PODUPN( XPLAN, O, IERR )
      IF( IERR.NE. 0 )THEN
        CALL DSERRE(1,IERR,'RPPNCR','APPEL PODUPN')
        GOTO 9999
      ENDIF
C   
      IF( IDIMC2.LE.0 )GOTO 9999  
      NBNUN = 1
      NBPOI = MAX(NPOINT,IND2-IND1+1)
      DO 100 I=1,NBPOI
        II = I+IND1-1
        IF( NPOINT.GT.0 )II = IPOINT(I)
        CALL COPIVE(COORD((II-1)*IDIMC+1),IDIMC,XPOINT)
        CALL DIFFVE(XPOINT,O,IDIMC,XPOINT)
        DO 20 J=1,IDIMC2
          XLGCOL = XMATT(J,1)*XPOINT(1)
          DO 10 K=2,IDIMC
            XLGCOL = XMATT(J,K)*XPOINT(K) + XLGCOL
   10     CONTINUE
          COORD2((I-1)*IDIMC2+J)= XLGCOL
   20   CONTINUE
  100 CONTINUE
C     
 9999 END
C


C     *****************************************************************
C     MODULE  : CG (CALCUL GEOMETRIQUE)
C     FICHIER : CG_REPERE.F
C     OBJET   : CALCUL POUR LA GEOMETRIE 3D
C     FONCT.  :
C     OBJET M33MUL : MULTIPLICATION DE MATRICES 3*3
C     OBJET M33INV : INVERSION D'UNE MATRICE 3*3
C     OBJET M33DET : DETERMINANT D'UNE MATRICE 3*3
C     OBJET M33APP : APPLIQUE UNE TRANSFORMATION A X
C     *****************************************************************
C
      SUBROUTINE M33MUL(MAT1,MAT2,MAT3,IERR) 
C     ******************************************************
C     OBJET M33MUL : MULTIPLICATION DE MATRICES 3*3
C     ******************************************************
      REAL    MAT1(3,*),MAT2(3,*),MAT3(3,*)
      INTEGER IERR
C
      INTEGER I,J,K
C
      DO 20 I=1,3
        DO 10 J = 1,3
        MAT3(I,J) = 0.0
        DO 5 K = 1,3
          MAT3(I,J) = MAT1(J,K)  * MAT2(K,I) + MAT3(I,J)
    5   CONTINUE
   10   CONTINUE
   20 CONTINUE
 9999 END
C
C
      SUBROUTINE M33INV(MAT,MATINV,IERR) 
C     ******************************************************
C     OBJET M33INV : INVERSION D'UNE MATRICE 3*3
C     ******************************************************
      REAL    MAT(3,*),MATINV(3,*)
      INTEGER IERR
C
      REAL    MATDET,MATEMP(3,3)
      INTEGER I,J
      REAL    ZERO
      PARAMETER (ZERO = 1.E-6)
C
      CALL M33DET(MAT,MATDET)
      IF( MATDET.LT. ZERO )THEN
        IERR = -1
        GOTO 9999
      ENDIF
      DO 20 I=1,3
        DO 10 J = 1,3
          MATEMP(I,J) = MAT(J,I) / MATDET
   10   CONTINUE
   20 CONTINUE
C     ---- VERIFICATION ---
C      CALL M33MUL(MATEMP,MAT,MATINV,IERR) 
C      PRINT *,'M33INV :  MAT*MATINV = ID '
C      DO 100 I=1,3
C        PRINT *,(MATINV(I,J),J=1,3)
C  100 CONTINUE
C
      DO 40  I=1,3
        DO 30 J = 1,3
          MATINV(I,J) = MATEMP(I,J) 
   30   CONTINUE
   40 CONTINUE
 9999 END
C
C
      SUBROUTINE M33DET(MAT,MATDET) 
C     ******************************************************
C     OBJET M33DET : DETERMINANT D'UNE MATRICE 3*3
C     ******************************************************
      REAL    MAT(3,*),MATDET
C
      MATDET = MAT(1,1) * (MAT(2,2)*MAT(3,3) - MAT(3,2)*MAT(2,3)) +
     >         MAT(1,2) * (MAT(2,3)*MAT(3,1) - MAT(3,3)*MAT(2,1)) +
     >         MAT(1,3) * (MAT(2,1)*MAT(3,2) - MAT(3,1)*MAT(2,2))
 9999 END
C
C
      SUBROUTINE M33APP(MAT,X,IDIMC,NBN,YT,Y) 
C     ******************************************************
C     OBJET M33APP : APPLIQUE UNE TRANSFORMATION A X
C
C     X ET Y PEUVENT ETRE LES MEMES TABLEAUX
C     YT TABLEAU DE TRAVAIL DE TAILLE IDIMC
C     ******************************************************
      REAL    MAT(3,*),X(3,*)
      INTEGER IDIMC,NBN
      REAL    YT(*),Y(3,*)
C
      INTEGER I,J,K
C
      DO 30 I=1,NBN
        DO 10 J=1,IDIMC
          YT(J) = 0.0
          DO 5  K=1,IDIMC
            YT(J) = YT(J) + MAT(J,K)*X(K,I)
    5     CONTINUE
   10   CONTINUE
        DO 20 J=1,IDIMC
          Y(J,I) = YT(J)
   20   CONTINUE
   30 CONTINUE
 9999 END
C


C     *****************************************************************
C     MODULE  : ES (ENTREES SORTIES)
C     FICHIER : ES_ERREUR.F
C     OBJET   : GESTION DES ERREURS ET AUTRES UTILITAIRES GENERAUX
C
C     FONCT.  :
C     OBJET DSINIT : INITIALISATION DES CONSTANTES DE DELOS (OBSOLET)
C     OBJET  DSINIT2 : INITIALISATION DES CONSTANTES DE DELOS
C     OBJET  DSERRE : ECRIT UN MESSAGE D'ERREUR (EN MODE DEBUG)
C
C     AUTEUR  : O.STAB
C     DATE    : 02.96 / 05.96
C     MODIFICATIONS :
C      AUTEUR, DATE, OBJET : O.STAB, 05.11.04, ajout du mode DEBUG
C
C
C     *****************************************************************
C
      SUBROUTINE DSINIT
C     *****************************************************************
C     OBJET DSINIT : INITIALISATION DES CONSTANTES DE DELOS (OBSOLET)
C
C          DOIT ETRE APPELE DE LE DEBUT DU PROGRAMME PRINCIPAL
C
C     *****************************************************************
      INTEGER IMODE
      COMMON /MODINI/IMODE
      IMODE = 2
      CALL ICGEPS
      CALL STINIT
      END
C
C
      SUBROUTINE DSINIT2(ITRACE)
C     *****************************************************************
C     OBJET  DSINIT2 : INITIALISATION DES CONSTANTES DE DELOS
C
C          DOIT ETRE APPELE DE LE DEBUT DU PROGRAMME PRINCIPAL
C
C     *****************************************************************      
      INTEGER ITRACE
      INTEGER IMODE
      COMMON /MODINI/IMODE
      IMODE = ITRACE
      CALL ICGEPS
      CALL STINIT
      END
C
      FUNCTION IDSLEN(CHAINE)
C     *****************************************************************
C     OBJET IDSLEN : RENVOI LA LONGUEUR D'UNE CHAINE
C     *****************************************************************
      INTEGER       IDSLEN 
      CHARACTER*(*) CHAINE
C
      INTEGER I,J,LCH
C     
      LCH = LEN(CHAINE) 
      J = LCH
      DO 10 I=1,LCH
        IF( CHAINE(J:J).NE.' ' )GOTO 888
        J = J - 1
   10 CONTINUE
  888 IDSLEN = J
C
  999 END     
C
C
      SUBROUTINE DSCHAI(IO,LABEL,NOM)
C     *****************************************************************
C     OBJET  DSCHAI : ECRIT UNE CHAINE SUR LE STANDARD OUTPUT
C     *****************************************************************
      CHARACTER*(*) NOM,LABEL
      INTEGER IO
C
      INTEGER    IECR
      PARAMETER (IECR = 6)
      INTEGER    IDSLEN
      EXTERNAL   IDSLEN
C
      IF( IO.EQ. 1 )THEN
C     --- STANDARD INPUT --- 
        WRITE ( UNIT = IECR, FMT = *, ERR = 999) 
     >  LABEL(:IDSLEN(LABEL)),NOM(:IDSLEN(NOM))
      ELSE
        IF( IO .EQ. 2 )THEN
C       --- ECRITURE DANS UN FICHIER ESPION ---
        WRITE ( UNIT = IECR, FMT = *) 'NON ENCORE IMPLEMENTE'   
        ELSE
          IF( IO.EQ. 3 )THEN
C         --- AFFICHAGE VIA INTERFACE GRAPHIQUE ---
        WRITE ( UNIT = IECR, FMT = *) 'NON ENCORE IMPLEMENTE'   
          ENDIF
        ENDIF
      ENDIF
C   10 FORMAT(A)
  999 END
C
C
      SUBROUTINE DSERRE(IO,NUM,MODULE,MESSAG)
C     *****************************************************************
C     OBJET  DSERRE : ECRIT UN MESSAGE D'ERREUR (EN MODE DEBUG)
C                     SUR LE STANDARD OUTPUT
C     *****************************************************************
      CHARACTER*(*) MESSAG,MODULE
      INTEGER NUM
      INTEGER IO
C
      INTEGER IMODE
      COMMON /MODINI/IMODE
      IF(IMODE.LT.2)GOTO 9999
C
      IF( NUM .EQ. -1 )THEN
        CALL DSCHAI(IO,
     >      'ERR -1  DONNEES INCORRECTES DANS :',MODULE)
      ELSE
        IF( NUM .EQ. -2 )THEN
          CALL DSCHAI(IO,
     >         'ERR -2  PROBLEME MEMOIRE DANS :',MODULE)
        ELSE
          IF( NUM .EQ. -3 )THEN
            CALL DSCHAI(IO,
     >           'ERR -3  NON ENCORE IMPLEMENTE DANS :',MODULE)
          ELSE
            PRINT *,NUM
          ENDIF
        ENDIF
      ENDIF      
      CALL DSCHAI(IO,MESSAG,' ')
 9999 END
C      
C     *****************************************************************
C     MODULE  : ST (STRUCTURE DES DONNEES)
C     FICHIER : ST_ENSEMBLE.F
C     OBJET   : MANIPULATION DES ENSEMBLES
C     FONCT.  : 
C          ENSTRI : TRI UN TABLEAU D'ENTIER DANS L'ORDRE CROISSANT
C          ENSCP  : COPIE UN TABLEAU D'ENTIER DANS UN AUTRE
C
C        OPERATIONS BOOLEENNES SUR DES ENSEMBLES 
C          ENSUNI : FAIT L'UNION ENTRE 2 TABLEAUX TRIES (CF ENSTRI)
C          ENSINT : FAIT L'INTERSECTION ENTRE 2 TABLEAUX TRIES (CF ENSTRI)
C          ENSDIF : FAIT LA DIFFERENCE ENTRE 2 TABLEAUX TRIES (CF ENSTRI)
C
C     AUTEUR  : O. STAB
C     DATE    : 03.95
C     MODIFICATIONS :
C      AUTEUR, DATE, OBJET : 
C
C
C     *****************************************************************
C
      SUBROUTINE ENSTRI(ITAB1,NB1)
C     *****************************************************
C     OBJET ENSTRI : TRI UN TABLEAU D'ENTIER DANS L'ORDRE CROISSANT
C     EN ENTREE:
C        ITAB1 : TABLEAU A ORDONNER
C        NB1   : CARDINAL DE NB1
C     EN SORTIE : 
C        IATB1 : TRIE
C     ******************************************************
      INTEGER   ITAB1(*), NB1
C
      CALL KNUTA(NB1,ITAB1)
      END
C
      SUBROUTINE ENSCP(ITAB1,NB1,ITAB2,NB2)
C     *****************************************************
C     OBJET ENSCP : COPIE D'UN TABLEAU D'ENTIER 
C     EN ENTREE:
C        ITAB1 : TABLEAU A COPIER
C        NB1   : CARDINAL DE NB1
C     EN SORIE : 
C        ITAB2 : COPIE DE ITAB1
C        NB2   : CARDINAL DE NB2 (=NB1)
C     ******************************************************
      INTEGER   ITAB1(NB1), NB1, ITAB2(NB1), NB2
C
      INTEGER   I
C
      DO 10 I=1,NB1
        ITAB2(I) = ITAB1(I)
   10 CONTINUE
      NB2 = NB1
      END
C         
C
      SUBROUTINE ENSAJO(ITAB1,NB1,ITAB2,NB2)
C     *****************************************************
C     OBJET ENSAJO : COPIE UN TABLEAU D'ENTIER DANS UN AUTRE
C     EN ENTREE:
C        ITAB1 : TABLEAU A COPIER
C        NB1   : CARDINAL DE NB1
C     EN SORIE : 
C        ITAB2 : CONCATENATION ITAB2+ITAB1
C        NB2   : CARDINAL DE NB2 (=NB1+NB2)
C     ******************************************************
      INTEGER   ITAB1(NB1), NB1, ITAB2(NB1), NB2
C
      INTEGER   I
C
      DO 10 I=1,NB1
        ITAB2(I+NB2) = ITAB1(I)
   10 CONTINUE
      NB2 = NB1+NB2
      END
C         
C
      SUBROUTINE ENCOMP(ITAB1,NB1,NB2)
C     *****************************************************
C     OBJET ENCOMP : COMPRIME UN TABLEAU D'ENTIER (SUPPRIME LES DOUBLONS)
C     EN ENTREE:
C        ITAB1 : TABLEAU 
C        NB1   : CARDINAL DE NB1
C     EN SORIE : 
C        ITAB1 : TABLEAU COMPRIME (ET TRIE)
C        NB2   : CARDINAL DE NB2 ( =< NB1)
C     ******************************************************
      INTEGER   ITAB1(NB1), NB1, NB2
C
      INTEGER   I,J
C
      CALL KNUTA(NB1,ITAB1)
      J = 1
      DO 10 I=2,NB1
        IF( ITAB1(J).EQ. ITAB1(I))GOTO 10
        J = J + 1
        ITAB1(J) = ITAB1(I)
   10 CONTINUE
      NB2 = J
      END
C         
      SUBROUTINE ENSUNI(ITAB1,NB1,ITAB2,NB2,ITAB3,NB3MAX,NB3,IERR)
C     ***********************************************************
C     OBJET : FAIT L'UNION ENTRE 2 TABLEAUX TRIES (CF ENSTRI)
C     EN ENTREE:
C        ITAB1,TAB2 : TABLEAUX
C        NB1  ,NB2  : CARDINAUX RESPECTIFS
C        NB3MAX     : TAILLE DU TABLEAU ITAB3
C     EN SORTIE : 
C        ITAB3  :  ITAB1 U ITAB2 (LE TABLEAU EST TRIE)
C         NB3   :  CARDINAL DE ITAB1 U ITAB3
C        IERR   :  CODE D'ERREUR 0 => OK,
C                  -N => MANQUE N CASES A ITAB3
C     ***********************************************************
      INTEGER   ITAB1(NB1),ITAB2(NB2),ITAB3(NB3MAX)
      INTEGER   NB1,NB2,NB3,NB3MAX,IERR 
C
      INTEGER   I,J,II,JJ
C
      I=1
      J=1
      NB3=0
      IERR = 0
   10 IF( J .GT. NB2 )THEN
        DO 20 II=I,NB1
          NB3 = NB3 + 1
          IF( NB3 .LE. NB3MAX )ITAB3(NB3) = ITAB1(II)
   20   CONTINUE
        IF( NB3 .GT. NB3MAX )IERR = NB3 - NB3MAX
        GOTO 999         
      ENDIF
C
      IF( I .GT. NB1 )THEN
        DO 30 JJ=J,NB2
          NB3 = NB3 + 1
          IF( NB3 .LE. NB3MAX)ITAB3(NB3) = ITAB2(JJ)
   30   CONTINUE
        IF( NB3 .GT. NB3MAX )IERR = NB3 - NB3MAX
        GOTO 999         
      ENDIF        
C
      NB3 = NB3 + 1
      IF(ITAB1(I) .GT. ITAB2(J))THEN
        IF( NB3 .LE. NB3MAX)ITAB3(NB3) = ITAB2(J)
        J = J + 1
      ELSE 
        IF(ITAB1(I) .LT. ITAB2(J))THEN
          IF( NB3 .LE. NB3MAX)ITAB3(NB3) = ITAB1(I)
          I = I + 1
        ELSE
          IF( NB3 .LE. NB3MAX)ITAB3(NB3) = ITAB1(I)
          I = I + 1
          J = J + 1
        ENDIF
      ENDIF
      GO TO 10
  999 END
C           
      SUBROUTINE ENSINT(ITAB1,NB1,ITAB2,NB2,ITAB3,NB3MAX,NB3,IERR)
C     ***********************************************************
C     OBJET : FAIT L'INTERSECTION ENTRE 2 TABLEAUX TRIES (CF ENSTRI)
C     EN ENTREE:
C        ITAB1,TAB2 : TABLEAUX  
C        NB1  ,NB2  : CARDINAUX RESPECTIFS
C        NB3MAX     : TAILLE DU TABLEAU ITAB3
C     EN SORTIE : 
C        ITAB3  :  ITAB1 N ITAB2 (LE TABLEAU EST TRIE)
C         NB3   :  CARDINAL DE ITAB1 N ITAB3
C        IERR   :  CODE D'ERREUR 0 => OK,
C                  -N => MANQUE N CASES A ITAB3
C     ***********************************************************
      INTEGER   ITAB1(NB1), ITAB2(NB2), ITAB3(NB3MAX)
      INTEGER   NB3MAX, NB1, NB2, NB3, IERR 
C
      INTEGER   I,J
C
      I=1
      J=1
      NB3=0
      IERR = 0
   10 IF(( J .GT. NB2 ) .OR. ( I .GT. NB1 ))GO TO 999
      IF(ITAB1(I) .GT. ITAB2(J))THEN
        J = J + 1
      ELSE IF(ITAB1(I) .LT. ITAB2(J))THEN
        I = I + 1
      ELSE
        NB3 = NB3 + 1
        IF( NB3 .LE. NB3MAX)ITAB3(NB3) = ITAB1(I)
        I = I + 1
        J = J + 1
      ENDIF
      GO TO 10
  999 END
C  
C
      SUBROUTINE ENSDIF(ITAB1,NB1,ITAB2,NB2,ITAB3,NB3MAX,NB3,IERR)
C     ***********************************************************
C     OBJET : FAIT LA DIFFERENCE ENTRE 2 TABLEAUX TRIES (CF ENSTRI)
C     EN ENTREE:
C        ITAB1,TAB2 : TABLEAUX  
C        NB1  ,NB2  : CARDINAUX RESPECTIFS
C        NB3MAX     : TAILLE DU TABLEAU ITAB3
C     EN SORTIE : 
C        ITAB3  :  ITAB1 - ITAB2 (LE TABLEAU EST TRIE)
C         NB3   :  CARDINAL DE ITAB1 - ITAB3
C        IERR   :  CODE D'ERREUR 0 => OK,
C                  -N => MANQUE N CASES A ITAB3
C     ***********************************************************
      INTEGER   ITAB1(NB1), ITAB2(NB2), ITAB3(NB3MAX)
      INTEGER   NB3MAX, NB1, NB2, NB3, IERR 
C
      INTEGER   I,J,II
C    
      I=1
      J=1
      NB3=0
      IERR = 0
   10 IF( J .GT. NB2 )THEN
        DO 20 II=I,NB1
          NB3 = NB3 + 1
          IF( NB3 .LE. NB3MAX)ITAB3(NB3) = ITAB1(II)
   20   CONTINUE
        IF( NB3 .GT. NB3MAX)IERR = NB3-NB3MAX
        GOTO 999         
      ENDIF
      IF( I .GT. NB1 )GO TO 999
      IF(ITAB1(I) .GT. ITAB2(J))THEN
        J = J + 1
      ELSE IF(ITAB1(I) .LT. ITAB2(J))THEN
        NB3 = NB3 + 1
        IF( NB3 .LE. NB3MAX)ITAB3(NB3) = ITAB1(I)
        I = I + 1
      ELSE
        I = I + 1
        J = J + 1
      ENDIF
      GO TO 10
  999 END
C        
C     **********************************************************************
C     MODULE  : ST  
C     FICHIER : ST_SPH.F
C     OBJET    : UTILITAIRES POUR LA GESTION DES SPHERES CIRCONSCRITES 
C     FONCT.   :
C      SPPERM  : PERMUTE 2 ELEMENTS D'UN TABLEAU
C      SPCOMP   : RENUMEROTE LES ELEMENTS D'UN TABLEAU POUR LES COMPACTER
C                  EN DEBUT : DE 1 A "NBNUM"
C
C     AUTEUR   : O. STAB 
C     DATE     : 03.95
C     MODIFICATIONS :
C      AUTEUR, DATE, OBJET :
C
C
C     **********************************************************************
C
      SUBROUTINE SPPERM(TAB,NBNMAX,NBE,IT1,IT2,IERR)
C     **********************************************************************
C     OBJET : PERMUTE 2 ELEMENTS D'UN TABLEAU
C     EN ENTREE:
C      ITAB     :   TABLEAU DES ELEMENTS
C      NBCMAX :    (2..6) NOMBRE DE COTES MAXIMUM DES ELEMENTS
C      NBE     :   NOMBRE D'ELEMENTS DU MAILLAGE
C      ITL,IT2:    LES 2 ELEMENTS A PERMUTER
C     EN SORTIE:
C     **********************************************************************
      REAL        TAB(*)
      INTEGER     NBNMAX,NBE
      INTEGER     IT1, IT2, IERR
C
      INTEGER I
      REAL     TAMPON(4)
C
      IF( IT1 .EQ. IT2 )GO TO 999
      IF((IT1.LT.1).OR.(IT1.GT.NBE).OR.
     >    (IT2.LT.1).OR.(IT2.GT.NBE))THEN
        IERR = -1
        GO TO 999
      ENDIF
C     ------------------ SAUVEGARDE IT2 ---
      DO 10 I=1,NBNMAX
       TAMPON(I)=TAB((IT2-1)*NBNMAX+I)
   10 CONTINUE
C     ---------- TRANSFERT IT1 -> IT2 ----------
      DO 20 I=1,NBNMAX
        TAB((IT2-1)*NBNMAX+I)=TAB((IT1-1)*NBNMAX+I)
   20 CONTINUE
C     ---------- TRANSFERT IT2 -> IT1 ----------
      DO 30 I=1,NBNMAX
        TAB((IT1-1)*NBNMAX+I)=TAMPON(I)
   30 CONTINUE
C     ------------------
  999 END
C
      SUBROUTINE SPCOMP(TAB,NBCOL,NBLIG,NUM,NBNUM,IERR)
C     **********************************************************************
C     OBJET : RENUMEROTE LES ELEMENTS D'UN TABLEAU POUR LES COMPACTER
C            EN DEBUT : DE 1 A "NBNUM"
C     EN ENTREE:
C      NUM     :   NUM(I) EST NUMERO DE L'ELEMENT QUI DOIT ETRE MIS EN I
C                  ATTENTION !! NUM DOIT ETRE TRIE AVEC ENSTRI
C      NBNUM   :   NOMBRE D'ELEMENTS A RENUMEROTER
C     EN SORTIE:
C     COMPLEXITE : O(NBNUM)
C     PRINCIPE     : LES PERMUTATIONS FONCTIONNENT SI NUM(I)>I
C                    C.A.D. L'ANCIENNE POSITION > A LA NOUVELLE
C                    ON EST DANS CE CAS SI NUM EST TRIE PAR ORDRE CROISS.
C     **********************************************************************

      REAL       TAB(*)
      INTEGER    NBCOL,NBLIG
      INTEGER    NUM(*),NBNUM,IERR
C
      INTEGER I
C
      DO 10 I=1,NBNUM
        CALL SPPERM(TAB,NBCOL,NBLIG,NUM(I),I,IERR)
   10 CONTINUE
      END
C
C     *******************************************************************
C     FICHIER  : ST_EVAL.F
C     OBJET    : EVALUATION DES MAILLAGES 1D 2D ET 3D 
C
C     FONCT.   :
C     OBJET STTTPG : ECRIT UN MAILLAGE SOUS FORME DE PROGRAMME FORTRAN
C     OBJET EVFCTT : MIN,MAX,SOMME D'UNE FONCTION SUR UN MAILLAGE 
C
C     AUTEUR   : O. STAB
C     DATE     : 07.95
C     TESTS    : 07.95
C     MODIFICATIONS :
C      AUTEUR, DATE, OBJET : O.STAB, 08.97, RESTRUCTURATION
C      AUTEUR, DATE, OBJET : O.STAB, 10.97, INTEGRATION V.2.0.0
C      AUTEUR, DATE, OBJET : O.STAB, 11.97, RESTRUCTURATION
C
C
C     *******************************************************************
C
      SUBROUTINE STTTPG(IDE,ITRNOE,NBNMAX,ITRTRI,NBCMAX,NOETRI,NOEMAX,
     >                  COORD,IDIMC,NBN,NBE,IERR)
C     *****************************************************************
C     OBJET STTTPG : ECRIT UN MAILLAGE SOUS FORME DE PROGRAMME FORTRAN 
C     EN ENTREE 
C       --------- LE MAILLAGE ---------------------
C       ITRNOE,NBNMAX,ITRTRI,NBCMAX,NOETRI,NOEMAX,NBN,NBE : LE MAILLAGE
C       COORD,IDIMC: LES COORDONNEES DES NOEUDS
C
C     EN SORTIE   : UNE EVALUATION
C       IERR      : CODE D'ERREUR
C                      -1 TOUS LES POINTS N'ONT PAS PU ETRE AJOUTES
C                      -2 ITVL OU RTVL TROP PETIT
C     REMARQUES :
C     **********************************************************************
      INTEGER IDE,NBE,ITRNOE(*),NBNMAX,ITRTRI(*),NBCMAX
      INTEGER IDIMC,NOETRI(*),NOEMAX,NBN,IERR
      REAL    COORD(*),R
C
      INTEGER  I,J
      INTEGER  IP,IX
      INTEGER ICLAV,IECR
      PARAMETER (ICLAV = 5, IECR = 6)
C
      IF( NBE.LE. 0 )GOTO 9999
      R = 1. / 15.
C
      WRITE(UNIT = IECR, FMT = '(A)') 
     >'      SUBROUTINE T3IXXX(IDE,IDIMC,R,COORD,'
      WRITE(UNIT = IECR, FMT = '(A)') 
     >'     >                  ITRNOE,NBNMAX,ITRTRI,NBCMAX,'
      WRITE(UNIT = IECR, FMT = '(A)')     
     >'     >                  NOETRI,NOEMAX,NBN,NBE)'
      WRITE(UNIT = IECR, FMT = '(A)')
     >'C     **********************************************'
      WRITE(UNIT = IECR, FMT = '(A)') 
     >'C     OBJET : MAILLAGE EN DUR             '
      WRITE(UNIT = IECR, FMT = '(A)') 
     >'C             A TOPOLOGIE CONSTANTE       '  
      WRITE(UNIT = IECR, FMT = '(A)') 
     >'C     **********************************************'
C
      WRITE(UNIT = IECR, FMT = '(A)') 
     >'      INTEGER IDE,IDIMC,ITRNOE(*),NBNMAX,ITRTRI(*)'
      WRITE(UNIT = IECR, FMT = '(A)') 
     >'      INTEGER NBCMAX,NBE,NBN,NOETRI(*),NOEMAX'
      WRITE(UNIT = IECR, FMT = '(A)') 
     >'      REAL R,COORD(*)'
C
      WRITE(UNIT = IECR, FMT = *) 
     >'      IDE = ',IDE
      WRITE(UNIT = IECR, FMT = *) 
     >'      NBNMAX = ',NBNMAX
      WRITE(UNIT = IECR, FMT = *) 
     >'      NBCMAX = ',NBCMAX
      WRITE(UNIT = IECR, FMT = *) 
     >'      NBN = ',NBN
      WRITE(UNIT = IECR, FMT = *) 
     >'      NBE = ',NBE
      WRITE(UNIT = IECR, FMT = '(A)') 
     >'C     ---- LES COORDONNEES DES NOEUDS ----'
      DO 5 I=1,NBN
        DO 4 J=1,IDIMC
          IX = (I-1)*IDIMC+J
      WRITE(UNIT = IECR, FMT = *) 
     >     '      COORD(',IX,') =',COORD(IX)*R,'*R'
   4    CONTINUE
   5  CONTINUE
      WRITE(UNIT = IECR, FMT = '(A)') 
     >'C     ---- LES TETRA INCIDENTS AUX NOEUDS ----'
      DO 30 I=1,NBE
        DO 10 J=1,NBNMAX
           IP = (I-1)*NBNMAX+J
      WRITE(UNIT = IECR, FMT = *) 
     >      '      ITRNOE(',IP,') = ',ITRNOE(IP)
   10   CONTINUE
        DO 20 J=1,NBCMAX
           IP = (I-1)*NBCMAX+J
      WRITE(UNIT = IECR, FMT = *) 
     >      '      ITRTRI(',IP,') = ',ITRTRI(IP)
   20   CONTINUE
   30 CONTINUE
      WRITE(UNIT = IECR, FMT = '(A)') 
     >'C     ---- LES TETRA INCIDENTS AUX NOEUDS ----'
      WRITE(UNIT = IECR, FMT = '(A)')      
     >'      IF(NOEMAX.LT.NBN)GOTO 9999'
      DO 40 I=1,NBN
      WRITE(UNIT = IECR, FMT = *) 
     >    '      NOETRI(',I,') =',NOETRI(I)
   40 CONTINUE
      WRITE(UNIT = IECR, FMT = '(A)') 
     >'C        '
      WRITE(UNIT = IECR, FMT = '(A)') 
     >' 9999 END'
C
C
 9999 END
C
      SUBROUTINE EVFCTT(ITRNOE,NBNMAX,FCVAL,
     >          COORD,IDIMC,NBN,NBE,
     >          VALMIN,VALMAX,NBEINT,
     >          RMINI,IMINI,RMAXI,IMAXI,RTOTA,IERR)
C     *****************************************************************
C     OBJET EVFCTT : MIN,MAX,SOMME D'UNE FONCTION SUR UN MAILLAGE 
C     EN ENTREE 
C        VALMIN,VALMAX : VALEUR MINIMUM ET MAXIMUM DE L'INTERVAL
C        FCVAL  : FONCTION DE 4 PARAMETRES 
C                 + LES COORDONNEES DES NBNMAX POINTS DE L'ELEMENT
C                 + DIMENSION DE L'ESPACE
C
C     EN SORTIE   : 
C        NBEINT: NOMBRE D'ELEMENTS DANS  L'INTERVALLE
C        RMINI : VALEUR MINIMUM
C        IMINI : INDICE DE L'ELEMENT DE VALEUR MINIMUM
C        RMAXI : VALEUR MAXIMUM
C        IMAXI : INDICE DE L'ELEMENT DE VALEUR MAXIMUM
C        RTOTA : TOTAL DES VALEUR 
C
C     REMARQUES :
C     **********************************************************************
      INTEGER ITRNOE(*),NBNMAX
      INTEGER IDIMC,NBN,NBE,IERR
      REAL    COORD(*)
      REAL    VALMIN,VALMAX
      INTEGER  NBEINT,IMINI,IMAXI
      REAL     RMINI,RMAXI,RTOTA
C
      INTEGER  I,J,IP(4)
      REAL     VAL,FCVAL
      EXTERNAL FCVAL
C
      RTOTA = 0.0
      RMAXI = -1.0
      RMINI = 1.0e38
      NBEINT = 0
C
      DO 120 I=1,NBE
C           ============
C       ---- CALCUL FCVAL ----
C           ============
C
        DO 10 J=1,NBNMAX
          IP(J)  = (ITRNOE((I-1)*NBNMAX+J)-1)*IDIMC+1
   10   CONTINUE
C
        GOTO (20,30,40,50,60,70,80) NBNMAX
C    
C       --- NBNMAX = 0 : IMPOSSIBLE --------
C          -------------------------------
        IERR = -1
        CALL DSERRE(1,IERR,'EVFCTT','ELEMENTS SANS NOEUDS')
        GOTO 9999           
C    
C       --- NBNMAX = 1 : ELEMENTS = NOEUDS ------------
C          -------------------------------
   20   CONTINUE
        VAL = FCVAL(COORD(IP(1)),IDIMC)
        GOTO 100
C    
C       --- NBNMAX = 2 : ELEMENTS = SEGMENTS ------------
C          -------------------------------
   30   CONTINUE
        VAL = FCVAL(COORD(IP(1)),COORD(IP(2)),IDIMC)
        GOTO 100
C    
C       --- NBNMAX = 3 : ELEMENTS = TRIANGLES ------------
C          -------------------------------
   40   CONTINUE
        VAL = FCVAL(COORD(IP(1)),COORD(IP(2)),
     >              COORD(IP(3)),IDIMC)
        GOTO 100
C
C    
C       --- NBNMAX = 4 : ELEMENTS = TETRA OU QUADRANGLES ------------
C          ----------------------------------------------
   50   CONTINUE
C       --- COMME ON EST EN 3D LA DIMENSION NE SERT A RIEN
C           MAIS ON POURRAIT UNIFORMISER :NECESSAIRE POUR 
C           DISTINGUER TETRA ET QUADRANGLES
C
        VAL = FCVAL(COORD(IP(1)),COORD(IP(2)),
     >              COORD(IP(3)),COORD(IP(4)))
        GOTO 100
C    
C       --- NBNMAX = 5,6,8 : ELEMENTS = PYRAM, PRISME, HEXA ------------
C          -------------------------------
   60   CONTINUE
   70   CONTINUE
   80   CONTINUE
        IERR = -3
        GOTO 9999
C       ------------------------------------------------
  100   CONTINUE
        RTOTA = RTOTA + VAL
        IF(( VAL.GT.VALMIN ).AND.( VAL.LT.VALMAX ))THEN
          NBEINT = NBEINT+1
        ENDIF
C
        IF( VAL.LT. RMINI )THEN
          RMINI = VAL
          IMINI = I
        ENDIF
        IF( VAL.GT. RMAXI )THEN
          RMAXI = VAL
          IMAXI = I
        ENDIF
  120 CONTINUE
C
 9999 END
C
C     *****************************************************************
C     MODULE  : ST (STRUCTURE DES DONNEES)
C     FICHIER : GEOMETRIE.F
C     OBJET   : CALCULS GEOMETRIQUES ELEMENTAIRES SUR LES ELEMENTS
C               D'UN MAILLAGE
C     FONCT.  : 
C          GTAILL : CALCULE LA TAILLE D'UN SIMPLEX
C          GORIEN : RENVOI L'ORIENTATION DE L'ELEMENT  
C          GBARYC  : CALCULE LE BARYCENTRE D'UN SIMPLEXE
C
C     AUTEUR  : O. STAB  
C     DATE    : 03.95
C     TESTS   : PARTIELS
C     MODIFICATIONS :
C      AUTEUR, DATE, OBJET :
C
C     REMARQUE : ---- A REPRENDRE AVEC LA LOGIQUE SUIVANTE ---- 
C                LA FONCTION LA PLUS BASSE CALCULE LE VECTEUR NORMALE (PAS NORME)
C                SI IDE=IDIMC => UN REEL QUI DONNE LA SURFACE
C                SI IDE<IDIMC => UN VECTEUR DONT LA NORME EST LA SURFACE
C
C                GORIEN DOIT RENVOYER UN VECTEUR OU UN SCALAIRE
C     *****************************************************************
C
      SUBROUTINE GTAILL(IPOINT,NBPOIN,IDE,COORD,IDIMC,TAILLE,IERR)
C     *****************************************************************
C     OBJET GTAILL : CALCULE LA TAILLE D'UN ELEMENT
C     EN ENTREE :
C       IPOINT  : NUMERO DES NOEUDS DE L'ELEMENT
C       NBPOIN  : NOMBRE DE NOEUDS DE L'ELEMENT
C       IDE     : DIMENSION DE L'ELEMENT
C       COORD   : COORDONNEES DES NOEUDS
C       IDIMC   : DIMENSION DE L'ESPACE
C     EN SORTIE :
C       TAILLE  : LONGUEUR D'UN SEGMENT EN 1D,2D ET 3D
C                 SURFACE D'UN TRIANGLE EN 2D ET 3D
C                 VOLUME D'UN TETRAEDRE (3D)
C       IERR    : 0 SI OK, -1 SI LES DONNEES SONT ERRONEES
C     *****************************************************************
      INTEGER IPOINT(*),NBPOIN,IDE, IDIMC
      REAL    COORD(*)
      REAL    TAILLE
      INTEGER IERR
C
      INTEGER J
      REAL    X
C
      EXTERNAL TRSURF,Q4SURF,TTVO
      REAL     TRSURF,Q4SURF,TTVO
C
      IERR = 0
      TAILLE = 0.0
      GOTO (100,200,300) IDE
C         ==============================
C     ---- CAS D'UN SOMMET  ---
C         ==============================
      GOTO 9999
C         ==============================
C     ---- CAS D'UN SEGMENT  ---
C         ==============================
 100  CONTINUE
      DO 110 J=1,IDIMC
        X = COORD(((IPOINT(2)-1)*IDIMC)+J) 
     >    - COORD(((IPOINT(1)-1)*IDIMC)+J)
        TAILLE = TAILLE + X*X
 110  CONTINUE
      TAILLE = SQRT( TAILLE )
      GOTO 9999
C
C         ==============================
C     ---- CAS D'UN ELEMENT SURFACIQUE  ---
C         ==============================
C
 200  CONTINUE
      IF( IDIMC.EQ.2 )THEN
C       ---- POLYGONE DANS LE PLAN ----
        CALL G2SFPL(IPOINT, NBPOIN, COORD, TAILLE)
      ELSE
C       ---- TRIANGLE DANS L'ESPACE ----
        IF( NBPOIN.EQ. 3) THEN
         TAILLE= TRSURF(COORD(((IPOINT(1)-1)*IDIMC)+1),
     >                  COORD(((IPOINT(2)-1)*IDIMC)+1),
     >                  COORD(((IPOINT(3)-1)*IDIMC)+1),
     >                  IDIMC)
C       ---- QUADRANGLE DANS L'ESPACE ----
        ELSE
          IF( NBPOIN.EQ. 4) THEN
           TAILLE = Q4SURF(COORD(((IPOINT(1)-1)*IDIMC)+1),
     >                     COORD(((IPOINT(2)-1)*IDIMC)+1),
     >                     COORD(((IPOINT(3)-1)*IDIMC)+1),
     >                     COORD(((IPOINT(4)-1)*IDIMC)+1),
     >                     IDIMC)
          ELSE
            IERR = -1
            CALL DSERRE(1,IERR,'GTAILL','UN POLYGONE DANS L ESPACE')
            GOTO 9999
          ENDIF
        ENDIF
      ENDIF
      GOTO 9999
C         ==============================
C     ---- CAS D'UN ELEMENT VOLUMIQUE  ---
C         ==============================
C
 300  CONTINUE
      IF( NBPOIN.EQ.4 )THEN
        TAILLE = TTVO(COORD(((IPOINT(1)-1)*IDIMC)+1),
     >                COORD(((IPOINT(2)-1)*IDIMC)+1),
     >                COORD(((IPOINT(3)-1)*IDIMC)+1),
     >                COORD(((IPOINT(4)-1)*IDIMC)+1))
C    bug 12.11.2007 :
C     >                IDIMC)
      ELSE
        IERR = -3
            CALL DSERRE(1,IERR,'GTAILL','VOLUME DE L HEXA, DU PRISME? ')
            GOTO 9999
      ENDIF
      GOTO 9999
C
 9999 END
C
C
      FUNCTION GORIEN(IPOINT, NBPOIN, IDE, COORD, IDIMC, ZERO )
C     *****************************************************************
C     OBJET GORIEN : RENVOI L'ORIENTATION DE L'ELEMENT +1 SI POSITIF
C             -1 SI NEGATIF, 0 SI NUL
C       IPOINT  : NUMERO DES NOEUDS DE L'ELEMENT
C       NBPOIN  : NOMBRE DE NOEUDS DE L'ELEMENT
C       IDE     : DIMENSION DE L'ELEMENT
C       COORD   : COORDONNEES DES NOEUDS
C       IDIMC   : DIMENSION DE L'ESPACE
C       ZERO    : SURFACE CONSIDEREE COMME NULLE
C     CONDITIONS D'APPLICATIONS : N'A PAS DE SENS SI LA DIMENSION DE 
C                L'ELEMENT EST INFERIEURE A LA DIMENSION DE L'ESPACE
C                POUR ORIENTER UN QUADRANGLE IL SUFFIT DE DONNER LE
C                PREMIER TRIANGLE.
C      POSITIF POUR UN TETRA AUX FACES NORMALES VERS L'INTERIEUR (TTVO)
C     *****************************************************************
      INTEGER GORIEN
      INTEGER IPOINT(*),NBPOIN,IDE, IDIMC
      REAL    COORD(*), ZERO 
      INTEGER IERR
C
      REAL    TAILLE 
C
      TAILLE = 0.0
      GORIEN= 0
      CALL GTAILL(IPOINT, NBPOIN, IDE, COORD, IDIMC, TAILLE, IERR )
      IF(IERR .NE. 0)THEN
        CALL DSERRE(1,IERR,'GORIEN','APPEL GTAILL ')
        GOTO 9999
      ENDIF
      IF( TAILLE .GT. ZERO )GORIEN= 1
      IF( TAILLE .LT. ZERO )GORIEN= -1
 9999 END
C
C      
      SUBROUTINE GBARYC(IT, N, C, IDIMC, BARYC, IERR)
C     *****************************************************************
C     OBJET : CALCULE LE BARYCENTRE D'UN ENSEMBLE DE POINTS
C     EN ENTREE :
C       IT      : NUMERO DES NOEUDS DE L'ELEMENT
C       N       : NOMBRE DE NOEUDS DE L'ELEMENT
C       C       : COORDONNEES DES NOEUDS
C       IDIMC   : DIMENSION DE L'ESPACE
C     EN SORTIE :
C       IERR    : 0 SI OK, -1 SI LES DONNEES SONT ERRONEES
C       BARYC   : LE BARYCENTRE
C     *****************************************************************
      INTEGER IT(*),N,IDIMC,IERR
      REAL    C(*),BARYC(*)
C
      INTEGER I,J
C
      IERR = -1
      DO 10 J=1,IDIMC
        BARYC(J) = 0.0
   10 CONTINUE
      IF( N.LE. 0 ) GOTO 999
      DO 30 I=1,N
        DO 20 J=1,IDIMC
          BARYC(J) = C((IT(I)-1)*IDIMC+J) + BARYC(J)
   20   CONTINUE
   30 CONTINUE
      DO 40 J=1,IDIMC
        BARYC(J) = BARYC(J) / N
   40 CONTINUE
      IERR = 0
  999 END
C     **********************************************************************
C     MODULE   : ST (STRUCTURE DES DONNEES)
C     FICHIER  : ST_MATERIAU.F
C     OBJET    : ASSOCIE LES MATERIAUX AU DIFFERENTES COMPOSANTES CONNEXES
C                A PARTIR DES FRONTIERES INTER-MATERIAUX
C
C     FONCT.   :
C      RGN1CC : ASSOCIE UNE VALEUR A LA COMPOSANTE CONNEXE 
C      RGCOMP: RENUMEROTE LES ELEMENTS EN FONCTION DES MATERIAUX POUR 
C                  LES COMPACTER EN INTERVALS
C      RGRGFR  : EXTRAIT LES MATERIAUX A PARTIR DE LA FRONTIERE 
C      RGRGNO : EXTRAIT LES MATERIAUX A PARTIR DES NOEUDS DE LA FRONTIERE 
C      RGFRRG  : EXTRAIT LES FRONTIERES A PARTIR DES MATERIAUX 
C      RGNORG : EXTRAIT LES NOEUDS DES FRONTIERES A PARTIR DES MATERIAUX 
C
C
C     AUTEUR   : O. STAB
C     DATE     : 08.95
C     MODIFICATIONS :
C        AUTEUR, DATE, OBJET :
C
C
C     **********************************************************************
C
      SUBROUTINE RGN1CC(IT,IVAL,IDE,ITRTRI,NBCMAX,NBE,
     >                     ITVL,ITBVAL,NBEVAL,IERR)
C     **********************************************************************
C     OBJET RGN1CC : ASSOCIE UNE VALEUR A LA COMPOSANTE CONNEXE 
C     EN ENTREE   :
C        IT       : UN ELEMENT DE LA COMPOSANTE CONNEXE
C        IVAL     : UNE VALEUR NON-NULLE A ASSOCIER A LA CC
C        IDE      : DIMENSION DES ELEMENTS DU MAILLAGE
C        ITRTRI  : TABLEAU DES ELEMENTS VOISINS
C        NBNMAX   : NOMBRE MAXI. D'ELEMENTS VOISINS
C        NBE      : NOMBRE D'ELEMENTS
C
C        ITVL : TABLEAU DE TRAVAIL = NBE + PILE (APPEL TMA1CC)
C
C     EN SORTIE :
C        ITBVAL  : SI ITC CONNEXE A IT ALORS ITBVAL(ITC) = IVAL
C        NBEVAL   : NOMBRE D'ELEMENTS MARQUES A IVAL 
C        IERR     : 0 SI OK
C                   -1 SI IVAL = 0
C     **********************************************************************
      INTEGER IT,IVAL,IDE,ITRTRI(*),NBCMAX,NBE
      INTEGER ITVL(*),ITBVAL(*),NBEVAL,IERR
C
      INTEGER ITRAV,NBTRAV,I
C
      IERR   = -1
      NBEVAL = 0
      IF( IVAL.EQ.0 )GOTO 999
      IERR   = 0
      ITRAV  = NBE + 1
      NBTRAV = NBE
      CALL TMA1CC(IDE,ITRTRI,NBCMAX,1,NBE,
     >      IT,ITVL(ITRAV),ITBVAL,NBTRAV,
     >      ITVL,NBEVAL,IERR)
      IF( IERR.NE. 0 )GOTO 999
      DO 10 I=1,NBEVAL
        ITBVAL(ITVL(I)) = IVAL
   10 CONTINUE   
  999 END
C
C
C
      SUBROUTINE RGRGFR(IFR,NBIFR,IMATFR,
     >                    IDE,ITRNOE,NBNMAX,ITRTRI,NBCMAX,
     >                    NOETRI,NBE,ITVL,
     >                    IMAT,IRGREF,IMATCC,NBRGCC,NCCMAX,IERR)
C     **********************************************************************
C     OBJET RGRGFR : AFFECTE LES MATERIAUX A PARTIR DE LA FRONTIERE 
C
C     EN ENTREE :
C       IFR     : FRONTIERE
C                 IFR((I-1)*2+1) IEME ELEMENT FRONTIERE 
C                 IFR((I-1)*2+2) COTE DU IEME ELEMENT FRONTIERE
C       NBIFR   : NOMBRE D'ELEMENTS FRONTIERE
C
C       IMATFR  : IMATFR((I-1)*2+1) EST LE MATERIAU A GAUCHE DE IFR((I-1)*2+1)
C                 SUR LE COTE IFR((I-1)*2+2)
C                 IMATFR((I-1)*2+2) EST LE MATERIAU A DROITE DE IFR((I-1)*2+1)
C                 SUR LE COTE IFR((I-1)*2+2) 
C
C       IDE,ITRNOE,NBNMAX,ITRTRI,NBCMAX,NOETRI,NBE : LE MAILLAGE
C
C       ITVL: TABLEAU DE TRAVAIL DE TAILLE = NBE + PILE (APPEL TMA1CC)
C
C       IMAT   : TABLEAU DE SORTIE TAILLE = NBE
C       IRGREF : "              "  TAILLE = NCCMAX
C       IMATCC : "              "  TAILLE = NCCMAX
C       NCCMAX : TAILLE DE IRGREF ET IMATCC
C                        SI = 0 ALORS ON NE REMPLI PAS IRGREF ET IMATCC
C
C     EN SORTIE  : 
C       IMAT     : IMAT(I) EST LE MATERIAU DE L'ELEMENT I
C       IRGREF   : TABLEAU DES MATERIAUX DE CHAQUE COMPOSANTE CONNEXE
C       IMATCC   : UN ELEMENT DE CHAQUE COMPOSANTE CONNEXE
C       NBRGCC   : NOMBRE DE COMPOSANTE CONNEXE MONO-MATERIAU
C     
C       IERR     : CODE D'ERREUR
C                  -1 UN ELEMENT FRONTIERE DE IFR N'EXISTE PAS
C                     TOUS LES ELEMENTS N'ONT PAS UN MATERIAU !
C                  -2 ITVL, IRGREF OU IMATCC TROP PETIT
C     **********************************************************************
      INTEGER    IFR(*),NBIFR,IMATFR(*)
      INTEGER    IDE,ITRNOE(*),NBNMAX,ITRTRI(*),NBCMAX
      INTEGER    NOETRI(*),NBE,ITVL(*)
      INTEGER    IMAT(*),IRGREF(*),IMATCC(*),NBRGCC,NCCMAX,IERR
C
      INTEGER I,J,MAT
      INTEGER NBVUE,IT1,IT2,I1,NBEMAT
C      
      IF( NBIFR.EQ. 0)THEN
C        ==========================================================
C     --- 1. MONO-MATERIAU : TOUS LES TRIANGLES SONT DE MATERIAU 1 ---
C        ==========================================================
        MAT = IMATFR(1)
        IF( MAT.LE. 0 )MAT = IMATFR(2)
        DO 10 I=1,NBE
   10     IMAT(I) = MAT
         IF( NCCMAX.GT.0 )THEN
           IRGREF(1) = MAT
           IMATCC(1)  = 1
         ENDIF           
C        
      ELSE
C        =======================================
C     --- 2. PLUSIEURS MATERIAUX                ----
C        =======================================
C
C        =====================
C     --- 2.1. INITIALISATION ----
C        =====================
      DO 15 I=1,NBIFR
        IT1 = IFR((I-1)*2+1)
        I1  = ABS(IFR((I-1)*2+2))
        IT2 = ITRTRI((IT1-1)*NBCMAX+I1)
        IF( IT2 .LE. 0 )GOTO 15
        ITRTRI((IT1-1)*NBCMAX+I1) = - IT2
        DO 11 J=1,NBCMAX
          IF( ITRTRI((IT2-1)*NBCMAX+J).EQ.IT1 )THEN
            ITRTRI((IT2-1)*NBCMAX+J) = -IT1
            GOTO 15
          ENDIF
   11   CONTINUE
   15 CONTINUE
      DO 20 I=1,NBE
        IMAT(I) = 0
   20 CONTINUE   
C        ====================================================
C     --- 2.2. RECHERCHE DES MATERIAUX 
C        ====================================================      
C
      NBRGCC = 0
      NBVUE = 0
      DO 30 I=1,NBIFR
        IT1 = IFR((I-1)*2+1)
        I1  = ABS(IFR((I-1)*2+2))
        IT2 = ABS(ITRTRI((IT1-1)*NBCMAX+I1))
C     ------- MATERIAU A GAUCHE ----------
C            ===================
      NBEMAT = 0
C      --- VERIFICATION ---
      IF((IT1.NE.0).AND.(IMAT(IT1).NE.0).AND.
     > (IMATFR((I-1)*2+1).GT.0))THEN
       IF( IMAT(IT1).NE.IMATFR((I-1)*2+1) )THEN
         IERR = -1
         CALL DSERRE(1,IERR,'RGRGFR',
     >                    ' 1 ELEMENT A 2 MATERIAUX')
       ENDIF     
       ENDIF
C      --- FIN DE VERIFICATION ---
      IF((IT1.NE.0).AND.(IMAT(IT1).EQ.0).AND.
     > (IMATFR((I-1)*2+1).GT.0))THEN
         NBRGCC = NBRGCC + 1
         CALL RGN1CC(IT1,IMATFR((I-1)*2+1),IDE,ITRTRI,
     >                 NBCMAX,NBE,ITVL,IMAT,NBEMAT,IERR)
         IF( NBRGCC.LE.NCCMAX )THEN
           IRGREF(NBRGCC) = IMATFR((I-1)*2+1)
           IMATCC(NBRGCC)  = IT1
         ENDIF           
       ENDIF
C     ------- MATERIAU A DROITE -----------
C            ===================
      NBVUE = NBEMAT + NBVUE
      NBEMAT = 0
C      --- VERIFICATION ---
      IF((IT2.NE.0).AND.(IMAT(IT2).NE.0).AND.
     > (IMATFR((I-1)*2+2).GT.0))THEN
       IF( IMAT(IT2).NE.IMATFR((I-1)*2+2) )THEN
         IERR = -1
         CALL DSERRE(1,IERR,'RGRGFR',
     >                    ' 1 ELEMENT A 2 MATERIAUX')
       ENDIF     
       ENDIF
C      --- FIN DE VERIFICATION ---
      IF((IT2.NE.0).AND.(IMAT(IT2).EQ.0).AND.
     > (IMATFR((I-1)*2+2).GT.0))THEN
         NBRGCC = NBRGCC + 1
         CALL RGN1CC(IT2,IMATFR((I-1)*2+2),IDE,ITRTRI,
     >                 NBCMAX,NBE,ITVL,IMAT,NBEMAT,IERR)
         IF( NBRGCC.LE.NCCMAX )THEN
           IRGREF(NBRGCC) = IMATFR((I-1)*2+2)
           IMATCC(NBRGCC)  = IT2
         ENDIF           
      ENDIF
      NBVUE = NBEMAT + NBVUE
C     --- FIN : ON A ATTRIBUE UN MAT. A TOUS LES ELEMENTS ----
      IF( NBVUE.EQ.NBE )GOTO 888
C     --- BOUCLE : ON A PAS VU TOUS LES ELEMENTS ---
   30 CONTINUE
C     --- ON A PAS VU TOUS LES ELEMENTS -----
      IERR = -1
      CALL DSERRE(1,IERR,'RGRGFR', ' ELEMENTS NON VUS ! ')
      GOTO 999
C
  888 IF((NCCMAX.NE.0).AND.
     >   (NCCMAX.LT.NBRGCC))THEN
          IERR = -2
         CALL DSERRE(1,IERR,'RGRGFR', ' IRGREF ET IMATCC')
         GOTO 999
       ENDIF     
C
C     --- UNE ARETE DE LA FRONTIERE N'EXISTE PAS ---
      IF( IERR.NE. 0 )GOTO 999
      ENDIF
C
  999 END
C
C
      SUBROUTINE RGRGNO(IFR,NBNIFR,NBIFR,IMATFR,
     >                     IDE,ITRNOE,NBNMAX,ITRTRI,NBCMAX,
     >                     NOETRI,NBE,ITVL,NITMAX,
     >                     IMAT,IRGREF,IMATCC,NBRGCC,NCCMAX,IERR)
C     **********************************************************************
C     OBJET RGRGNO : EXTRAIT LES REGIONS A PARTIR DES NOEUDS DE LA FRONTIERE 
C             VOIR RGRGFR
C
C     EN ENTREE  : IDEM RGRGFR
C       NBNIFR   : NOMBRE DE NOEUDS DES ELEMENTS DE LA FRONTIERE
C
C       ITVL : TAILLE > 2*NBIFR + NBE + PILE (APPEL TMA1CC)
C
C      NCCMAX : TAILLE DE IRGREF ET IMATCC
C                        SI = 0 ALORS ON NE REMPLI PAS IRGREF ET IMATCC
C     EN SORTIE  : 
C       IMAT     : IMAT(I) EST LE MATERIAU DE L'ELEMENT I
C       IRGREF   : IRGREF(I) = MATERIAUX DE LA COMPOSANTE CONNEXE I
C       IMATCC   : IMATCC(I) = UN ELEMENT DE LA COMPOSANTE CONNEXE I
C       NBRGCC   : NOMBRE DE COMPOSANTE CONNEXE MONO-MATERIAU
C     
C       IERR     : CODE D'ERREUR
C                 -1 UN ELEMENT FRONTIERE DE IFR N'EXISTE PAS
C                    TOUS LES ELEMENTS N'ONT PAS UN MATERIAU !
C                 -2 ITVL, IRGREF OU IMATCC TROP PETIT
C
C     REMARQUE : IL FAUDRAIT TESTER LE CAS D'UN MATERIAU EN PLUSIEURS CC !
C     **********************************************************************
      INTEGER    IFR(*),NBIFR,NBNIFR,IMATFR(*)
      INTEGER    IDE,ITRNOE(*),NBNMAX,ITRTRI(*),NBCMAX
      INTEGER    NOETRI(*),NBE,ITVL(*),NITMAX
      INTEGER    IMAT(*),IRGREF(*),IMATCC(*),NBRGCC,NCCMAX,IERR
C
      INTEGER I,MAT,ITRAV,NITMX2
      INTEGER IT1,IT2,I1,I2
C      
      IF( NBIFR.EQ. 0)THEN
C        ==========================================================
C     --- 1. MONO-MATERIAU : TOUS LES TRIANGLES SONT DE MATERIAU 1 ---
C        ==========================================================
        NBRGCC = 1
        MAT = IMATFR(1)
        IF( MAT.LE. 0 )MAT = IMATFR(2)
        DO 10 I=1,NBE
   10     IMAT(I) = MAT
        IF( NCCMAX.GT.0 )THEN
          IRGREF(1) = MAT
          IMATCC(1)  = 1
        ENDIF
        IERR = 0           
        GOTO 9999
      ENDIF
C
      IERR = 0
      NBRGCC = 0
      ITRAV = 2*NBIFR+1
      NITMX2 = NITMAX - ITRAV 
      DO 30 I=1,NBIFR
        CALL SFRIDE(IFR((I-1)*NBNIFR+1),NBNIFR,IDE,
     >              ITRNOE,NBNMAX,ITRTRI,NBCMAX,
     >              NOETRI,NBE,ITVL(ITRAV),NITMX2,
     >              IT1,IT2,I1,I2,IERR )
        IF(IERR.NE.0)THEN
          CALL DSERRE(1,IERR,'RGRGNO','APPEL SFRIDE')
          GOTO 9999
        ENDIF
        IF( IT1.NE.0 )THEN
          ITVL((I-1)*2+1) = IT1
          ITVL((I-1)*2+2) = I1
        ELSE
C          IF( IMATFR((I-1)*2+1).NE. 0 )GOTO 999
          IF( IT2.EQ. 0 )THEN
            IERR = -1
            CALL DSERRE(1,IERR,'RGRGNO','STRUCTURE INCORRECTE')
            GOTO 9999
          ENDIF
          ITVL((I-1)*2+1) = IT2
          ITVL((I-1)*2+2) = I2
        ENDIF
   30 CONTINUE
C
      CALL  RGRGFR(ITVL,NBIFR,IMATFR,
     >          IDE,ITRNOE,NBNMAX,ITRTRI,NBCMAX,
     >          NOETRI,NBE,ITVL(ITRAV),
     >          IMAT,IRGREF,IMATCC,NBRGCC,NCCMAX,IERR)
        IF(IERR.NE.0)THEN
          CALL DSERRE(1,IERR,'RGRGNO','APPEL RGRGFR')
          GOTO 9999
        ENDIF
C
 9999 END
C
      SUBROUTINE RGCOMP(IDE,ITRNOE,NBNMAX,ITRTRI,NBCMAX,
     >                   NOETRI,NOEMAX,NBE,ITVL,
     >                   IMAT,IRGREF,NRGREF,
     >                   IREFMA,ITRIRG,NREFRG,NRRGMX,IERR)
C     **********************************************************************
C     OBJET RGCOMP : RENUMEROTE LES ELEMENTS EN FONCTION DU NUMERO DE REGION
C                    (POUR LES COMPACTER EN INTERVALS)
C
C     EN ENTREE  :
C       IDE,ITRNOE,NBNMAX,ITRTRI,NBCMAX,NOETRI,NBE : LE MAILLAGE
C
C       ITVL     : TABLEAU DE TRAVAIL DE MAX(NRGREF,2*NBE)
C                  SI NRGREF = 1 SEUL ITVL(1) EST UTILISE
C
C       IMAT     : IMAT(I) EST LE NUMERO DU MATERIAU DE L'ELEMENT I
C                  IRGREF(IMAT(I)) EST LA REFERENCE DU MATERIAU DE L'ELEMENT I
C       IRGREF   : TABLEAU DES REFERENCES DES MATERIAUX 
C       NRGREF   : NOMBRE DE REFERENCES DANS IRGREF 
C                  DANS LE CAS OU L'ON NE CONNAIT PAS IRGREF ET NRGREF 
C                  ON PEUT DONNER IMAT,NBE
C
C       IREFMA   : TABLEAU DE SORTIE TAILLE = NRRGMX (ON PEUT UTILISER IRGREF)
C       ITRIRG   : "              "  TAILLE = NRRGMX
C       NRRGMX   : TAILLE DE IREFMA ET ITRIRG
C                        SI = 0 ALORS ON NE REMPLI PAS IREFMA ET ITRIRG
C
C     EN SORTIE  : 
C       IREFMA   : IREFMA(I) = REFERENCE DU IEME MATERIAU  
C                  (ON PEUT UTILISER IRGREF)
C       ITRIRG   : ITRIRG(I-1)+1, ITRIRG(I) = INTERVAL CONTENANT
C                         LE ELEMENTS DE MATERIAU IREFMA(I)
C       NBRGCC   : NOMBRE DE MATERIAUX (= NOMBRE D'INTERVALS)
C     
C       IERR     : CODE D'ERREUR
C     **********************************************************************
      INTEGER    IDE,ITRNOE(*),NBNMAX,ITRTRI(*),NBCMAX
      INTEGER    NOETRI(*),NOEMAX,NBE,ITVL(*)
      INTEGER    IMAT(*),IRGREF(*),NRGREF
      INTEGER    IREFMA(*),ITRIRG(*),NREFRG,NRRGMX,IERR
C
      INTEGER ITRAV,INUM,I
C
      IF(NBE.EQ.0)GOTO 999
C     --- 1.1 COMPRESSION DES MATERIAUX (CAS PLUSIEURS CC) ---
C        ==================================================
      ITRAV = 1
C     --- TAILLE ITVL > NRGREF ---
      CALL  TBVTAB(IRGREF,NRGREF,ITVL(ITRAV),
     >                IREFMA,NREFRG,NRRGMX,IERR)
      IF( IERR .NE. 0 )THEN
        CALL DSERRE(1,IERR,'RGCOMP','APPEL TBVTAB')
        GOTO 999
      ENDIF
      IF( NREFRG.EQ.1 )THEN
        ITRIRG(1) = NBE
        GOTO 999
      ENDIF
C
C     --- 1.2 RENUMEROTATION DES ELEMENTS ---------------------
C        =================================
      INUM    = 1
C     --- TAILLE ITVL > NBE ---
      CALL  TBNUIT(IMAT,NBE,IREFMA,NREFRG,
     >                 ITVL(INUM),
     >                 ITRIRG,IERR)
      IF( IERR .NE. 0 )THEN
        CALL DSERRE(1,IERR,'RGCOMP','APPEL TBNUIT')
        GOTO 999
      ENDIF
C
      ITRAV   = NBE + INUM
      CALL  NURENU(IDE,ITRNOE,NBNMAX,
     >       ITRTRI,NBCMAX,NOETRI, 
     >       NOEMAX,NBE,ITVL(INUM),ITVL(ITRAV),IERR)      
      IF( IERR .NE. 0 )THEN
        CALL DSERRE(1,IERR,'RGCOMP','APPEL NURENU')
        GOTO 999
      ENDIF
C
      DO 10 I=2,NREFRG
        ITRIRG(I) = ITRIRG(I-1) + ITRIRG(I)
   10 CONTINUE
C   
  999 END
C
      SUBROUTINE RGFRRG(IDE,ITRNOE,NBNMAX,ITRTRI,NBCMAX,
     >                    NBE,IMAT,NBMAT,
     >                    IFR,NBIFR,NIFMAX,IMATFR,NRGMAX,IERR)
C     **********************************************************************
C     OBJET RGFRRG: EXTRAIT LES FRONTIERES A PARTIR DES MATERIAUX 
C
C     EN ENTREE  :
C       IDE,ITRNOE,NBNMAX,ITRTRI,NBCMAX,NBE : LE MAILLAGE
C       IMAT     : IMAT(I) EST LE MATERIAU DE L'ELEMENT I
C       NBMAT    : NOMBRE DE MATERIAU
C
C       NIFMAX : NOMBRE MAXIMUM D'ELEMENTS FRONTIERE 
C       NRGMAX : SI = 0 ON NE REMPLI PAS IMATFR
C                  SINON NOMBRE MAXIMUM DE REFERENCE DES ELEMENTS
C                  FRONTIERE
C       IFR      : EST UN TABLEAU DE SORTIE DE 2*NIFMAX
C       IMATFR   : EST UN TABLEAU DE SORTIE INUTILISE SI NRGMAX = 0
C                  DE 2*NRGMAX SINON. NOTONS QUE LA MEME TAILLE EST 
C                  SOUHAITE POUR IFR ET IMATFR
C
C     EN SORTIE  : 
C       IFR      : FRONTIERES 
C                  IFR((I-1)*2+1) ELEMENT APPARTENANT A LA FRONTIERE
C                  IFR((I-1)*2+2) COTE DE L'ELEMENT SUR LA FRONTIERE
C                  "    "     "   POSITIF SI C'EST UNE FRONTIERE REELLE
C                  "    "     "   NEGATIF SI C'EST UNE FRONTIERE INTERIEURE
C       NBIFR    : NOMBRE D'ELEMENTS FRONTIERE
C         (LES ELEMENTS DES FRONTIERES INTERIEURES SONT COMPTES 2 FOIS)
C
C       IMATFR   : IMATFR((I-1)*2+1) EST LE MATERIAU DE IFR((I-1)*2+1)
C                  IMATFR((I-1)*2+2) EST LE MATERIAU DU VOISIN DE 
C                  IFR((I-1)*2+1) SUR LE COTE IFR((I-1)*2+2)
C     
C       IERR     : CODE D'ERREUR
C                   0 SI OK
C                  -2 SI IFR OU IMATFR SONT TROP PETITS
C     **********************************************************************
      INTEGER    IDE,ITRNOE(*),NBNMAX,ITRTRI(*),NBCMAX,NBE
      INTEGER    IMAT(*),NBMAT,NIFMAX,NRGMAX 
      INTEGER    IFR(*),IMATFR(*),NBIFR,IERR
C
      INTEGER  IGMAT,JDMAT,I,J,JVOIS,NBC,NBRN
      INTEGER  STRNBN,STRNBC
      EXTERNAL STRNBN,STRNBC
C
      IGMAT = 1
      JDMAT = 1
      NBIFR = 0
      DO 20 I=1,NBE
        NBRN = STRNBN(I,ITRNOE,NBNMAX)
        NBC  = STRNBC(NBRN,IDE)
        IF( NBMAT.NE. 0 )IGMAT = IMAT(I)
        DO 10 J=1,NBC
C          JVOIS = ABS(ITRTRI((I-1)*NBNMAX+J))
C         REMPLACE PAR : O.STAB 29.07.99 
          JVOIS = ABS(ITRTRI((I-1)*NBCMAX+J))
C         ---- FRONTIERE EXTERNE (PAS DE VOISIN) ----
          IF( JVOIS .EQ. 0 )THEN
            NBIFR = NBIFR+1
            IF( NIFMAX.GE. NBIFR )THEN          
              IFR((NBIFR-1)*2+1) = I
              IFR((NBIFR-1)*2+2) = J  
            ELSE
              IERR = -2
            ENDIF
            IF( NRGMAX.GE. NBIFR )THEN          
              IMATFR((NBIFR-1)*2+1) = IGMAT
              IMATFR((NBIFR-1)*2+2) = 0
            ELSE
              IF( NRGMAX.NE. 0 )IERR = -2
            ENDIF
            GOTO 10
          ENDIF
C
          IF( NBMAT.NE. 0 )JDMAT = IMAT(JVOIS)
          IF( IGMAT.EQ.JDMAT )GOTO 10
C         ---- FRONTIERE INTERNE (VOISIN DE MAT DIFF) ----
          NBIFR = NBIFR+1
          IF( NIFMAX.GE. NBIFR )THEN          
            IFR((NBIFR-1)*2+1) = I
            IFR((NBIFR-1)*2+2) = -J    
          ELSE
            IERR = -2
          ENDIF                    
          IF( NRGMAX.GE. NBIFR )THEN          
            IMATFR((NBIFR-1)*2+1) = IGMAT
            IMATFR((NBIFR-1)*2+2) = JDMAT
          ELSE
            IF( NRGMAX.NE. 0 )IERR = -2
          ENDIF
   10   CONTINUE
   20 CONTINUE
C
  999 END
C
C
      SUBROUTINE RGNORG(IDE,ITRNOE,NBNMAX,ITRTRI,NBCMAX,
     >                    NBE,IMAT,NBMAT,
     >           IFR,NBIFR,NIFMAX,NBNIFR,IMATFR,NRGMAX,IERR)
C     **********************************************************************
C     OBJET RGNORG : EXTRAIT LES NOEUDS DES FRONTIERES DES REGIONS
C             VOIR RGFRRG
C
C     EN ENTREE  : IDEM RGFRRG
C         NBNIFR : NOMBRE MAX. DE NOEUD DES ELEMENTS FRONTIERE
C     EN SORTIE  :
C       IFR     : FRONTIERE
C                 IFR((I-1)*NBNIFR+1) PREMIER NOEUD DE L'ELEMENT FRONTIERE I
C                 IFR((I-1)*NBNIFR+2) DEUXIEME "   "    "   "   "    "     I
C       NBIFR   : NOMBRE D'ELEMENTS FRONTIERE
C
C     **********************************************************************
      INTEGER    IDE,ITRNOE(*),NBNMAX,ITRTRI(*),NBCMAX,NBE
      INTEGER    IMAT(*),NBMAT,NIFMAX,NRGMAX
      INTEGER    IFR(*),IMATFR(*),NBIFR,NBNIFR,IERR
C
      INTEGER IIFR,I
C
      IERR = 0 
C     --- ON DECALE A PRIORI LE DEBUT POUR NE PAS AVOIR A REDECALER 
C         A LA FIN ET ECONOMISER DE LA PLACE ---
C
      IIFR = (NIFMAX * (NBNIFR - 2)) + 1
      CALL RGFRRG(IDE,ITRNOE,NBNMAX,ITRTRI,NBCMAX,
     >              NBE,IMAT,NBMAT,IFR(IIFR),NBIFR,NIFMAX,
     >              IMATFR,NRGMAX,IERR)
      IF( IERR.NE. 0 )GOTO 999
      IF( ((NBNIFR - 2) * NBIFR).GT.IIFR )THEN
        IERR = -2
        GOTO 999
      ENDIF
C
      DO 10 I=1,NBIFR
        CALL TNOFRT(IDE,ITRNOE,NBNMAX,IFR((I-1)*2+IIFR),
     >                  IFR((I-1)*2+IIFR+1),IFR((I-1)*NBNIFR+1))
   10 CONTINUE
C
  999 END
C

C     *****************************************************************
C     MODULE  : ST (STRUCTURE DES DONNEES)
C     FICHIER : ST_TABLEAU.F
C     OBJET   : MANIPULATION DE TABLEAUX D'ENTIERS 
C     FONCT.  :
C       FONCTIONS DE TRI : 
C       -----------------
C       KNUTP      : DONNE L'ORDRE CROISSANT POUR UN TABLEAU D'ENTIERS
C           TRI PAR INCREMENT DECROISSANT (SHELL SORTING - KNUTH 1973)
C       KNUTA      : TRI UN TABLEAU D'ENTIERS DANS L'ORDRE CROISSANT
C       IORDRE     : IMPOSE UN ORDRE DONNE A UN TABLEAU D'ENTIERS 
C       INVORD     : INVERSE L'ORDRE D'UN TABLEAU D'ENTIERS
C
C       INTERVALLES :
C       -------------
C       TBV2IT : CONVERTIT UN TABLEAU D'ENTIER EN UN TABLEAU 
C                    D'INTERVALLES 
C       TBIT2V : CONVERTIT UN TABLEAU D'INTERVALLES EN TABLEAU
C                    D'ENTIERS
C       TBNUIT : DONNE UNE NUMEROTATION POUR OBTENIR DES INTERVALS
C       TBVTAB    : RENVOI LES VALEURS DISTINCTES D'UN TABLEAU, 
C                    TRIEES DANS L'ORDRE CROISSANT
C
C
C     AUTEUR  : O. STAB
C     DATE    : 08.95
C     MODIFICATIONS :
C      AUTEUR, DATE, OBJET : stab,7.5.2002, bug dans TBV2IT
C
C
C     *****************************************************************
C
C
      SUBROUTINE KNUTP(N,L,NARG)
C     ***************************************************************
C     OBJET : DONNE L'ORDRE CROISSANT POUR UN TABLEAU D'ENTIERS
C          TRI PAR INCREMENT DECROISSANT (SHELL SORTING - KNUTH 1973)
C
C     ON TRIE LES N TERMES NARG(I) POUR I=1,N
C
C     TRI PAR INCREMENT DECROISSANT (SHELL SORTING)
C     COMPLEXITE EN N PUISSANCE 3/2 ET MEME STATISTIQUEMENT EN N**1.2
C
C     POUR EN SAVOIR PLUS : KNUTH, "THE ART OF COMPUTER PROGRAMMING",
C                           VOL 3 : SORTING AND SEARCHING,
C                           ADDISON-WESLEY, 1973.
C
C     KNUTP : P COMME PASSIF, C.A.D. QUE LES ARGUMENTS NARG(I) POUR
C             I=1 A N NE SONT PAS "PERMUTES" (TABLEAU NARG NON MODIFIE).
C             MAIS CE MODULE DETERMINE LE TABLEAU L(I) POUR I=1 A N
C             DE SORTE QUE LA SUITE NARG(L(I)) SOIT ORDONNEE.
C             VOIR AUSSI KNUTA.
C
C     REMARQUE : NARG PEUT ETRE DE TOUT TYPE ET TOUTE LOI D'ORDRE
C                PEUT ETRE INTRODUITE. IL SUFFIT D'INTERVENIR
C                AUX ENDROITS INDIQUES AINSI : '***** ICI : ...'.
C
C     ***************************************************************
      INTEGER N,L(*),NARG(*)
      INTEGER NARGJ
      INTEGER I,J,II,JJ,K,INCR
C
C     ON N'A RIEN A TRIER
C
      IF(N.LE.0) GOTO 9999
      DO 10 I=1,N
        L(I)=I
   10 CONTINUE
      IF(N.LE.1) GOTO 9999
C
C     POUR J=INCR+1,N, LA SOUS-SUITE NARG(L(J+H*INCR)), H=...,-3,-2,-1,0
C     SERA ORDONNEE (TRI HABITUEL PAR INSERTION SEQUENTIELLE).
C
C     DES QUE INCR=1 ON A ATTEINT L'OBJECTIF FINAL.
C
C     INCR SUBIT UNE DECROISSANCE PROGRESSIVE DE SORTE QU'AU
C     DEBUT IL EST GRAND (LA SOUS-SUITE A TRIER A UN CARDINAL FAIBLE)
C     ENSUITE QUAND INCR DIMINUE LA PROFONDEUR DES PERMUTATIONS
C     NECESSAIRES RESTE LIMITEE GRACE AU TRI DE LA SOUS-SUITE
C     CORRESPONDANT A LA VALEUR PRECEDENTE DE L'INCREMENT (LE PAS).
C
      INCR=N
C
C     DECROISSANCE DE L'INCREMENT PAR DIVISION PAR 2
C
   20 INCR=INCR/2
C
C     POUR TOUT J VARIANT DE INCR+1 A N,
C     LA SOUS-SUITE NARG(L(J+H*INCR)) AVEC H=...,-3,-2,-1,0
C     SERA ORDONNEE.
C
      DO 50 J=INCR+1,N
C
C       ON PROCEDE PAR RECURENCE : LE FAIT QUE LES ELEMENTS
C       NARG(L(J+H*INCR)) DEPUIS LE DEBUT JUSQU'A J+H*INCR=K-INCR
C       SOIENT DEJA ORDONNES EST UTILISE POUR ALLER JUSTE PLACER
C       CONVENALEMENT L'ELEMENT L(K) : INSERTION SEQUENTIELLE.
C
        JJ=L(J)
        NARGJ=NARG(JJ)
        K=J
        DO 30 I=J-INCR,1,-INCR
          II=L(I)
C
C         ***** ICI :  LOI D'ORDRE
C         COMPARER NARG(II) ET NARGJ=NARG(JJ)
C         SI NARG(II) EST AVANT OU EGAL A NARGJ ALLER EN 40
C
          IF(NARG(II).LE.NARGJ) GOTO 40
C
C         DECALLAGE VERS LA DROITE DU I EME TERME
C
          L(K)=II
          K=I
   30   CONTINUE
C
C       ON VIENT DE TROUVER LA PLACE CONVENABLE POUR NARG(L(J))
C
   40   L(K)=JJ
C
C       FIN DU TRI DE LA SOUS-SUITE ASSOCIEE A J
C
   50 CONTINUE
C
C     PEUT-ON ENCORE DIMINUER L'INCREMENT (LE PAS) ?
C
      IF(INCR.GT.1) GOTO 20
C
C     INCR=1, LE TRI FINAL EST ACHEVE. MERCI DE VOTRE VISITE.
C
 9999 END
C
C
C
      SUBROUTINE KNUTA(N,NARG)
C     ***************************************************************
C     OBJET : TRI UN TABLEAU D'ENTIERS DANS L'ORDRE CROISSANT
C          TRI PAR INCREMENT DECROISSANT (SHELL SORTING - KNUTH 1973)
C
C     ON TRIE LES N TERMES NARG(I) POUR I=1,N
C
C     TRI PAR INCREMENT DECROISSANT (SHELL SORTING)
C     COMPLEXITE EN N PUISSANCE 3/2 ET MEME STATISTIQUEMENT EN N**1.2
C
C     POUR EN SAVOIR PLUS : KNUTH, "THE ART OF COMPUTER PROGRAMMING",
C                           VOL 3 : SORTING AND SEARCHING,
C                           ADDISON-WESLEY, 1973.
C
C     KNUTA : A COMME ACTIF, C.A.D. QUE LES ARGUMENTS NARG(I) POUR
C             I=1 A N SONT PHYSIQUEMENT "PERMUTES" (TABLEAU NARG MODIFIE).
C             VOIR AUSSI KNUTP.
C
C
C     REMARQUE : NARG PEUT ETRE DE TOUT TYPE ET TOUTE LOI D'ORDRE
C                PEUT ETRE INTRODUITE. IL SUFFIT D'INTERVENIR
C                AUX ENDROITS INDIQUES AINSI : '***** ICI : ...'.
C
C     ***************************************************************
      INTEGER N,NARG(*)
      INTEGER NARGJ
      INTEGER I,J,K,INCR
C
C     ON N'A RIEN A TRIER
C
      IF(N.LE.1) GOTO 9999
C
C     POUR J=INCR+1,N, LA SOUS-SUITE NARG(J+H*INCR), H=...,-3,-2,-1,0
C     SERA ORDONNEE (TRI HABITUEL PAR INSERTION SEQUENTIELLE).
C
C     DES QUE INCR=1 ON A ATTEINT L'OBJECTIF FINAL.
C
C     INCR SUBIT UNE DECROISSANCE PROGRESSIVE DE SORTE QU'AU
C     DEBUT IL EST GRAND (LA SOUS-SUITE A TRIER A UN CARDINAL FAIBLE)
C     ENSUITE QUAND INCR DIMINUE LA PROFONDEUR DES PERMUTATIONS
C     NECESSAIRES RESTE LIMITEE GRACE AU TRI DE LA SOUS-SUITE
C     CORRESPONDANT A LA VALEUR PRECEDENTE DE L'INCREMENT (LE PAS).
C
      INCR=N
C
C     DECROISSANCE DE L'INCREMENT PAR DIVISION PAR 2
C
   10 INCR=INCR/2
C
C     POUR TOUT J VARIANT DE INCR+1 A N,
C     LA SOUS-SUITE NARG(J+H*INCR) AVEC H=...,-3,-2,-1,0
C     SERA ORDONNEE.
C
      DO 40 J=INCR+1,N
C
C       ON PROCEDE PAR RECURENCE : LE FAIT QUE LES ELEMENTS
C       NARG(J+H*INCR) DEPUIS LE DEBUT JUSQU'A J+H*INCR=K-INCR
C       SOIENT DEJA ORDONNES EST UTILISE POUR ALLER JUSTE PLACER
C       CONVENALEMENT L'ELEMENT NARG(K) : INSERTION SEQUENTIELLE.
C
C
C         ***** ICI :  SAUVEGARDE DE NARG(J)
C
        NARGJ=NARG(J)
        K=J
        DO 20 I=J-INCR,1,-INCR
C
C         ***** ICI :  LOI D'ORDRE
C         COMPARER NARG(I) ET NARGJ=NARG(J)
C         SI NARG(I) EST AVANT OU EGAL A NARGJ ALLER EN 30
C
          IF(NARG(I).LE.NARGJ) GOTO 30
C
C         ***** ICI :  AFFECTER LE CONTENU DE NARG(I) A NARG(K)
C
          NARG(K)=NARG(I)
          K=I
   20   CONTINUE
C
C         ***** ICI :  AFFECTER LE CONTENU DE NARGJ A NARG(K)
C
   30   NARG(K)=NARGJ
C
C       FIN DU TRI DE LA SOUS-SUITE ASSOCIEE A J
C
   40 CONTINUE
C
C     PEUT-ON ENCORE DIMINUER L'INCREMENT (LE PAS) ?
C
      IF(INCR.GT.1) GOTO 10
C
C     INCR=1, LE TRI FINAL EST ACHEVE. MERCI DE VOTRE VISITE.
C
 9999 END
C
C
C
      SUBROUTINE IORDRE(N,L,M,NARG)
C     ***************************************************************
C     OBJET : IMPOSE UN ORDRE DONNE A UN TABLEAU D'ENTIERS 
C
C     IMPOSER UN ORDRE (FOURNI DANS LE TABLEAU L) A UN TABLEAU NARG
C     M : TABLEAU DE TRAVAIL D'AU MOINS N ENTIERS
C
C       ENTREE :
C       POUR I=1 A N, NARG(L(I)) EST LE I EME ARGUMENT DANS LA LISTE
C       ORDONNEE. IL OCCUPE DONC INITIALEMENT LA POSITION L(I).
C
C       ATTENTION : L SOIT ETRE UNE PERMUTATION DES N ENTIERS DE 1 A N.
C
C       SORTIE :
C       POUR I=1 A N, NARG(I) EST LE I EME ARGUMENT DANS LA LISTE
C       ORDONNEE. IL OCCUPE DONC LA POSITION I CORESPONDANT A SON RANG.
C       POSONS J=L(J), ALORS NARG(M(J)) EST MAINTENANT L'ARGUMENT QUI
C       INITIALEMENT ETAIT A LA POSITION J.
C       AUTREMENT DIT, LE TABLEAU M EST LA PERMUTATION RECIPROQUE DE L.
C       EN PARTICULIER, LES DEUX APPELS SUCCESSIFS SUIVANTS CONDUISENT
C       A LA FABRICATION DE M (A PARTIR DE L) ET A NARG INCHANGE :
C       CALL IORDRE(N,L,M,NARG) PUIS CALL IORDRE(N,M,L,NARG).
C
C     ***************************************************************
      INTEGER N,L(*),M(*),NARG(*)
      INTEGER NARGI
      INTEGER I,LI,MI
C
C     ON N'A RIEN A FAIRE
C
      IF(N.LE.1) GOTO 9999
C
C     PERMUTATION M INVERSE DE L :
C
      DO 10 I=1,N
        M(L(I))=I
   10 CONTINUE
C
C     IMPOSER A NARG L'ORDRE DEFINI PAR L.
C     LES TABLEAUX L ET M SONT CASSES.
C
      DO 20 I=1,N
        LI=L(I)
        MI=M(I)
        NARGI=NARG(I)
        NARG(I)=NARG(LI)
        NARG(LI)=NARGI
        L(MI)=LI
        M(LI)=MI
   20 CONTINUE
C
C     RESTAURATION DES TABLEAUX L (INITIAL) ET M (SON INVERSE).
C
      DO 30 I=1,N
        LI=L(I)
        MI=M(I)
        L(MI)=I
        M(LI)=I
   30 CONTINUE
 9999 END
C
C
C
      SUBROUTINE INVORD(N,NARG)
C     ***************************************************************
C     OBJET : INVERSE L'ORDRE D'UN TABLEAU D'ENTIERS
C
C     INVERSER L'ODRDRE DANS LE TABLEAU NARG
C
C       ENTREE :
C       N TERMES NARG(1),NARG(2), ... , NARG(N)
C
C       SORTIE :
C       LA TABLEAU NARG DEVIENT : NARG(N),NARG(N-1), ... , NARG(1)
C
C     ***************************************************************
      INTEGER N,NARG(*)
      INTEGER NARGI
      INTEGER I
C
C     ON N'A RIEN A FAIRE
C
      IF(N.LE.1) GOTO 9999
C
C     PERMUTATION DE NARG(I) ET DE NARG(N+1-I)
C
      DO 10 I=1,N
        NARGI=NARG(I)
        NARG(I)=NARG(N+1-I)
        NARG(N+1-I)=NARGI
   10 CONTINUE
 9999 END
C
      SUBROUTINE  TBV2IT(ITABRG,NBE,INVMAX,IREFRG,NBINTV,
     >                       NINVMX,IERR)
C     **********************************************************************
C     OBJET TBV2IT : CONVERTIT UN TABLEAU D'ENTIERS EN UN TABLEAU D'INTERVALLES 
C                    LE TABLEAU N'EST PAS COMPRIME (VOIR RGCOMP)
C     EN ENTREE :
C       ITABRG  : TABLEAU D'ENTIERS
C       NBE     : TAILLE DU TABLEAU D'ENTIERS
C
C       INVMAX ,IREMAT  :  TABLEAUX DE SORTIE
C       NINVMX        :  TAILLE DES TABLEAUX
C
C     EN SORTIE :
C       INVMAX : INVMAX(I-1)+1,INVMAX(I) PREMIER ET DERNIER ELEMENTS DE
C                 DE L'INTERVAL I 
C       IREMAT  : IREMAT(I) ENTIER ASSOCIEE A L'INTERVAL I
C       NBINTV  : NOMBRE D'INTERVALS
C          IERR : -2 SI INVMAX ET IREMAT SONT TROP PETITS                
C     **********************************************************************
      INTEGER INVMAX(*),IREFRG(*),NBINTV,NINVMX
      INTEGER ITABRG(*),NBE,IERR
C
      INTEGER I
C
      IERR = -2
      IF(NINVMX.LT.1)GOTO 999
      NBINTV = 1
C     --- bug 07.05.2002 : il faut initialiser INVMAX(1) au cas ou !
      INVMAX(NBINTV) = 0
      IREFRG(NBINTV) = ITABRG(1)
      DO 10 I=1,NBE
        IF( ITABRG(I).NE.IREFRG(NBINTV))THEN
          NBINTV = NBINTV + 1
          IF( NBINTV.GT.NINVMX )GOTO 999
          IREFRG(NBINTV) = ITABRG(I)
          INVMAX(NBINTV) = 1
        ELSE
          INVMAX(NBINTV) = INVMAX(NBINTV) + 1     
        ENDIF
   10 CONTINUE
C     --- ajout o.stab BUG 07.05.2002 ---
      DO 20 I=2,NBINTV
        INVMAX(I) = INVMAX(I) + INVMAX(I-1)
 20   CONTINUE
C
      IERR = 0
C
  999 END
C      
      SUBROUTINE  TBIT2V(INVMAX,IREFRG,NBINTV,ITABRG,NBE,IERR)
C     **********************************************************************
C     OBJET TBIT2V : CONVERTIT UN TABLEAU D'INTERVALLES EN TABLEAU D'ENTIERS
C
C     EN ENTREE :
C       INVMAX : INVMAX(I-1)+1,INVMAX(I) PREMIER ET DERNIER ELEMENTS DE
C                 DE L'INTERVAL I 
C       IREMAT  : IREMAT(I) ENTIER ASSOCIEE A L'INTERVAL I
C       NBINTV  : NOMBRE D'INTERVALS
C
C       ITABRG : TABLEAU A REMPLIR
C       NBE     : TAILLE DU TABLEAU A REMPLIR
C     EN SORTIE :
C       ITABRG : ITABRG(I) EST LA VALEUR DE L'ELEMENT I
C          IERR : -1 SI UNE REFERENCE EST HORS DE [1:NBE]
C     **********************************************************************
      INTEGER INVMAX(*),IREFRG(*),NBINTV
      INTEGER ITABRG(*),NBE,IERR
C
      INTEGER I,J,IDMAT,IFMAT
C
      IERR = -1
      IDMAT = 1
      DO 20 I=1,NBINTV
          IFMAT = INVMAX(I)
          IF((IFMAT.GT.NBE).OR.(IFMAT.LT.1))GOTO 999
          DO 10 J=IDMAT,IFMAT
            ITABRG(J) = IREFRG(I)
   10   CONTINUE
      IDMAT = IFMAT+1
   20 CONTINUE
C
      IERR = 0
  999 END
C
      SUBROUTINE  TBNUIT(ITABRG,NBE,IREFRG,NBREF,INUM,
     >                       ICARD,IERR)
C     **********************************************************************
C     OBJET TBNUIT : DONNE UNE NUMEROTATION POUR OBTENIR DES INTERVALS
C
C     EN ENTREE :
C       ITABRG : ITABRG(I) = LA VALEUR DE L'ELEMENT I
C       NBE     : NOMBRE D'ELEMENTS
C       IREFRG : LES DIFFERENTES VALEURES DES ELEMENTS (-1 INTERDIT)
C                 CHAQUE VALEUR DE ITABRG APPARAIT UNE ET UNE SEULE 
C                 FOIS DANS IREFRG
C       NBREF   : NOMBRE DE VALEURES DIFFERENTES
C
C     EN SORTIE :
C       INUM    : INUM(I) = NOUVEAU NUMERO DE L'ELEMENT I
C                 POUR OBTENIR DES INTERVALS. ILS SONT DANS L'ORDRE
C                 DE IREFRG
C       ICARD   : CARD(I) = CARDINAL DE LA REFERENCE IREFRG(I)
C          IERR : 0 SI OK
C                -1 SI IL MANQUE UNE REFERENCE, SI UNE REFERENCE EST DOUBLE.
C     ***********************************************************************
      INTEGER ITABRG(*),NBE,IREFRG(*),NBREF
      INTEGER INUM(*),ICARD(*),IERR
C
      INTEGER I,J,IRENUM
C
      IERR = -1
      IF( NBREF.GT.NBE )THEN
        CALL DSERRE(1,IERR,'TBNUIT',' REFERENCES > ELEMENTS ')
        GOTO 999
      ENDIF
C        ============================================
C     --- 1. PARCOURS DE ITABRG
C         ON EMPILE LES NUMEROS DES ELEMENTS 
C         D'UN MEME MATERIAU 
C        ============================================
      IRENUM = 0
      DO 20 I=1,NBE
        INUM(I) = -1
   20 CONTINUE
      DO 50 I=1,NBREF
        ICARD(I)   = 0
        DO 40 J=1,NBE
          IF( ITABRG(J).EQ.IREFRG(I))THEN
            IRENUM = IRENUM + 1
            INUM(IRENUM) = J
            ICARD(I) = ICARD(I) + 1
          ENDIF        
   40   CONTINUE
   50 CONTINUE
C
      IF( IRENUM.NE.NBE )THEN
        CALL DSERRE(1,IERR,'TBNUIT','ELEMENTS SANS REFERENCES')
        GOTO 999
      ENDIF
      DO 60 I=1,NBE
        IF( INUM(I) .EQ. -1 )GOTO 999
   60 CONTINUE
C
      IERR = 0
C   
  999 END
C
      SUBROUTINE  TBVTAB(ITABRG,NBE,ITVL,IREFRG,NBREF,
     >                      NREFMX,IERR)
C     **********************************************************************
C     OBJET TBVTAB : RENVOI LES VALEURS DISTINCTES ET TRIEES D'UN TABLEAU, 
C             TRIEES DANS L'ORDRE CROISSANT 
C     EN ENTREE :
C       ITABRG : UN ENSEMBLE DES REFERENCES 
C                 (PAR EXEMPLE ITABRG(I) = MATERIAU DE L'ELEMENT I)
C       NBE     : NOMBRE DE REFERENCES
C       ITVL: TABLEAU DE TRAVAIL DE TAILLE = NBE
C
C       IREFRG : TABLEAU RESULTAT (ON PEUT UTILISER ITABRG)
C       NREFMX: TAILLE DU TABLEAU RESULTAT
C
C     EN SORTIE :
C       IREFRG : LES REFERENCES DISTINCTES DE IREFRG TRIEES DANS 
C                 L'ORDRE CROISSANT 
C       NBREF   : NOMBRE DE REFERENCES DISTINCTES (ON PEUT UTILISER NBE)
C          IERR : 0 SI OK
C                -2 SI IREFRG EST TROP PETIT
C     **********************************************************************
      INTEGER ITABRG(*),NBE,IREFRG(*),NBREF,ITVL(*)
      INTEGER NREFMX,IERR
C
      INTEGER I,IREF,NBREF2
C
      IREF = 1
      DO 10 I=1,NBE
        ITVL(IREF-1+I) = ITABRG(I)
   10 CONTINUE
      CALL KNUTA(NBE,ITVL(IREF))
      NBREF2 = 1
      IF(NREFMX.GT.0)THEN
        IREFRG(NBREF2) = ITVL(IREF)
      ELSE
        IERR = -2
      ENDIF
      DO 20 I=2,NBE
c        IF( ITVL(I-1+IREF).NE.ITVL(NBREF2-1+IREF) ) BUG DU 10.10.98
        IF( ITVL(I-1+IREF).NE.IREFRG(NBREF2) )
     >     NBREF2 = NBREF2+1
        IF( NREFMX.GE.NBREF2 )THEN
          IREFRG(NBREF2) = ITVL(I-1+IREF)
        ELSE
          IERR = -2
        ENDIF
   20 CONTINUE  
C
      NBREF = NBREF2
C
  999 END
C     *****************************************************************
C     MODULE  : ST (STRUCTURE DES DONNEES)
C     FICHIER : D3_ENSEMBLE.F
C     OBJET   : MANIPULATION DES ENSEMBLES DE N-UPLETS (A FAIRE)
C     FONCT.  : 
C
C     AUTEUR  : O. STAB
C     DATE    : 04.97
C     MODIFICATIONS :
C      AUTEUR, DATE, OBJET :
C
C                              
C     *****************************************************************C
C
      SUBROUTINE IORDR2(NBLIG,NBCOL,IORDRE,ITVL,NARG)
C     ***************************************************************
C     OBJET IORDR2: IMPOSE UN ORDRE DONNE A UN TABLEAU 2D D'ENTIERS 
C
C     IMPOSER UN ORDRE (FOURNI DANS LE TABLEAU IORDRE) A UN TABLEAU NARG
C     ITVL : TABLEAU DE TRAVAIL D'AU MOINS NBLIG ENTIERS
C
C     EN ENTREE :
C       POUR I=1 A N, NARG(IORDRE(I)) EST LE I EME ARGUMENT DANS LA LISTE
C       ORDONNEE. IL OCCUPE DONC INITIALEMENT LA POSITION IORDRE(I).
C
C       ATTENTION : IORDRE DOIT ETRE UNE PERMUTATION DES NBLIG ENTIERS
C                   DE 1 A NBLIG.
C
C     EN SORTIE :
C       POUR I=1 A NBLIG, NARG(I) EST LE I EME ARGUMENT DANS LA LISTE
C       ORDONNEE. IL OCCUPE DONC LA POSITION I CORESPONDANT A SON RANG.
C       POSONS J=IORDRE(J), ALORS NARG(ITVL(J)) EST MAINTENANT L'ARGUMENT 
C       QUI INITIALEMENT ETAIT A LA POSITION J.
C       AUTREMENT DIT, LE TABLEAU M EST LA PERMUTATION RECIPROQUE DE L.
C       EN PARTICULIER, LES DEUX APPELS SUCCESSIFS SUIVANTS CONDUISENT
C       A LA FABRICATION DE ITVL (A PARTIR DE IORDRE) ET A NARG INCHANGE :
C       CALL IORDRE(NBLIG,NBCOL,IORDRE,ITVL,NARG) 
C       PUIS CALL IORDRE(NBLIG,NBCOL,ITVL,IORDRE,NARG).
C
C     ***************************************************************
      INTEGER NBLIG,NBCOL,IORDRE(*),ITVL(*),NARG(*)
C
      INTEGER I,J,LI,MI,ITEMP
C
C     ON N'A RIEN A FAIRE
C
      IF(NBLIG.LE.1) GOTO 9999
C
C     PERMUTATION ITVL INVERSE DE IORDRE :
C
      DO 10 I=1,NBLIG
        ITVL(IORDRE(I))=I
   10 CONTINUE
C
C     IMPOSER A NARG L'ORDRE DEFINI PAR IORDRE.
C     LES TABLEAUX IORDRE ET M SONT CASSES.
C
      DO 20 I=1,NBLIG
        LI=IORDRE(I)
        MI=ITVL(I)
C       ---- ON PERMUTE 2 LIGNE ----
        DO 40 J=1,NBCOL
          ITEMP=NARG((I-1)*NBCOL+J)
          NARG((I-1)*NBCOL+J)=NARG((LI-1)*NBCOL+J)
          NARG((LI-1)*NBCOL+J)=ITEMP
   40   CONTINUE
C       ---------------------------
        IORDRE(MI)=LI
        ITVL(LI)=MI
   20 CONTINUE
C
C     RESTAURATION DES TABLEAUX L (INITIAL) ET M (SON INVERSE).
C
      DO 30 I=1,NBLIG
        LI=IORDRE(I)
        MI=ITVL(I)
        IORDRE(MI)=I
        ITVL(LI)=I
   30 CONTINUE
 9999 END
C
C
      SUBROUTINE KNUTP2(N,L,ICOL,NBCOL,NARG)
C     ***************************************************************
C     OBJET KNUTP2: IDEM KNUTP FONCTIONNANT SUR DES TABLEAUX 2D
C
C     EN ENTREE :
C         NARG : TABLEAU D'ENTIERS
C         N    : NOMBRE DE LIGNES
C         NBCOL: NOMBRE DE COLONNES
C         ICOL : COLONNE A TRIER
C
C     EN SORTIE :
C         L    : INDICE DES ELEMENTS DE NARG TEL QUE 
C                LA SUITE NARG((L(I)-1)*NBCOL+ICOL) SOIT ORDONNEE
C
C     COMMENTAIRES KNUTP:
C
C     ON TRIE LES N TERMES NARG(I) POUR I=1,N
C
C     TRI PAR INCREMENT DECROISSANT (SHELL SORTING)
C     COMPLEXITE EN N PUISSANCE 3/2 ET MEME STATISTIQUEMENT EN N**1.2
C
C     POUR EN SAVOIR PLUS : KNUTH, "THE ART OF COMPUTER PROGRAMMING",
C                           VOL 3 : SORTING AND SEARCHING,
C                           ADDISON-WESLEY, 1973.
C
C     KNUTP : P COMME PASSIF, C.A.D. QUE LES ARGUMENTS NARG(I) POUR
C             I=1 A N NE SONT PAS "PERMUTES" (TABLEAU NARG NON MODIFIE).
C             MAIS CE MODULE DETERMINE LE TABLEAU L(I) POUR I=1 A N
C             DE SORTE QUE LA SUITE NARG(L(I)) SOIT ORDONNEE.
C             VOIR AUSSI KNUTA.
C
C     REMARQUE : NARG PEUT ETRE DE TOUT TYPE ET TOUTE LOI D'ORDRE
C                PEUT ETRE INTRODUITE. IL SUFFIT D'INTERVENIR
C                AUX ENDROITS INDIQUES AINSI : '***** ICI : ...'.
C
C     ***************************************************************
      INTEGER N,L(*),NARG(*)
      INTEGER ICOL,NBCOL
      INTEGER NARGJ
C
      INTEGER I,J,II,JJ,K,INCR
C
C     ON N'A RIEN A TRIER
C
      IF(N.LE.0) GOTO 9999
      DO 10 I=1,N
        L(I)=I
   10 CONTINUE
      IF(N.LE.1) GOTO 9999
C
C     POUR J=INCR+1,N, LA SOUS-SUITE NARG(L(J+H*INCR)), H=...,-3,-2,-1,0
C     SERA ORDONNEE (TRI HABITUEL PAR INSERTION SEQUENTIELLE).
C
C     DES QUE INCR=1 ON A ATTEINT L'OBJECTIF FINAL.
C
C     INCR SUBIT UNE DECROISSANCE PROGRESSIVE DE SORTE QU'AU
C     DEBUT IL EST GRAND (LA SOUS-SUITE A TRIER A UN CARDINAL FAIBLE)
C     ENSUITE QUAND INCR DIMINUE LA PROFONDEUR DES PERMUTATIONS
C     NECESSAIRES RESTE LIMITEE GRACE AU TRI DE LA SOUS-SUITE
C     CORRESPONDANT A LA VALEUR PRECEDENTE DE L'INCREMENT (LE PAS).
C
      INCR=N
C
C     DECROISSANCE DE L'INCREMENT PAR DIVISION PAR 2
C
   20 INCR=INCR/2
C
C     POUR TOUT J VARIANT DE INCR+1 A N,
C     LA SOUS-SUITE NARG(L(J+H*INCR)) AVEC H=...,-3,-2,-1,0
C     SERA ORDONNEE.
C
      DO 50 J=INCR+1,N
C
C       ON PROCEDE PAR RECURENCE : LE FAIT QUE LES ELEMENTS
C       NARG(L(J+H*INCR)) DEPUIS LE DEBUT JUSQU'A J+H*INCR=K-INCR
C       SOIENT DEJA ORDONNES EST UTILISE POUR ALLER JUSTE PLACER
C       CONVENALEMENT L'ELEMENT L(K) : INSERTION SEQUENTIELLE.
C
        JJ=L(J)
C        NARGJ=NARG(JJ)
        NARGJ=NARG((JJ-1)*NBCOL+ICOL)
        K=J
        DO 30 I=J-INCR,1,-INCR
          II=L(I)
C
C         ***** ICI :  LOI D'ORDRE
C         COMPARER NARG(II) ET NARGJ=NARG(JJ)
C         SI NARG(II) EST AVANT OU EGAL A NARGJ ALLER EN 40
C
C          IF(NARG(II).LE.NARGJ) GOTO 40
          IF(NARG((II-1)*NBCOL+ICOL).LE.NARGJ) GOTO 40
C
C         DECALLAGE VERS LA DROITE DU I EME TERME
C
          L(K)=II
          K=I
   30   CONTINUE
C
C       ON VIENT DE TROUVER LA PLACE CONVENABLE POUR NARG(L(J))
C
   40   L(K)=JJ
C
C       FIN DU TRI DE LA SOUS-SUITE ASSOCIEE A J
C
   50 CONTINUE
C
C     PEUT-ON ENCORE DIMINUER L'INCREMENT (LE PAS) ?
C
      IF(INCR.GT.1) GOTO 20
C
C     INCR=1, LE TRI FINAL EST ACHEVE. MERCI DE VOTRE VISITE.
C
 9999 END
C
C
C
      SUBROUTINE TBILEX(ITB,NBN,NBE,NBO,NBT,
     >                  ITVL,NTIMAX,
     >                  ITBLEX,IERR)
C     **********************************************************************
C     OBJET TBIMAG : TRI LEXICO D'UN TABLEAU D'ENTIER
C
C     EN ENTREE :
C       ITB : TABLEAU DE NBN*NBE ENTIERS
C       NBN : NOMBRE D'ENTIER PAR ELEMENT (DE COLONNES)
C       NBE : NOMBRE D'ELEMENTS (DE LIGNES)
C       NBO : ORDRE DU TRI (<= NBN)
C       NBT : NOMBRE D'ELEMENTS A TRIER (<=NBE)
C
C       ITVL   : TABLEAU D'ENTIER (POUR LE TRAVAIL)
C       NTIMAX : LA TAILLE NECESSAIRE DEPEND DES DONNEES
C                AU MIN =1     : SI L'ORDRE 1 EST DISTINCTIF
C                AU MAX =3*NBE+NBO : SI 1 ERE COLONNE IDENTIQUE
C       ITBLEX : TABLEAU D'ENTIER DE TAILLE = NBE
C
C     EN SORTIE :
C       ITBLEX : INDICE DES ELEMENTS DE ITB POUR QUE ITB(ITBLEX(I))
C                SOIT TRIE DANS L'ORDRE CROISSANT LEXICOGRAPHIQUE
C       IERR  :  0 SI OKAY
C                -2 ITVL TROP PETIT
C
C     **********************************************************************
      INTEGER ITB(*),NBN,NBE,NBO,NBT
      INTEGER ITVL(*),NTIMAX
      INTEGER ITBLEX(*),IERR
C
      INTEGER ICOL,IED,IE,IV,NBE2,L2,ITRAV,J,IEMAX
C
      IERR = 0
      ICOL = 1
      CALL KNUTP2(NBE,ITBLEX,ICOL,NBN,ITB)
      IF((NBO.EQ.1).OR.(NBN.EQ.1)) GOTO 9999
C
      IED = 1
C         =========================================
C     ---- ON PASSE A UN ELEMENT SUIVANT IED=IED+1 ---
C     ---- OU A L'ORDRE SUIVANT      ICOL = ICOL+1 ---
C         =========================================
C      IEMAX = NBE+1
      IEMAX = 1
      ITVL(ICOL-1+IEMAX) = NBE+1
   20 CONTINUE
      IF( IED.GE.NBE )GOTO 9999
      IE = IED
      IV = ITB((ITBLEX(IE)-1)*NBN+ICOL)
   30 IE = IE + 1
C
C     --- TANT QUE LES ELEMENTS SONT IDENTIQUES A L'ORDRE ICOL ---
      IF((IE.LT.ITVL(ICOL-1+IEMAX)).AND.
     >   (ITB((ITBLEX(IE)-1)*NBN+ICOL).EQ.IV))GOTO 30
C
      NBE2 = IE-IED
C
C     --- ELEMENT UNIQUE : IL EST ORDONNE ! ---
      IF( NBE2.LE.1 )THEN
*        WRITE(6,*) IED,' DEJA DANS L ORDRE POUR LE NIVEAU ',ICOL 
        IED = IE
        IF(( IED.EQ.NBT ).OR.( IED.EQ.NBE ))GOTO 9999        
        IF(IE.EQ.ITVL(ICOL-1+IEMAX))THEN
*          WRITE(6,*) IED,' ON A FINI LE NIVEAU ',ICOL 
C          IEMAX = NBE + 1
C          ICOL  = 1
          ICOL  = ICOL - 1
        ENDIF
        GOTO 20
      ENDIF
C
C     --- IL FAUT TRIER DE IED A IE SUR L'ORDRE :(ICOL+1) ----
*      WRITE(6,*) 'TRI DE ',IED,' A ',(IE-1),' SUR L ORDRE ',(ICOL+1) 
C
C      L2    = NBE2 + ITRAV
      L2    = NBO + IEMAX
      ITRAV = L2 + NBE2
      IF( (NTIMAX-ITRAV).LT.NBE2 )THEN
        IERR = -2
        GOTO 9999
      ENDIF
      DO 40 J=1,NBE2
        ITVL(J-1+ITRAV) = ITB((ITBLEX(IED+J-1)-1)*NBN+ICOL+1)
   40 CONTINUE
*      WRITE(6,*) 'COLONNE = ',(ITVL(J-1+ITRAV),J=1,NBE2)    
C
      CALL KNUTP(NBE2,ITVL(L2),ITVL(ITRAV))
*      WRITE(6,*) 'ORDRE = ',(ITVL(L2+J-1),J=1,NBE2)    
C     ---- MISE A JOUR DE ITBLEX ----
      CALL IORDRE(NBE2,ITVL(L2),ITVL(ITRAV),ITBLEX(IED))
C
      IF(((ICOL+1).EQ.NBO).OR.((ICOL+1).EQ.NBN))THEN
*        WRITE(6,*) IED,' ON A FINI LE NIVEAU ',ICOL 
        IED   = IE
        ICOL = ICOL - 1
C        IEMAX = NBE + 1
C        ICOL  = 1
        IF(( IED.EQ.NBT ).OR.( IED.EQ.NBE ))GOTO 9999        
        GOTO 20
      ENDIF
      ICOL = ICOL+1
      ITVL(ICOL-1+IEMAX) = IE
      GOTO 20
C     
 9999 END
C
      SUBROUTINE TBIMAG(ITB1,NBN1,NBE1,ITB2,NBN2,NBE2,
     >                  ITVL,NTIMAX,
     >                  IMAG1,IERR)
C     **********************************************************************
C     OBJET TBIMAG : INDICES DES ELEMENTS COMMUNS DE 2 TABLEAUX
C
C     EN ENTREE :
C       ITB1 : TABLEAU DE NBN1*NBE1 ENTIERS
C       NBN1 : NOMBRE D'ENTIER PAR ELEMENT (SANS ORDRE !)
C       NBE1 : NOMBRE D'ELEMENTS
C       ITB2,NBN2,NBE2 : IDEM
C
C       ITVL   : TABLEAU D'ENTIER (POUR LE TRAVAIL)
C       NTIMAX : LA TAILLE NECESSAIRE DEPEND DES DONNEES
C                AU MIN = NBE1+NBE2 : SI L'ORDRE 1 EST DISTINCTIF
C                AU MAX = 4*(NBE1+NBE2) : SI 1 ERE COLONNE IDENTIQUE
C       IMAG1  : TABLEAU D'ENTIER DE TAILLE = NBE
C
C     EN SORTIE :
C       IMAG1 : IMAG(I) = EST LA POSITION DE L'ELEMENT I DE ITB1 DANS ITB2
C               OU IMAG(I) = 0 SI L'ELEMENT N'EST PAS PRESENT DANS ITB2
C       IERR  :  0 SI OKAY
C               -2 ITVL TROP PETIT
C
C     REMARQUE : 
C                ATTENTION ITB1 ET ITB2 SONT MODIFIES
C     **********************************************************************
      INTEGER ITB1(*),NBN1,NBE1,ITB2(*),NBN2,NBE2
      INTEGER ITVL(*),NTIMAX
      INTEGER IMAG1(*),IERR
C
      INTEGER IE,IT1,ITRAV,NITMX2,IT2,IE1,IE2,IETB1,IETB2,IDIFF,I,J
C
C     --- TRI DES ENTIERS DE CHAQUE ELEMENT ---
C
      DO 10 IE=1,NBE1      
        CALL KNUTA(NBN1,ITB1((IE-1)*NBN1+1))
   10 CONTINUE      
      DO 20 IE=1,NBE2      
        CALL KNUTA(NBN2,ITB2((IE-1)*NBN2+1))
   20 CONTINUE      
C
C     --- TRI DES ELEMENTS ---
C
      IT1    = 1
      ITRAV  = NBE1 + IT1
      NITMX2 = NTIMAX - ITRAV
      IF( NITMX2.LE.0 )THEN
        IERR = -2
        CALL DSERRE(1,IERR,'TBIMAG',' PAS DE PLACE')
        GOTO 9999
      ENDIF
      CALL TBILEX(ITB1,NBN1,NBE1,NBN1,NBE1,
     >                  ITVL(ITRAV),NITMX2,
     >                  ITVL(IT1),IERR)
C      PRINT *,'TBIMAG : IT1 =',
C     > ((ITB1((ITVL(IE1-1+IT1)-1)*NBN1+J),J=1,NBN1),IE1=1,NBE1)
      IF( IERR.NE.0 )THEN
        CALL DSERRE(1,IERR,'TBIMAG',' 1 APPEL TBILEX')
        GOTO 9999
      ENDIF
      IT2    = NBE1 + IT1
      ITRAV  = NBE2 + IT2
      NITMX2 = NTIMAX - ITRAV
      CALL TBILEX(ITB2,NBN2,NBE2,NBN2,NBE2,
     >                  ITVL(ITRAV),NITMX2,
     >                  ITVL(IT2),IERR)
C      PRINT *,'TBIMAG : IT2 =',
C     > ((ITB2((ITVL(IE2-1+IT2)-1)*NBN2+J),J=1,NBN2),IE2=1,NBE2)
      IF( IERR.NE.0 )THEN
        CALL DSERRE(1,IERR,'TBIMAG',' 2 APPEL TBILEX')
        GOTO 9999
      ENDIF
C
C     --- COMPARAISON DES ELEMENTS ---
C
      IE1 = 1
      IE2 = 1
C
C       --- TANT QUE IE1 > IE2 : IE2 = IE2 + 1
C
   40 CONTINUE
      IF( IE1.GT. NBE1 )GOTO 9999
      IF( IE2.GT. NBE2 )THEN
         DO 50 I=IE1,NBE1
           IMAG1(ITVL(I-1+IT1)) = 0
   50    CONTINUE
         GOTO 9999
      ENDIF
      IETB1 = ITVL(IE1-1+IT1)
      IETB2 = ITVL(IE2-1+IT2)
      DO 60 J=1,MAX(NBN1,NBN2)
        IDIFF = ITB1((IETB1-1)*NBN1+J)-ITB2((IETB2-1)*NBN2+J)
        IF( IDIFF.GT. 0)THEN
          IE2 = IE2 + 1
          GOTO 40
        ENDIF
        IF( IDIFF.LT. 0)THEN
          IE1 = IE1 + 1
          GOTO 40
        ENDIF
   60 CONTINUE
      IMAG1(IETB1) = IETB2
      IE1 = IE1 + 1
      IE2 = IE2 + 1
      GOTO 40
C
 9999 END
C
C     *****************************************************************
C     MODULE  : ST (STRUCTURE DES DONNEES)
C     FICHIER : ST_NUMERO.F
C     OBJET   : RENUMEROTE UN MAILLAGE 2D OU 3D
C     FONCT.  : 
C          NUPERM  : PERMUTE 2 ELEMENTS D'UN MAILLAGE
C          NURENU  : RENUMEROTE LES ELEMENTS D'UN MAILLAGE
C          NUCOMP  : RENUMEROTE LES ELEMENTS D'UN MAILLAGE POUR LES 
C                        COMPACTER EN DEBUT : DE 1 A "NBNUM"
C
C     AUTEUR  : O. STAB 
C     DATE    : 03.95
C     TESTS   : O.STAB 03.95
C     MODIFICATIONS :
C      AUTEUR, DATE, OBJET : O.STAB, 08.97, NUPERM BUG_25
C
C
C     *****************************************************************
C
      SUBROUTINE NUPERM(IDE,ITRNOE,NBNMAX,ITRTRI,NBCMAX,NOETRI,
     >                   NOEMAX,NBE,IT1,IT2,IERR)
C     *****************************************************************
C     OBJET : PERMUTE 2 ELEMENTS D'UN MAILLAGE
C     EN ENTREE:
C      IDE    :  (1..3) DIMENSION DES ELEMENTS (POURRA SERVIR)
C      ITRNOE:  LES NOEUDS DES ELEMENTS
C      NBNMAX :  (2..8) NOMBRE DE NOEUDS MAXIMUM DES ELEMENTS 
C      ITRTRI:  LES VOISINS DES ELEMENTS
C      NBCMAX :  (2..6) NOMBRE DE COTES MAXIMUM DES ELEMENTS 
C      NOEMAX: SI NOEMAX = 0 ALORS NOETRI N'EST PAS CONSIDERE
C      NBE    :  NOMBRE D'ELEMENTS DU MAILLAGE
C      IT1,IT2:  LES 2 ELEMENTS A PERMUTER
C     EN SORTIE:
C       ITRNOE: MIS A JOUR
C       ITRTRI: MIS A JOUR 
C       NOETRI : MIS A JOUR
C         IERR : CODE D'ERREUR 0 => OK
C               -1 => DONNEES INCOHERENTES
C     CONDITION D'APPLICATION : TOUT MAILLAGE
C     *****************************************************************
      INTEGER    IDE,ITRNOE(*),NBNMAX,ITRTRI(*),NBCMAX,NOETRI(*),NBE
      INTEGER    NOEMAX,IT1, IT2, IERR
C
      INTEGER I,J,K,ITRTR2(6),ITRNO2(8),IT(3),ITR,IFRINT
      INTEGER NNT,NTRTRI(2*6,3)
C      
      IERR = 0
      IF( IT1 .EQ. IT2 )GO TO 999
      IF((IT1.LT.1).OR.(IT1.GT.NBE).OR.
     >   (IT2.LT.1).OR.(IT2.GT.NBE))THEN
         IERR = -1
         CALL DSERRE(1,IERR,' NUPERM','NUMERO HORS INTERVAL')      
         GO TO 999
      ENDIF
C     ---- MISE A JOUR DES REFERENCES A IT1 ET IT2 ---
      IT(1) = IT1
      IT(2) = IT2
      IT(3) = IT1
      NNT = 0
      DO 10 K=1,2
        IF( NOEMAX .GT. 0 )THEN
C       -- MISE A JOUR DES NOEUDS FAISANT REFERENCE A IT1,IT2 ---
          DO 20 I=1,NBNMAX
C            IF( NOETRI(ITRNOE((IT(K)-1)*NBNMAX+I)) .EQ. IT(K) )
C            BUG_25 : IL FAUT TESTER LE NUMERO DU NOEUD !!!
C                     MAILLAGE MIXTE OU ELEMENTS VIDE (A CREER)
            IF(( ITRNOE((IT(K)-1)*NBNMAX+I) .NE. 0 ).AND.
     >         ( NOETRI(ITRNOE((IT(K)-1)*NBNMAX+I)) .EQ. IT(K) ))
     >          NOETRI(ITRNOE((IT(K)-1)*NBNMAX+I)) = IT(K+1)
   20     CONTINUE
        ENDIF
C       --- DEBUT AJOUT DU 14.08.97 O.STAB ----------------------
C           POUR POUVOIR TRAITER SEULEMENT ITRNOE, PAS ITRTRI = 0
C           TRIVIAL MAIS PERMET D'UTILISER LES MEMES FONCTIONS
C
        IF( NBCMAX .EQ. 0 )THEN
        DO 21 I=1,NBNMAX
          ITRNO2(I)=ITRNOE((IT2-1)*NBNMAX+I)
   21   CONTINUE
        DO 22 I=1,NBNMAX
          ITRNOE((IT2-1)*NBNMAX+I)=ITRNOE((IT1-1)*NBNMAX+I)
   22   CONTINUE
        DO 23 I=1,NBNMAX
          ITRNOE((IT1-1)*NBNMAX+I)=ITRNO2(I)
   23   CONTINUE        
        GOTO 999
        ENDIF
C       --- FIN AJOUT DU 14.08.97 O.STAB ------------------------
C
C     ---- MISE A JOUR DES ELEMENTS VOISINS DE IT1,IT2 ---
        DO 30 I=1,NBCMAX
          ITR = ITRTRI((IT(K)-1)*NBCMAX+I)
          IF((ITR.NE.0).AND.(ITR.NE.IT(K+1))
     >        .AND.(ITR.NE.-IT(K+1)))THEN
            IFRINT = 1
            IF( ITR .LT. 0 )THEN 
              IFRINT = -1
              ITR = - ITR
            ENDIF
            DO 40 J=1,NBCMAX
             IF( (ITRTRI((ITR-1)*NBCMAX+J).EQ.IT(K)) .OR.
     >           (ITRTRI((ITR-1)*NBCMAX+J).EQ.-IT(K)) )THEN
                  NNT = NNT + 1
                  NTRTRI(NNT,1) = ITR
                  NTRTRI(NNT,2) = J
                  NTRTRI(NNT,3) = IFRINT * IT(K+1)
C                  ITRTRI((ITR-1)*NBCMAX+J) = IFRINT * IT(K+1)
             GO TO 30
             ENDIF
   40       CONTINUE
C         --- IL Y A UN BUG DANS LA STRUCTURE ---
          IERR = -1
          CALL DSERRE(1,IERR,' NUPERM',' STRUCTURE MAILLAGE')      
          GO TO 999
          ENDIF
   30   CONTINUE
   10 CONTINUE  
C     ------------------ MIS AJOUR DES VOISINS DE IT1,IT2 ---
      DO 45 I=1,NNT
       ITRTRI((NTRTRI(I,1)-1)*NBCMAX+NTRTRI(I,2))=NTRTRI(I,3)      
   45 CONTINUE
C     ------------------ SAUVEGARDE IT2 ---
      DO 50 I=1,NBCMAX
        IF( ITRTRI((IT2-1)*NBCMAX+I) .EQ. IT1 )THEN
          ITRTR2(I)=IT2
        ELSE IF( ITRTRI((IT2-1)*NBCMAX+I).EQ.-IT1)THEN
          ITRTR2(I)=-IT2
        ELSE
          ITRTR2(I)=ITRTRI((IT2-1)*NBCMAX+I)
        ENDIF
   50 CONTINUE
      DO 60 I=1,NBNMAX
        ITRNO2(I)=ITRNOE((IT2-1)*NBNMAX+I)
   60 CONTINUE
C     ---------- TRANSFERT IT1 -> IT2 ----------
      DO 70 I=1,NBCMAX
        IF( ITRTRI((IT1-1)*NBCMAX+I) .EQ. IT2 )THEN
          ITRTRI((IT2-1)*NBCMAX+I)=IT1
        ELSE IF( ITRTRI((IT1-1)*NBCMAX+I) .EQ. -IT2 )THEN
          ITRTRI((IT2-1)*NBCMAX+I)=-IT1
        ELSE 
          ITRTRI((IT2-1)*NBCMAX+I)=ITRTRI((IT1-1)*NBCMAX+I)
        ENDIF
   70 CONTINUE
      DO 80 I=1,NBNMAX
        ITRNOE((IT2-1)*NBNMAX+I)=ITRNOE((IT1-1)*NBNMAX+I)
   80 CONTINUE
C     ---------- TRANSFERT IT2 -> IT1 ----------
      DO 90 I=1,NBCMAX
        ITRTRI((IT1-1)*NBCMAX+I)=ITRTR2(I)
   90 CONTINUE
      DO 100 I=1,NBNMAX
        ITRNOE((IT1-1)*NBNMAX+I)=ITRNO2(I)
  100 CONTINUE
C     ------------------
  999 END
C
      SUBROUTINE NURENU(IDE,ITRNOE,NBNMAX,ITRTRI,NBCMAX,NOETRI, 
     >                   NOEMAX,NBE,NUM,ITRAMA,IERR)
C     *****************************************************************
C     OBJET : RENUMEROTE LES ELEMENTS D'UN MAILLAGE
C     EN ENTREE:
C      IDE    :  (1..3) DIMENSION DES ELEMENTS 
C      ITRNOE:  LES NOEUDS DES ELEMENTS
C      NBNMAX :  (2..8) NOMBRE DE NOEUDS MAXIMUM DES ELEMENTS 
C      ITRTRI:  LES VOISINS DES ELEMENTS
C      NBCMAX :  (2..6) NOMBRE DE COTES MAXIMUM DES ELEMENTS 
C      NOEMAX: SI NOEMAX = 0 ALORS NOETRI N'EST PAS CONSIDERE
C      NBE    :  NOMBRE D'ELEMENTS DU MAILLAGE
C       NUM    : NUM(I) EST NUMERO DE ELEMENTS QUI DOIT ETRE MIS EN I
C       ITRAMA        : "    "   "    "  DE TAILLE = NBE
C     EN SORTIE:
C       ITRNOE: MIS A JOUR
C       ITRTRI: MIS A JOUR 
C       NOETRI : MIS A JOUR
C     CONDITION D'APPLICATION : TOUT MAILLAGE
C     REMARQUE : COPIE DE IORDRE DE S.M. TIJANI
C     *****************************************************************
      INTEGER    IDE,ITRNOE(*),NBNMAX,ITRTRI(*),NBCMAX,NOETRI(*),NBE
      INTEGER    NOEMAX, NUM(*), ITRAMA(*), IERR
C
C     ---- COPIE DE IORDRE (S.M.TIJANI )----
C
      INTEGER I,LI,MI
C
C     ON N'A RIEN A FAIRE
C
      IERR = 0
      IF(NBE.LE.1) GOTO 9999
C
C     PERMUTATION M INVERSE DE L :
C
      DO 10 I=1,NBE
        ITRAMA(NUM(I))=I
   10 CONTINUE
C
C     IMPOSER A NARG L'ORDRE DEFINI PAR L.
C     LES TABLEAUX L ET M SONT CASSES.
C
      DO 20 I=1,NBE
        LI=NUM(I)
        MI=ITRAMA(I)
        CALL NUPERM(IDE,ITRNOE,NBNMAX,ITRTRI,NBCMAX,NOETRI,
     >                NOEMAX,NBE,I,LI,IERR)        
        IF( IERR .LT. 0 )GO TO 9999
        NUM(MI)=LI
        ITRAMA(LI)=MI
   20 CONTINUE
C
C     RESTAURATION DES TABLEAUX L (INITIAL) ET M (SON INVERSE).
C
      DO 30 I=1,NBE
        LI=NUM(I)
        MI=ITRAMA(I)
        NUM(MI)=I
        ITRAMA(LI)=I
   30 CONTINUE
 9999 END
C
C
      SUBROUTINE NUCOMP(IDE,ITRNOE,NBNMAX,ITRTRI,NBCMAX,NOETRI,
     >                   NOEMAX,NBE,NUM,NBNUM,IERR)
C     *****************************************************************
C     OBJET : RENUMEROTE LES ELEMENTS D'UN MAILLAGE POUR LES COMPACTER
C             EN DEBUT : DE 1 A "NBNUM"
C     EN ENTREE:
C      IDE    :  (1..3) DIMENSION DES ELEMENTS 
C      ITRNOE:  LES NOEUDS DES ELEMENTS
C      NBNMAX :  (2..8) NOMBRE DE NOEUDS MAXIMUM DES ELEMENTS 
C      ITRTRI:  LES VOISINS DES ELEMENTS
C      NBCMAX :  (2..6) NOMBRE DE COTES MAXIMUM DES ELEMENTS 
C      NBE    :  NOMBRE D'ELEMENTS DU MAILLAGE
C      NOEMAX: SI NOEMAX = 0 ALORS NOETRI N'EST PAS CONSIDERE
C      NUM    :  NUM(I) EST NUMERO DE L'ELEMENT QUI DOIT ETRE MIS EN I
C                ATTENTION !! NUM DOIT ETRE TRIE AVEC ENSTRI
C      NBNUM  :  NOMBRE D'ELEMENTS A RENUMEROTER
C     EN SORTIE:
C       ITRNOE: MIS A JOUR
C       ITRTRI: MIS A JOUR 
C       NOETRI : MIS A JOUR
C     CONDITION D'APPLICATION : TOUT MAILLAGE
C     COMPLEXITE : O(NBNUM) ALORS QUE STRRENUM EST EN O(NBE)
C     PRINCIPE   : LES PERMUTATIONS FONCTIONNENT SI NUM(I)>I
C                  C.A.D. L'ANCIENNE POSITION > A LA NOUVELLE
C                  ON EST DANS CE CAS SI NUM EST TRIE PAR ORDRE CROISS.
C     *****************************************************************
      INTEGER    IDE,ITRNOE(*),NBNMAX,ITRTRI(*),NBCMAX,NOETRI(*),NBE
      INTEGER    NOEMAX,NUM(*),NBNUM,IERR
C
      INTEGER I
C
      DO 10 I=1,NBNUM
        CALL NUPERM(IDE,ITRNOE,NBNMAX,ITRTRI,NBCMAX,NOETRI,
     >                NOEMAX,NBE,NUM(I),I,IERR)
        IF( IERR .NE. 0 )GOTO 999
   10 CONTINUE
  999 END
C     **********************************************************************
C     FICHIER  : ST_MEMOIRE.F
C     OBJET    : NOMBRE MAXIMUM DE POINTS ET D'ELEMENTS (DU MAILLAGE)
C                EN FONCTION DE LA MEMOIRE DISPONIBLE ET DU TRAITEMENT
C
C     FONCT.   :
C     OBJET MEMOMX : NBRE MAXIMUM DE NOEUDS ET D'ELEMENTS EN FCT MEMOIRE
C     OBJET DS4MAX : RENVOI LE NOMBRE MAXIMUM DE POINTS ET D'ELEMENTS
C     OBJET DSGMAX : RENVOI LE NOMBRE MAXIMUM DE POINTS ET D'ELEMENTS
C     OBJET DS1MAX : RENVOI LE NOMBRE MAXIMUM DE POINTS ET D'ELEMENTS
C
C     AUTEUR   : O. STAB
C     DATE     : 10.10.98
C     TESTS    :  
C     MODIFICATIONS :
C        AUTEUR, DATE, OBJET : O.STAB, 28.07.99, EXTRAIT DE DS1, DS4...
C        AUTEUR, DATE, OBJET : O.STAB, 02.02.05, modif DS4MAX ajout de 50 
C                              points pour la triangulation
C        AUTEUR, DATE, OBJET : O.STAB, 26.05.05, modif DSGMAX,DS4MAX 
C                              NBEMAX quand NBTOT=0 !
C
C     A FAIRE : REFLECHIR SUR L'INTERET DE METTRE DANS L'API !
C     **********************************************************************
C
      SUBROUTINE MEMOMX(NITMAX,NRTMAX,NI,NR,TI,TR,NBPMAX,NBEMAX,IERR)
C     **********************************************************************
C     OBJET MEMOMX : NBRE MAXIMUM DE NOEUDS ET D'ELEMENTS EN FCT MEMOIRE
C
C     EN ENTREE   :
C       NITMAX : NOMBRE D'ENTIERS DISPONIBLES
C       NRTMAX : NOMBRE DE REELS DISPONIBLES
C       NI     : NOMBRE D'ENTIERS PAR NOEUD
C       NR     : NOMBRE DE REELS  PAR NOEUD
C       TI     : NOMBRE D'ENTIERS PAR TRIANGLE
C       TR     : NOMBRE DE REELS  PAR TRIANGLES
C
C     EN SORTIE   :
C       NBPMAX : NOMBRE MAXIMUM DE POINTS (OU -1 SI INDEFINI)
C       NBEMAX : NOMBRE MAXIMUM DE TRIANGLES (OU -1 SI INDEFINI)
C       IERR   : 0 => OK, -1 => ERREUR DANS LES DONNEES
C
C     REMARQUE : 2 EQUATIONS 2 INCONNUES :
C                (1) NITMAX = NI * NBPMAX  +  TI * NBEMAX
C                (2) NRTMAX = NR * NBPMAX  +  TR * NBEMAX
C     **********************************************************************
      INTEGER NITMAX,NRTMAX,NI,NR,TI,TR
      INTEGER NBPMAX,NBEMAX,IERR
C
      INTEGER IDENOM
C
      IERR = 0
      NBEMAX = -1
      NBPMAX = -1
C     ---- ON A QU'UNE EQUATION AVEC UNE INCONNUE ----
      IF(( TI.EQ. 0 ).AND.( TR.EQ.0 ))THEN
          IF(( NI.GT. 0 ).AND.( NR.GT.0 ))THEN
             NBPMAX = MIN(NITMAX/NI,NRTMAX/NR)
            ELSE
            IF( NI.GT. 0 )THEN
              NBPMAX = NITMAX/NI
            ELSE
            IF( NR.GT. 0 )THEN
              NBPMAX = NRTMAX/NR
            ENDIF
            ENDIF
            ENDIF
        GOTO 9999
      ENDIF
C     ---- ON A QU'UNE EQUATION AVEC UNE INCONNUE ----
      IF(( NI.EQ. 0 ).AND.( NR.EQ.0 ))THEN
          IF(( TI.GT. 0 ).AND.( TR.GT.0 ))THEN
             NBEMAX = MIN(NITMAX/TI,NRTMAX/TR)
            ELSE
            IF( NI.GT. 0 )THEN
              NBEMAX = NITMAX/TI
            ELSE
            IF( NR.GT. 0 )THEN
              NBEMAX = NRTMAX/TR
            ENDIF
            ENDIF
            ENDIF
        GOTO 9999
      ENDIF
C
      IDENOM  = TR * NI - TI * NR 
      IF( IDENOM.EQ. 0 )THEN
C         ON MAJORE : NBEMAX = 2 * NBPMAX ET ON RESOUD.
          IERR = -1
          CALL DSERRE(1,IERR,'MMTRMX',' LES EQUATIONS SONT LIEES ')
          GOTO 9999
      ENDIF
      NBPMAX  = ( NITMAX * TR - NRTMAX * TI ) / IDENOM
C
      NBEMAX  = ( NRTMAX * NI - NITMAX * NR ) / IDENOM
C
C      PRINT *,'NITMAX,NRTMAX,NI,NR,TI,TR = ',NITMAX,NRTMAX,NI,NR,TI,TR
C      PRINT *,'NBPMAX, NBEMAX = ',NBPMAX,NBEMAX
C     
 9999 END
C

C
      SUBROUTINE DS4MAX(IDIMC,NMT,NBN,NBE,NBPTOT,
     >                  PSTRUC,PITRRG,TSN,ICOEF,IDIMG,
     >                  NITMAX,NRTMAX,
     >                  NBPMAX,NBEMAX,IERR)
C     **********************************************************************
C     OBJET DS4MAX : RENVOI LE NOMBRE MAXIMUM DE POINTS ET D'ELEMENTS
C     **********************************************************************
      INTEGER IDIMC,NMT,NBN,NBE,NBPTOT,NITMAX,NRTMAX
      INTEGER PSTRUC,PITRRG,TSN,ICOEF,IDIMG
      INTEGER NBPMAX,NBEMAX,IERR
C
      INTEGER NI,NR,TI,TR,NITMX2
      INTEGER IMEMAT,NBNMAX,NBCMAX,IDE
C
      NBNMAX = 3
      NBCMAX = 3
      IDE = 2
      IERR = 0
C        =======================
C     --- 1.1. ALLOCATION       ---
C        =======================
C     ETAPE 1 :
C     -------
C     ALLOCATION DU TABLEAU D'ENTIERS
C     POINTEURS : IREFRG | INTMAT | ITRNOE | ITRTRI | NOETRI 
C     TAILLES   : NMT    , NMT    , NBEMAX , NBEMAX , NBPMAX
C
C     ALLOCATION DU TABLEAU DE REELS
C     POINTEURS : ICOORD |
C     TAILLES   : NBPMAX
C
C     ETAPE 2 : CAS MULTI-REGIONS, 1 SEUL ENTIER (HOMOGENE)
C     -------
C     ALLOCATION DU TABLEAU D'ENTIERS
C     POINTEURS : ...NOETRI | ITRIRG | IFR    | IMATFR
C     TAILLES   :           , NBEMAX , 2*NBIFR, 2*NBIFR
C
C     ETAPE 4 : CAS MULTI-REGIONS
C     -------
C     ALLOCATION DU TABLEAU D'ENTIERS
C     POINTEURS : ...IMATFR | ITRIRG
C     TAILLES   :           , NBEMAX 
C
C     ALLOCATION DU TABLEAU DE REELS
C     POINTEURS : ICOORD | ITBDEN
C     TAILLES   :        , NBPMAX
C
C
C            NOETRI + ITBDEN
        NI = 1 + 1
C            ICOORD + ICOORD (RFITER) + TSN
        NR = IDIMC + IDIMC + 1
C       STRUCTURE ET REGIONS
C            ITRNOE + ITRTRI + (ITRIRG + IFR + IMATFR) + ITRIRG 
        IMEMAT =  1 + 2 + 2 
        IF( NMT.EQ.1 )IMEMAT = 0
        TI = NBNMAX + NBCMAX +   IMEMAT        + 1
C            ISPHER + COEF 
        TR = IDE+1 + 1
C
C     ---- NOMBRE DE NOEUDS FIXES PAR LA CAPACITE MEMOIRE ---
C
      IF( NBPTOT.EQ.-1 )THEN
        NITMX2 = NITMAX - 2 * NMT
        CALL  MEMOMX(NITMX2,NRTMAX,NI,NR,TI,TR,NBPMAX,NBEMAX,IERR)
        IF( IERR.NE. 0 )THEN
           CALL DSERRE(1,IERR,'DS4ESF',' APPEL MEMOMX ')
C           PRINT *,'NI,NR,TI,TR = ',NI,NR,TI,TR
           GOTO 9999
        ENDIF
        NBEMAX = MIN(NBEMAX,2*NBPMAX-2)
C       --- POUR CHAQUE NOEUD AJOUTE ON CREE 2 ELEMENTS !
        NBPMAX = MIN((NBEMAX - NBE ) / 2 + NBN, NBPMAX)
C        PRINT *,'NBEMAX, NBPMAX = ',NBEMAX,NBPMAX
      ENDIF
C
C     ---- PAS DE NOUVEAUX NOEUDS ----
C
      IF( NBPTOT.EQ.0 )THEN
        NBPMAX = NBN
C        NBEMAX = NBE <- c'est un maillage lineique !!!!
C       bug corrige 23.05.2005 t=2n-2-a'
        NBEMAX = NBN*2 -5
      ENDIF
C
C     ---- NOMBRE TOTAL DE NOEUDS ATTEINT ----
C       
      IF(( NBPTOT.GT.0 ).AND.( NBPTOT.LT.NBN ))THEN
        IERR = -1
        CALL DSERRE(1,IERR,'DS4ESF','MAXIMUM DEJA ATTEINT')
        GOTO 9999
      ENDIF
C
C     ---- NOMBRE TOTAL DE NOEUDS IMPOSES ----
C       
      IF( NBPTOT.GE.NBN )THEN
C       ajout 01.02.2005 : il faut faire de la place pour les triangles bidons !
        NBPMAX = NBPTOT+50
        NBEMAX = MIN((NITMAX - NI * NBPMAX ) / TI,
     >               (NRTMAX - NR * NBPMAX ) / TR )
        NBEMAX = MIN(NBEMAX,2*NBPMAX-2)
      ENDIF
C
 9999 END
C
      SUBROUTINE DSGMAX(IDIMC,NMT,NBN,NBE,NBPTOT,
     >                  PSTRUC,PITRRG,TSN,ICOEF,IDIMG,
     >                  NITMAX,NRTMAX,
     >                  NBPMAX,NBEMAX,IERR)
C     **********************************************************************
C     OBJET DSGMAX : RENVOI LE NOMBRE MAXIMUM DE POINTS ET D'ELEMENTS
C     EN ENTREE :
C       NBN,NBE,NMT : MAILLAGE LINEIQUE
C     EN SORTIE : NBPMAX, NBEMAX : POUR UN MAILLAGE TRIANGULAIRE
C     **********************************************************************
      INTEGER IDIMC,NMT,NBN,NBE,NBPTOT,NITMAX,NRTMAX
      INTEGER PSTRUC,PITRRG,TSN,ICOEF,IDIMG
      INTEGER NBPMAX,NBEMAX,IERR
C
      INTEGER NI,NR,TI,TR
      INTEGER NITMX2
      INTEGER IPROJ,IEXTR
      INTEGER IMEMAT,NBNMAX,NBCMAX,IDE
C
      NBNMAX = 3
      NBCMAX = 3
      IDE = 2
      IERR = 0
      IPROJ = 0
      IF(IDIMC.EQ.3)IPROJ = 1
      IEXTR = 0
      IF(NMT.GT.1)IEXTR = 1
C     -------- POUR LES ENTIERS --------------------------
C     POUR LE MAILLAGE TRIANGULAIRE :
C     NISIZE = NBNMAX*NBE + NBCMAX*NBE      + NBN    + NBE
C              ITRNOE     | ITRTRI          | NOETRI | ITRIRG
C     AUQUEL S'AJOUTE LES ARETES : 
C            = NBARET*2   + NBARET*2
C              IARET      | IAR2RG
C     NBARET < 3*NBE : MAIS ON PEUT FAIRE L'HYPOTHESE : NBARET = NBE
C
C     -------- POUR LES REELS    --------------------------
C     POUR LE MAILLAGE TRIANGULAIRE :                          (POUR LES CERCLE)
C     NRSIZE = NBN*TSN  + NBN*IDIMC + NBN*IDIMG + NBN*IPROJ + NBN*IEXTR + NBE *3
C
C     ---- ENTIERS PAR NOEUDS : NOETRI + ITBDEN
      NI = 1 + 1
C 
C     --- DANS LE CAS POINTS SEULEMENT ON NE RAFFINE PAS ?? ---
C     ---- REELS PAR NOEUDS :
C          ICOORD + ICOORD (RFITER) + TSN
      NR = 2*IDIMC + IDIMG + TSN + IPROJ + IEXTR
C
C     ---- POUR LES TRIANGLES :
C      TI = NBNMAX + PSTRUC*NBCMAX + PITRRG +  (IARET+IAR2RG)
      TI = NBNMAX + PSTRUC*NBCMAX + PITRRG + 4
C          ISPHER + COEF
      TR = 3 + 1
C
      IF( NBPTOT.EQ.-1 )THEN
        NITMX2 = NITMAX - 2 * NMT
        CALL  MEMOMX(NITMX2,NRTMAX,NI,NR,TI,TR,NBPMAX,NBEMAX,IERR)
        IF( IERR.NE. 0 )THEN
           CALL DSERRE(1,IERR,'DSGMAX',' APPEL MEMOMX ')
C           PRINT *,'NI,NR,TI,TR = ',NI,NR,TI,TR
           GOTO 9999
        ENDIF
        NBEMAX = MIN(NBEMAX,2*NBPMAX-2)
C       --- POUR CHAQUE NOEUD AJOUTE ON CREE 2 ELEMENTS !
        NBPMAX = MIN((NBEMAX - NBE ) / 2 + NBN, NBPMAX)
C        PRINT *,'NBEMAX, NBPMAX = ',NBEMAX,NBPMAX
      ENDIF
C
C     ---- PAS DE NOUVEAUX NOEUDS ----
C
      IF( NBPTOT.EQ.0 )THEN
        NBPMAX = NBN
C        NBEMAX = NBE <- c'est un maillage lineique !!!!
C       bug corrige 23.05.2005 t=2n-2-a'
        NBEMAX = NBN*2 -5
      ENDIF
C
C     ---- NOMBRE TOTAL DE NOEUDS ATTEINT ----
C       
      IF(( NBPTOT.GT.0 ).AND.( NBPTOT.LT.NBN ))THEN
        IERR = -1
        CALL DSERRE(1,IERR,'DSGMAX','MAXIMUM DEJA ATTEINT')
        GOTO 9999
      ENDIF
C
C     ---- NOMBRE TOTAL DE NOEUDS IMPOSES ----
C       
      IF( NBPTOT.GT.NBN )THEN
        NBPMAX = NBPTOT
        NBEMAX = MIN((NITMAX - NI * NBPMAX ) / TI,
     >               (NRTMAX - NR * NBPMAX ) / TR )
        NBEMAX = MIN(NBEMAX,2*NBPMAX-2)
      ENDIF
C
 9999 END
C
C
      SUBROUTINE DS1MAX(IDIMC,NMT,NBN,NBE,NBPTOT,
     >                  PSTRUC,PITRRG,TSN,ICOEF,IDIMG,
     >                  NITMAX,NRTMAX,
     >                  NBPMAX,NBEMAX,IERR)
C     **********************************************************************
C     OBJET DS1MAX : RENVOI LE NOMBRE MAXIMUM DE POINTS ET D'ELEMENTS
C     **********************************************************************
      INTEGER IDIMC,NMT,NBN,NBE,NBPTOT,NITMAX,NRTMAX
      INTEGER PSTRUC,PITRRG,TSN,ICOEF,IDIMG
      INTEGER NBPMAX,NBEMAX,IERR
C
      INTEGER NI,NR,TI,TR
      INTEGER IMEMAT,NBNMAX,NBCMAX,IDE
C
      NBNMAX = 0
      NBCMAX = 0
      IF( NBE.GT.0 )THEN
        NBNMAX = 2
        NBCMAX = 2
      ENDIF
      IDE = 1
      IERR = 0
C
C
C     NISIZE = NBNMAX*NBE + NBCMAX*NBE      + NBN    + NBE
C              ITRNOE     | ITRTRI          | NOETRI | ITRIRG
      NI = PSTRUC
C     --- DANS LE CAS POINTS SEULEMENT ON NE RAFFINE PAS ---
      NR = IDIMC + IDIMG 
      IF(NBE.GT.0)NR = 2*IDIMC + IDIMG + TSN + 1
      TI = NBNMAX + PSTRUC*NBCMAX + PITRRG
      TR = ICOEF
C
      IF( NBPTOT.EQ.-1 )THEN
C       NBPMAX = NBN + (NBEMAX-NBE)
C       NITMX2 = NBPMAX*NI + NBEMAX*TI
C       NRTMX2 = NBPMAX*NR + NBEMAX*TR
        CALL MEMOMX(NITMAX,NRTMAX,NI,NR,TI,TR,NBPMAX,NBEMAX,IERR)
        IF( IERR.NE.0 )THEN
          CALL DSERRE(1,IERR,'DS1MEM','APPEL MEMOMX ')
          GOTO 9999
        ENDIF
C        NBPMAX = NRTMX2 / NR
C        NBEMAX = ( NITMX2 - NBN*NI + NBE*NI ) / (NI + TI)
        IF( NBEMAX.LT.0 )THEN
          IF(NBE.EQ.0)THEN
             NBEMAX = 0
          ELSE
             IERR = -1
             CALL DSERRE(1,IERR,'DS1MEM','NBEMAX INDETERMINE ')
             GOTO 9999
          ENDIF
        ENDIF             
        NBPMAX = MIN( NBPMAX, NBN + (NBEMAX-NBE))
        NBEMAX = MIN( NBEMAX, NBE + (NBPMAX-NBN))
C        PRINT *,'NBPMAX, NBEMAX = ',NBPMAX,NBEMAX
      ENDIF

      IF( NBPTOT.EQ.0 )THEN
        NBPMAX = NBN
        NBEMAX = NBE
      ENDIF

      IF( NBPTOT.GT.NBN )THEN
        NBPMAX = NBPTOT
        NBEMAX = ( NITMAX - NBN*NI + NBE*NI ) / (NI + TI)
        NBEMAX = MIN(NBEMAX,  NBE + (NBPMAX-NBN))
      ENDIF

C     NISIZE = NBNMAX*NBE + NBCMAX*NBE      + NBN    + NBE
C              ITRNOE     | ITRTRI          | NOETRI | ITRIRG
C      NBCMAX = NBNMAX
C      NISIZE = NBNMAX     + NBCMAX*PSTRUC  + PSTRUC + PITRRG
C     DANS R1ITER ON COPIE LES COORDONNEES : 2 * IDIMC + COEF
C     DANS R1DIR  ON CALCULE TOUS LES POINTS SUR UN SEGMENT.
C     SI TAILLE SOUHAITE AUX NOEUDS : IRADEC + NBPMAX
C     D'OU :
C      NBPMAX = (NRTMAX - IRTRAV)/ (2*IDIMC+IDIMG+1+1)
C     NBPNEW EST UNE BORNE SUPERIEURE QUAND ELLE EST DONNEE
C      IF( NBPNEW.GE. 0 )NBPMAX = MIN( NBPNEW+NBN ,NBPMAX )
C      NBPMAX = MIN( ((NITMAX - ITRAV) / NISIZE), NBPMAX)
 9999 END
C
C     *****************************************************************
C     MODULE  : ST (STRUCTURE DES DONNEES)
C     FICHIER : ST_NOEUD.F
C     OBJET   : RENUMEROTE LES NOEUDS D'UN MAILLAGE 2D OU 3D
C     FONCT.  : 
C
C     OBJET NUNONU : RENUMEROTE LES NOEUDS D'UN MAILLAGE
C     OBJET NUNOCP : COMPRIME LES NUMEROS DES NOEUDS D'UN MAILLAGE
C     OBJET          EN DEBUT : DE 1 A "NBNUM"
C     OBJET NUNISO : RENUMEROTATION, LES NOEUDS ISOLES SONT MIS EN FIN 
C     OBJET NUENUL : RENUMEROTATION, LES ELEMENTS NULS SONT MIS EN FIN 
C     OBJET NUGCNU : GARBAGE COLLECTOR ELEMENTS ET POINTS
C
C     AUTEUR  : O. STAB 
C     DATE    : 08.96
C     TESTS   :  
C     MODIFICATIONS :
C      AUTEUR, DATE, OBJET :
C
C
C     *****************************************************************
C
C
      SUBROUTINE NUNONU(ITRNOE,NBNMAX,NOETRI,NOEMAX,NBE,
     >                  COORD,IDIMC,
     >                  NUM,NBNUM,ITRAMA,IERR)
C     *****************************************************************
C     OBJET NUNONU : RENUMEROTE LES NOEUDS D'UN MAILLAGE
C
C     EN ENTREE:
C      ITRNOE,NBNMAX,NBE,NOETRI,NOEMAX :  LE MAILLAGE
C      NBNMAX: SI NBNMAX = 0 ALORS ITRNOE N'EST PAS CONSIDERE
C      NOEMAX: SI NOEMAX = 0 ALORS NOETRI N'EST PAS CONSIDERE
C      
C
C      COORD,IDIMC : COORDONNEES DES NOEUDS
C      IDIMC : SI IDIMC = 0 ALORS COORD N'EST PAS CONSIDERE
C
C      NUM    :  NUM(I) EST NUMERO DE L'ELEMENT QUI DOIT ETRE MIS EN I
C                ATTENTION !! NUM DOIT ETRE TRIE AVEC ENSTRI
C      NBNUM  :  NOMBRE DE NOEUDS A RENUMEROTER
C      ITRAMA :  TABLEAU DE TRAVAIL DE TAILLE = MAX(NUM(I))
C
C     EN SORTIE:
C       ITRNOE : MIS A JOUR
C       NOETRI : MIS A JOUR
C       COORD  : MIS A JOUR
C
C     CONDITION D'APPLICATION : TOUT MAILLAGE
C     REMARQUE : COPIE DE IORDRE DE S.M. TIJANI
C     *****************************************************************
      INTEGER    ITRNOE(*),NBNMAX,NOETRI(*),NBE
      REAL       COORD(*)
      INTEGER    IDIMC
      INTEGER    NOEMAX, NUM(*), NBNUM, ITRAMA(*), IERR
C
C     ---- COPIE DE IORDRE (S.M.TIJANI )----
C
      INTEGER I,J,LI,MI
      INTEGER NUMOLD,ITAMPO
      REAL    RTAMPO
C
C     ON N'A RIEN A FAIRE
C
      IERR = 0
C     ----- modif o.stab : 03/04/2003  COMMENT CE BUG est-il reste la ??!!
C           APPEL ds NUGCNU qui est appele : dans blocos.f, hexos.f et sm_smooth
C     ----- modif o.stab : 03/04/2003  NUM est remplace par ITRAMA !!!
C      IF(NBNUM.LE.1) GOTO 9999
C
C      DO 20 I=1,NBE
C           -----------------------------------
C       --- MISE A JOUR DES NOEUDS DES ELEMENTS ---
C           -----------------------------------
C        DO 10 J=1,NBNMAX
C          NUMOLD = ITRNOE((I-1)*NBNMAX + J)
C          IF((NUMOLD.GT.0 ).AND.(NUMOLD.LE.NBNUM))THEN
C            ITRNOE((I-1)*NBNMAX + J) = NUM(NUMOLD)
C          ENDIF  
C   10   CONTINUE
C   20 CONTINUE
C
C     PERMUTATION M INVERSE DE L :
C
      DO 30 I=1,NBNUM
        ITRAMA(NUM(I))=I
   30 CONTINUE
C
      DO 20 I=1,NBE
C           -----------------------------------
C       --- MISE A JOUR DES NOEUDS DES ELEMENTS ---
C           -----------------------------------
        DO 10 J=1,NBNMAX
          NUMOLD = ITRNOE((I-1)*NBNMAX + J)
          IF((NUMOLD.GT.0 ).AND.(NUMOLD.LE.NBNUM))THEN
            ITRNOE((I-1)*NBNMAX + J) = ITRAMA(NUMOLD)
          ENDIF  
   10   CONTINUE
   20 CONTINUE
C     IMPOSER A NARG L'ORDRE DEFINI PAR L.
C     LES TABLEAUX L ET M SONT CASSES.
C
      DO 50 I=1,NBNUM
        LI=NUM(I)
        MI=ITRAMA(I)
C           ----------------------
C       --- PERMUTATION DES NOEUDS ---
C           ----------------------
          IF( NOEMAX.NE.0)THEN
            ITAMPO         = NOETRI(I)
            NOETRI(I)      = NOETRI(LI)
            NOETRI(LI) = ITAMPO
          ENDIF
          DO 40 J=1,IDIMC
            RTAMPO                = COORD((I-1)*IDIMC+J)
            COORD((I-1)*IDIMC+J)  = COORD((LI-1)*IDIMC+J)
            COORD((LI-1)*IDIMC+J) = RTAMPO
   40     CONTINUE
C
C       LE NOUVEAU NUMERO DE LI EST I
C       LE NOUVEAU NUMERO DE MI A CHANGE, C'EST DEVENU LI
C
        NUM(MI)=LI
        ITRAMA(LI)=MI
   50 CONTINUE
C
C     RESTAURATION DES TABLEAUX L (INITIAL) ET M (SON INVERSE).
C
      DO 60 I=1,NBE
        LI=NUM(I)
        MI=ITRAMA(I)
        NUM(MI)=I
        ITRAMA(LI)=I
   60 CONTINUE
 9999 END
C
C
      SUBROUTINE NUNOCP(ITRNOE,NBNMAX,NOETRI,NOEMAX,NBE,
     >                  COORD,IDIMC,
     >                  NUM,NBNUM,IERR)
C     *****************************************************************
C     OBJET NUNOCP : COMPRIME LES NUMEROS DES NOEUDS D'UN MAILLAGE
C     OBJET          EN DEBUT : DE 1 A "NBNUM"
C
C     EN ENTREE:
C      ITRNOE,NBNMAX,NBE,NOETRI,NOEMAX :  LE MAILLAGE
C      NBNMAX: SI NBNMAX = 0 ALORS ITRNOE N'EST PAS CONSIDERE
C      NOEMAX: SI NOEMAX = 0 ALORS NOETRI N'EST PAS CONSIDERE
C      
C
C      COORD,IDIMC : COORDONNEES DES NOEUDS
C      IDIMC : SI IDIMC = 0 ALORS COORD N'EST PAS CONSIDERE
C
C      NUM    :  NUM(I) EST NUMERO DE L'ELEMENT QUI DOIT ETRE MIS EN I
C                ATTENTION !! NUM DOIT ETRE TRIE AVEC ENSTRI
C      NBNUM  :  NOMBRE DE NOEUDS A RENUMEROTER
C
C     EN SORTIE:
C       ITRNOE : MIS A JOUR
C       NOETRI : MIS A JOUR
C       COORD  : MIS A JOUR
C
C     CONDITION D'APPLICATION : TOUT MAILLAGE
C     COMPLEXITE : O(NBNUM) + O(NBE)
C     PRINCIPE   : LES PERMUTATIONS FONCTIONNENT SI NUM(I)>I
C                  C.A.D. L'ANCIENNE POSITION > A LA NOUVELLE
C                  ON EST DANS CE CAS SI NUM EST TRIE PAR ORDRE CROISS.
C     *****************************************************************
      INTEGER    ITRNOE(*),NBNMAX,NOETRI(*),NOEMAX,NBE
      REAL       COORD(*)
      INTEGER    IDIMC
      INTEGER    NUM(*),NBNUM,IERR
C
      INTEGER I,J,ITAMPO,NUMOLD
      REAL    RTAMPO
C
      DO 20 I=1,NBE
C           -----------------------------------
C       --- MISE A JOUR DES NOEUDS DES ELEMENTS ---
C           -----------------------------------
        DO 10 J=1,NBNMAX
          NUMOLD = ITRNOE((I-1)*NBNMAX + J)
          IF((NUMOLD.GT.0).AND.(NUMOLD.LE.NBNUM))THEN
            ITRNOE((I-1)*NBNMAX + J) = NUM(NUMOLD)
          ENDIF  
   10   CONTINUE
   20 CONTINUE
C           ----------------------
C       --- MISE A JOUR DES NOEUDS ---
C           ----------------------
        DO 40 I=1,NBNUM
          IF( NOEMAX.NE.0)THEN
            ITAMPO         = NOETRI(I)
            NOETRI(I)      = NOETRI(NUM(I))
            NOETRI(NUM(I)) = ITAMPO
          ENDIF
          DO 30 J=1,IDIMC
            RTAMPO = COORD((I-1)*IDIMC+J)
            COORD((I-1)*IDIMC+J) = COORD((NUM(I)-1)*IDIMC+J)
            COORD((NUM(I)-1)*IDIMC+J) = RTAMPO
   30     CONTINUE
   40   CONTINUE   
C
        IERR = 0
C
 9999 END
C
      SUBROUTINE NUNISO(NOETRI,NBN,NUM,NBISOL,IERR)
C     *****************************************************************
C     OBJET NUNISO : PROPOSE UNE RENUMEROTATION POUR METTRE EN FIN LES
C     OBJET          NOEUDS ISOLES.
C              
C     EN ENTREE:
C      NOETRI: TABLEAU DES ELEMENTS INCIDENTS AUX NOEUDS
C      NBN   : NOMBRE DE NOEUDS
C
C     EN SORTIE:
C       NBISOL : NOMBRE DE NOEUDS ISOLES
C       NUM    : NOUVELLE NUMEROTATION 
C                NUM(I) =  NOUVEAU NUMERO DU NOEUD I
C                NUM EST UN TABLEAU DE TAILLE NBN
C
C     CONDITION D'APPLICATION : TOUT MAILLAGE
C     *****************************************************************
      INTEGER    NOETRI(*),NBN
      INTEGER    NUM(*),NBISOL,IERR
C
      INTEGER I
C
      NBISOL = 0
      I = 1 
   10 IF(I.GT.(NBN-NBISOL))GOTO 9999
C     --- LE NOEUD EST ISOLE ---
      IF( NOETRI(I).EQ.0 )THEN
C
C       --- RECHERCHE D'UN NOEUD (A LA FIN) POUR PERMUTER ---
   20   IF( NOETRI(NBN-NBISOL).EQ. 0 )THEN
           NUM(NBN-NBISOL) = NBN-NBISOL
           NBISOL = NBISOL + 1
C          --- TOUS LES NOEUDS SONT ISOLES ---
           IF( NBISOL.EQ.NBN )GOTO 9999
C          --- ON A TROUVE TOUS LES NOEUDS ISOLES ---
           IF( I.GT.(NBN-NBISOL))GOTO 9999
           GOTO 20  
        ENDIF
C
C       --- ON A LE NOEUD POUR PERMUTER ---
        NUM(NBN-NBISOL) = I
        NUM(I) = NBN-NBISOL
        NBISOL = NBISOL + 1
      ELSE
        NUM(I) = I
      ENDIF
      I = I + 1
      GOTO 10
C      
 9999 END
C      
C
      SUBROUTINE NUENUL(ITRNOE,NBNMAX,NBE,NUM,NBENUL,IERR)
C     *****************************************************************
C     OBJET NUENUL : PROPOSE UNE RENUMEROTATION POUR METTRE EN FIN LES 
C     OBJET          ELEMENTS NULS.
C              
C     EN ENTREE:
C      ITRNOE: LES NOEUDS DES ELEMENTS DU MAILLAGE
C      NBNMAX: NOMBRE MAXIMUM DE NOEUDS PAR ELEMENT
C      NBE   : NOMBRE D'ELEMENTS
C
C     EN SORTIE:
C       NBENUL : NOMBRE D'ELEMENTS NULS
C       NUM    : NOUVELLE NUMEROTATION 
C                NUM(I) =  NOUVEAU NUMERO DE L'ELEMENT I
C                NUM EST UN TABLEAU DE TAILLE NBE
C
C
C     CONDITION D'APPLICATION : TOUT MAILLAGE
C     REMARQUE : IDEM NUNISO => UTILITAIRE SUR LES TABLEAUX ?
C     *****************************************************************
      INTEGER    ITRNOE(*),NBNMAX,NBE
      INTEGER    NUM(*),NBENUL,IERR
C
      INTEGER I
C
      NBENUL = 0
      I = 1 
   10 IF(I.GT.(NBE-NBENUL))GOTO 9999
C     --- LE NOEUD EST ISOLE ---
      IF( ITRNOE((I-1)*NBNMAX+1).EQ.0 )THEN
C
C       --- RECHERCHE D'UN NOEUD (A LA FIN) POUR PERMUTER ---
   20   IF( ITRNOE((NBE-NBENUL-1)*NBNMAX+1).EQ. 0 )THEN
           NUM(NBE-NBENUL) = NBE-NBENUL
           NBENUL = NBENUL + 1
C          --- TOUS LES NOEUDS SONT ISOLES ---
           IF( NBENUL.EQ.NBE )GOTO 9999
C          --- ON A TROUVE TOUS LES NOEUDS ISOLES ---
           IF( I.GT.(NBE-NBENUL))GOTO 9999
           GOTO 20  
        ENDIF
C
C       --- ON A LE NOEUD POUR PERMUTER ---
        NUM(NBE-NBENUL) = I
        NUM(I) = NBE-NBENUL
        NBENUL = NBENUL + 1
      ELSE
        NUM(I) = I
      ENDIF
      I = I + 1
      GOTO 10
C      
 9999 END
C      
C
      SUBROUTINE NUGCNU(IDE,ITRNOE,NBNMAX,ITRTRI,NBCMAX,
     >                  NOETRI,NOEMAX,NBE,COORD,IDIMC,NBP,
     >                  ITVL,NITMAX,IERR)
C     *****************************************************************
C     OBJET NUGCNU : GARBAGE COLLECTOR ELEMENTS ET POINTS
C     OBJET          SUPPRIME LES ELEMENTS NULS ET LES POINTS ISOLES
C     OBJET          LES POINTS ET LES ELEMENTS SONT RENUMEROTES !!!
C              
C     EN ENTREE:
C      ITRNOE,NBNMAX,ITRITRI,NBCMAX,NOETRI,NOEMAX,NBE :  LE MAILLAGE
C      NBNMAX: SI NBNMAX = 0 ALORS ITRNOE N'EST PAS CONSIDERE
C      NOEMAX: SI NOEMAX = 0 ALORS NOETRI N'EST PAS CONSIDERE
C      COORD,NBP : COORDONNEES ET NOMBRE DE NOEUDS
C      IDIMC : DIMENSION DE L'ESPACE, SI IDIMC = 0 ALORS ON NE COMPRIME
C              PAS LES NOEUDS.
C         
C      ITVL(NITMAX) : TABLEAU DE TRAVAIL (ENTIERS), SA TAILLE EST DE
C                      2*NBP POUR LA RENUMEROTATION DES NOEUDS
C                    + 2*NBE POUR LA RENUMEROTATION DES ELEMENTS
C                    + NBP SI NOETRI N4EST PAS DONNE (NOEMAX=0)                     
C
C     EN SORTIE:
C       ITRNOE,NBE,ITRTRI,NOETRI,COORD,NBN : MIS A JOUR
C
C     CONDITION D'APPLICATION : TOUT MAILLAGE
C     *****************************************************************
      INTEGER    IDE,ITRNOE(*),NBNMAX,ITRTRI(*),NBCMAX 
      INTEGER    NOETRI(*),NOEMAX,NBE
      REAL       COORD(*)
      INTEGER    IDIMC,NBP,ITVL(*),NITMAX,IERR
C
      INTEGER I,J,NUM,ITRAMA,NUM1,NBISOL,NBENUL
      INTEGER NOETR2 
C
      NUM = 1
      NBISOL = 0
      NBENUL = 0
      IF(IDIMC.EQ.0)GOTO 40
C        ============================
C     --- 1. COMPRESSION DES NOEUDS  ---
C        ============================
      IF( NOEMAX.EQ. 0 )THEN  
        NOETR2 = 0      
        NUM    = NBP + NOETR2
      ENDIF
      ITRAMA = NUM + NBP
      IF( NITMAX .LT. ITRAMA+NBP )THEN
         IERR = -2
         CALL DSERRE(1,IERR,'NUCGNU',' POUR COMPRIMER LES NOEUDS')          
         CALL ESEINT(1,'PLACE NECESSAIRE  : ',ITRAMA+NBP,1)
         CALL ESEINT(1,'PLACE DISPONIBLE  : ',NITMAX,1)
         GOTO 9999        
      ENDIF
C
C     ---- RECHERCHE DES NOEUDS CONNECTES ----
C         --------------------------------
      IF( NOEMAX.EQ. 0 )THEN
        DO 105 I=1,NBP
          ITVL(NOETR2+I) = 0
  105   CONTINUE
        DO 120 I=1,NBE
          DO 110 J=1,NBNMAX
            NUM1 = ITRNOE((I-1)*NBNMAX+J)
            IF( NUM1.NE.0 )ITVL(NOETR2+NUM1) = I
  110     CONTINUE    
  120   CONTINUE 
C
        CALL NUNISO(ITVL(NOETR2+1),NBP,ITVL(NUM+1),NBISOL,IERR)
      ELSE
C
        CALL NUNISO(NOETRI,NBP,ITVL(NUM+1),NBISOL,IERR)
      ENDIF
C
      IF( IERR.NE. 0 )THEN
         CALL DSERRE(1,IERR,'NUCGNU',' APPEL NUNISO ')          
         GOTO 9999        
      ENDIF
C
C     ---- SUPPRESSION DES NOEUDS PAS CONNECTES ----
C         --------------------------------------
      CALL NUNONU(ITRNOE,NBNMAX,NOETRI,NOEMAX,NBE,
     >            COORD,IDIMC,
     >            ITVL(NUM+1),NBP,ITVL(ITRAMA+1),IERR)
      IF( IERR.NE. 0 )THEN
         CALL DSERRE(1,IERR,'NUCGNU',' APPEL NUNONU ')          
         GOTO 9999        
      ENDIF
      NBP = NBP - NBISOL
C
C        ==============================
C     --- 2. COMPRESSION DES ELEMENTS  ---
C        ==============================
C
   40 IF( IDE.EQ. 0 )GOTO 9999
      CALL NUENUL(ITRNOE,NBNMAX,NBE,ITVL(NUM+1),NBENUL,IERR)
      IF( IERR.NE. 0 )THEN
         CALL DSERRE(1,IERR,'NUCGNU',' APPEL NUENUL ')          
         GOTO 9999        
      ENDIF
C
      ITRAMA = NUM + NBE
      CALL NURENU(IDE,ITRNOE,NBNMAX,ITRTRI,NBCMAX,NOETRI, 
     >            NOEMAX,NBE,ITVL(NUM+1),ITVL(ITRAMA+1),IERR)
C
      IF( IERR.NE. 0 )THEN
         CALL DSERRE(1,IERR,'NUCGNU',' APPEL NURENU ')          
         GOTO 9999        
      ENDIF
C
      NBE = NBE - NBENUL
C
C
 9999 END
C
      
                  
            
C     *****************************************************************
C     MODULE  : ST (STRUCTURE DES DONNEES)
C     FICHIER : ST_0DSTRUCT.F
C     OBJET   : AJOUT DE POINTS DANS UN MAILLAGE
C     FONCT.  : 
C               S0AJNO  : AJOUTE UN POINT ISOLE OU LIBRE
C               S0DTNO  : SUPPRIME LE POINT ISOLE OU LIBRE 
C
C     AUTEUR  : O. STAB  
C     DATE    : 03.95
C     TESTS   : A FAIRE
C     MODIFICATIONS :
C      AUTEUR, DATE, OBJET :
C
C
C     *****************************************************************
C
C
      SUBROUTINE S0AJNO(XYZ,COORD,IDIMC,NBN,NBNMAX,
     >                     NOETRI,NOEMAX,NNEW,IERR)
C     *****************************************************************
C     OBJET : AJOUTE UN POINT ISOLE OU LIBRE
C     EN ENTREE :
C        XYZ   : TABLEAU DES COORDONNEES DU POINT
C        COORD : TABLEAU DES COORDONNEES DE TOUS LES POINTS
C        IDIMC : DIMENSION DE L'ESPACE
C        NBN   : NOMBRE DE NOEUDS DEJA EXISTANT
C        NBNMAX: NOMBRE MAXIMUM DE NOEUD DANS COORD
C        NOEMAX : SI = 0 NOETRI N'EST PAS MIS A JOUR
C                   SINON NOEMAX = TAILLE DE NOETRI
C     EN SORTIE : 
C        COORD, NOETRI ET NBN MODIFIES
C        NNEW  : NUMERO DU NOEUD AJOUTE
C        IERR  : CODE D'ERREUR 0 SI OK, -2 SI COORD EST TROP PETIT
C     *****************************************************************
      REAL XYZ(*),COORD(*)
      INTEGER IDIMC,NBN,NBNMAX,IERR
      INTEGER NOETRI(*),NOEMAX,NNEW
C
      INTEGER J
C
      IF( NBN.GE.NBNMAX )THEN
        IERR = -2
        CALL DSERRE(1,IERR,'ST','DANS S0AJNO : TROP DE POINTS')
        GOTO 999
      ENDIF
      NBN = NBN + 1
      DO 10 J=1,IDIMC    
        COORD((NBN-1)*IDIMC+J) = XYZ(J)
   10 CONTINUE
      NNEW = NBN
      IF( NOEMAX.GT. 0 )THEN
        IF( NOEMAX.LT.NNEW )THEN
          IERR =-2
          CALL DSERRE(1,IERR,'ST','DANS S0AJNO : NOETRI TROP PETIT')
          GOTO 999
        ENDIF
        NOETRI(NNEW) = 0
      ENDIF
      IERR = 0
  999 END
C      
      SUBROUTINE S0DTNO(IPADET,COORD,IDIMC,NBN,NBNMAX,
     >                     NOETRI,NOEMAX,IERR)
C     *****************************************************************
C     OBJET : SUPPRIME LE POINT ISOLE OU LIBRE 
C     EN ENTREE :
C        IPADET : LE POINT A SUPPRIMER
C        COORD : TABLEAU DES COORDONNEES DE TOUS LES POINTS
C        IDIMC : DIMENSION DE L'ESPACE
C        NBN   : NOMBRE DE NOEUDS DEJA EXISTANT
C        NBNMAX: NOMBRE MAXIMUM DE NOEUD DANS COORD (POURRA SERVIR)
C        NOEMAX : SI = 0 NOETRI N'EST PAS MIS A JOUR
C                   SINON NOEMAX = TAILLE DE NOETRI
C     EN SORTIE : 
C        COORD, NOETRI ET NBN MODIFIES
C        IERR  : CODE D'ERREUR 0 SI OK, -1 SI C'EST IMPOSSIBLE
C     *****************************************************************
      REAL    COORD(*)
      INTEGER IPADET,IDIMC,NBN,NBNMAX,IERR
      INTEGER NOETRI(*),NOEMAX
C
      INTEGER J
C     --- ON NE PEUT SUPPRIMER QUE LE DERNIER POINT 
C         IL DOIT ETRE ISOLE ---
      IF((IPADET.NE.NBN ).OR.
     >   ((NOEMAX.NE.0).AND.(NOETRI(IPADET).NE.0)))THEN
        IERR = -1
        CALL DSERRE(1,IERR,'ST',
     >              'DANS S0DTNO : POINT ENCORE CONNECTE')
        GOTO 999
      ENDIF
C
      DO 10 J=1,IDIMC    
        COORD((NBN-1)*IDIMC+J) = 0.0
   10 CONTINUE
      NBN = NBN - 1
      IERR = 0
  999 END
C      
C     *****************************************************************
C     MODULE  : ST (STRUCTURE DES DONNEES)
C     FICHIER : ST_1DSTRUCT.F
C     OBJET   : CONSTRUCTION D'UN MAILLAGE LINEIQUE
C     FONCT.  : 
C         S1AJNO : DECOUPE UNE ARETE PAR UN SOMMET
C         S1CRAR  : AJOUTE UNE ARETE ENTRE 2 SOMMETS EXISTANTS
C         S1LNFM   : RENVOI 1 SI LE CONTOUR ACCESSIBLE EST FERME
C                       0 SINON
C
C     AUTEUR  : O. STAB  
C     DATE    : 03.95
C     TESTS   : A FAIRE
C     MODIFICATIONS :
C      AUTEUR, DATE, OBJET : O.STAB, 05.98, S1AJNO (CAS NBCMAX = 0)
C
C
C     *****************************************************************
C
      FUNCTION SFAC1D( IT1, IT2, N1, N2, IDE, I1, I2 )
C     *****************************************************************
C     OBJET SFAC1D : RECHERCHE LA FACE COMMUME A 2 ELEMENTS
C     *****************************************************************
      INTEGER SFAC1D
      INTEGER IT1(N1), IT2(N2), N1,N2, IDE, I1, I2
C
      INTEGER I,J
C     ------------------------
C     CAS DES ARETES : ON REALISE 4 COMPARAISONS (N1=N2=2)
C     ------------------------
      DO 30 I=1,N1 
        DO 40 J=1,N2
          IF (IT1(I) .EQ. IT2(J)) THEN
              I1 = I
              I2 = J
              IF( I.EQ.J )THEN
                   SFAC1D = -1
                ELSE 
                   SFAC1D = 1
              ENDIF
              GOTO 9999
          ENDIF
   40   CONTINUE
   30 CONTINUE
 9999 END
C
      SUBROUTINE S1INVE(N, IDE, ITRNOE, ITRTRI )
C     ************************************************************
C     OBJET S1INVE : INVERSE L'ORIENTATION D'UN ELEMENT A N NOEUDS
C     ************************************************************
      INTEGER   N, IDE, ITRNOE(N), ITRTRI(N)
C     
      INTEGER   ITRNO1, ITRTR1
C
   10 ITRNO1    = ITRNOE(1)
      ITRNOE(1) = ITRNOE(2)
      ITRNOE(2) = ITRNO1
      ITRTR1    = ITRTRI(1)
      ITRTRI(1) = ITRTRI(2)
      ITRTRI(2) = ITRTR1 
 9999 END
C
      FUNCTION S1NBCO(N,IDE)
C     ****************************************************************
C     OBJET  S1NBCO : NOMBRE DE FACES D'UN ELEMENT DE N NOEUDS
C     ************************************************************
      INTEGER S1NBCO
      INTEGER N,IDE
C
      S1NBCO = N
 9999 END
C
      FUNCTION S1SOFA(IDE,I,N,IFAC)
C     ************************************************************
C     OBJET S1SOFA : INDICES DES FACES INCIDENTES AU SOMMET I 
C     ************************************************************
      INTEGER  S1SOFA
      INTEGER  IDE,I,N,IFAC(*)
C
      IFAC(1) = I
      S1SOFA  = 1
 9999 END
C
      FUNCTION S1OPFA(IDE,N,IFE)
C     ************************************************************
C     OBJET S1OPFA : INDICE DE L'ENTITE OPPOSEE A FACE IFE
C     EN SORTIE: 
C         POUR LES TRIANGLES   : LE SOMMET OPPOSE A L'ARETE
C         POUR LES QUADRANGLES : L'ARETE OPPOSEE A L'ARETE
C     ************************************************************
      INTEGER S1OPFA
      INTEGER IDE,N,IFE
C   
      S1OPFA = MOD(IFE,N)+1  
 9999 END
C
      FUNCTION S1FASO(IDE,N,I,ISOM)
C     ************************************************************
C     OBJET S1FASO : INDICES DES SOMMETS DE LA FACE I (SENS DIRECT)
C     ************************************************************
      INTEGER S1FASO
      INTEGER IDE,N,I,ISOM(*)
C
      ISOM(1) = MOD(I+1-2,N)+1
      S1FASO  = 1
 9999 END
C     
C
      SUBROUTINE S1AJNO(IE,IS,NBE,ITRNOE,NBNMAX,ITRTRI,NBCMAX,
     >                   NOETRI,NOEMAX,IENEW,IERR)
C     *****************************************************************
C     OBJET : DECOUPE UNE ARETE PAR UN SOMMET
C            |IA|-- IE -->|IB|
C            |IA|-- IE -->|IS|-- IENEW -->|IB|
C
C     EN ENTREE:
C      IE     : NUMERO DE L'ARETE A DECOUPER
C      IS     : NUMERO DU SOMMET
C      NBE,ITRNOE,NBNMAX,ITRTRI,NBCMAX,NOETRI,NOEMAX : LE MAILLAGE
C      NBCMAX : SI <= 0 ITRTRI N'EST PAS MIS A JOUR
C      NOEMAX : SI <= 0 NOETRI N'EST PAS MIS A JOUR
C
C     EN SORTIE :
C      ITRNOE,NBE : LE MAILLAGE MODIFIE
C      ITRTRI     : SI NBCMAX > 0
C      NOETRI     : SI NOEMAX > 0
C      IENEW  : LE NUMERO DE L'ARETE CREE
C      IERR   :  0 SI OK
C               -1 SI LES DONNEES SONT ERRONEES
C               -2 SI NOETRI EST TROP PETIT
C
C     REMARQUE  : C'EST LE SEMV (SPLIT EDGE MAKE VERTEX)
C     *****************************************************************
      INTEGER   IE,IS,NBE
      INTEGER   ITRNOE(*),NBNMAX,ITRTRI(*),NBCMAX
      INTEGER   NOETRI(*), NOEMAX,IENEW,IERR
C
      INTEGER   ISEXTR, IESUIV
C
      IENEW = 0
      IF((IE.LE.0).OR.(IS.LE.0))THEN
        IERR = -1
        CALL DSERRE(1,IERR,'ST','DANS S1AJNO : NUMERO INCORRECT')
        GOTO 9999
      ENDIF
      ISEXTR = ITRNOE((IE-1)*NBNMAX+2)
C      IESUIV = ITRTRI((IE-1)*NBCMAX+2)
      IF(ISEXTR.LE.0)THEN
        IERR = -1
        CALL DSERRE(1,IERR,'ST',
     >              'DANS S1AJNO : PAS D ARETE A DECOUPER')
        GOTO 9999
      ENDIF
C
C     --- CREATION DU NOUVEL ELEMENT ----------------
C
      IENEW = NBE + 1
      ITRNOE((IENEW-1)*NBNMAX+1) = IS
      ITRNOE((IENEW-1)*NBNMAX+2) = ISEXTR
C      ITRTRI((IENEW-1)*NBCMAX+1) = IE
C      ITRTRI((IENEW-1)*NBCMAX+2) = IESUIV
      IF( NOEMAX.GT.0 )THEN
        IF( NOEMAX.LT.IS)THEN
          CALL DSERRE(1,IERR,'ST','DANS S1AJNO : NOEMAX TROP PETIT')
          IERR = -2
          GOTO 9999
        ENDIF
        NOETRI(IS) = IENEW
        NOETRI(ISEXTR) = IENEW
      ENDIF      
C
C     --- MISE A JOUR DE IE ET DE IESUIV ------------ 
C
      ITRNOE((IE-1)*NBNMAX+2) = IS
C      ITRTRI((IE-1)*NBCMAX+2) = IENEW
C      IF( IESUIV .GT. 0 )ITRTRI((IESUIV-1)*NBCMAX+1) = IENEW
C      NBE = NBE+1
C
C     --- MISE A JOUR DE ITRTRI ------------ 
C     IENEW EST CREE ENTRE IE ET IESUIV : IE, IENEW,IESUIV
      IF( NBCMAX.GT.0 )THEN
        IESUIV = ITRTRI((IE-1)*NBCMAX+2)
        ITRTRI((IENEW-1)*NBCMAX+1) = IE
        ITRTRI((IENEW-1)*NBCMAX+2) = IESUIV
        ITRTRI((IE-1)*NBCMAX+2) = IENEW
        IF( IESUIV .GT. 0 )ITRTRI((IESUIV-1)*NBCMAX+1) = IENEW
        IF( IESUIV .LT. 0 )ITRTRI((-IESUIV-1)*NBCMAX+1) = -IENEW
      ENDIF
      NBE = NBE + 1
C
 9999 END
C
C
      SUBROUTINE S1CRAR(ISO,ISE,NBE,ITRNOE,NBNMAX,ITRTRI,NBCMAX,
     >                   NOETRI,NOEMAX,IENEW,IERR)
C     *****************************************************************
C     OBJET : AJOUTE UNE ARETE ENTRE 2 SOMMETS EXISTANTS
C            |ISO|            |ISE|
C            |ISO|-- IENEW -->|ISE|
C     EN ENTREE:
C      ISO     : NUMERO DU SOMMET ORIGINE
C      ISE     : NUMERO DU SOMMET EXTREMITE
C      NBE,ITRNOE,NBNMAX,ITRTRI,NBCMAX,NOETRI,NOEMAX :LE MAILLAGE
C     EN SORTIE : LE MAILLAGE MODIFIE
C      IENEW    : LE NUMERO DE L'ARETE CREE
C      IERR     :  0 SI OK
C               -1 SI LES DONNEES SONT ERRONEES
C               -2 SI NOETRI EST TROP PETIT
C               -3 SI HORS DES CONDITIONS D'APPLICATION
C     CONDITION D'APPLICATION  : C'EST LE MEV (MAKE EDGE AND VERTEX)
C                ISO NE DOIT AVOIR AUCUNE ARETE QUI EN PART
C                ISE NE DOIT AVOIR AUCUNE ARETE QUI Y ARRIVE
C     *****************************************************************
      INTEGER   ISO,ISE,NBE
      INTEGER   ITRNOE(*),NBNMAX,ITRTRI(*),NBCMAX
      INTEGER   NOETRI(*), NOEMAX,IENEW,IERR
C
      INTEGER   IEO,IES
C
      IERR = -1
      IENEW = 0
      IF((ISO.LE.0).OR.(ISE.LE.0))GOTO 999
C
C     ---- ON VERIFIE LE SOMMET ORIGINE ----------------
C
      IF((ISO.GT.NOEMAX).OR.(ISE.GT.NOEMAX ))GOTO 999
      IEO = NOETRI(ISO)
      IF( ( IEO.NE.0 ).AND. 
     >    ( (ITRTRI((IEO-1)*NBCMAX+2).NE.0).OR.
     >      (ITRNOE((IEO-1)*NBNMAX+2).NE.ISO) ) )THEN
        IERR = -3
        GOTO 999
      ENDIF 
C
C     ---- ON VERIFIE LE SOMMET EXTREMITE --------------
C
      IES = NOETRI(ISE)
      IF( ( IES.NE.0 ).AND.
     >    ( (ITRTRI((IES-1)*NBCMAX+1).NE.0).OR.
     >      (ITRNOE((IES-1)*NBNMAX+1).NE.ISE) ) )THEN
          IERR = -3
          GOTO 999
      ENDIF 
C
C     --- CREATION DU NOUVEL ELEMENT ----------------
C
      IENEW = NBE
      ITRNOE((IENEW-1)*NBNMAX+1) = ISO
      ITRNOE((IENEW-1)*NBNMAX+2) = ISE
      ITRTRI((IENEW-1)*NBCMAX+1) = IEO
      ITRTRI((IENEW-1)*NBCMAX+2) = IES
C
C     --- MISE A JOUR DE IE ET DE IESUIV ------------ 
C
      IF( IES .NE. 0 )ITRTRI((IES-1)*NBCMAX+1) = IENEW
      IF( IEO .NE. 0 )ITRTRI((IEO-1)*NBCMAX+2) = IENEW
C
      NBE = NBE+1
      IERR = 0
C
  999 END
C
      FUNCTION S1LNFM(IT,ITRTRI,NBCMAX,ITD,ITF,NBE)
C     *****************************************************************
C     OBJET :   RENVOI 1 SI LE CONTOUR ACCESSIBLE DE IT EST FERME
C               0 SINON
C
C     EN ENTREE : 
C          IT     : UN ELEMENT DE LA CHAINE
C          ITRTRI: MAILLAGE LINEIQUE
C          NBCMAX : NOMBRE DE COTE DES ELEMENTS
C     EN SORTIE     :  
C         NBE     : LE NOMBRE D'ARETES 
C         ITD     : ARETE DE DEBUT
C         ITF     : ARETE DE FIN
C
C     *****************************************************************
      INTEGER S1LNFM
      INTEGER IT,ITRTRI(*),NBCMAX
      INTEGER ITD,ITF,NBE
C
      INTEGER ISENS,ITI,ITS
C
      IF(IT.LE.0)THEN
        S1LNFM = -1
        GOTO 999
      ENDIF
      ITD = 0
      ITF = 0
      ITI = IT
      ISENS = 0
      NBE = 0
C      
   10 ITS = ITRTRI((ITI-1)*NBCMAX+1+ISENS)
      IF(ITS.EQ.0)THEN
        IF(ISENS.EQ.0)THEN 
C         --- ON REPART DANS L'AUTRE SENS ---
          ISENS = 1
          ITD   = ITI
          ITI   = IT
          NBE = NBE + 1
          GOTO 10
        ELSE
          ITF = ITI
          GOTO 20
        ENDIF
      ELSE
        ITI = ITS
        NBE = NBE+1
      ENDIF 
      IF(ITI.NE.IT)GOTO 10
C
   20 IF(ITD.EQ.0)THEN
        IF(ITF.NE.0)THEN
          S1LNFM = -1
        ELSE
          S1LNFM = 1
          ITD = IT
          ITF = ITRTRI((ITD-1)*NBCMAX+1)
        ENDIF
      ELSE
        IF(ITF.EQ.0)THEN
          S1LNFM = -1
        ELSE
          S1LNFM = 0
        ENDIF
      ENDIF
C          
  999 END
C      
      
      
C     *****************************************************************
C     MODULE  : ST (STRUCTURE DES DONNEES)
C     FICHIER : ST_2DSTRUCT.F
C     OBJET   : CONSULTATION, CONSTRUCTION ET MODIFICATION DE LA 
C               STRUCTURE DE DONNE DU MAILLAGE 2D
C     FONCT.  : 
C        S2NBCO   : CALCUL LE NOMBRE DE COTE REEL D'UN ELEMENT
C        S2GLUE   : COLLAGE D'UN ELEMENT 
C        S2GLAR   : COLLE LA FRONTIERE D'UN MAILLAGE SUR LA FRONTIERE
C                     D'UN DEUXIEME
C     OBJET S2SOTR : RENVOI DANS L'ORDRE LES SOMMETS OU ELEMENTS CONNECTES A ISOMM
C
C     AUTEUR  : O. STAB
C     DATE    : 03.95
C     TESTS   : A FAIRE
C     MODIFICATIONS :
C      AUTEUR, DATE, OBJET : STAB, 02.03, AJOUT S2SOTR
C
C     *****************************************************************
C
      FUNCTION SFAC2D( IT1, IT2, N1, N2, IDE, I1, I2 )
C     *****************************************************************
C     OBJET SFAC2D : RECHERCHE LA FACE COMMUME A 2 ELEMENTS
C     *****************************************************************
      INTEGER SFAC2D
      INTEGER IT1(N1), IT2(N2), N1,N2, IDE, I1, I2
C
      INTEGER I,J
C     -----------------------
C     CAS DES TRIANGLES OU DES QUADRANGLES  
C     ON REALISE N1*N2*2  COMPARAISONS (X,Y) AVEC (A,B) ET (B,A)
C     ------------------------
      DO 10 I=1,N1 
        DO 20 J=1,N2 
          IF ( (IT1(I) .EQ. IT2(J))  .AND.
     >         (IT1(MOD(I,N1)+1) .EQ. IT2(MOD(J,N2)+1)) ) THEN
              I1 = I
              I2 = J
              SFAC2D = -1
              GOTO 9999
          ENDIF
          IF( (IT1(I) .EQ. IT2(MOD(J,N2)+1))  .AND.
     >        (IT1(MOD(I,N1)+1) .EQ. IT2(J)) ) THEN
              I1 = I
              I2 = J
              SFAC2D = 1
              GOTO 9999
          ENDIF    
   20   CONTINUE
   10 CONTINUE
 9999 END
C
      SUBROUTINE S2INVE(N, IDE, ITRNOE, ITRTRI )
C     ************************************************************
C     OBJET S2INVE : INVERSE L'ORIENTATION D'UN ELEMENT A N NOEUDS
C     CONDITION D'APPLICATION : TRIANGLE, QUADRANGLE
C     ************************************************************
      INTEGER   N, IDE, ITRNOE(N), ITRTRI(N)
C     
      INTEGER   I, ITRNO1, ITRTR1
C
   20 ITRNO1   = ITRNOE(N)
      ITRNOE(N) = ITRNOE(2)
      ITRNOE(2) = ITRNO1
      DO 25 I=1,(N/2)
        ITRTR1       = ITRTRI(I)
        ITRTRI(I)     = ITRTRI(N-I+1)
        ITRTRI(N-I+1) = ITRTR1
   25 CONTINUE
 9999 END
C
C
C
      FUNCTION S2NBCO(N,IDE)
C     ****************************************************************
C     OBJET  S2NBCO : NOMBRE DE FACES D'UN ELEMENT DE N NOEUDS
C     ************************************************************
      INTEGER S2NBCO
      INTEGER N,IDE
C
      S2NBCO = N
 9999 END
C
      FUNCTION S2SOFA(IDE,I,N,IFAC)
C     ************************************************************
C     OBJET S2SOFA : INDICES DES FACES INCIDENTES AU SOMMET I 
C     ************************************************************
      INTEGER  S2SOFA
      INTEGER  IDE,I,N,IFAC(*)
C
      IF( I.EQ.1 )THEN
        IFAC(1) = N
      ELSE
        IFAC(1) = I-1
      ENDIF
      IFAC(2) = I
      S2SOFA = 2
 9999 END
C
      FUNCTION S2OPFA(IDE,N,IFE)
C     ************************************************************
C     OBJET S2OPFA : INDICE DE L'ENTITE OPPOSEE A FACE IFE
C     EN SORTIE: 
C         POUR LES TRIANGLES   : LE SOMMET OPPOSE A L'ARETE
C         POUR LES QUADRANGLES : L'ARETE OPPOSEE A L'ARETE
C     ************************************************************
      INTEGER S2OPFA
      INTEGER IDE,N,IFE
C   
      S2OPFA = MOD(IFE+1,N)+1  
 9999 END
C
      FUNCTION S2FASO(IDE,N,I,ISOM)
C     ************************************************************
C     OBJET S2FASO : INDICES DES SOMMETS DE LA FACE I (SENS DIRECT)
C     ************************************************************
      INTEGER S2FASO
      INTEGER IDE,N,I,ISOM(*)
C
      INTEGER K
C
      DO 10 K=1,2
        ISOM(K) = MOD(I+K-2,N)+1
 10   CONTINUE
      S2FASO = 2
 9999 END
C     
C
      SUBROUTINE S2FASU(IDE,NBNE,ISOM,IFAC)
C     ************************************************************
C     OBJET S2FASU : FACE SUIVANTE SUR SOMMET(S)
C     ************************************************************
      INTEGER   IDE,NBNE,ISOM(1)
      INTEGER   IFAC     
C
      IFAC = MOD(ISOM(1)+(NBNE-2),NBNE)+1
C
 9999 END
C
C
C      FUNCTION S2NBCO_OLD(IT,ITRNOE, NMAX)
C     ****************************************************************
C     OBJET :  
C        CALCUL LE NOMBRE DE COTE REEL D'UN ELEMENT 
C        NECESSAIRE QUAND ON A DES MAILLAGES MIXTES (TRIANGLE,TETRA)
C     EN ENTREE:
C      NMAX   :  (3,4) NOMBRE DE COTES MAXIMUM DES ELEMENTS DU 
C                 MAILLAGE
C      IT     :  INDICE DE L'ELEMENT 
C      ITRNOE:  LES NOEUDS DES ELEMENTS
C     EN SORTIE: 
C     CONDITION D'APPLICATION : TRIANGLE, QUADRANGLE
C     ************************************************************
C      INTEGER S2NBCO
C      INTEGER ITRNOE(*), IT, NMAX
C
C      S2NBCO = 3
C          --- CAS DU QUADRANGLE ---
C      IF((NMAX.EQ.4).AND.(ITRNOE((IT-1)*NMAX+4).NE.0))S2NBCO = 4
C      END
C
      SUBROUTINE S2GLUE(IT,IDE,ITRNOE,NBNMAX,ITRTRI,NBCMAX,
     >                     NOETRI,IERR)
C     *****************************************************************
C     OBJET S2GLUE : COLLAGE D'UN ELEMENT 
C             MISE A JOUR DU TABLEAUX ITRTRI POUR CONNECTER L'ELEMENT
C             AVEC LE RESTE
C     EN ENTREE   :
C        IT       :L'ELEMENT A COLLER
C        IDE,ITRNOE,NBNMAX,ITRTRI,NBCMAX,NOETRI : LE MAILLAGE
C     EN SORTIE   : LE MAILLAGE MODIFIE
C        IERR     : 0 SI OK, -1 SI DONNEES ERRONEES
C     CONDITIONS D'APPLICATION :
C     *****************************************************************
      INTEGER   IT,IDE,ITRNOE(*),NBNMAX,ITRTRI(*),NBCMAX
      INTEGER   NOETRI(*),IERR
C
C     PRINCIPE :
C     RECHERCHE DES FACES COMMUNES ENTRE IT ET NOETRI(ITRNOE(IT))
C
      INTEGER  IATR(4),I,ITC,IF,NIT,NITC,IFIT,IFITC
      INTEGER  SFAC2D, STRNBN, ISENS, NP
      EXTERNAL SFAC2D, STRNBN
C
      NIT = STRNBN(IT,ITRNOE,NBNMAX)
      ISENS = 1
      DO 10 I=1,NIT
        IF( ITRTRI((IT-1)*NBCMAX+I).EQ.0 )THEN
          IATR(I) = 1
        ELSE 
          IATR(I)= 0
        ENDIF
   10 CONTINUE
      DO 30 I=1,NIT
        IF( IATR(I) .EQ. 1 )THEN
         NP = ITRNOE((IT-1)*NBNMAX+I)
         CALL SESFR2(NP,ISENS,IDE,ITRNOE,NBNMAX,ITRTRI,
     >                  NBCMAX,NOETRI,ITC,IF)
C        --- DE LA PREMIERE ARETE DE FRONTIERE ---
         IF( ITRTRI((ITC-1)*NBCMAX+IF) .NE. 0 )THEN
           IERR = -1
           GO TO 999
         ENDIF
   20    CALL SESFR1(ITC,IF,ITRTRI,NBCMAX,ITC,IF)
         IF( ITRTRI((ITC-1)*NBCMAX+IF) .NE. 0 )GO TO 20
         NITC = STRNBN(ITC,ITRNOE,NBNMAX)
C        --- A LA DERNIERE ARETE DE FRONTIERE ---
         IF( SFAC2D(IT,ITC,NIT,NITC,IDE,IFIT,IFITC).EQ.1)THEN
           ITRTRI((IT-1)*NBCMAX  + IFIT)  = IFITC
           ITRTRI((ITC-1)*NBCMAX + IFITC) = IFIT
         ENDIF
         ITRTRI((IT-1)*NBCMAX  + I)  = 0
        ENDIF
   30 CONTINUE 
  999 END
C
C
      SUBROUTINE S2GLAR(IFR1,NBF1,IFR2,NBF2,ITRNOE,NBNMAX,
     >                     ITRTRI,NBCMAX,NBCCOL)
C     *****************************************************************
C     OBJET S2GLAR : COLLE LA FRONTIERE D'UN MAILLAGE SUR UNE AUTRE 
C
C     EN ENTREE: 
C       IFR1 : FRONTIERE A COLLER
C       NBFR1: NOMBRE D'ELEMENTS DE LA FRONTIERE
C       IFR2 : FRONTIERE SUR LAQUELLE ON COLLE
C       NBFR2: NOMBRE D'ELEMENTS DE LA FRONTIERE
C       --- LE MAILLAGE ------------------------
C       ITRNOE,NBNMAX,ITRTRI,NBCMAX : LE MAILLAGE
C
C     EN SORTIE:  LE MAILLAGE MODIFIE (ITRTRI)
C       NBCCOL: LE NOMBRE D'ARETE DE IFR1 COLLEES A IFR2
C     REMARQUES : 
C        PAS DE VERIFICATION DE LA REGULARITE DE LA FRONTIERE
C        LES 2 MAILLAGES DOIVENT ETRE DANS LES MEMES TABLEAUX
C        ET ORIENTES DE LA MEME FACON.
C     COMPLEXITE : POUR CHAQUE ARETE DE IFR1 ON PARCOURS TOUTES LES
C        ARETES DE IFR2 
C        ON UTILISE PAS LA STRUCTURE (ITRITRI) POUR LE PARCOURS CAR 
C        ELLE N'EST PAS FORCEMENT CORRECTE.
C
C     *****************************************************************
      INTEGER IFR1(*),NBF1,IFR2(*),NBF2
      INTEGER ITRNOE(*),NBNMAX,ITRTRI(*),NBCMAX,NBCCOL
C
      INTEGER I,J,IT1,IT2,IF1,IF2,IORIG,IEXTR,NBRN1
      INTEGER ISENS
      INTEGER  STRNBN
      EXTERNAL STRNBN
C
C     --- MISE A JOUR DE ITRTRI -----------------
C
      NBCCOL = 0
      DO 20 I=1,NBF1
       NBRN1 = STRNBN(I,ITRNOE,NBNMAX)
       IT1 = IFR1((I-1)*2+1)
       IF1 = IFR1((I-1)*2+2)
C      --- POUR LES FRONTIERES INTERIEURES ---
       ISENS = 1
       IF( IF1.LT. 0 )THEN
         ISENS = -1
         IF1 = -IF1
       ENDIF
       IEXTR = ITRNOE((IT1-1)*NBNMAX+MOD(IF1,NBRN1)+1)
       DO 10 J=1,NBF2
         IT2 = IFR2((J-1)*2+1)
         IF2 = IFR2((J-1)*2+2)
C        --- POUR LES FRONTIERES INTERIEURES ---
         IF( IF2.LT. 0 )THEN
           ISENS = -1
           IF2 = -IF2
         ENDIF
         IORIG = ITRNOE((IT2-1)*NBNMAX+IF2)
         IF( IORIG .EQ. IEXTR )THEN
           ITRTRI((IT2-1)*NBCMAX+IF2) = ISENS * IT1
           ITRTRI((IT1-1)*NBCMAX+IF1) = ISENS * IT2
           NBCCOL = NBCCOL+1
           GO TO 20           
         ENDIF
   10  CONTINUE
C      --- ON EST SUR LA FRONTIERE ---
       ITRTRI((IT1-1)*NBCMAX+IF1) = 0
   20 CONTINUE
  999 END
C
      SUBROUTINE S2SOTR(ISOMM,ITYPE,
     >                 IDE,ITRNOE,NBNMAX,ITRTRI,NBCMAX,NOETRI,
     >                 ISOMFR,NBTRSO,ITABSE,ITABMX,IERR)
C     *****************************************************************
C     OBJET S2SOTR : RENVOI DANS L'ORDRE LES SOMMETS OU ELEMENTS CONNECTES A ISOMM
C
C     EN ENTREE :
C          ISOMM  : LE SOMMET SUR LEQUEL ON TOURNE
C          ITYPE  : 0 on stocke les sommets  (dans ITABSE)
C                   1 "  "    " les elements (dans ITABSE)
C          ITABSE : Tableau ou seront stockes objets connectes a ISOMM 
C          ITABMX : Taille de ITABSE
C     EN SORTIE :
C          ISOMFR : 1 si le sommet appartient a la frontiere
C                   0 sinon
C          NBTRSO : nombre de triangles incidents a ISOMM
C                   le nombre de sommets = NBTRSO + ISOMFR
C          ITABSE : Tableau des elements connectes a ISOMM (dans l'ordre)
C                   ou
C                   Tableau des sommets connectes a ISOMM (dans l'ordre)
C                   si ISOMFR=0 ITABSE(i) est ferme
C                   si ISOMFR=1 ITBASE(i) est ouvert
C 
C     REMARQUE  : 
C     *****************************************************************
      INTEGER ISOMM,ITYPE
      INTEGER IDE,ITRNOE(*),NBNMAX,ITRTRI(*),NBCMAX,NOETRI(*)
      INTEGER ISOMFR,NBTRSO,ITABSE(*),ITABMX,IERR
C
      EXTERNAL STRKSF
      INTEGER  STRKSF
      INTEGER ITRDEB,IARDEB,IT,IAR,IT2,IAR2,I,ISENS
      INTEGER ISOMAR(2),NBSOAR,NBNE,ISO,IARS,ISOMEX
C
      NBTRSO = 0
      ISOMFR = 1
C
      NBNE  = 3
C     --- SENS EST INUTILISE !!!! ????
      ISENS = 1
      CALL SESFR2(ISOMM,ISENS,IDE,ITRNOE,NBNMAX,ITRTRI,
     >                     NBCMAX,NOETRI,ITRDEB,IARDEB)
C     --- le sommet n'appartient a aucun element ! ---
      IF((IARDEB.LE.0 ).OR.( ITRDEB.LE.0 ))GOTO 9999
      IT  = ITRDEB
      IAR = IARDEB
C
 10   CONTINUE
      NBTRSO = NBTRSO + 1
      IARS = MOD(IAR,3)+1
      IF( ITYPE.EQ.0 )THEN
        IF( NBTRSO.LT.ITABMX )THEN
C         -- on stocke l'origine de l'arete ---
          ITABSE(NBTRSO)= ITRNOE((IT-1)*NBNMAX+IAR)
C         -- on stocke l'extremitee de l'arete suivante ---
          ISOMEX = MOD(IARS,3)+1
          ITABSE(NBTRSO+1)= ITRNOE((IT-1)*NBNMAX+ISOMEX)
        ENDIF
      ELSE
      IF( NBTRSO.LE.ITABMX )ITABSE(NBTRSO)= IT
      ENDIF
C 
      CALL SESFR1(IT,IARS,ITRTRI,NBCMAX,IT2,IAR2)
      IF( IT2.LE.0 )THEN
C     --- le sommet est sur la frontiere ---
        ISOMFR = 1
        GOTO 20
      ENDIF
      IF((IT2.EQ.ITRDEB).AND.(IAR2.EQ.IARDEB))THEN
C     --- le sommet est interieur ---
        ISOMFR = 0
        GOTO 20
      ENDIF
      IAR = IAR2
      IT  = IT2
      GOTO 10
C     --- on sort de la boucle
 20   CONTINUE
C      WRITE(*,*) 'SOMMET ' , ISOMM
C      WRITE(*,*) 'NBTRSO = ',NBTRSO,' ISOMFR = ',ISOMFR
C      WRITE(*,*) (ITABSE(I),I=1,NBTRSO+ISOMFR)
C      WRITE(*,*) '------------------------------------'
 9999 END
C
C     *****************************************************************
C     MODULE  : ST (STRUCTURE DES DONNEES)
C     FICHIER : ST3D_STRUCT.F
C     OBJET   : CONSULTATION, CONSTRUCTION ET MODIFICATION DE LA 
C               STRUCTURE DE DONNE DU MAILLAGE 3D
C     FONCT.  : 
C
C       SFAC3D :   RECHERCHE LA FACE COMMUNE A 2 ELEMENTS 3D
C
C       S3NBCO :   CALCUL DU NOMBRE DE COTE D'UN ELEMENT 
C       S3NBCF :   CALCUL DU NOMBRE DE COTE DE LA FACE D'UN ELEMENT
C      
C       S3FDIA :   FACE DIRECTE SUR UNE ARETE  (INDICE RELATIF)
C       S3A2FA :   ARETE COMMUNE A 2 FACES (INDICE RELATIF)
C       S3FASO :   K SOMMETS DE LA FACE (INDICE RELATIF)
C       S3SOFA :   K FACES AU SOMMET (INDICE RELATIF)
C       S3OPFA :   ENTITE OPPOSEE A FACE (INDICE RELATIF)
C 
C       S3INVE :   INVERSE L'ORIENTATION D'UN ELEMENT 3D
C
C     AUTEUR  : O. STAB
C     DATE    : 03.95
C     TESTS   : 
C
C     MODIFICATIONS :
C      AUTEUR, DATE, OBJET : O.STAB, 26.06.96, AJOUT SFAC3D (A TERMINER)
C
C     MODIFICATIONS :
C      AUTEUR, DATE, OBJET :
C
C
C     *****************************************************************
C
      SUBROUTINE SFRI3D(NN,NBNN,
     >                  IDE,ITRNOE,NBNMAX,ITRTRI,NBCMAX,
     >                  NOETRI,NBE,ITVL,NITMAX,
     >                  IT1,IT2,I1,I2,IERR)
C     *************************************************************
C     OBJET SFRI3D : ELEMENTS SUR LA FACE NN (VOIR SFRIDE)
C         EN ATTENDANT....
C     *************************************************************
      INTEGER   NN(*),NBNN,IDE,ITRNOE(*),NBNMAX,ITRTRI(*),NBCMAX
      INTEGER   NOETRI(*),NBE,ITVL(*),NITMAX
      INTEGER   IT1,IT2,I1,I2,IERR
C
      IERR = -3
 9999 END
C
      FUNCTION SFAC3D( IT1, IT2, N1, N2, IDE, I1, I2 )
C     *****************************************************************
C     OBJET SFAC3D : RECHERCHE LA FACE COMMUME A 2 ELEMENTS
C         RENVOI LES INDICES I1 ET I2 CORRESPONDANTS AUX FRONTIERES
C         COMMUNES DES ELEMENTS IT1 ET IT2. 
C
C     EN ENTREE:
C      IT1,IT2:  LES ELEMENTS A TESTER
C      N1     :  (2..4) NOMBRE DE NOEUDS DE IT1
C      N2     :  (2..4) NOMBRE DE NOEUDS DE IT2
C
C     EN SORTIE: 
C      I1,I2  :  INDICES DES FRONTIERES COMMUNES
C      SFAC3D :  0 SI AUCUNE ARETE COMMUNE
C            -1 SI I1 ET I2 SONT PARCOURUS DANS LE MEME
C               SENS POUR IT1 ET IT2
C             1 SI "  "     "   "         DANS LE SENS INVERSE
C
C     CONDITION D'APPLICATION : TETRA, HEXA...
C     REMARQUE : N'UTILISE PAS LA STRUCTURE DE DONNEES MAILLAGE
C                N'EXPLOITE AUCUNE HYPOTHESE SUR IT1 ET IT2
C     *****************************************************************
      INTEGER SFAC3D
      INTEGER IT1(N1), IT2(N2), N1,N2, IDE, I1, I2
C
      INTEGER IT12(16),ISOM(16)
      INTEGER NBNF1(6),NBNF2(6),ISOMT1(4,6),ISOMT2(4,6)
      INTEGER I,IFF,IFF1,IFF2,NBF1,NBF2,INO,ISENS,NBNC,INO2
      INTEGER  S3NBCO,S3FASO
      EXTERNAL S3NBCO,S3FASO
C
C      WRITE(6,*) 'ON ENTRE DANS SFAC3D it1,it2 = ',IT1,IT2
C      IDE = 3
C      WRITE(*,*) 'ON COMPARE :'
C      WRITE(*,*) (IT1(I),I=1,N1), 'ET '
C      WRITE(*,*) (IT2(I),I=1,N2) 
C
C     COMPARER LA SIGNATURE DES 4 NOEUDS POUR OPTIMISER
C     --------------------------------------------------
      DO 50 I=1,N1
       ISOM(I) = IT1(I)
   50 CONTINUE 
      DO 51 I=1,N2
       ISOM(I+N1) = IT2(I)
   51 CONTINUE
      CALL KNUTA(N1+N2,ISOM) 
      NBNC = 0     
      DO 52 I=1,(N1+N2-1)
        IF(ISOM(I).EQ.ISOM(I+1))NBNC = NBNC+1
   52 CONTINUE
C      WRITE(*,*) 'NOMBRE DE NOEUDS EN COMMUN :',NBNC
C
      IF( NBNC.LT.3 )THEN
        SFAC3D = 0         
        GOTO 9999
      ENDIF 
C
      IF(((N1.EQ.8).OR.(N2.EQ.8)).AND.(NBNC.EQ.3))THEN
        SFAC3D = 0
        GOTO 9999
      ENDIF
C      WRITE(6,*) 'IT1,IT2 = ',IT1,IT2
C
C     --- IL Y A AU MOINS 3 NOEUDS EN COMMUN ---
C         IL FAUT TROUVER LES FACES ET LEURS INDICES
C
C     --- LES FACES DE IT1 ---
C
C      WRITE(*,*) 'PREMIER ELEMENT'
      ISENS = 1
      NBF1 = S3NBCO(N1,3)
      DO 61 IFF=1,NBF1
C        NBNF1(IFF) = S3FASO(IFF,N1,ISENS,ISOMT1(1,IFF))
        NBNF1(IFF) = S3FASO(3,N1,IFF,ISOMT1(1,IFF))
C        WRITE(*,*) 'FACE :',IFF,' DE ',NBNF1(IFF),' SOMMETS ='
C        WRITE(*,*) (ISOMT1(INO,IFF),INO=1,3)
C        WRITE(*,*) 'ELEMENT =',(IT1(INO),INO=1,4)
        DO 60 INO=1,NBNF1(IFF)
          ISOMT1(INO,IFF)= IT1(ISOMT1(INO,IFF))
C          WRITE(*,*) ISOMT1(INO,IFF)
   60   CONTINUE
C        CALL KNUTA(NBNF1(IFF),ISOMT1(1,IFF))
   61 CONTINUE
C
C     --- LES FACES DE IT2 ---
C
C      WRITE(*,*) 'SECOND ELEMENT'
      NBF2 = S3NBCO(N2,3)
      DO 63 IFF=1,NBF2
C        NBNF2(IFF) = S3FASO(IFF,N2,ISENS,ISOMT2(1,IFF))
        NBNF2(IFF) = S3FASO(3,N2,IFF,ISOMT2(1,IFF))
C        WRITE(*,*) 'FACE :',IFF,' DE ',NBNF2(IFF),' SOMMETS ='
C        WRITE(*,*) (ISOMT2(INO,IFF),INO=1,3)
        DO 62 INO=1,NBNF2(IFF)
          ISOMT2(INO,IFF)= IT2(ISOMT2(INO,IFF))
   62   CONTINUE
C        CALL KNUTA(NBNF2(IFF),ISOMT2(1,IFF))
   63 CONTINUE
C
C     --- COMPARAISON ---
C
C      WRITE(*,*) 'COMPARAISON'
C      WRITE(*,*) 'FACES = ',((ISOMT1(INO,IFF1),INO=1,3),'/',IFF1=1,4)
C      WRITE(*,*) 'FACES = ',((ISOMT2(INO,IFF1),INO=1,3),'/',IFF1=1,4)
      DO 80 IFF1=1,NBF1
        DO 75 IFF2=1,NBF2
          IF( NBNF1(IFF1).EQ.NBNF2(IFF2) )THEN
            INO = 1
            INO2 = 1
C           ---- ON CHERCHE LE DEBUT ---------------------
   74       IF( ISOMT1(INO,IFF1).NE.ISOMT2(INO2,IFF2))THEN
              INO2 = INO2 + 1
              IF( INO2.GT.NBNF2(IFF2) ) GOTO 75
              GOTO 74
            ENDIF
C           ---- ON RECHERCHE LE SENS --------------------
            IF( ISOMT1(INO+1,IFF1).NE.
     >          ISOMT2(MOD(INO2,NBNF2(IFF2))+1,IFF2))THEN
              ISENS = -1
            ELSE
              ISENS = 1
            ENDIF
C
C           ---- ON COMPARE 2 LISTES CIRCULAIRES ---------         
C
   77       INO  = INO+1
            IF(ISENS.EQ.1)THEN
              INO2 = MOD(INO2,NBNF2(IFF2)) + 1
            ELSE 
              INO2 = NBNF2(IFF2) - MOD(NBNF2(IFF2)+1-INO2,NBNF2(IFF2))
            ENDIF
            IF( ISOMT1(INO,IFF1).NE.ISOMT2(INO2,IFF2))GOTO 75
C           ---- 
            IF( INO.EQ. NBNF1(IFF1) )THEN
              I1 = IFF1
              I2 = IFF2
              SFAC3D = -ISENS
C              WRITE(*,*) 'FACE COMMUNE :',I1,I2
              GOTO 9999
            ENDIF
            GOTO 77
          ENDIF
   75   CONTINUE
   80 CONTINUE
C
      SFAC3D = 0         
C
 9999 END                  
C
C
      SUBROUTINE S3INVE(N, IDE, ITRNOE, ITRTRI )
C     ************************************************************
C     OBJET S3INVE : INVERSE L'ORIENTATION D'UN ELEMENT A N NOEUDS
C         
C     EN ENTREE:
C      N      :  (2..4) NOMBRE DE NOEUDS DE L'ELEMENT 
C      ITRNOE:  LES NOEUDS DU TRIANGLES
C      ITRTRI:  LES VOISINS DU TRIANGLES
C     EN SORTIE: 
C      ITRTRI :  MIS A JOUR
C      ITRNOE :  MIS A JOUR
C     CONDITION D'APPLICATION : TETRAEDRE
C
C     REMARQUE : PERMUTER LES NOEUDS (I,J) REVIENT A PERMUTER LES
C                FACE (I,J) ET A INVERSER LE SENS DE TOUTES LES 
C                FACES
C     ************************************************************
      INTEGER   N,IDE,ITRNOE(N),ITRTRI(N)
C     
      INTEGER   ITRNO1, ITRTR1
C
      IF( N.EQ.4 )THEN
          ITRNO1 = ITRNOE(3)
          ITRNOE(3) = ITRNOE(2)
          ITRNOE(2) = ITRNO1
          ITRTR1 = ITRTRI(3)
          ITRTRI(3) = ITRTRI(2)
          ITRTRI(2) = ITRTR1           
      ENDIF
      END
C
C
      FUNCTION S3NBCO(N,IDE)
C     *************************************************************
C     OBJET  S3NBCO : NOMBRE DE FACES D'UN ELEMENT DE N NOEUDS
C     CONDITION D'APPLICATION : TETRA, PYRA, PRISME, HEXA
C     MODIF 21.01.99 : AJOUT DE L'ELEMENT VIDE
C     ************************************************************
      INTEGER S3NBCO
      INTEGER N,IDE
C
      INTEGER IERR
C      
      GOTO (5,1,1,1,100,100,100,1,200) (N+1)
C        =====================
C     --- ELEMENT VIDE ---
C        =====================
    5 S3NBCO = 0
      GOTO 9999
C        =====================
C     --- ELEMENT NON RECONNU ---
C        =====================
    1 S3NBCO = -1
      IERR = -1
      CALL DSERRE(1,IERR,'S3NBCO',' TYPE D ELEMENT INCONNU')
      GOTO 9999
C        ====================================
C     --- CAS DU TETRAEDRE, PYRAMIDE, PRISME ---
C        ====================================
  100 S3NBCO = N
      GOTO 9999
C        ==================
C     --- CAS DE L'HEXAEDRE ---
C        ==================
  200 S3NBCO = 6
      GOTO 9999
C
 9999 END
C
      FUNCTION S3NBCF(NBC,NF)
C     ************************************************************
C     OBJET :  CALCUL DU NOMBRE DE COTE DE LA FACE D'UN ELEMENT
C        NECESSAIRE QUAND ON A DES ELEMENTS (PRISME,PYRA...)
C     EN ENTREE:
C      NBC   :  (4,5,6,8) NOMBRE DE COTES DE L'ELEMENTS 
C      NF    :  NUMERO DE LA FACE
C     EN SORTIE: 
C     CONDITION D'APPLICATION : TETRA
C     ************************************************************
      INTEGER S3NBCF
      INTEGER NBC, NF
C
      S3NBCF  = 4
      IF( NBC .EQ. 4 )GO TO 999
      S3NBCF = -1      
  999 END
C
C      SUBROUTINE S3FDIA(I,J,N,IFACE) REMPLACE PAR :
      SUBROUTINE S3FASU(IDE,N,ISOM,IFAC)
C     ************************************************************
C     OBJET S3FASU : FACE DIRECTE SUR UNE ARETE (INDICE RELATIF)
C     EN ENTREE:
C      ISOM(1,2):  LES INDICES DES SOMMETS DE L'ARETE
C      N      :  (4) NOMBRE DE COTES DE L'ELEMENT 
C                 TETRA(4),PYRAM(5),PRISME(6),HEXA(8)
C     EN SORTIE: 
C      IFACE  :  INDICE DE LA FACE DIRECTE DANS LE TABLEAU TRITRI
C     CONDITION D'APPLICATION : TETRAEDRE SEULEMENT
C
C     A TESTER
C     ************************************************************
      INTEGER   IDE, N, ISOM(2), IFAC
C     
      COMMON /STRTET/ ITA2F(4,4),IT2FA(4,4),IT3SF(3,4)
      INTEGER ITA2F, IT2FA, IT3SF
C
      IF( N .EQ. 4 )THEN
C     --- CAS DU TETRAEDRE ---
        IFAC = IT2FA(ISOM(1),ISOM(2))
      ENDIF
  999 END
C
      SUBROUTINE S3A2FA(I,J,N,N1,N2)
C     ************************************************************
C     OBJET : ARETE COMMUNE A 2 FACES (INDICE RELATIF)
C     EN ENTREE:
C      I,J    :  LES INDICES DES FACES DE L'ELEMENT
C      N      :  (4) NOMBRE DE COTES DE L'ELEMENT 
C                 TETRA(4),PYRAM(5),PRISME(6),HEXA(8)
C     EN SORTIE: 
C      N1,N2  :  INDICE DES EXTREMITES DE L'ARETE (DIRECTE POUR I)
C     CONDITION D'APPLICATION : TETRAEDRE SEULEMENT
C
C     A TESTER
C     ************************************************************
      INTEGER   I, J, N, N1, N2
C     
      COMMON /STRTET/ ITA2F(4,4),IT2FA(4,4),IT3SF(3,4)
      INTEGER ITA2F, IT2FA, IT3SF
C
      IF( N .EQ. 4 )THEN
C     --- CAS DU TETRAEDRE ---
        N1 = ITA2F(I,J)
        N2 = ITA2F(J,I)
      ENDIF
  999 END
C
C      FUNCTION S3FASO(I,N,ISENS,ISOM) A ETE MODIFIE LE 14.08.98
      FUNCTION S3FASO(IDE,N,I,ISOM)
C     ************************************************************
C     OBJET S3FASO : INDICES DES SOMMETS DE LA FACE I (SENS DIRECT)
C     CONDITION D'APPLICATION : TETRAEDRE ET HEXAEDRE SEULEMENT
C     ************************************************************
      INTEGER S3FASO
      INTEGER IDE,I,N,ISOM(*)
C     
      COMMON /STRTET/ ITA2F(4,4),IT2FA(4,4),IT3SF(3,4)
      INTEGER ITA2F, IT2FA, IT3SF
      COMMON /STRHEX/ IQ4SF(4,6),IQ3FS(3,8)
      INTEGER IQ4SF,IQ3FS
      INTEGER ISENS,J,IERR
C
      ISENS = 1
      GOTO (1,1,1,100,1,1,1,200) N
C        =====================
C     --- ELEMENT NON RECONNU ---
C        =====================
    1 S3FASO = 0
      IERR = -1
      CALL DSERRE(1,IERR,'S3FASO',' TYPE D ELEMENT INCONNU')
      GOTO 9999
C        ==================
C     --- CAS DU TETRAEDRE ---
C        ==================
  100 S3FASO = 3
      IF( ISENS .EQ. 1 )THEN
          DO 110 J=1,S3FASO
            ISOM(J) = IT3SF(J,I)
  110     CONTINUE
        ELSE
          DO 120 J=1,S3FASO
            ISOM(J) = IT3SF(S3FASO+1-J,I)
  120     CONTINUE        
        ENDIF
        GOTO 9999
C        ==================
C     --- CAS DE L'HEXAEDRE ---
C        ==================
  200 S3FASO = 4
      IF( ISENS .EQ. 1 )THEN
          DO 210 J=1,S3FASO
            ISOM(J) = IQ4SF(J,I)
  210     CONTINUE
        ELSE
          DO 220 J=1,S3FASO
            ISOM(J) = IQ4SF(S3FASO+1-J,I)
  220     CONTINUE        
        ENDIF
        GOTO 9999
C
 9999 END
C
C
      FUNCTION S3SOFA(IDE,I,N,IFAC)
C     ************************************************************
C     OBJET S3SOFA : INDICES DES FACES INCIDENTES AU SOMMET I 
C     CONDITION D'APPLICATION : TETRAEDRE ET HEXAEDRE SEULEMENT
C     ************************************************************
      INTEGER  S3SOFA
      INTEGER  IDE,I,N,IFAC(*)
C     
      COMMON /STRTET/ ITA2F(4,4),IT2FA(4,4),IT3SF(3,4)
      INTEGER ITA2F, IT2FA, IT3SF
      COMMON /STRHEX/ IQ4SF(4,6),IQ3FS(3,8)
      INTEGER IQ4SF,IQ3FS
      INTEGER J,IERR
C
C      write(6,*) 'INDICE DU SOMMET = ',I
C      write(6,*) 'NOMBRE DE NOEUDS = ',N
      GOTO (1,1,1,100,1,1,1,200) N
C        =====================
C     --- ELEMENT NON RECONNU ---
C        =====================
    1 S3SOFA = 0
      IERR = -1
      CALL DSERRE(1,IERR,'S3SOFA',' TYPE D ELEMENT INCONNU')
      GOTO 9999
C        ==================
C     --- CAS DU TETRAEDRE ---
C        ==================
C
  100 S3SOFA = 3
          DO 110 J=1,S3SOFA
            IFAC(J) = IT3SF(J,I)
  110     CONTINUE
        GOTO 9999
C        ==================
C     --- CAS DE L'HEXAEDRE ---
C        ==================
  200 S3SOFA = 3
          DO 210 J=1,S3SOFA
            IFAC(J) = IQ3FS(J,I)
  210     CONTINUE
        GOTO 9999
C
 9999 END
C
      FUNCTION S3OPFA(IDE,N,IFE)
C     ************************************************************
C     OBJET S3OPFA : INDICE DE L'ENTITE OPPOSEE A FACE IFE
C     EN SORTIE: 
C         POUR LES TETRAEDRES  : INDICE DU NOEUD OPPOSE
C         POUR L'HEXAEDRE      : FACE OPPOSEE
C         POUR LE PRISME       : ARETE OPPOSE POUR LES FACES QUAD
C                                FACE OPPOSE POUR LES FACES TRI
C         POUR LA PYRAMIDE     :
C                              
C     CONDITION D'APPLICATION : TETRAEDRE
C     ************************************************************
      INTEGER S3OPFA
      INTEGER IDE,N, IFE
C     
      IF( N .EQ. 4 )THEN
C       --- CAS DU TETRAEDRE ---
        S3OPFA = IFE
C        PRINT *,'A FAIRE'
      ELSE
        S3OPFA = 0
      ENDIF
  999 END
C
C
C
C
C
*      BLOCK DATA STRU3D
C
C     POUR LES TETRA : 
C             ITA2F : ARETE PARTAGEE PAR 2 FACES
C                    ITA2F(I,J),ITA2F(J,I) = L'ARETE COMMUNE
C                    AU FACES I ET J ET DIRECTE POUR I
C
C             IT2FA : LES 2 FACES INCIDENTES A UNE ARETE
C                    IT2FA(I,J) = FACE DIRECTE POUR L'ARETE I,J
C                    IT2FA(J,I) = FACE INDIRECTE
C
C             IT3SF : LES 3 SOMMETS D'UNE FACE
C
*      COMMON /STRTET/ ITA2F(4,4),IT2FA(4,4),IT3SF(4,3)
*      INTEGER ITA2F, IT2FA, IT3SF
*      DATA ITA2F / 0,4,2,3, 3,0,4,1, 4,1,0,2, 2,3,1,0 /
*      DATA IT2FA / 0,4,2,3, 3,0,4,1, 4,1,0,2, 2,3,1,0 /
*      DATA IT3SF / 4,3,2, 3,4,1, 4,2,1, 1,2,3 /
*      END
C
      SUBROUTINE ST3INI
C     **********************************************************************
C     OBJET : INITIALISE LES CONSTANTES STRUCTURALES DU COMMON STRTET
C
C     REMARQUE  :
C       L'INITIALISATION DES CONSTANTES EST REALISE PAR PROCEDURE
C       PLUTOT QUE PAR UN BLOCK DATA POUR DES RAISONS DE PORTABILITE.
C       ST3INI DOIT ETRE APPELEE AU DEBUT DE CHAQUE PROGRAMME
C     **********************************************************************
C
C     POUR LES TETRA : 
C             ITA2F : ARETE PARTAGEE PAR 2 FACES
C                    ITA2F(I,J),ITA2F(J,I) = L'ARETE COMMUNE
C                    AU FACES I ET J ET DIRECTE POUR I
C
C             IT2FA : LES 2 FACES INCIDENTES A UNE ARETE
C                    IT2FA(I,J) = FACE DIRECTE POUR L'ARETE I,J
C                    IT2FA(J,I) = FACE INDIRECTE
C
C             IT3SF : LES 3 SOMMETS D'UNE FACE
C
      COMMON /STRTET/ ITA2F(4,4),IT2FA(4,4),IT3SF(3,4)
      INTEGER ITA2F, IT2FA, IT3SF
      COMMON /STRHEX/ IQ4SF(4,6),IQ3FS(3,8)
      INTEGER IQ4SF,IQ3FS
C
C          =================================
C     ----     POUR LES TETRAEDRES          ----
C          =================================
C
C          ===========================================
C     ---- ITA2F(I,J) = ITA2F(J,I) = L'ARETE COMMUNE
C                    AU FACES I ET J ET DIRECTE POUR I
C     A REVOIR
C          ===========================================
      ITA2F(1,1) = 0
      ITA2F(2,1) = 4 
      ITA2F(3,1) = 2
      ITA2F(4,1) = 3
C
      ITA2F(1,2) = 3
      ITA2F(2,2) = 0
      ITA2F(3,2) = 4
      ITA2F(4,2) = 1
C
      ITA2F(1,3) = 4
      ITA2F(2,3) = 1
      ITA2F(3,3) = 0
      ITA2F(4,3) = 2
C
      ITA2F(1,4) = 2
      ITA2F(2,4) = 3
      ITA2F(3,4) = 1
      ITA2F(4,4) = 0
C
C
C          ===========================================
C     ---- IT2FA(I,J) = FACE DIRECTE POUR L'ARETE I,J ----
C                       IT2FA(J,I) = FACE INDIRECTE
C     A REVOIR
C          ===========================================
      IT2FA(1,1) = 0
      IT2FA(2,1) = 4 
      IT2FA(3,1) = 2
      IT2FA(4,1) = 3
C
      IT2FA(1,2) = 3
      IT2FA(2,2) = 0
      IT2FA(3,2) = 4
      IT2FA(4,2) = 1
C
      IT2FA(1,3) = 4
      IT2FA(2,3) = 1
      IT2FA(3,3) = 0
      IT2FA(4,3) = 2
C
      IT2FA(1,4) = 2
      IT2FA(2,4) = 3
      IT2FA(3,4) = 1
      IT2FA(4,4) = 0
C
C          =================================
C     ---- IT3SF(I,J) = NOEUD I DE LA FACE J ----
C          =================================
      IT3SF(1,1) = 2
      IT3SF(2,1) = 4 
      IT3SF(3,1) = 3
C
      IT3SF(1,2) = 3
      IT3SF(2,2) = 4
      IT3SF(3,2) = 1
C
      IT3SF(1,3) = 4
      IT3SF(2,3) = 2
      IT3SF(3,3) = 1
C
      IT3SF(1,4) = 1
      IT3SF(2,4) = 2
      IT3SF(3,4) = 3     
C
C          =================================
C     ----     POUR LES HEXAEDRES          ----
C          =================================
C
C
C          =================================
C     ---- IQ4SF(I,J) = NOEUD I DE LA FACE J ----
C          =================================
C
      IQ4SF(1,1) = 1
      IQ4SF(2,1) = 2
      IQ4SF(3,1) = 3
      IQ4SF(4,1) = 4
C
      IQ4SF(1,2) = 1
      IQ4SF(2,2) = 5
      IQ4SF(3,2) = 6
      IQ4SF(4,2) = 2
C
      IQ4SF(1,3) = 2
      IQ4SF(2,3) = 6
      IQ4SF(3,3) = 7
      IQ4SF(4,3) = 3
C
      IQ4SF(1,4) = 3
      IQ4SF(2,4) = 7
      IQ4SF(3,4) = 8
      IQ4SF(4,4) = 4
C
      IQ4SF(1,5) = 4
      IQ4SF(2,5) = 8
      IQ4SF(3,5) = 5
      IQ4SF(4,5) = 1
C
      IQ4SF(1,6) = 5
      IQ4SF(2,6) = 8
      IQ4SF(3,6) = 7
      IQ4SF(4,6) = 6
C
C          =================================
C     ---- IQ3FS(I,J) = FACE I AU NOEUD J ----
C          =================================
C
      IQ3FS(1,1) = 1
      IQ3FS(2,1) = 2
      IQ3FS(3,1) = 5
C
      IQ3FS(1,2) = 2
      IQ3FS(2,2) = 1
      IQ3FS(3,2) = 3
C
      IQ3FS(1,3) = 3
      IQ3FS(2,3) = 1
      IQ3FS(3,3) = 4
C
      IQ3FS(1,4) = 4
      IQ3FS(2,4) = 1
      IQ3FS(3,4) = 5
C
      IQ3FS(1,5) = 2
      IQ3FS(2,5) = 6
      IQ3FS(3,5) = 5
C
      IQ3FS(1,6) = 3
      IQ3FS(2,6) = 6
      IQ3FS(3,6) = 2
C
      IQ3FS(1,7) = 4
      IQ3FS(2,7) = 6
      IQ3FS(3,7) = 3
C
      IQ3FS(1,8) = 5
      IQ3FS(2,8) = 6
      IQ3FS(3,8) = 4
C

      END
C     *****************************************************************
C     MODULE  : ST (STRUCTURE DES DONNEES)
C     FICHIER : ST_STRUCT.F
C     OBJET   : CONSULTATION, CONSTRUCTION ET MODIFICATION DE LA 
C               STRUCTURE DE DONNE DU MAILLAGE (1D, 2D, 3D)
C     FONCT.  : 
C       SUR LES MAILLAGES:
C           CONSTRUCTION :
C               SORIEN : ORIENTE UN MAILLAGE
C               SMACRE  : CREER LA STRUCTURE DE DONNEE MAILLAGE
C               SFRICR  : FRONTIERE (INTER MATERIAUX) CREEE DANS UN 
C                          MAILLAGE EXISTANT
C               SMADET  : DETRUIT 1 ELEMENTS D'UN MAILLAGE
C           PARCOURS     :
C               SESFR1: ELEMENT SUIVANT SUR FRONTIERE IDE-1
C               SESFR2: ELEMENT PREMIER SUR FRONTIERE IDE-2
C               SFRIDE  : FRONTIERE IDE-1 COMMUNE AUX ELEMENTS
C        SUR LES MAILLES :
C               STRNBN   : NOMBRE DE NOEUD DE L'ELEMENT
C
C     AUTEUR  : O. STAB
C     DATE    : 03.95
C     TESTS   : O.STAB 03.95
C     MODIFICATIONS :
C      AUTEUR, DATE, OBJET : O.STAB, 07.96, LE 3D (SMACRE,FAIDE,STRKFS)
C      AUTEUR, DATE, OBJET : O.STAB, 10.96, AJOUT DE NBPMAX DANS SMACRE
C      AUTEUR, DATE, OBJET : O.STAB, 04.97, BUG_15 (1D) + NETTOYAGE
C      AUTEUR, DATE, OBJET : O.STAB, 08.98, EXTRACTION DE ST_GENERIC.F
C      AUTEUR, DATE, OBJET : O.STAB, 01.05, modification de SFRICR 
C                            on traite une singularite en 2D IFR(1) 
C
C     *****************************************************************
C
      SUBROUTINE SORIEN(IDE,ITRNOE,NBNMAX,ITRTRI,NBCMAX,NBE,
     >                  ITVL,NBITL,ITRAMA,NCC,IERR)
C     *****************************************************************
C     OBJET : ORIENTE UN MAILLAGE
C             LES ELEMENTS DE CHAQUE COMPOSANTE CONNEXE SONT ORIENTES 
C             DE LA MEME FACON
C     EN ENTREE:
C      IDE    :  (1..3) DIMENSION DES ELEMENTS 
C      ITRNOE:  LES NOEUDS DES ELEMENTS
C      NBNMAX :  (2..8) NOMBRE DE NOEUDS MAXIMUM DES ELEMENTS 
C      ITRTRI:  LES VOISINS DES ELEMENTS
C      NBCMAX :  (2..6) NOMBRE DE COTES MAXIMUM DES ELEMENTS 
C      NBE    :  NOMBRE D'ELEMENTS DU MAILLAGE
C      ITVL,NBITL : TABLEAU DE TRAVAIL NBITL < (NBCMAX+1)*NBE
C      ITRAMA        : "    "   "    "  DE TAILLE = NBE
C     EN SORTIE:
C      ITRNOE: MIS A JOUR
C      ITRTRI: MIS A JOUR 
C          NCC : NOMBRE DE COMPOSANTES CONNEXES
C         IERR : CODE D'ERREUR 0 => OK
C               -1 => DONNEES INCOHERENTES
C               -2 => TABLEAU ITVL EST TROP PETIT
C     CONDITION D'APPLICATION : ARETE, TRIANGLE, QUADRANGLE, TETRA
C     *****************************************************************
      INTEGER    IDE,ITRNOE(*),NBNMAX,ITRTRI(*),NBCMAX,NBE
      INTEGER    ITVL(*),NBITL,ITRAMA(*),NCC,IERR
C
      DIMENSION ITT(7)
      EXTERNAL  SFAIDE
      INTEGER   SFAIDE
      INTEGER   I,J,ITT,NBTRA,IP,IM,NOP,II,N1,N2
C 
      NCC = 0
      IERR = 0
      IF( NBE.EQ. 0 )GOTO 9999
      IF( NBE.LT. 0 )THEN
        IERR = -1
        GOTO 9999
      ENDIF
      IF( (NBCMAX+1).GT.NBITL )THEN
        IERR = -2
        GO TO 9999
      ENDIF
C                     
C     INITIALISATION
C     --------------
      DO 10 I=1,NBE
        ITRAMA(I) = 0
   10 CONTINUE
C
C     ON BOUCLE SUR LES COMPOSANTES CONNEXES
C     ---------------------------------------
C
      DO 70 I=1,NBE
      IF( ITRAMA(I) .EQ. 0 )THEN
      NCC = NCC + 1
      ITVL(1) = I
      DO 20 J=1,NBCMAX
        ITVL(J+1) = ITRTRI((I-1)*NBCMAX+J)
   20 CONTINUE
      ITRAMA(I)  = 1
      NBTRA = NBCMAX+1
C
C     ON BOUCLE TANTQUE ITVL N'EST PAS VIDE
C     ----------------------------------------
C
C     TRANSFERT DU PERE TT(N+1) ET DE SES N VOISINS
C     ---------------------------------------------
   30 DO 40 J=1,NBCMAX+1
        ITT(J)  = ITVL(NBTRA-J+1)
   40 CONTINUE
      NBTRA = NBTRA-(NBCMAX+1)  
C 
C     TRAITEMENT DES N VOISINS
C     ------------------------
      DO 60 J=1,NBCMAX
        IF(( ITT(J) .NE. 0 ) .AND. (ITRAMA(ITT(J)) .NE. 1 )) THEN
          N1 = NBNMAX
          N2 = NBNMAX 
          IF((NBNMAX.EQ.4).AND.(IDE.EQ.2))THEN
C           --- CAS D'UN MAILLAGE MIXTE QUADRANGLES, TRIANGLES--
            IF(ITRNOE((ITT(J)-1)*NBNMAX+4).EQ.0)N1= 3
            IF(ITRNOE((ITT(NBCMAX+1)-1)*NBNMAX+4).EQ.0)N2= 3
          ENDIF  
          NOP=SFAIDE(ITRNOE((ITT(J)-1)*NBNMAX+1),
     >      ITRNOE((ITT(NBCMAX+1)-1)*NBNMAX+1),N1,N2,IDE,IM,IP) 
C           IL Y A UN BUG
C           -------------
            IF( NOP .EQ. 0 )THEN
              IERR = -1
              GO TO 9999
            ENDIF
            IF( NOP .LT. 0 ) THEN
              CALL SINVOR(IM,N1,IDE,ITRNOE((ITT(J)-1)*NBNMAX+1),
     >                    ITRTRI((ITT(J)-1)*NBCMAX+1))
            ENDIF
C     SES VOISINS SERONT A TRAITER
C     ----------------------------
            IF( (NBTRA+NBCMAX+1).GT.NBITL )THEN
              IERR = -2
              GO TO 9999
            ENDIF
            ITVL(NBTRA+1) = ITT(J)
            DO 50 II=1,NBCMAX
              ITVL(NBTRA+II+1) = ITRTRI(((ITT(J)-1)*NBCMAX)+II)
   50       CONTINUE
            NBTRA = NBTRA + (NBCMAX+1)
            ITRAMA(ITT(J)) = 1
          ENDIF           
   60 CONTINUE
      IF( NBTRA .GT. NBITL )THEN
        IERR = -2
        GO TO 9999
        ENDIF
      IF( NBTRA .NE. 0 )GO TO 30
      ENDIF
   70 CONTINUE
 9999 END      
C
C
      SUBROUTINE SMACRE(IDE,ITRI,NBE,NBPMAX,
     >                  ITRNOE,NBNMAX,ITRTRI,NBCMAX,NOETRI,NOEMAX,
     >                  ITVL,NBTRAV,IERR)
C     *****************************************************************
C     OBJET : CREER LA STRUCTURE DE DONNEE MAILLAGE 
C             ITRI -> ITRNOE, ITRTRI, NOETRI
C     EN ENTREE:
C      IDE    :  (1..3) DIMENSION DES ELEMENTS 
C      NBE    :  NOMBRE D'ELEMENTS DU MAILLAGE
C      NBPMAX : NOMBRE MAXIMUM DE POINTS 
C               IL PEUT ETRE SUPERIEUR AUX NOEUDS CONNECTES DANS ITRI
C               0 SI ON NE LE CONNAIT PAS
C      ITRI   : ITRI(I,J) EST LE NOEUD J DE L'ELEMENT I
C      NBNMAX :  (2..8) NOMBRE DE NOEUDS MAXIMUM DES ELEMENTS 
C      NBCMAX :  (2..6) NOMBRE DE COTES MAXIMUM DES ELEMENTS 
C      NOEMAX : TAILLE DU TABLEAU NOETRI
C                SI NOEMEMAX = 0 NOETRI NE SERA PAS REMPLI
C       ITVL   : TABLEAU DE TRAVAIL
C       NBTRAV : TAILLE DU TABLEAU DE TRAVAIL
C                AU MIN = 0 => O(N2)
C                AU MAX = (NBR MAX D'ELEMENTS EN 1 NOEUD + 1) *
C                         (NUMERO MAXI DU NOEUD DANS ITRI)
C                         => O(N)
C     EN SORTIE:
C       ITRNOE : ITRNOE(I,J) EST LE NOEUD J DU TRIANGLE I
C                LES ELEMENTS NE SONT PAS ORIENTES
C                PEUT ETRE LE MEME TABLEAU QUE ITRI
C       ITRTRI : ITRTRI(I,J) EST LE TRIANGLE INCIDENT AU TRIANGLE I SUR 
C                L'ARETE J
C       NOETRI : NOETRI(I) EST UN DES TRIANGLES CONTENANT LE NOEUD I
C       IERR   : CODE D'ERREUR 0 => OK
C                -NB => TABLEAU NOETRI TROP PETIT TAILLE SOUHAITE = NB
C     CONDITION D'APPLICATION : ARETE, TRIANGLE, QUADRANGLE, TETRA      
C     *****************************************************************
      INTEGER   IDE,ITRI(*),NBE,NBPMAX
      INTEGER   ITRNOE(*),NBNMAX,ITRTRI(*),NBCMAX
      INTEGER   NOETRI(*), NOEMAX, ITVL(*), NBTRAV, IERR
C
      EXTERNAL  SFAIDE,STRKFS
      INTEGER   SFAIDE,STRKFS
      INTEGER   I,J,K, IT1,IT2, IT, NBNOE, N1,N2, NBTMAX, ITNV, NIJ
C     --- POUR LES TESTS ---
C      REAL*4    X(2),Z(3)
      INTEGER   NBATST, NBLIN,IFAC(3),NBFN,KK,IFVUE
C     EXTERNAL  ETIME
C     REAL*4    ETIME
C
      IERR = 0
      IF( NBE.EQ. 0 )GOTO 9999
      IF( NBE.LT. 0 )THEN
        IERR = -1
        GOTO 9999
      ENDIF
      NBATST = 0
      NBLIN = 0
C
C         ================
C     ---- INITIALISATION  ----
C         ================
C
      DO 10 I=1,(NBE*NBCMAX)
          ITRTRI(I) = -1
   10 CONTINUE
      NBNOE = 0
      DO 20 I=1,(NBE*NBNMAX)
        IF( ITRI(I).GT.NBNOE )NBNOE = ITRI(I)
   20 CONTINUE
C 
C     L'INDICE D'UN NOEUD DEPASSE LA TAILLE DU TABLEAU
C
C     --- BUG10 25.10.96 -------------------------------
      IF((NOEMAX.GT.0).AND.
     >   ((NBNOE.GT.NOEMAX).OR.(NBPMAX.GT.NOEMAX)))THEN
        IERR = -2
        GO TO 9999
      ENDIF
C     --- INITIALISATION DU TABLEAU DE TRAVAIL ---
      NBTMAX = NBTRAV / NBNOE
C     MODIF O.STAB 1.9.99 : POUR LIMITER LE TRAITEMENT 
C     ET NE PAS INITIALISER TOUT ITVL !!!!!!
      NBTMAX = MIN( NBE, NBTMAX )
      IF( NBTMAX .LT. 2 )GO TO 90
      DO 30 I=1,(NBNOE * NBTMAX)
        ITVL(I) = 0
   30 CONTINUE
C
C         =============================
C     ---- CALCUL DES VOISINS : ITRTRI ----
C         =============================
C
C      Z(1) =ETIME(X)
      DO 50 I=1,NBE
C     ----------------------------------------------------------
C     REMPLISSAGE LINEAIRE MAIS PROBABILISTE (2/5) DES VOISINS 
C     PRINCIPE : SI UN AUTRE ELEMENT PARTAGE UN NOEUD AVEC 
C     UN AUTRE ELEMENT, ALORS PEUT ETRE PARTAGE T'IL UNE ARETE ?
C     ----------------------------------------------------------
C
       N1 = NBNMAX
       IF( (NBNMAX.EQ.4).AND.(IDE.EQ.2).AND.
     >     (ITRI((I-1)*NBNMAX+4).EQ.0))N1= 3
       DO 40 J=1,N1
         IT = ITRI((I-1)*NBNMAX+J) 
         IF(IT.LE.0)GOTO 40
         K = ITVL((IT-1)*NBTMAX+1)
         IF(K.LT.(NBTMAX-1))THEN
           ITVL((IT-1)*NBTMAX+1)  = K+1
           ITVL((IT-1)*NBTMAX+K+2)= I
         ENDIF
   40  CONTINUE
   50 CONTINUE
C
C
      NBLIN = 0
      DO 80 I=1,NBE
        N1 = NBNMAX
C       --- BUG6 05.09.96 : ITRTRI(4) = 0 -----
        IF( (IDE.EQ.2).AND.(NBNMAX.EQ.4).AND.
     >      (ITRI((I-1)*NBNMAX+4).EQ.0))THEN
          N1= 3
          ITRTRI((I-1)*NBCMAX + 4) = 0
        ENDIF
*        WRITE(*,*)' ELEMENT ',I
        DO 70 J=1,N1
C
C       POUR TOUTES LES FACES INCIDENTES AU NOEUD J
C
          NBFN = STRKFS(IDE,J,N1,IFAC)
*          WRITE(*,*)' NOEUD = ',J
          DO 55 K=1,NBFN
*          WRITE(*,*)' IFAC(',K,') = ',IFAC(K)
*          WRITE(*,*)' VOISIN = ',ITRTRI((I-1)*NBCMAX + IFAC(K))
            IF( ITRTRI((I-1)*NBCMAX + IFAC(K)).EQ.-1)GOTO 56
   55     CONTINUE
          GOTO 70
C         --- REMPLACE :
C          IF( ITRTRI((I-1)*NBCMAX + J).EQ.0)THEN
C
   56      IT = ITRI((I-1)*NBNMAX+J)
*           WRITE(*,*) 'ON TESTE LE NOEUD ',J,' DE L ELEMENT ',I
           IF(IT.LE.0)GOTO 70
C         ---- DANS LE TABLEAU DES ELEMENTS INCIDENTS ---
*          WRITE(*,*)'LISTE ='
          DO 65 K=1,ITVL((IT-1)*NBTMAX+1)
           ITNV = ITVL((IT-1)*NBTMAX+K+1)
*           WRITE(*,*)'ELEMENT SUR ',J,' ITNV = ',ITNV 
           IF(ITNV.NE.I)THEN
            N2 =NBNMAX
            IF( (NBNMAX.EQ.4).AND.(IDE.EQ.2).AND.
     >          (ITRI((ITNV-1)*NBNMAX+4).EQ.0))N2= 3            
            IF(SFAIDE(ITRI((I-1)*NBNMAX+1),
     >                  ITRI((ITNV-1)*NBNMAX+1), 
     >                  N1,N2,IDE,IT1,IT2 ).NE.0)THEN
*            WRITE(*,*) ITNV,' ET ',I,' SONT ADJACENTS SUR ',IT1,IT2
                 ITRTRI((I-1)*NBCMAX + IT1) = ITNV
                 ITRTRI((ITNV-1)*NBCMAX + IT2) = I
                 NBLIN = NBLIN + 1
            ENDIF
           ENDIF
   65     CONTINUE
C          ENDIF
   70   CONTINUE
   80  CONTINUE 
C      Z(2) = ETIME( X )
C
C     ----------------------------------------------------------
C     REMPLISSAGE EN O(N2) DES VOISINS 
C     ----------------------------------------------------------
C               
   90 NBATST = 0
C     ------------------------------- POUR TOUTES LES MAILLES: I
      DO 100 I=1,NBE-1
        N1 = NBNMAX
        IF( (NBNMAX.EQ.4).AND.(IDE.EQ.2).AND.
     >      (ITRI((I-1)*NBNMAX+4).EQ.0))N1= 3
C
C       ------(A) PRE-TRAITEMENT DES FACES INCIDENTES AUX NOEUDS 
C       ----------------- POUR TOUS LES NOEUDS DE LA MAILLE I: J
        DO 110 J=1,N1          
          IT = ITRI((I-1)*NBNMAX+J)
          IF(IT.LE.0)GOTO 110
C              ----------------------------------------
C         ---- AUCUNE MAILLE INCIDENTE A J N'A DE FACE 
C              COMMUNE AVEC I : ON LES A TOUTES TESTEES :
C              ON EST SUR LA FRONTIERE                 ----
C              ----------------------------------------
          IF((NBTMAX.GT.2).AND.
     >       (ITVL((IT-1)*NBTMAX+1).LT.(NBTMAX-1)))THEN
            NBFN = STRKFS(IDE,J,N1,IFAC)
            DO 91 KK=1,NBFN
              IF( ITRTRI((I-1)*NBCMAX + IFAC(KK)).EQ.-1)
     >            ITRTRI((I-1)*NBCMAX + IFAC(KK)) = 0
   91       CONTINUE
          ENDIF
C       ----------------------------------- FIN DE BOUCLE SUR J
  110   CONTINUE
C
C       -----(B) TRAITEMENT SYSTEMATIQUE DES FACES NON VISITEES 
C       ------------------------------------------------------- 
C       RECHERCHE D'UNE FACE DE LA MAILLE I NON ENCORE VISITEE  
C       ------------------------------------------------------- 
        IFVUE = 0
        DO 95 KK=1,NBCMAX
          IF( ITRTRI((I-1)*NBCMAX + KK).EQ.-1)IFVUE=IFVUE+1
   95   CONTINUE
C
C       ------------------------------------------------------- 
C       IL EXISTE UNE FACE DE LA MAILLE I NON ENCORE VISITEE  
C       ON PARCOURS TOUTES LES MAILLES DE KK=I+1 A NBE 
C       -------------------------------------------------------
        IF(IFVUE.GT.0)THEN 
          NBATST = NBATST+1
C       ------------------ POUR TOUS LE ELEMENTS DE I A NBE: K
          DO 120 K=I+1,NBE
           N2 = NBNMAX
           IF( (NBNMAX.EQ.4).AND.(IDE.EQ.2).AND.
     >         (ITRI((K-1)*NBNMAX+4).EQ.0))N2= 3           
           IF(SFAIDE(ITRI((I-1)*NBNMAX+1), 
     >               ITRI((K-1)*NBNMAX+1),
     >               N1,N2,IDE,IT1,IT2).NE.0)
     >     THEN
            ITRTRI((I-1)*NBCMAX + IT1) = K
            ITRTRI((K-1)*NBCMAX + IT2) = I
           ENDIF
  120     CONTINUE
C       -------------------------- FIN DE BOUCLE DE I A NBE: K
C
C       ------------- LES FACES JAMAIS VISITEES SONT FRONTIERE
          DO 196 KK=1,NBCMAX
            IF( ITRTRI((I-1)*NBCMAX + KK).EQ.-1)
     >          ITRTRI((I-1)*NBCMAX + KK) = 0
  196     CONTINUE
        ENDIF
  100 CONTINUE
C     ----------------- PARCOURS DES FACES DU DERNIER ELEMENT
      DO 197 KK=1,NBCMAX
              IF( ITRTRI((NBE-1)*NBCMAX + KK).EQ.-1)
     >         ITRTRI((NBE-1)*NBCMAX + KK) = 0
  197 CONTINUE
C
C      Z(3)=ETIME(X)
C     --------------------------------------------
C      PRINT *,'NB DE TRIANGLES STOQUES = ',NBTMAX
C      PRINT *,'NB EN QUADRATIQUE       = ',NBATST
C      PRINT *,'NB LINEAIRE             = ',NBLIN
C      PRINT *,'NB TOTAL                = ',(NBE*NBCMAX)
C      PRINT *,'TEMPS LINEAIRE          = ',(Z(2)-Z(1))
C      PRINT *,'TEMPS QUADRATI          = ',(Z(3)-Z(2))
C                       
C     INITIALISATION DE ITRNOE
C     -------------------------
      DO 130 I=1,(NBE*NBNMAX)
          ITRNOE(I) = ITRI(I)
  130 CONTINUE
C
C     INITIALISATION DE  NOETRI
C     -------------------------
      IF(NOEMAX.GT.0)THEN
      DO 135 I=1,MAX(NBNOE,NBPMAX)
        NOETRI(I) = 0
  135 CONTINUE
      DO 140 I=1,NBE
C       --- BUG17 AJOUT DE LA LIGNE QUI SUIT O.STAB 07/02/96
        N1 = NBNMAX
        IF( (NBNMAX.EQ.4).AND.(IDE.EQ.2).AND.
     >      (ITRI((I-1)*NBNMAX+4).EQ.0))N1= 3      
       DO 150 J=1, N1
          NIJ  = ITRI((I-1)*NBNMAX+J)
          IF(NIJ.GT.0)NOETRI(NIJ) = I
  150  CONTINUE
  140 CONTINUE 
      ENDIF 
C     ---- POUR LE DEBUG ----------------------------------
*        CALL PRITAB('ITRINOE ',ITRNOE,NBE,NBNMAX,1)
*        CALL PRITAB('ITRITRI ',ITRTRI,NBE,NBCMAX,1)
*        CALL PRITAB('NOETRI  ',NOETRI,NBNOE,1,1)
C
 9999 END      
C
C
      SUBROUTINE SFRICR(IFR,NBIFR,IDE,ITRNOE,NBNMAX,ITRTRI,NBCMAX,
     >                   NOETRI,NBE,ITVL,NITMAX,IERR)
C     >                   NOETRI,NBE,IERR)
C     ****************************************************************
C     OBJET SFRICR : FRONTIERE (INTER MATERIAUX) CREEE DANS UN MAILLAGE  
C        AJOUT D'UN SOMMET, D'UNE ARETE OU D'UNE FACETTE A LA FRONTIERE
C        INTER-MATERIAUX.
C     EN ENTREE:
C      IFR    :  TABLEAU DES NOEUDS DE L'ELEMENT FRONTIERE
C      NBIFR  :  NOMBRE DE NOEUDS DE L'ELEMENT FRONTIERE
C      IDE    :  (1..3) DIMENSION DES ELEMENTS 
C      ITRNOE:  LES NOEUDS DES ELEMENTS
C      NBNMAX :  (2..8) NOMBRE DE NOEUDS MAXIMUM DES ELEMENTS 
C      ITRTRI:  LES VOISINS DES ELEMENTS
C      NBCMAX :  (2..6) NOMBRE DE COTES MAXIMUM DES ELEMENTS 
C      NOETRI :  TABLEAU DES ELEMENTS INCIDENT AUX NOEUDS
C      NBE    :  NOMBRE D'ELEMENTS DU MAILLAGE
C     EN SORTIE: 
C      ITRTRI:  MIS A JOUR
C      IERR   :  CODE D'ERREUR 0 => OK, -1 => L'ELEMENT FRONTIERE
C                N'EXISTE PAS DANS LE MAILLAGE
C     CONDITION D'APPLICATION :      
C     ****************************************************************
      INTEGER   IFR(*),NBIFR
      INTEGER   IDE,ITRNOE(*),NBNMAX,ITRTRI(*),NBCMAX,NOETRI(*),NBE
      INTEGER   ITVL(*),NITMAX
      INTEGER   IERR 
C
      INTEGER   IT1, IT2, I1, I2 
      INTEGER   IFR1
C  
      IERR = 0 
      CALL SFRIDE(IFR,NBIFR,IDE,ITRNOE,NBNMAX,ITRTRI,NBCMAX,
     >             NOETRI,NBE,ITVL,NITMAX,IT1,IT2,I1,I2,IERR)
      IF(( IT1 .EQ. 0 ) .AND. ( IT2 .EQ. 0 ))THEN
C       L'ARETE IFR(1),IFR(2) (ou  LA FACETTE IFR(1),IFR(2),IFR(3))  N'EXISTE PAS
        IF( NBIFR.NE.2 )THEN
          IERR = -1
          GOTO 9999
        ENDIF 
C       on essaye un truc pour traiter une singularite en IFR(1) !!! 01.2005
C       la singularite est en IFR(1), on va tourner sur IFR(2) => il faut les permuter.
        IFR1 = IFR(1)
        IFR(1) = IFR(2)
        IFR(2) = IFR1
        CALL SFRIDE(IFR,NBIFR,IDE,ITRNOE,NBNMAX,ITRTRI,NBCMAX,
     >              NOETRI,NBE,ITVL,NITMAX,IT1,IT2,I1,I2,IERR)
      IF(( IT1 .EQ. 0 ) .AND. ( IT2 .EQ. 0 ))THEN
        IERR = -1
        GOTO 9999
      ENDIF
      ENDIF
C
      IF(( IT1 .GT. 0 ) .AND. ( IT2 .GT. 0 ))THEN
        IF(ITRTRI((IT1-1)*NBCMAX+I1).GT.0)
     >  ITRTRI((IT1-1)*NBCMAX+I1) = -ITRTRI((IT1-1)*NBCMAX+I1)
        IF(ITRTRI((IT2-1)*NBCMAX+I2).GT.0)
     >  ITRTRI((IT2-1)*NBCMAX+I2) = -ITRTRI((IT2-1)*NBCMAX+I2)
      ENDIF
C
 9999 END
C
      SUBROUTINE SESFR1(IT,IAR,ITRTRI,NBCMAX,IT2,IAR2)
C     *******************************************************
C     OBJET SESFR1 : ELEMENT SUIVANT SUR FRONTIERE IDE-1
C        TRIANGLE SUIVANT SUR ARETE / TETRA SUIVANT SUR FACE
C     EN ENTREE:
C      IT     :  LE TRIANGLE INITIAL
C      IAR    :  L'ARETE INITIALE DE IT
C      NBCMAX :  NOMBRE DE COTES MAXIMUM DES ELEMENTS DU MAILLAGE
C      ITRTRI:  TABLEAU DES VOISINS
C     EN SORTIE: 
C      IT1 :  LE TRIANGLE SUIVANT
C      IAR1:  INDICE DE L'ARETE IAR POUR LE TRIANGLE IT1
C     CONDITION D'APPLICATION : TRIANGLE, QUADRANGLE, TETRA   
C     REMARQUE : NE CONSIDERE PAS LES FRONTIERES INTERNES
C     *******************************************************
      INTEGER   IT,IAR,NBCMAX,ITRTRI(*),IT2,IAR2
C
      INTEGER J,IT1,IAR1,IT0
C      
      IAR1 = 0
      IT1 = ITRTRI((IT-1)*NBCMAX+IAR)
      IF( IT1 .EQ. 0 )GO TO 20
      IF( IT1 .LT. 0 )IT1 = -IT1
C     --- RECHERCHE DE L'ARETE IAR1 DE IT1 ---
      DO 10 J=1,NBCMAX
        IT0 = ITRTRI((IT1-1)*NBCMAX + J)
        IF( IT0.LT. 0 )IT0 = -IT0
        IF( IT0 .EQ. IT )THEN
          IAR1 = J
          GO TO 20
        ENDIF
   10 CONTINUE
   20 IT2  = IT1
      IAR2 = IAR1
  999 END        
C

      SUBROUTINE SESFR2(NN,ISENS,IDE,ITRNOE,NBNMAX,ITRTRI,
     >                     NBCMAX,NOETRI,ITP,IAR)
C     ************************************************************
C     OBJET SESFR2 : ELEMENT PREMIER SUR FRONTIERE IDE-2
C        TRIANGLE PREMIER SUR SOMMET / TETRA PREMIER SUR ARETE
C        RECHERCHE DU TRIANGLE DE DEPART ET DE SON ARETE POUR 
C        TOURNER AUTOUR D'UN SOMMET DANS UN SENS DONNE
C     EN ENTREE:
C      NN     :  LE SOMMET OU L'ARETE SUR LEQUEL ON TOURNE
C      ISENS  :  LE SENS DANS LEQUEL ON VEUT TOURNER
C     EN SORTIE: 
C      ITP :  LE TRIANGLE DE DEPART
C      IAR :  INDICE DE L'ARETE DE DEPART POUR LE TRIANGLE IPT
C             -1 SI "NN" N'APPARTIENT PAS A L'ELEMENT
C     REMARQUE : NE CONSIDERE PAS LES FRONTIERES INTERNES
C     ************************************************************
      INTEGER   NN(*),ISENS,IDE,ITRNOE(*),NBNMAX,ITRTRI(*)
      INTEGER   NBCMAX,NOETRI(*),ITP,IAR      
C
      INTEGER  IT,JJ,J,IDEBUT,IAR1,ISOM(2),NBNE
      INTEGER  STRNBN 
      EXTERNAL STRNBN
C     
      ITP = 0
      IDEBUT = NOETRI(NN(1))
      IT = IDEBUT
C
C     --- ON RECHERCHE LE PREMIER NOEUD : NN ---
C          
      IAR = 0
      IAR1 = 0
      ISOM(1) = 0
      ISOM(2) = 0 
      DO 15 JJ=1,(IDE-1)
        DO 10 J=1,NBNMAX
          IF(ITRNOE((IT-1)*NBNMAX+J) .EQ. NN(JJ))THEN
            ISOM(JJ) = J
            GOTO 15
          ENDIF
 10     CONTINUE
        IAR = -1
        GOTO 9999
 15   CONTINUE
      IF( ISOM(IDE-1).EQ.0 )THEN
        IAR = -1
        GOTO 9999
      ENDIF
C
      IF( NBNMAX.EQ.3 )THEN
        NBNE = NBNMAX
      ELSE
        NBNE = STRNBN(IT,ITRNOE,NBNMAX)
      ENDIF
      CALL STFASU(IDE,NBNE,ISOM,IAR1)
C 
C        IF(ITRNOE((IT-1)*NBNMAX+J) .EQ. NN(1))THEN
C          IF( IDE .EQ. 2 )THEN
C            IF( NBNMAX.EQ.3 )THEN
C              IAR1 = MOD(J+(NBNMAX-2),NBNMAX)+1
C            ELSE
C              NBNE = STRNBN(IT,ITRNOE,NBNMAX)
C              IAR1 = MOD(J+(NBNE-2),NBNE)+1
C            ENDIF
C            GO TO 20
C          ELSE 
C         --- CAS 3D ---
C            DO 3 K=1,NBNMAX
C              IF( ITRNOE((IT-1)*NBNMAX+K).EQ.0 )GO TO 4
C    3       CONTINUE
C    4       NBRN = K
C            DO 5 K=1,NBRN
C             IF(ITRNOE((IT-1)*NBNMAX+K) .EQ. NN(2))THEN
C            --- FACE DIRECTE OU INDIRECTE INCIDENTE A L'ARETE JK 
C               CALL S3FDIA(J,K,NBRN,IAR1)
C               GO TO 20 
C             ENDIF         
C    5       CONTINUE
C          ENDIF
C        ENDIF
C   10 CONTINUE
C     ---- ON A PAS TROUVER L'ARETE OU LA FACE ---
C      IAR = -1 
C      GO TO 999
C
   20 ITP = IT
      IAR = IAR1
C      IF( ISENS .EQ. 1)IAR = MOD(IAR+(NBNMAX-2),NBNMAX)+1
      CALL SESFR1(ITP,IAR,ITRTRI,NBCMAX,IT,IAR1)
      IF( IT .EQ. 0 )GO TO 9999
C     --- ON PASSE AU TRIANGLE SUIVANT,ARETE PREC ---  
C      IAR1 = MOD(IAR1+(NBNMAX-2),NBNMAX)+1
C           REMPLACER PAR O.STAB BUG 8 :
C
      IF( NBNMAX.EQ.3 )THEN
        IAR1 = MOD(IAR1+(NBNMAX-2),NBNMAX)+1
      ELSE
        NBNE = STRNBN(IT,ITRNOE,NBNMAX)
        IAR1 = MOD(IAR1+(NBNE-2),NBNE)+1
      ENDIF
      IF( IT .NE. IDEBUT )GO TO 20       

 9999 END        
C
C
      SUBROUTINE SFRIDE(NN,NBNN,
     >                  IDE,ITRNOE,NBNMAX,ITRTRI,NBCMAX,
     >                  NOETRI,NBE,ITVL,NITMAX,
     >                  IT1,IT2,I1,I2,IERR)
C     *************************************************************
C     OBJET SFRIDE : ELEMENT INCIDENT SUR UNE FACE (IDE-1)
C        RECHERCHE DES TRIANGLES QUI PARTAGENT L'ARETE NN(1..2)
C        RECHERCHE DES TETRAEDRES QUI PARTAGENT LE TRIANGLE NN(1..3)
C        
C     EN ENTREE:
C      NN     :  TABLEAU DES SOMMETS DE LA FACE
C      NBNN   :  NOMBRE DE SOMMETS DE LA FACE
C      IDE    :  DIMENSION DES ELEMENTS DU MAILLAGE
C      NBE    :  NOMBRE D'ELEMENTS DU MAILLAGE
C      ITVL,NITMAX : TABLEAU DE TRAVAIL (NECESSAIRE SEULEMENT EN 3D)
C
C     EN SORTIE: 
C      IT1 :  L'ELEMENT QUI CONTIENT LA FACE NN(1),NN(2)...
C       I1 :  L'INDICE DE LA FACE DE L'ELEMENT
C      IT2 :  L'ELEMENT QUI CONTIENT LA FACE ...NN(2),NN(1)
C       I2 :  L'INDICE DE LA FACE DE L'ELEMENT
C     REMARQUE : NE PREND PAS EN COMPTE LES FRONTIERES INTERNES
C                SFRI3D POUR LE 3D, SFRI2D POUR LE 2D, SFRI1D...
C                ATTENTION : NOETRI EST OBLIGATOIRE !!!
C     *************************************************************
      INTEGER   NN(*),NBNN
      INTEGER   IDE,ITRNOE(*),NBNMAX,ITRTRI(*),NBCMAX
      INTEGER   NOETRI(*),NBE,ITVL(*),NITMAX
      INTEGER   IT1,IT2,I1,I2,IERR
C
      GOTO(10,20,30) IDE
        IERR = -1
        GOTO 9999
C       ---- CAS 1D ET 2D :
   10   CONTINUE
        CALL SFRI1D(NN,NBNN,
     >              IDE,ITRNOE,NBNMAX,ITRTRI,NBCMAX,
     >              NOETRI,NBE,ITVL,NITMAX,
     >              IT1,IT2,I1,I2,IERR)
        GOTO 9999
   20   CONTINUE
        CALL SFRI2D(NN,NBNN,
     >              IDE,ITRNOE,NBNMAX,ITRTRI,NBCMAX,
     >              NOETRI,NBE,ITVL,NITMAX,
     >              IT1,IT2,I1,I2,IERR)
        GOTO 9999
C       --- CAS 3D :
   30   CONTINUE
        CALL SFRI3D(NN,NBNN,
     >              IDE,ITRNOE,NBNMAX,ITRTRI,NBCMAX,
     >              NOETRI,NBE,ITVL,NITMAX,
     >              IT1,IT2,I1,I2,IERR)
C
 9999 END
C
C      SUBROUTINE SFRIDE(NN,NBNN,IDE,ITRNOE,NBNMAX,ITRTRI,NBCMAX,
C     >                   NOETRI,NBE,IT1,IT2,I1,I2)
C     MODIF SFRIDE EXTENSION 3D : CHANGEMENT SIGNATURE
      SUBROUTINE SFRI1D(NN,NBNN,
     >                  IDE,ITRNOE,NBNMAX,ITRTRI,NBCMAX,
     >                  NOETRI,NBE,ITVL,NITMAX,
     >                  IT1,IT2,I1,I2,IERR)
C     *************************************************************
C     OBJET SFRI1D : RECHERCHE DES ARETES PARTAGEANT UN SOMMET NN(1)
C        
C     EN ENTREE:
C      NN     :  TABLEAU DES SOMMETS DE L'ELEMENT FRONTIERE
C      NBNN   :  NOMBRE DE SOMMETS
C      IDE    :  DIMENSION DES ELEMENTS DU MAILLAGE
C      NBE    :  NOMBRE D'ELEMENTS DU MAILLAGE
C
C     EN SORTIE: 
C      IT1 :  LE TRIANGLE QUI CONTIENT L'ARETE NN(1),NN(2)
C       I1 :  L'INDICE DE L'ARETE DE IT1 EGALE A NN(1),NN(2)
C      IT2 :  LE TRIANGLE QUI CONTIENT L'ARETE NN(2),NN(1)
C       I2 :  L'INDICE DE L'ARETE DE IT2 EGALE A NN(2),NN(1)
C     REMARQUE : 2D SEULEMENT (TRIANGLES, QUADRANGLES, MIXTE)
C                NE PREND PAS EN COMPTE LES FRONTIERES INTERNES
C                SFRI3D POUR LE 3D
C                IL FAUDRAIT AJOUTER UN TABLEAU DE TRAVAIL POUR 
C                AVOIR LA MEME SIGNATURE
C     *************************************************************
      INTEGER   NN(*),NBNN
      INTEGER   IDE,ITRNOE(*),NBNMAX,ITRTRI(*),NBCMAX
      INTEGER   NOETRI(*),NBE,ITVL(*),NITMAX
      INTEGER   IT1,IT2,I1,I2,IERR
C
      INTEGER   J1,J2,ISENS,IT,J,IDEBUT,NNT,ITAMPO
      INTEGER   STRNBN
      EXTERNAL  STRNBN
C     
      IT1 = 0
      IT2 = 0
      I1 = 0
      I2 = 0
      IERR = 0
      IF( IDE.NE.1 )THEN
        IERR = -3
        CALL DSERRE(1,IERR,'SFRI1D',' NE FONCTIONNE QU EN 1D')
        GOTO 9999
      ENDIF
      ISENS = 1
C     --- BOUCLE SUR LE SENS
   10 CONTINUE
      IDEBUT = NOETRI(NN(1))
      IT = IDEBUT
C     --- NOEUD ISOLE     
      IF( IT.EQ.0 )GOTO 9999
C
C     --- ON RECHERCHE LE PREMIER NOEUD : NN(1) ---
C
   20 CONTINUE
      J1 = 0
      DO 30 J=1,NBNMAX
        IF(ITRNOE((IT-1)*NBNMAX+J) .EQ. NN(1))J1 = J
   30 CONTINUE
C     --- L'ELEMENT NE CONTIENT PAS LE NOEUD / BUG STRUCTURE
      IF(J1.EQ.0)THEN
        IERR = -1
        CALL DSERRE(1,IERR,'SFRI1D','STRUCTURE INCORRECTE')
        GO TO 9999
      ENDIF
C     ----------------------------------------------------
C     SENS DIRECT => ARETE PARTANT DU NOEUD N1 
C     SENS INDIRE => ARETE ARRIVANT AU NOEUD => ARETE PREC
C     ----------------------------------------------------
C     EN 2D LE NOMBRE DE COTE = NOMBRE DE NOEUDS
      NNT = STRNBN(IT,ITRNOE,NBNMAX)
      IF( ISENS .EQ. -1 )J1 = MOD(J1+(NNT-2),NNT)+1
      IT1 = IT
      I1 = J1
      IT2 = ITRTRI((IT1-1)*NBCMAX+J1)
      IF( IT2 .EQ. 0 )GO TO 9999
      IF( IT2 .LT. 0 )IT2 = -IT2
      DO 110 J=1,NBNMAX
        IF( NN(1) .EQ. ITRNOE((IT2-1)*NBNMAX+J))THEN
          I2 = J
          GOTO 9999
        ENDIF
  110 CONTINUE 
C     --- ERREUR ---
      IERR = -1
      CALL DSERRE(1,IERR,'SFRI1D','STRUCTURE INCORRECTE 2')
C
 9999 END
C
      SUBROUTINE SFRI2D(NN,NBNN,
     >                  IDE,ITRNOE,NBNMAX,ITRTRI,NBCMAX,
     >                  NOETRI,NBE,ITVL,NITMAX,
     >                  IT1,IT2,I1,I2,IERR)
C     *************************************************************
C     OBJET SFRI2D : FRONTIERE IDE-1 COMMUNE AUX ELEMENTS
C        RECHERCHE DES TRIANGLES QUI PARTAGENT L'ARETE NN(1..2)
C        
C     EN ENTREE:
C      NN     :  TABLEAU DES SOMMETS DE L'ELEMENT FRONTIERE
C      NBNN   :  NOMBRE DE SOMMETS
C      IDE    :  DIMENSION DES ELEMENTS DU MAILLAGE
C      NBE    :  NOMBRE D'ELEMENTS DU MAILLAGE
C
C     EN SORTIE: 
C      IT1 :  LE TRIANGLE QUI CONTIENT L'ARETE NN(1),NN(2)
C       I1 :  L'INDICE DE L'ARETE DE IT1 EGALE A NN(1),NN(2)
C      IT2 :  LE TRIANGLE QUI CONTIENT L'ARETE NN(2),NN(1)
C       I2 :  L'INDICE DE L'ARETE DE IT2 EGALE A NN(2),NN(1)
C     REMARQUE : 2D SEULEMENT (TRIANGLES, QUADRANGLES, MIXTE)
C                NE PREND PAS EN COMPTE LES FRONTIERES INTERNES
C                SFRI3D POUR LE 3D
C                IL FAUDRAIT AJOUTER UN TABLEAU DE TRAVAIL POUR 
C                AVOIR LA MEME SIGNATURE
C     *************************************************************
      INTEGER   NN(*),NBNN
      INTEGER   IDE,ITRNOE(*),NBNMAX,ITRTRI(*),NBCMAX
      INTEGER   NOETRI(*),NBE,ITVL(*),NITMAX
      INTEGER   IT1,IT2,I1,I2,IERR
C
      INTEGER   J1,J2,ISENS,IT,J,IDEBUT,NNT,ITAMPO
      INTEGER   STRNBN
      EXTERNAL  STRNBN
C     
      IT1 = 0
      IT2 = 0
      I1 = 0
      I2 = 0
      IERR = 0
      IF( IDE.NE.2 )THEN
        IERR = -3
        CALL DSERRE(1,IERR,'SFRI2D',' NE FONCTIONNE PAS EN 3D')
        GOTO 9999
      ENDIF
      ISENS = 1
C     --- BOUCLE SUR LE SENS
   10 CONTINUE
      IDEBUT = NOETRI(NN(1))
      IT = IDEBUT
C     --- NOEUD ISOLE     
      IF( IT.EQ.0 )GOTO 9999
C
C     --- ON RECHERCHE LE PREMIER NOEUD : NN(1) ---
C
   20 CONTINUE
      J1 = 0
      DO 30 J=1,NBNMAX
        IF(ITRNOE((IT-1)*NBNMAX+J) .EQ. NN(1))J1 = J
   30 CONTINUE
C     --- L'ELEMENT NE CONTIENT PAS LE NOEUD / BUG STRUCTURE
      IF(J1.EQ.0)THEN
        IERR = -1
        CALL DSERRE(1,IERR,'SFRI2D','STRUCTURE INCORRECTE')
        GO TO 9999
      ENDIF
C     ----------------------------------------------------
C     SENS DIRECT => ARETE PARTANT DU NOEUD N1 
C     SENS INDIRE => ARETE ARRIVANT AU NOEUD => ARETE PREC
C     ----------------------------------------------------
C     EN 2D LE NOMBRE DE COTE = NOMBRE DE NOEUDS
      NNT = STRNBN(IT,ITRNOE,NBNMAX)
C     --- ON RECHERCHE LE DEUXIEME NOEUD : NN(2) ---
      IF( ISENS .EQ. 1 )THEN
C     --- ARETE PARTANT DU NOEUD N1 =>TEST DU NOEUD EXTREMITE
        J2 = MOD(J1,NNT)+1  
      ELSE
C     --- ARETE ARRIVANT AU NOEUD N1 =>TEST DU NOEUD ORIGINE
        J1 = MOD(J1+(NNT-2),NNT)+1
        J2 = J1
      ENDIF
      IF( NN(2) .EQ. ITRNOE((IT-1)*NBNMAX+J2))THEN
          IT1 = IT
          I1 = J1
          IT2 = ITRTRI((IT1-1)*NBCMAX+J1)
          IF( IT2 .EQ. 0 )THEN
            IF( ISENS.EQ.1 )GOTO 9999
C           --- BUG5 POUR RESPECTER L'ORIENTATION NN(1),NN(2)
            IT2 = IT1
            I2 = I1
            I1 = 0
            IT1 = 0
            GO TO 9999
          ENDIF
          IF( IT2 .LT. 0 )IT2 = -IT2
          DO 210 J=1,NBNMAX
            IF((ISENS.EQ.1).AND.
     >        (NN(2).EQ.ITRNOE((IT2-1)*NBNMAX+J)))THEN
              I2 = J
              GOTO 9999
            ENDIF
C           --- BUG5 POUR RESPECTER L'ORIENTATION NN(1),NN(2)
            IF((ISENS.EQ.-1).AND.
     >        (NN(1).EQ.ITRNOE((IT2-1)*NBNMAX+J)))THEN         
              I2 = J
              ITAMPO = IT1
              IT1 = IT2
              IT2 = ITAMPO
              ITAMPO = I1
              I1 = I2
              I2 = ITAMPO
              GOTO 9999
            ENDIF
  210     CONTINUE
C         --- ERREUR ---
          IERR = -1
          CALL DSERRE(1,IERR,'SFRI2D','STRUCTURE INCORRECTE 3')
          GOTO 9999
      ENDIF
C
C     --- ON PASSE AU TRIANGLE SUIVANT ---
C
      IT = ITRTRI((IT-1)*NBCMAX+J1)
      IF( IT .EQ. 0 )THEN
        IF( ISENS .EQ. 1 )THEN
C     --- ON EST ARRIVE SUR LA FRONTIERE : ON CHANGE DE SENS ---
          ISENS = -1
          GO TO 10
        ELSE 
C     --- ON ARRIVE SUR LA FRONTIERE EN TOURNANT DANS LES 2 SENS ---
          GOTO 9999
        ENDIF
      ELSE 
        IF( IT .LT. 0 )THEN
          IT = -IT
        ENDIF
      ENDIF        
      IF( IT .NE. IDEBUT )THEN
        GO TO 20
      ENDIF
C
 9999 END        
C
      FUNCTION STRNBN(IT,ITRNOE,NBNMAX)
C     *************************************************************
C     OBJET STRNBN : RENVOI LE NOMBRE REEL DE NOEUD DE L'ELEMENT IT
C     *************************************************************
      INTEGER STRNBN
      INTEGER IT,ITRNOE(*),NBNMAX
C
      STRNBN = 0
   10 IF( ITRNOE((IT-1)*NBNMAX + STRNBN + 1).EQ.0 )GO TO 999
      STRNBN = STRNBN + 1
      IF( (STRNBN+1).GT.NBNMAX )GO TO 999
      GO TO 10
  999 END
C
      SUBROUTINE SMADET(IDE,ITRNOE,NBNMAX,ITRTRI,NBCMAX,NBE,NOETRI, 
     >                   NOEMAX,IT1,N,ISOMP,NBSOMP,IERR)
C     *****************************************************************
C     OBJET SMADET : DETRUIT 1 ELEMENTS D'UN MAILLAGE
C     EN ENTREE:
C      IDE    :  (1..3) DIMENSION DES ELEMENTS 
C      ITRNOE:  LES NOEUDS DES ELEMENTS
C      NBNMAX :  (2..8) NOMBRE DE NOEUDS MAXIMUM DES ELEMENTS 
C      ITRTRI:  LES VOISINS DES ELEMENTS
C      NBCMAX :  (2..6) NOMBRE DE COTES MAXIMUM DES ELEMENTS 
C      NBE    :  NOMBRE D'ELEMENTS DU MAILLAGE
C      NOEMAX  MISE A JOUR DE NOETRI SI NON NUL
C      IT1    :  L'ELEMENTS A DETRUIRE
C      N      :  NOMBRE DE NOEUDS DE L'ELEMENT IT1
C     EN SORTIE:
C       ITRNOE: MIS A JOUR
C       ITRTRI: MIS A JOUR 
C       NOETRI : MIS A JOUR
C         IERR : CODE D'ERREUR 0 => OK
C               -1 => DONNEES INCOHERENTES
C     CONDITION D'APPLICATION : TOUT MAILLAGE AVEC UNE RESTRICTION
C       LA DESTRUCTION DE LA MAILLE NE DOIT PAS CREER DE SINGULARITES
C       SUR LA FRONTIERE (SINON NOETRI() N'EST PLUS VALIDE). 
C               
C     *****************************************************************
      INTEGER    IDE,ITRNOE(*),NBNMAX,ITRTRI(*),NBCMAX,NOETRI(*),NBE
      INTEGER    NOEMAX, IT1, N, ISOMP(*), NBSOMP, IERR
C
      INTEGER  I,J,ITR,NBFAC,IFAC(4)
      INTEGER  STRKFS
      EXTERNAL STRKFS
C      
      IERR = 0
      IF((IT1.LT.1).OR.(IT1.GT.NBE))THEN
         IERR = -1
         GO TO 999
      ENDIF
C
C     ---- MISE A JOUR DES NOEUDS FAISANT REFERENCE A IT1 ---
C
      IF( NOEMAX.NE.0 )THEN
        DO 20 I=1,NBNMAX
          IF( NOETRI(ITRNOE((IT1-1)*NBNMAX+I)) .EQ. IT1 )THEN
            NBFAC = STRKFS(IDE,I,N,IFAC)
            DO 5 J=1,NBFAC
               ITR = ITRTRI((IT1-1)*NBCMAX+IFAC(J))
               IF(ITR.NE.0)GO TO 10
    5       CONTINUE
C           --- UN SOMMET EST PERDU ---
            NBSOMP = NBSOMP+1
            ISOMP(NBSOMP) = ITRNOE((IT1-1)*NBNMAX+I)    
   10       NOETRI(ITRNOE((IT1-1)*NBNMAX+I)) = ITR
          ENDIF
   20   CONTINUE
      ENDIF
C      
C     ---- MISE A JOUR DES ELEMENTS VOISINS DE IT1 ---
C
        DO 30 I=1,NBCMAX
          ITR = ITRTRI((IT1-1)*NBCMAX+I)
          IF(ITR.NE.0)THEN
            IF( ITR .LT. 0 )ITR = - ITR
            DO 40 J=1,NBCMAX
             IF((ITRTRI((ITR-1)*NBCMAX+J).EQ.IT1) .OR.
     >          (ITRTRI((ITR-1)*NBCMAX+J).EQ.-IT1) )THEN
               ITRTRI((ITR-1)*NBCMAX+J) = 0
               GO TO 30
             ENDIF
   40       CONTINUE
C         --- IL Y A UN BUG DANS LA STRUCTURE ---
          IERR = -2
          GO TO 999
          ENDIF
   30   CONTINUE
C     ---------- INITIALISATION DE IT1 ----------
      DO 90 I=1,NBCMAX
        ITRTRI((IT1-1)*NBCMAX+I)=0
   90 CONTINUE
      DO 100 I=1,NBNMAX
        ITRNOE((IT1-1)*NBNMAX+I)=0
  100 CONTINUE
C     ------------------
  999 END
C
C     *****************************************************************
C     MODULE  : ST (STRUCTURE DES DONNEES)
C     FICHIER : ST_GENERIC.F
C     OBJET   : CONSULTATION, CONSTRUCTION ET MODIFICATION DE LA 
C               STRUCTURE DE DONNE DU MAILLAGE (1D, 2D, 3D)
C     FONCT.  : 
C       SUR LES MAILLAGES:
C           CONSTRUCTION :
C               SINVOR : INVERSE L'ORIENTATION D'UN ELEMENT
C               SORIEN : ORIENTE UN MAILLAGE
C           PARCOURS     :
C               SFAIDE : RECHERCHE LA FACE COMMUME A 2 ELEMENTS
C        SUR LES MAILLES :
C               STINIT   : INITIALISATION DES STRUCTURES DE DELOS
C               STRNBC   : NOMBRE DE COTE DE L'ELEMENT
C               STRKFS   : K FACES AU SOMMET (INDICE RELATIF)
C               STRKSF   : K SOMMET DE  LA FACE(INDICE RELATIF)
C               STREOF   : ENTITE OPPOSEE A FACE (INDICE RELATIF)
C
C     AUTEUR  : O. STAB
C     DATE    : 03.95
C     TESTS   : O.STAB 03.95
C     MODIFICATIONS :
C      AUTEUR, DATE, OBJET : O.STAB, 07.96, LE 3D (SMACRE,FAIDE,STRKFS)
C      AUTEUR, DATE, OBJET : O.STAB, 10.96, AJOUT DE NBPMAX DANS SMACRE
C      AUTEUR, DATE, OBJET : O.STAB, 04.97, BUG_15 (1D) + NETTOYAGE
C      AUTEUR, DATE, OBJET : O.STAB, 08.98, ISOLE DANS ST_GENERIC
C
C
C     *****************************************************************
C
      SUBROUTINE STINIT
C     *****************************************************************
C     OBJET STINIT : INITIALISATION DES STRUCTURES DE DELOS
C                    SINVOR FONCTION GENERIQUE DES STxINI 
C          STINIT DOIT ETRE APPELE DE LE DEBUT DU PROGRAMME PRINCIPAL
C     *****************************************************************      
      CALL ST3INI
      END
C
      SUBROUTINE STFASU(IDE,NBNE,ISOM,IFAC)
C     ************************************************************
C     OBJET STFASU : FACE SUIVANTE SUR SOMMET(S)
C                    STFASU FONCTION GENERIQUE DES SxFASU 
C     EN ENTREE:
C        ...ISOM : LE SOMMET (2D) OU LES 2 SOMMETS DE L'ARETE (3D)
C     EN SORTIE: 
C           IFAC : L'INDICE DE LA FACE SUIVANTE
C     ************************************************************
      INTEGER   IDE,NBNE,ISOM(*)
      INTEGER   IFAC     
C
      GOTO( 10, 20, 30 ) IDE
C     --- CAS 0D ET 1D :
 10   CONTINUE
      IFAC = -1
      GOTO 9999
C     --- CAS 2D :
 20   CONTINUE
      CALL S2FASU(IDE,NBNE,ISOM,IFAC)
      GOTO 9999
C     --- CAS 3D :
 30   CONTINUE
      CALL S3FASU(IDE,NBNE,ISOM,IFAC)
      GOTO 9999
C
 9999 END
C
C
      SUBROUTINE SINVOR(II, N, IDE, ITRNOE, ITRTRI )
C     ************************************************************
C     OBJET SINVOR : INVERSE L'ORIENTATION D'UN ELEMENT
C                    SINVOR FONCTION GENERIQUE DES SxINVE 
C     EN ENTREE:
C      II     :   (OBSOLET)
C      N      :  (2..4) NOMBRE DE NOEUDS DE L'ELEMENT 
C                 ARETE(2),TRIANGLE(3),QUADR(4),TETRA(4)
C      IDE    :  (1..3) DIMENSION DE L'ELEMENT 
C                 ARETE(1),TRIANGLE(2),TETRA(3)
C      ITRNOE:  LES NOEUDS DU TRIANGLES
C      ITRTRI:  LES VOISINS DU TRIANGLES
C     EN SORTIE: 
C      ITRTRI :  MIS A JOUR
C      ITRNOE :  MIS A JOUR
C     CONDITION D'APPLICATION : ARETE, TRIANGLE, QUADRANGLE, TETRA
C     ************************************************************
      INTEGER   II, N, IDE, ITRNOE(N), ITRTRI(N)
C     
      INTEGER   I, ITRNO1, ITRTR1
C
      GOTO(10,20,30) IDE
      GOTO 999
C     --- CAS 1D ---
   10 ITRNO1   = ITRNOE(1)
      ITRNOE(1) = ITRNOE(2)
      ITRNOE(2) = ITRNO1
      ITRTR1   = ITRTRI(1)
      ITRTRI(1) = ITRTRI(2)
      ITRTRI(2) = ITRTR1 
      GOTO 999
C     --- CAS 2D ---
   20 ITRNO1   = ITRNOE(N)
      ITRNOE(N) = ITRNOE(2)
      ITRNOE(2) = ITRNO1
      DO 25 I=1,(N/2)
        ITRTR1       = ITRTRI(I)
        ITRTRI(I)     = ITRTRI(N-I+1)
        ITRTRI(N-I+1) = ITRTR1
   25 CONTINUE
      GOTO 999            
C     --- CAS 3D ---
   30 CALL S3INVE(N,IDE,ITRNOE,ITRTRI)
      GOTO 999            
C
  999 END
C
      FUNCTION SFAIDE( IT1, IT2, N1, N2, IDE, I1, I2 )
C     *****************************************************************
C     OBJET SFAIDE : RECHERCHE LA FACE COMMUME A 2 ELEMENTS
C             SFAIDE FONCTION GENERIQUE DES SFACxD 
C         RENVOI LES INDICES I1 ET I2 CORRESPONDANTS AUX FRONTIERES
C         COMMUNES DES ELEMETS IT1 ET IT2. 
C     EN ENTREE:
C      IT1,IT2:  LES ELEMENTS A TESTER
C      N1     :  (2..4) NOMBRE DE NOEUDS DE IT1
C      N2     :  (2..4) NOMBRE DE NOEUDS DE IT2
C      IDE    :  (1..3) DIMENSION DES ELEMENTS
C     EN SORTIE: 
C      I1,I2  :  INDICES DES FRONTIERES COMMUNES
C      SFAIDE :  0 SI AUCUNE ARETE COMMUNE
C            -1 SI L'ARETE I1 ET L'ARETE I2 SONT PARCOURUS DANS LE MEME
C               SENS POUR IT1 ET IT2
C             1 SI "  "     "   "         "   "            DANS LE SENS
C               INVERSE
C     CONDITION D'APPLICATION : ARETE, TRIANGLE, QUADRANGLE, TETRA
C     REMARQUE : N'UTILISE PAS LA STRUCTURE DE DONNEES MAILLAGE
C                N'EXPLOITE AUCUNE HYPOTHESE SUR IT1 ET IT2
C     *****************************************************************
      INTEGER SFAIDE
      INTEGER IT1(N1), IT2(N2), N1,N2, IDE, I1, I2
C
      INTEGER I,J 
      EXTERNAL SFAC3D
      INTEGER  SFAC3D
C
      IF( IDE.EQ.2 )THEN
C     -----------------------
C     CAS DES TRIANGLES OU DES QUADRANGLES  
C     ON REALISE N1*N2*2  COMPARAISONS (X,Y) AVEC (A,B) ET (B,A)
C     ------------------------
      DO 10 I=1,N1 
        DO 20 J=1,N2 
          IF ( (IT1(I) .EQ. IT2(J))  .AND.
     >         (IT1(MOD(I,N1)+1) .EQ. IT2(MOD(J,N2)+1)) ) THEN
              I1 = I
              I2 = J
              SFAIDE = -1
              GOTO 999
          ENDIF
          IF( (IT1(I) .EQ. IT2(MOD(J,N2)+1))  .AND.
     >        (IT1(MOD(I,N1)+1) .EQ. IT2(J)) ) THEN
              I1 = I
              I2 = J
              SFAIDE = 1
              GOTO 999
          ENDIF    
   20   CONTINUE
   10 CONTINUE
      ELSE 
      IF( IDE.EQ.1)THEN
C     ------------------------
C     CAS DES ARETES : ON REALISE 4 COMPARAISONS (N1=N2=2)
C     ------------------------
      DO 30 I=1,N1 
        DO 40 J=1,N2
          IF (IT1(I) .EQ. IT2(J)) THEN
              I1 = I
              I2 = J
              IF( I.EQ.J )THEN
                   SFAIDE = -1
                ELSE 
                   SFAIDE = 1
              ENDIF
              GOTO 999
          ENDIF
   40   CONTINUE
   30 CONTINUE
      ELSE 
      IF( IDE .EQ. 3 )THEN
C     ----------------------------
C     CAS DES TETRAEDRES : ON REALISE 4*4*6 = 96 COMPARAISONS
C     ----------------------------
        SFAIDE = SFAC3D( IT1, IT2, N1, N2, IDE, I1, I2 )
        GOTO 999
      ENDIF 
      ENDIF
      ENDIF        
      SFAIDE = 0         
  999 END                  
C

      FUNCTION STRNBC(N,IDE)
C     *************************************************************
C     OBJET STRNBC : NOMBRE DE FACES D'UN ELEMENT DE N NOEUDS
C             STRNBC FONCTION GENERIQUE DES SxNBCO 
C
C     *************************************************************
      INTEGER STRNBC
      INTEGER N,IDE
C
      INTEGER  S3NBCO
      EXTERNAL S3NBCO
C
      IF( IDE .EQ. 3 )THEN
        STRNBC = S3NBCO(N,IDE)
      ELSE
        STRNBC = N
      ENDIF
      END
C
      FUNCTION STRKFS(IDE,I,N,IFAC)
C     ************************************************************
C     OBJET STRKFS : INDICES DES FACES INCIDENTES AU SOMMET I 
C             STRKFS FONCTION GENERIQUE DES SxSOFA 
C     EN ENTREE:
C      I      :  L'INDICE DU SOMMET DE L'ELEMENT
C      N      :  (4) NOMBRE DE NOEUD DE L'ELEMENT 
C                 TETRA(4),PYRAM(5),PRISME(6),HEXA(8)
C     EN SORTIE: 
C      IFAC  :  INDICE DES FACES INCIDENTES AU NOEUD 
C     CONDITION D'APPLICATION : TETRAEDRE SEULEMENT
C     ************************************************************
      INTEGER STRKFS
      INTEGER IDE, I, N, IFAC(*)
C     
      INTEGER  S3SOFA
      EXTERNAL S3SOFA
C
      GOTO (10,20,30 ) IDE
C     ---- CAS 1D --------
C     LA FACE DE L'ELEMENT EST LE SOMMET LUI MEME
   10 IFAC(1) = I
      STRKFS  = 1
      GOTO 999
C     ---- CAS 2D --------
   20 IF(I.EQ.1)THEN 
        IFAC(1) = N
      ELSE
        IFAC(1) = I-1
      ENDIF
      IFAC(2) = I
      STRKFS = 2
      GOTO 999
C     ---- CAS 3D -------- 
   30 STRKFS = S3SOFA(IDE,I,N,IFAC)
      GOTO 999
C
  999 END
C
      FUNCTION STRKSF(IDE,N,INDIC,IFAC)
C     ************************************************************
C     OBJET STRKSF : INDICES DES SOMMETS DE LA FACE I (SENS DIRECT)
C             STRKSF FONCTION GENERIQUE DES SxFASO 
C     EN ENTREE:
C      INDIC     :  L'INDICE DE LA FACE DE L'ELEMENT
C      N      :  (4) NOMBRE DE NOEUDS DE L'ELEMENT 
C                 TETRA(4),PYRAM(5),PRISME(6),HEXA(8)
C     EN SORTIE: 
C      IFAC  :  INDICE DES SOMMETS DE LA FACE 
C     CONDITION D'APPLICATION : TETRAEDRE SEULEMENT
C     ************************************************************
      INTEGER STRKSF
      INTEGER IDE, INDIC, N, IFAC(*)      
C
       INTEGER NBNF,K
       INTEGER  S3FASO
       EXTERNAL S3FASO
C
      IF( (IDE.EQ.2) .OR. (IDE.EQ.1) )THEN
C     -------------------------------------
C     --- CAS 1D, 2D ----------------------
C     --- NBR DE NOEUDS = NBRE DE COTES ---
C     -------------------------------------
        DO 30 K=1,IDE 
         IFAC(K) = MOD(INDIC+K-2,N)+1
   30   CONTINUE    
      STRKSF = IDE
      ELSE 
      IF( IDE .EQ. 3 )THEN
C     ----------------------------------------------------
C     --- CAS 3D : NOMBRE DE COTES REELS DE L'ELEMENTS ---
C     ---          NOMBRE DE NOEUDS DE LA FACE J       ---
C     ----------------------------------------------------
        NBNF = S3FASO(IDE,N,INDIC,IFAC)
        STRKSF = NBNF
      ELSE 
        STRKSF = 0
      ENDIF
      ENDIF
      END
C
      FUNCTION STREOF(IDE,N,IFE)
C     ************************************************************
C     OBJET STREOF : INDICE DE L'ENTITE OPPOSEE A FACE IFE
C             STREOF FONCTION GENERIQUE DES SxOPFA 
C     EN ENTREE:
C      IFE     :  L'INDICE DE LA FACE DE L'ELEMENT
C      N      :  (4) NOMBRE DE NOEUD DE L'ELEMENT 
C                 TETRA(4),PYRAM(5),PRISME(6),HEXA(8)
C     EN SORTIE: 
C         POUR LES TETRAEDRES ET TRIANGLE : INDICE DU NOEUD OPPOSE
C         POUR LES QUADRANGLES : ARETE OPPOSEE
C     CONDITION D'APPLICATION : TETRAEDRE ET TRIANGLE SEULEMENT
C     ************************************************************
      INTEGER STREOF
      INTEGER IDE, N, IFE
C     
      INTEGER  S3OPFA
      EXTERNAL S3OPFA
C
      IF( IDE .EQ. 3 )THEN
        STREOF = S3OPFA(IDE,N,IFE)
        GOTO 999
      ENDIF         
      IF(IDE.EQ.1)THEN
        STREOF = MOD(IFE,N)+1
        GOTO 999
      ENDIF
      IF(IDE.EQ.2)THEN
C     --- TRI OU QUAD ---
        STREOF = MOD(IFE+1,N)+1
        GOTO 999
       ENDIF
       STREOF = 0
  999 END
C     *****************************************************************
C     MODULE  : ST (STRUCTURE DES DONNEES)
C     FICHIER : ST_1STRUCT.F
C     OBJET   : FONCTIONS PRATIQUES POUR LA CREATION DE MAILLAGES 
C
C     FONCT.  : 
C       SMAOCR  : CREER LA STRUCTURE DE DONNEE MAILLAGE ORIENTEE
C                   (CAS DE PLUSIEURS COMPOSANTES CONNEXES)
C       SFRCRE : CREER LE MAILLAGE FRONTIERE D'UN ENSEMBLE DE 
C                   MAILLES
C
C     AUTEUR  : O. STAB
C     DATE    : 03.95
C     MODIFICATIONS :
C      AUTEUR, DATE, OBJET : O.STAB, 19.01.99 BUG APPEL SINVOR
C
C
C     *****************************************************************
C
C
      SUBROUTINE SMAOCR(IDE,ITRI,NBE,COORD,NCOORD,IDIMC,
     >                   ITRNOE,NBNMAX,ITRTRI,NBCMAX,NOETRI,NOEMAX,
     >                   ITVL,NBTRAV,NCC,IERR)
C     *****************************************************************
C     OBJET : CREER LA STRUCTURE DE DONNEE MAILLAGE ORIENTEE
C                   (CAS DE PLUSIEURS COMPOSANTES CONNEXES)
C             ITRI -> ITRNOE, ITRTRI, NOETRI
C     EN ENTREE:
C      IDE    :  (1..3) DIMENSION DES ELEMENTS 
C      NBE    :  NOMBRE D'ELEMENTS DU MAILLAGE
C      ITRI   :  ITRI(I,J) EST LE NOEUD J DE L'ELEMENT I
C      NBNMAX :  (2..8) NOMBRE DE NOEUDS MAXIMUM DES ELEMENTS 
C      NBCMAX :  (2..6) NOMBRE DE COTES MAXIMUM DES ELEMENTS 
C      NOEMAX:   TAILLE DU TABLEAU NOETRI
C     EN SORTIE:
C       ITRNOE: ITRNOE(I,J) EST LE NOEUD J DU TRIANGLE I
C                PEUT ETRE LE MEME TABLEAU QUE ITRI
C       ITRTRI: ITRTRI(I,J) EST L'ELEMENT INCIDENT A L'ELEMENT I SUR 
C                LE COTE J
C       NOETRI : NOETRI(I) EST UN DES ELEMENTS CONTENANT LE NOEUD I
C                AU MIN = (NBCMAX+1)*NBE 
C                AU MAX = MAX((NBCMAX+1)*NBE ,
C                             (NBR MAX D'ELEMENTS EN 1 NOEUD + 1) *
C                             (NUMERO MAXI DU NOEUD DANS ITRI))
C                         => O(N)
C       IERR   : CODE D'ERREUR 0 => OK
C                -2 => LE TABLEAU ITVL EST TROP PETIT 
C                -NB => TABLEAU NOETRI TROP PETIT TAILLE SOUHAITE = NB
C     CONDITION D'APPLICATION : ARETE, TRIANGLE, QUADRANGLE, TETRA      
C     *****************************************************************
      INTEGER   IDE,ITRI(*),NBE
      REAL      COORD(*)
      INTEGER   NCOORD,IDIMC,ITRNOE(*),NBNMAX,ITRTRI(*),NBCMAX
      INTEGER   NOETRI(*), NOEMAX, ITVL(*), NBTRAV
      INTEGER   NCC,IERR
C
      INTEGER  STRNBN, GORIEN
      EXTERNAL STRNBN, GORIEN
      INTEGER  ITRAM,ITRAP,N,INDC,I,K,NBTRIP(100),IND,IEC
      REAL     ZERO
C
      ZERO = 0.0
      CALL SMACRE(IDE,ITRI,NBE,NCOORD,ITRNOE,NBNMAX,ITRTRI,NBCMAX,
     >                   NOETRI,NOEMAX,ITVL,NBTRAV,IERR)
C
      IF( IERR.LT.0 )THEN
        CALL DSERRE(1,IERR,'SMAOCR ',' APPEL SMACRE ')
        GO TO 999
      ENDIF
      ITRAM = NBTRAV - NBE
      CALL SORIEN(IDE,ITRNOE,NBNMAX,ITRTRI,NBCMAX,NBE,
     >                  ITVL,ITRAM,ITVL(ITRAM),NCC,IERR)
      IF(( IERR.LT.0 ).OR.( NCC.LE.0 ))THEN
        CALL DSERRE(1,IERR,'SMAOCR ',' APPEL SORIEN ')
        GO TO 999
      ENDIF
      IF( IDE.LT.IDIMC )GO TO 999
C
C    --- ORIENTATION GEOMETRIQUE IDENTIQUE POUR CHAQUE CC
C        N'A DE SENS QUE SI LA DIMENSION DES ELEMENTS EST
C        IDENTIQUE A LA DIMENSION DE L'ESPACE
C
      IF( NCC.EQ.1 )THEN
C
C     --- UNE SEULE COMPOSANTE CONNEXE -----------------
C
        N = STRNBN(1,ITRNOE,NBNMAX)
C        IF( GORIEN(ITRNOE(1),N,COORD,IDIMC,ZERO).EQ.-1)THEN
C        O.STAB 12.97 AJOUT DE IDE DANS LES PARAMETRES DE GORIEN
        IF( GORIEN(ITRNOE(1),N,IDE,COORD,IDIMC,ZERO).EQ.-1)THEN
          DO 30 I=1,NBE
            N = STRNBN(I,ITRNOE,NBNMAX)
C            CALL SINVOR(N,IDE,ITRNOE((I-1)*NBNMAX+1),
C           BUG 19.01.99 O.STAB : PREMIER PARAMETRE (OUBLIE) INUTILISE
            CALL SINVOR(1,N,IDE,ITRNOE((I-1)*NBNMAX+1),
     >                        ITRTRI((I-1)*NBCMAX+1))
   30     CONTINUE
        ENDIF
      ELSE
C
C     --- PLUSIEURS COMPOSANTES CONNEXES ---------------
C
        ITRAP = NBTRAV - NBE
        ITRAM = ITRAP - NBE
        IND = 1
C
C       BUG3 O.STAB 03.08.95 NOMBRE DE PARAMETRES INCORRECT
C
        CALL TMAPAR(IDE,ITRTRI,NBCMAX,IND,NBE,
     >                ITVL,ITVL(ITRAM),ITRAM,
     >                ITVL(ITRAP),NBTRIP,NCC,100,IERR) 
        IF( IERR.LT.0 )THEN
          CALL DSERRE(1,IERR,'SMAOCR ',' APPEL TMAPAR ')
          GO TO 999
        ENDIF
        INDC = 1
        DO 50 I=1,NCC        
          N = STRNBN(ITVL(ITRAP+INDC),ITRNOE,NBNMAX)
C          IF( GORIEN(ITRNOE(INDC),N,COORD,IDIMC,ZERO).EQ.-1)THEN
C        O.STAB 12.97 AJOUT DE IDE DANS LES PARAMETRES DE GORIEN
          IF( GORIEN(ITRNOE(INDC),N,IDE,COORD,IDIMC,ZERO).EQ.-1)THEN
            DO 40 K=0,(NBTRIP(I)-1)
              IEC = ITVL(ITRAP+INDC+K)
              N = STRNBN(IEC,ITRNOE,NBNMAX)
C
C       BUG4 O.STAB 15.09.95 : NUMERO RELATIF DU COTE (SINVOR)
C
C              CALL SINVOR(ITVL(ITRAP+INDC+K),N,IDE,ITRNOE,
C     >             ITRTRI)
C     REMPLACER PAR :
C
              CALL SINVOR(1,N,IDE,ITRNOE((IEC-1)*NBNMAX+1),
     >             ITRTRI((IEC-1)*NBCMAX+1))
   40       CONTINUE
          ENDIF
   50   CONTINUE
      ENDIF
  999 END     
C
C
      SUBROUTINE SFRCRE(IDE,IFR,NBIFR,ITRNOE,NBNMAX,
     >                    ITVL,NTRMAX,
     >                    LTRNOE,NNFMAX,LTRTRI,NCFMAX,NBF,
     >                    LNOETR,NBFNOE,NCC,IERR)
C     *****************************************************************
C     OBJET : CREER LE MAILLAGE FRONTIERE D'UN ENSEMBLE DE MAILLES
C              
C     EN ENTREE: 
C      IFR    :  IFR((I-1)*2+1) DONNE LE NUMERO DU IEME ELEMENT QUI A 
C                UNE FACE SUR LA FRONTIERE
C                IFR((I-1)*2+2) DONNE LE NUMERO RELATIF DE LA FACE DU
C                IEME ELEMENT
C      NBIFR  :  NOMBRE D'ELEMENT DE LA FRONTIERE
C
C      IDE    :  (1..3) DIMENSION DES ELEMENTS 
C      NBNMAX :  (2..8) NOMBRE DE NOEUDS MAXIMUM DES ELEMENTS 
C      ITRNOE: ITRNOE(I,J) EST LE NOEUD J DE L'ELEMENT I
C      ITVL: TABLEAU DE TRAVAIL        
C      NTRMAX: TAILLE DU TABLEAU DE TRAVAIL 
C               SI IFR FORME 1 SEULE COMPOSANTE CONNEXE
C               AU MINIMUM    = 2*((NBIFR*(NBCMAX-2))+2*NBCMAX)
C               2D TRIANGLES  = 2 * NBIFR + 12
C               QUAD OU TETRA = 4 * NBIFR + 16
C               AU MAX = (NBR MAX D'ELEMENTS EN 1 NOEUD + 1) *
C                         NUMERO MAXI DU NOEUD DANS IFR
C
C      NNFMAX : NOMBRE MAXIMUM DE NOEUD SUR UNE FACE DE LA FRONTIERE
C      NCFMAX : NOMBRE MAXIMUM DE COTE D'UNE FACE DE LA FRONTIERE
C      NBFNOE  : TAILLE DU TABLEAU LNOETR
C                SI NBFNOE = 0 LNOETR NE SERA PAS REMPLI
C
C     EN SORTIE: LE MAILLAGE DE LA FRONTIERE ET SES CARACTERISTIQUES
C        LTRNOE: 
C        LTRTRI:
C        LNOETR:
C        NBF    : NOMBRE DE FACES DE LA FRONTIERE
C        NCC    : NOMBRE DE COMPOSANTES CONNEXES
C        IERR   : CODE D'ERREUR 
C                  0 SI OK
C                 -1 SI LES DONNEES SONT ERRONEES
C                 -2 SI ITVL TROP PETIT
C
C     NIVEAU : INTERFACE UTILISATEUR
C     *****************************************************************
      INTEGER   IDE,IFR(*),NBIFR,ITRNOE(*),NBNMAX
      INTEGER   ITVL(*),NTRMAX
      INTEGER   LTRNOE(*),NNFMAX,LTRTRI(*),NCFMAX,NBF
      INTEGER   LNOETR(*),NBFNOE,NCC,IERR
C
      INTEGER I,J,IDEF
      INTEGER ITRAV,ITRAM,NBTRAV
C
C     NOEUDS DE LA FRONTIERE
C     ----------------------
C
      IF( (NCFMAX * NBIFR).GT.NTRMAX )THEN
         IERR = -2
         GO TO 999
      ENDIF 
C
      DO 10 I=1,NBIFR
        CALL TNOFRT(IDE,ITRNOE,NBNMAX,IFR((I-1)*2+1),
     >             IFR((I-1)*2+2),ITVL((I-1)*NCFMAX+1))
   10 CONTINUE
      NBF = NBIFR
C      PRINT *,' FRONTIERE '
C      PRINT *,' ',((ITVL((I-1)*NCFMAX+J),J=1,NCFMAX),I=1,NBF)
C
C     CONSTRUCTION DU MAILLAGE FRONTIERE
C     ----------------------------------
      IDEF = IDE - 1
C     --- ALLOCATION DES TABLEAUX : ITRAV,ITRAM,ITRAP ----
C     TOPOFRTM OCCUPE ITVL DE 1 - NBF*NCFMAX
C     ITRAM DOIT AVOIR LA TAILLE DE NBF
C     NBTRAV PEUT VARIER DE 0 A (NCFMAX + 1) * NBF 
C     -------------------------------------------------   
      IF( NTRMAX .LT. (NBF * (NCFMAX+1)) )THEN
        IERR = -2
        GO TO 999
      ENDIF
C
      ITRAV  = (NBF * NCFMAX ) + 1
      NBTRAV = NTRMAX -  ( NBF * NCFMAX )
C
      IF( NBTRAV.LT. 0 )THEN
         IERR = -2
         GO TO 999
      ENDIF 
C
      CALL SMACRE(IDEF,ITVL,NBF,0,LTRNOE,NNFMAX,
     >             LTRTRI,NCFMAX,LNOETR,NBFNOE,
     >             ITVL(ITRAV),NBTRAV,IERR)
C
C      PRINT *,' MAILLAGE FRONTIERE '
C      PRINT *,' ',((LTRNOE((I-1)*NNFMAX+J),J=1,NNFMAX),I=1,NBF)
C      PRINT *,' ',((LTRTRI((I-1)*NCFMAX+J),J=1,NCFMAX),I=1,NBF)
C
      IF( IERR .NE. 0 )THEN
        CALL DSERRE(1,IERR,'SFRCRE',' APPEL SMACRE ')
        GO TO 999
      ENDIF
C
      ITRAM  = 1
      ITRAV  = NBF + 1
      NBTRAV = NTRMAX -  NBF
      CALL SORIEN(IDEF,LTRNOE,NNFMAX,LTRTRI,NCFMAX,NBF,
     >              ITVL(ITRAV),NBTRAV,ITVL(ITRAM),NCC,IERR)
      IF( IERR .NE. 0 )THEN
        CALL DSERRE(1,IERR,'SFRCRE',' APPEL SORIEN ')
        GO TO 999
      ENDIF
C
  999 END
C  
            
    
C     *****************************************************************
C     MODULE  : ST (STRUCTURE DES DONNEES)
C     FICHIER : ST_TOPOLOGIE.F
C     OBJET   : FONCTIONS TOPOLOGIQUES SUR LE MAILLAGE
C     FONCT.  :
C         TMAFRT   : CALCULE LA FRONTIERE D'UN ENSEMBLE DE MAILLES 
C                    CONSECUTIVES DANS LE MAILLAGE 
C         TNOFRT   : RENVOI LES NOEUDS DE LA FRONTIERE D'UN ELEMENT
C         TNOFRM   : CALCUL LES NOEUDS DE LA FRONTIERE D'UN ENSEMBLE 
C                    DE MAILLES CONSECUTIVES DANS LE MAILLAGE 
C         TMA1CC   : CALCUL DES ELEMENTS CONNEXE AVEC 1 ELEMENT DONNE
C         TMAPAR   : PARTITIONNE UN MAILLAGE EN COMPOSANTES
C                    CONNEXES ET MATERIAUX
C     AUTEUR  : O. STAB
C     DATE    : 03.95
C     TESTS   : O.STAB 03.95
C     MODIFICATIONS :
C      AUTEUR, DATE, OBJET :
C
C
C     *****************************************************************
C
C
      SUBROUTINE TMAFRT(IDE,ITRNOE,NBNMAX,ITRTRI,NBCMAX,IND,NBE,
     >                   IFAC,NBFAC,NFAMAX,IERR)
C     **************************************************************
C     OBJET :  
C        CALCULE LA FRONTIERE D'UN ENSEMBLE DE MAILLES CONSECUTIVES
C        DANS LE MAILLAGE 
C     EN ENTREE:
C      IDE    :  (1..3) DIMENSION DES ELEMENTS 
C      ITRNOE :  LES NOEUDS DES ELEMENTS
C      NBNMAX :  (2..8) NOMBRE DE NOEUDS MAXIMUM DES ELEMENTS 
C      ITRTRI :  LES VOISINS DES ELEMENTS
C      NBCMAX :  (2..6) NOMBRE DE COTES MAXIMUM DES ELEMENTS 
C      IND    :  INDICE DU PREMIER ELEMENT DE L'ENSEMBLE
C      NBE    :  NOMBRE D'ELEMENTS DE L'ENSEMBLE
C      NFAMAX :  NOMBRE MAXIMUM D'ELEMENTS FRONTIERE
C
C     EN SORTIE: 
C      IFAC  :  LISTE DES FACES DE LA FRONTIERE 
C               NUMERO D'ELEMENT,INDICE DE LA FACE POUR L'ELEMENT
C               L'INDICE EST POSITIF SI LA FRONTIERE EST REELLE
C               L'INDICE EST NEGATIF SI C'EST UNE FRONTIERE INTERIEURE
C               EN ABSOLU 0 < | INDICE | < NBCMAX+1
C      NBFAC :  NOMBRE D'ELEMENTS DE LA FRONTIERE
C      IERR  :  CODE D'ERREUR 0 => OK, -2 => NCFMAX TROP PETIT
C     CONDITION D'APPLICATION : MAILLAGE MIXTE 1D,2D ET 
C                               ET TETRAEDRES
C     ************************************************************
      INTEGER    IDE,ITRNOE(*),NBNMAX,ITRTRI(*),NBCMAX,IND,NBE
      INTEGER    IFAC(*),NBFAC,NFAMAX,IERR
C
      INTEGER    I,J,INDF,NBRN,NBC 
      EXTERNAL   STRNBN,STRNBC
      INTEGER    STRNBN,STRNBC
C
      IERR = 0
      NBFAC = 0
      INDF = (NBE-IND)+1
      DO 20 I=IND,INDF
        DO 10 J=1,NBCMAX
          IF(( ITRTRI((I-1)*NBCMAX+J) .LE. 0 ).OR.
     >       ( ITRTRI((I-1)*NBCMAX+J) .GT. INDF ))THEN 
             NBRN = STRNBN(I,ITRNOE,NBNMAX)   
             NBC  = STRNBC(NBRN,IDE)
             IF(NBC.LT.J)GO TO 20
             NBFAC = NBFAC + 1
             IF(NBFAC.GT.NFAMAX)THEN
               IERR = -2
               GO TO 999
             ENDIF
             IFAC((NBFAC-1)*2+1) = I
             IFAC((NBFAC-1)*2+2) = J
C            --- POUR LES FRONTIERES INTERIEURES ---
             IF(ITRTRI((I-1)*NBCMAX+J).LT.0)
     >          IFAC((NBFAC-1)*2+2) = -J
          ENDIF
   10   CONTINUE
   20 CONTINUE
  999 END
C
      SUBROUTINE TNOFRT(IDE,ITRNOE,NBNMAX,IT,IFAC,IFR)
C     **************************************************************
C     OBJET :  
C        RENVOI LES NOEUDS DE LA FRONTIERE D'UN ELEMENT
C     EN ENTREE:
C      IDE    :  (1..3) DIMENSION DES ELEMENTS 
C      ITRNOE:  LES NOEUDS DES ELEMENTS
C      NBNMAX :  (2..8) NOMBRE DE NOEUDS MAXIMUM DES ELEMENTS 
C      IT     :  INDICE DE L'ELEMENT
C      IFAC   :  INDICE DE LA FACE
C
C      NCFMAX:  NOMBRE MAXIMUM DE SOMMETS DES ELEMENTS FRONTIERE
C                =IDE SAUF EN 3D POUR LES PRISMES,PYRAMIDES,HEXA
C     EN SORTIE: 
C      IFR   :  LISTE DES NOEUDS DE LA FRONTIERE
C      IERR  :  CODE D'ERREUR 0 => OK, -2 => NCFMAX TROP PETIT
C     CONDITION D'APPLICATION : MAILLAGE MIXTE 1D,2D ET 
C                               ET TETRAEDRES
C     ************************************************************
      INTEGER    IDE,ITRNOE(*),NBNMAX,IT,IFAC,IFR(*),NBIFR
C
      INTEGER    K,NBRN,NBNF,INDNF(4) 
      EXTERNAL   STRKSF, STRNBN
      INTEGER    STRKSF, STRNBN
C
      INTEGER IT1
C
      IT1 = IT 
      NBRN = STRNBN(IT1,ITRNOE,NBNMAX)
      NBNF = STRKSF(IDE,NBRN,ABS(IFAC),INDNF) 
      DO 10 K=1,NBNF
        IFR(K) = ITRNOE((IT1-1)*NBNMAX+INDNF(K)) 
   10 CONTINUE 
      NBIFR = NBNF   
  999 END
C
C
      SUBROUTINE TNOFRM(IDE,ITRNOE,NBNMAX,ITRTRI,NBCMAX,IND,NBE,
     >                    IFR,NBIFR,NFRMAX,NCFMAX,IERR)
C     **************************************************************
C     OBJET :  
C        CALCULE LES NOEUDS DE LA FRONTIERE D'UN ENSEMBLE DE MAILLES 
C        CONSECUTIVES DANS LE MAILLAGE 
C     EN ENTREE:
C      IDE    :  (1..3) DIMENSION DES ELEMENTS 
C      ITRNOE:  LES NOEUDS DES ELEMENTS
C      NBNMAX :  (2..8) NOMBRE DE NOEUDS MAXIMUM DES ELEMENTS 
C      ITRTRI:  LES VOISINS DES ELEMENTS
C      NBCMAX :  (2..6) NOMBRE DE COTES MAXIMUM DES ELEMENTS 
C      IND    :  INDICE DU PREMIER ELEMENT DE L'ENSEMBLE
C      NBE    :  NOMBRE D'ELEMENTS DE L'ENSEMBLE
C      NCFMAX:  NOMBRE MAXIMUM DE SOMMETS DES ELEMENTS FRONTIERE
C                =IDE SAUF EN 3D POUR LES PRISMES,PYRAMIDES,HEXA
C     EN SORTIE: 
C      IFR   :  LISTE DES ELEMENTS DE LA FRONTIERE
C      NBIFR :  NOMBRE D'ELEMENTS DE LA FRONTIERE
C      IERR  :  CODE D'ERREUR 0 => OK, -2 => NCFMAX TROP PETIT
C     CONDITION D'APPLICATION : MAILLAGE MIXTE 1D,2D ET 
C                               ET TETRAEDRES
C     ************************************************************
      INTEGER    IDE,ITRNOE(*),NBNMAX,ITRTRI(*),NBCMAX,IND,NBE
      INTEGER    IFR(*),NBIFR,NFRMAX,NCFMAX,IERR
C
      INTEGER    I,J,K,INDF,NBRN, NBNF,NBC,INDNF(4) 
      EXTERNAL   STRNBN,STRNBC,STRKSF
      INTEGER    STRNBN,STRNBC,STRKSF
C
      IERR = 0
      IF((IDE.LT. 3).AND.(IDE .GT. NCFMAX))THEN
        IERR = -2
        GO TO 999
      ENDIF
C
      NBIFR = 0
      INDF = (NBE-IND)+1
      DO 30 I=IND,INDF
        DO 20 J=1,NBCMAX
          IF(( ITRTRI((I-1)*NBCMAX+J) .LE. 0 ).OR.
     >       ( ITRTRI((I-1)*NBCMAX+J) .GT. INDF ))THEN 
             NBRN = STRNBN(I,ITRNOE,NBNMAX)   
             NBC  = STRNBC(NBRN,IDE)
             IF(NBC.LT.J)GO TO 30
             NBIFR = NBIFR + 1
             IF(NBIFR.GT.NFRMAX)THEN
               IERR = -2
               GO TO 999
             ENDIF
C            --- RECOPIE DES NOEUDS ---
             NBNF = STRKSF(IDE,NBRN,J,INDNF)  
             IF( NBNF .GT. NCFMAX )THEN
              IERR = -2
              GO TO 999
             ENDIF                      
             DO 10 K=1,NBNF
               IFR((NBIFR-1)*NCFMAX+K) = 
     >           ITRNOE((I-1)*NBNMAX+INDNF(K)) 
   10       CONTINUE    
          ENDIF
   20   CONTINUE
   30 CONTINUE
  999 END
C
C
C
      SUBROUTINE TMA1CC(IDE,ITRTRI,NBCMAX,IND,NBE,
     >                  IT,ITVL,ITRAMA,NBITL,ICON,NBICON,IERR)
C     **************************************************************
C     OBJET :  
C        CALCUL DES ELEMENTS APPARTENANT A UN ENSEMBLE
C        DE MAILLES CONSECUTIVES ET CONNEXE AVEC 1 ELEMENT DONNE
C     EN ENTREE:
C      IDE    :  (1..3) DIMENSION DES ELEMENTS 
C      ITRTRI:  LES VOISINS DES ELEMENTS
C      NBCMAX :  (2..6) NOMBRE DE COTES MAXIMUM DES ELEMENTS 
C      IND    :  INDICE DU PREMIER ELEMENT DE L'ENSEMBLE
C      NBE    :  NOMBRE D'ELEMENTS DE L'ENSEMBLE
C      IT     :  L'ELEMENT DE DEPART
C      ITVL,NBITL : TABLEAU DE TRAVAIL NBITL < N*NBE
C      ITRAMA        : "    "   "    "  DE TAILLE = NBE
C     EN SORTIE: 
C      ICON   :  LISTE DES ELEMENTS CONNEXES AVEC IT
C      NBICON :  NBRE D'ELEMENTS DE ICON
C      IERR   :  CODE D'ERREUR 0 => OK, -2 => ITVL TROP PETIT
C     CONDITION D'APPLICATION : MAILLAGE MIXTE 1D,2D ET 
C                               ET TETRAEDRES
C     ATTENTION : ITRAMA DOIT ETRE INITIALISE 
C         NORMALEMENT ITRAMA(0..NBE) = 0 
C         SI ITRAMA(I)=1 ON CONSIDERE QUE L'ELEMENT I EST BLOQUANT
C         IT EST MIS DANS LA COMPOSANTE CONNEXE
C     ************************************************************
      INTEGER    IDE,ITRTRI(*),NBCMAX,IND,NBE
      INTEGER    IT,ITRAMA(*),ITVL(*),NBITL,ICON(*),NBICON,IERR
C
      INTEGER    I,J, NBTRA, ITT
C
      ITVL(1) = IT
      ITRAMA(IT) = 1
      NBTRA = 1
      IERR = 0
C
C     ON BOUCLE TANTQUE ITVL N'EST PAS VIDE
C     ----------------------------------------
  310 J     = ITVL(NBTRA)
      NBTRA  = NBTRA-1  
      NBICON = NBICON+1
      ICON(NBICON) = J
C     ON MET LES VOISINS A TRAITER DANS ITVL
C     ------------------------------------------
      DO 350 I=1,NBCMAX 
        ITT = ITRTRI(((J-1)*NBCMAX)+I)
C        IF((ITT.GT.IND).AND.(ITRAMA(ITT).NE.1))THEN
C       BUG2 O.STAB 03.08.95
        IF((ITT.GE.IND).AND.(ITRAMA(ITT).EQ.0))THEN
            NBTRA = NBTRA + 1
            IF( NBTRA .GT. NBITL )THEN
              IERR = -2
              GO TO 999
            ENDIF
C
            ITVL(NBTRA) = ITT
            ITRAMA(ITT) = 1
        ENDIF
  350 CONTINUE
      IF( NBTRA .NE. 0 )GO TO 310
  999 END
C
C
C
      SUBROUTINE TMAPAR(IDE,ITRTRI,NBCMAX,IND,NBE,
     >                   ITVL,ITRAMA,NBIT1,
     >                   ITRPAR,NBTRIP,NBPART,NPARMX,IERR)      
C     **************************************************************
C     OBJET : PARTITIONNE UN MAILLAGE EN FONCTION DES COMPOSANTES
C             CONNEXES ET DES MATERIAUX
C     EN ENTREE:
C      IDE    :  (1..3) DIMENSION DES ELEMENTS 
C      ITRTRI:  LES VOISINS DES ELEMENTS
C      NBCMAX :  (2..6) NOMBRE DE COTES MAXIMUM DES ELEMENTS 
C      IND    :  INDICE DU PREMIER ELEMENT DE L'ENSEMBLE
C      NBE    :  NOMBRE D'ELEMENTS DE L'ENSEMBLE
C      ITVL,NBITL : TABLEAU DE TRAVAIL NBITL < NBCMAX*NBE
C      ITRAMA        : "    "   "    "  DE TAILLE = NBE
C     EN SORTIE :
C       NBPAR  : NOMBRE DE MATERIAUX
C       NBTRIP : NBTRIP(I) DONNE LE NOMBRE DE TRIANGLE DU MATERIAU I
C       ITRPAR: TABLEAU DES TRIANGLES TRIES EN FONCTION DU MATERIAU
C                LES TRIANGLES DU MATERIAU I SONT ENTRE :
C                  ITRPAR(NBTRIP(I-1)+1) ET ITRPAR(NBTRIP(I))
C       IERR   :  CODE D'ERREUR 0 => OK, -2 => ITVL TROP PETIT
C     ***************************************************************
      INTEGER   IDE,ITRTRI(*),NBCMAX,IND,NBE
      INTEGER   ITRPAR(*), NBTRIP(*),NBPART,NPARMX,IERR
      INTEGER   ITRAMA(*), ITVL(*), NBIT1
C
      INTEGER   I, IT, INDICE, NBTT, INDF
C
C     INITIALISATION
C     --------------
      NBPART = 0
      IERR = 0
      NBTT = 0
      INDF = (NBE-IND)+1
      DO 10 I=IND,INDF
        ITRAMA(I) = 0
   10 CONTINUE
      NBTT=0
      IT = IND
   20 IF( NBTT .EQ. NBE )GOTO 888
   30 IF( ITRAMA(IT) .NE. 0 )THEN
        IT=IT+1
        IF( IT .GT. INDF )GO TO 999
        GO TO 30
      ENDIF    
      NBPART = NBPART+1  
      IF( NBPART.GT.NPARMX)THEN
        IERR = -2
        GO TO 999
        ENDIF
      INDICE = NBTT+1
      NBTRIP(NBPART) = 0
      CALL TMA1CC(IDE,ITRTRI,NBCMAX,IND,NBE,IT,ITVL,ITRAMA,
     >       NBIT1,ITRPAR(INDICE),NBTRIP(NBPART),IERR)
       IF( IERR .NE. 0 )GO TO 999
      NBTT = NBTT + NBTRIP(NBPART)    
      GO TO 20
C     --- POUR LE DEBUG ---
  888 DO 890 I=IND,INDF
        IF( ITRAMA(I).EQ.0 )THEN
          IERR = -1
        ENDIF
  890 CONTINUE
  999 END
  
C     *****************************************************************
C     MODULE  : ST (MODULE STRUCTURE)
C     FICHIER : ST_POLYGON.F
C     OBJET   : OPERATIONS ELEMENTAIRES SUR LES POLYGONES SIMPLEMENT
C               CONNEXES
C
C     FONCT.  : 
C        ARTOPL: EXTRAIT UN POLYGONE FERME D'UN MAILLAGE D'ARETES 
C        SPLIPL: DECOUPE (SPLIT) UN POLYGONE PAR UNE ARETE 
C
C     AUTEUR  : O. STAB
C     DATE    : 03.95
C     MODIFICATIONS :
C      AUTEUR, DATE, OBJET : STAB, 12.97, COMMENTAIRES
C
C
C     *****************************************************************
C
C
      SUBROUTINE ARTOPL(IARNOE,NBNMAX,IARAR,NBCMAX,IPOLY,NBPP)
C     *****************************************************************
C     OBJET ARTOPL : EXTRAIT UN POLYGONE FERME D'UN MAILLAGE D'ARETES 
C
C     EN ENTREE :
C         IARNOE,NBNMAX: NOEUDS DES ARETES 
C             IARNOE((I-1)*NBNMAX+1) NOEUD ORIGINE DE L'ARETE I
C             IARNOE((I-1)*NBNMAX+2) NOEUD EXTREMITE DE L'ARETE I
C         IARAR,NBCMAX: ARETE ADJACENTES
C             IARAR((I-1)*NBNMAX+1) ARETE PRECEDENTE DE I
C             IARNOE((I-1)*NBNMAX+2) ARETE SUIVANTE DE I
C
C     EN SORTIE :
C         IPOLY : TABLEAU DES NUMEROS DES NOEUDS 
C         NBPP : NOMBRE DE POINTS DU POLYGONE.
C
C     *****************************************************************
      INTEGER IARNOE(*),NBNMAX,IARAR(*),NBCMAX,IPOLY(*),NBPP
C
      INTEGER IDEBUT,ISUIV
C
      IDEBUT = 1
      NBPP = 1
      IPOLY(1) = IARNOE(1)
      ISUIV = IARAR(2)
   10 IF( ISUIV .EQ. IDEBUT )GO TO 999 
      NBPP = NBPP+1
      IPOLY(NBPP) = IARNOE((ISUIV-1)*NBNMAX+1)
      ISUIV = IARAR((ISUIV-1)*NBCMAX+2)
      GO TO 10 
  999 END
C
      SUBROUTINE SPLIPL(IPOLY,NBPP,NN,IPOLY1,NBPP1,IPOLY2,NBPP2,IERR)
C     *****************************************************************
C     OBJET SPLIPL : DECOUPE (SPLIT) UN POLYGONE PAR UNE ARETE 
C
C     EN ENTREE:
C      IPOLY,NBPP: POLYGONE A DECOUPER
C      NN : NOEUDS DE L'ARETE DE COUPE (NN(1),NN(2))
C
C     EN SORTIE:
C       IPOLY1 : CONTIENT L'ARETE NN(1) VERS NN(2) 
C               EN IPOLY1(NBPP1)IPOLY(1)
C       IPOLY2 : CONTIENT L'ARETE NN(2) VERS NN(1)
C               EN IPOLY2(NBPP2)IPOLY(1)
C       IERR  : 0 SI OK, -1 SI NN(1) OU NN(2) NE SONT PAS CORRECTS
C               C.A.D. SI NN(1) = NN(2) OU SI NN(1) OU NN(2) 
C               NE SONT PAS DANS IPOLY
C
C     *****************************************************************
      INTEGER IPOLY(*),NBPP,NN(*),IPOLY1(*),NBPP1,IPOLY2(*),NBPP2,IERR
C      
      INTEGER INM1,INM2,I,I1,I2
C
      IERR = -1
      IF(NN(1).EQ.NN(2))THEN
        CALL DSERRE(1,IERR,'SPLIPL',' ARETE: ORIGINE=EXTREMITE')       
        GO TO 999
      ENDIF
C     --- RECHERCHE NN(2) ---
      INM1 = 0
      INM2 = 0
      DO 10 I=1,NBPP
        IF( IPOLY(I).EQ. NN(1) )INM1 = I
        IF( IPOLY(I).EQ. NN(2) )INM2 = I
   10 CONTINUE  
      IF(INM1.EQ.0)THEN
        CALL DSERRE(1,IERR,'SPLIPL',' ORIGINE HORS POLYGONE')       
        GO TO 999
      ENDIF
      IF(INM2.EQ.0)THEN
        CALL DSERRE(1,IERR,'SPLIPL',' EXTREMITE HORS POLYGONE')       
        GO TO 999
      ENDIF
C     --- POLY1 DE : INM2 -> INM1 ---
      IF( INM1.LT.INM2 )THEN
        NBPP2 = INM2 - INM1 + 1
        NBPP1 = NBPP - NBPP2 + 2
      ELSE
        NBPP1 = INM1 - INM2 + 1
        NBPP2 = NBPP - NBPP1 + 2
      ENDIF
      I1 = INM2
      DO 20 I=1,NBPP1 
        IPOLY1(I) = IPOLY(I1)
        I1 = MOD(I1,NBPP)+1
   20 CONTINUE
      I2 = INM1
      DO 30 I=1,NBPP2 
        IPOLY2(I) = IPOLY(I2)
        I2 = MOD(I2,NBPP)+1
   30 CONTINUE
      IERR = 0      
  999 END
C
C     *****************************************************************
C     MODULE  : 
C     FICHIER : ST_DOMAIN.F
C     OBJET   : GESTION DES MAILLAGES LINEIQUES ET DES GEOMETRIES DE DOMAINES
C     FONCT.  :
C
C     OBJET DFR2FR : TRANSFORME UN MAILLAGE LINEIQUE EN FRONTIERE DE DOMAINE
C                    DFR2FR ANCIENNEMENT DANS ESLIFR !
C     OBJET DFR2RG : AFFECTE LES REGIONS A PARTIR DE LA FRONTIERE
C                    DFR2RG ANCIENNEMENT DANS LES PROGRAMMES 
C     OBJET DRG2FR : EXTRAIT LA FRONTIERE (GEOMETRIQUE) D'UN MAILLAGE 
C                    DRG2FR ANCIENNEMENT TMAFRM !
C
C     LA FRONTIERE D'UN DOMAINE EST UN MAILLAGE POUR LEQUEL ON A
C     LES INFORMATION SUIVANTES :
C       + MATERIAU A GAUCHE, MATERIAU A DROITE DE CHAQUE ELEMENT FRONTIERE
C       + INDICES DES ELEMENTS REELS DE FRONTIERE.
C         (IFREEL, NFREEL : INTERVAL DES INDICES)
C
C     **********************************************************************
C
      SUBROUTINE REFREG(IEL,TRIMAT,REFMAT,NMT,IMAT,IERR)
C     **************************************************************
C     OBJET REFREG : DONNE LA REFERENCE DE REGION D'UN ELEMENT 
C
C     EN ENTREE:
C      IEL    : NUMERO DE L'ELEMENT
C      TRIMAT : TABLEAU DES INTERVALS
C      REFMAT : TABLEAU DES REFERENCES
C      NMT    : NOMBRE DE REGIONS
C
C     EN SORTIE:
C         IMAT : REFERENCE DE LA REGION DE IEL
C         IERR : 0 SI TROUVE, -1 SI HORS INTERVAL
C     **************************************************************
      INTEGER IEL,TRIMAT(*),REFMAT(*),NMT
      INTEGER IMAT,IERR
C
      IF( IEL .LE. 0 )THEN 
        IMAT = 0
        IERR = -1
        GOTO 9999
      ENDIF
C      
      DO 10 IMAT=1,NMT
        IF( TRIMAT(IMAT).GE. IEL )GOTO 9999
   10 CONTINUE
C     ---- ON A PAS TROUVE  L'INTERVAL DES MATERIAUX ----
      IMAT = 0
      IERR = -1
 9999 END
C
C
      SUBROUTINE DFR2FR(IDE1,ITRNO1,NBNMX1,NBE1,
     >                  ITRIR1,NR1MAX,IMTRF1,NMT1,INTIN1,NBINT1,
     >                  IMATGD,IFREEL,NFREEL,NMAT,
     >                  ITVL,NITMAX,IERR)
C     **********************************************************************
C     OBJET DFR2FR : TRANSFORME UN MAILLAGE LINEIQUE EN FRONTIERE DE DOMAINE
C     EN ENTREE :
C       ITRIR1,NR1MAX : ITRIR1(I) = REGION DE L'ELEMENT I (SI NR1MAX > 0)
C       IMTRF1,NMT1   : IMTRF1(I) = REFERENCE DE LA IEME REGION (SI NMT1>0)
C       INTIN1,NBINT1 : INTIN1(I-1),INTIN1(I) = INDICE DU PREMIER ET DERNIER 
C                       ELEMENT DE REFERENCE IMTRF1(I) (SI NBINT1>0)
C     EN SORTIE :
C       LA MAILLAGE A ETE ORDONNE !
C       IMATGD : IMATGD(I) MATERIAU GAUCHE ET DROIT DE L'ELEMENT I
C       IFREEL : INDICE DU PREMIER ELEMENT DE FRONTIERE (EXTERIEUR = REELLE)
C       NFREEL : NOMBRE D'ELEMENTS DE FRONTIERE (REELLE)
C       NMAT   : NOMBRE DE MATERIAUX
C
C             3 TYPES DE FRONTIERES :
C               FRONTIERES REELLES (VIDE/PLEIN)
C               IMATGD() = (0,+I) OU (+I,0)
C               FRONTIERES INTER-MATERIAUX (MATI/MATJ)
C               IMATGD() = (+I,+J)
C               FRONTIERES GEOMETRIQUES (MATI/MATI)
C               IMATGD() = (+I,+I)
C               UN MATERIAU INCONNU = -1
C
C              CONVENTIONS POUR LE MAILLAGE :
C               LES ELEMENTS DE LA FRONTIERE REELLE (MAT > 0)
C               LES ELEMENTS DES FRONTIERES INTER-MATERIAUX (MAT < 0)
C               LES ELEMENTS IMPOSEES POUR LES RACCORDS (MAT = 0)
C
C     **********************************************************************
      INTEGER IDE1,ITRNO1(*),NBNMX1,NBE1
      INTEGER ITRIR1(*),NR1MAX,IMTRF1(*),NMT1,INTIN1(*),NBINT1
      INTEGER IMATGD(*),IFREEL,NFREEL,NMAT
      INTEGER ITVL(*),NITMAX,IERR
C
      INTEGER MATG,MATD,NOEMX2,NBCMX2,NRGREF,ITRTRI,NOETRI
      INTEGER INTMAT,IREF,I,J,IDMAT,IFMAT,NMT2,IMAT
      INTEGER ITRAV,NITMX2
C
      IERR   = 0
      ITRAV  = 1
      NITMX2 = NITMAX
      IF((NMT1.EQ.0).AND.(NBE1.EQ.0))THEN
        NMAT = 0
        IFREEL = 0
        NFREEL = 0
        GOTO 9999
      ENDIF
      IF(NMT1.EQ.0)THEN
C     ---- ON POURRAIT ANALYSER ITRIR1 SI IL EST DONNE ! POUR L'INSTANT ERREUR
       IERR = -1
        CALL DSERRE(1,IERR,'DFR2FR','PAS DE MATERIAU ?')
        GOTO 9999
      ENDIF
C     NMT1   = 1 PAS BESOIN DE TRIER
C     NBINT1 = DEJA TRIE !
      IF((NMT1.EQ.1).OR.(NBINT1.EQ.NMT1))GOTO 200
C         -----------------------------------------
C     --- 1.RENUMEROTATION  : MATERIAUX CROISSANT  ---
C         -----------------------------------------
      NOEMX2 = 0
      NBCMX2 = 0
      NRGREF = 0
      ITRTRI = 1
      NOETRI = 1
      INTMAT = ITRAV 
      ITRAV  = INTMAT + NMT1
      NITMX2 = NITMAX - ITRAV + 1
      IF(( NITMX2.LT.1 ).OR.
     >   ((NMT1.GT.1).AND.(NITMX2.LT. MAX(NMT1,2*NBE1))))THEN
         IERR = -2
         CALL DSERRE(1,IERR,'DFR2FR','PLACE POUR APPEL A RGCOMP')
         GOTO 9999
      ENDIF
      CALL RGCOMP(IDE1,ITRNO1,NBNMX1,
     >       ITVL(ITRTRI),NBCMX2,ITVL(NOETRI), 
     >       NOEMX2,NBE1,ITVL(ITRAV),
C     IMTREF EN ENTREE ET SORTIE : A VERIFIER ...
     >       ITRIR1,IMTRF1,NMT1,
     >       IMTRF1,ITVL(INTMAT),NRGREF,NMT1,IERR)
C         -----------------------------------------
C     ---- 2. FRONTIERE = REFERENCE POSITIVE       ---
C         -----------------------------------------
 200  CONTINUE
C     ---- UN SEUL MATERIAU ---
      IF(NMT1.LE.1)THEN
        IFREEL = 1
        NFREEL = NBE1
        GOTO 300
      ENDIF
C     ---- ON A LES REFERENCES ----
      DO 210 IREF=1,NMT1
        IF( IMTRF1(IREF).GT.0 )GOTO 220
 210  CONTINUE
      IERR = -1
      CALL DSERRE(1,IERR,'DFR2FR','PAS DE FRONTIERE GEOMETRIQUE ! ')
      GOTO 9999
 220  CONTINUE
      IFREEL = 1
      IF( IREF.GT.1 )THEN
C     ---- ON A DONNE LES INTERVALS ---
      IF(NBINT1.EQ.NMT1)THEN
         IFREEL = INTIN1(IREF-1)
      ELSE
C     ---- ON A CALCULE LES INTERVALS ---
         IFREEL = ITVL(INTMAT+IREF-2)
      ENDIF
      ENDIF
      NFREEL = NBE1 - IFREEL + 1
C        --------------------------------------------
C     --- 3. RECONNAISSANCE DE LA GEOMETRIE          ---
C        --------------------------------------------
 300  CONTINUE
      IDMAT = 1
      DO 20 I=1,NMT1
          IF(NBINT1.EQ.NMT1)THEN
             IFMAT = INTIN1(I)
          ELSE
             IFMAT = ITVL(INTMAT+I-1)
          ENDIF
          IF( IMTRF1(I) .LT.0 )THEN
            MATG = - IMTRF1(I) 
            MATD = - 1
          ELSE
          IF( IMTRF1(I) .EQ.0 )THEN
            MATG = -1
            MATD = -1
          ELSE
            MATG = IMTRF1(I)
            MATD = IMTRF1(I)
          ENDIF
          ENDIF     
        DO 10 J=IDMAT,IFMAT
          IMATGD((J-1)*2+1) = MATG
          IMATGD((J-1)*2+2) = MATD         
  10    CONTINUE
      IDMAT = IFMAT+1
  20  CONTINUE
      GOTO 500
C      
C     --- UNE VARIANTE ????
      DO 410 I=1,NBE1
C      ---- FRONTIERE INTERNE ----
       IF( ITRIR1(I).LT.0 )THEN     
            MATG = - ITRIR1(I) 
            MATD = - 1
          ELSE
C      ---- ARETE IMPOSEE ----
          IF( ITRIR1(I) .EQ.0 )THEN
            MATG = -1
            MATD = -1
          ELSE
C      ---- FRONTIERE GEOMETRIQUE ----
C     (ON NE SAIT PAS DE QUEL COTE EST LE MAT)
            MATG = ITRIR1(I)
            MATD = ITRIR1(I)
          ENDIF
          ENDIF     
          IMATGD((I-1)*2+1) = MATG
          IMATGD((I-1)*2+2) = MATD         
 410  CONTINUE
C        --------------------------------------------
C     --- 5. CALCUL DU NOMBRE DE MATERIAU(X)         ----
C        --------------------------------------------
C     --- ON NE PREND QUE LES  VALEURS POSITIVES DISTINCTES ---
 500  CONTINUE
      IMAT = ITRAV
      ITRAV = IMAT + NMT1
      NITMX2 = NITMAX - ITRAV + 1
      IF( NITMX2.LT.0 )THEN
        IERR = -2
        CALL DSERRE(1,IERR,'DFR2FR','PLUS DE PLACE (1)')
        GOTO 9999
      ENDIF
      NMT2 = 0
      DO 530 I=1,NMT1
         IF( IMTRF1(I).GT.0 )THEN
            NMT2 = NMT2 + 1
            ITVL(IMAT+NMT2-1) = IMTRF1(I)
         ELSE
         IF( IMTRF1(I).LT.0 )THEN
            NMT2 = NMT2 + 1
            ITVL(IMAT+NMT2-1) = -IMTRF1(I)
         ENDIF
         ENDIF
 530  CONTINUE 
      IF( NMT2.GT.1 )THEN 
        IF( NITMX2.LT.NMT2 )THEN
          IERR = -2
          CALL DSERRE(1,IERR,'DFR2FR','PLUS DE PLACE (2)')
          GOTO 9999
        ENDIF
        CALL  TBVTAB(ITVL(IMAT),NMT2,ITVL(ITRAV),ITVL(IMAT),NMAT,
     >                  NMT1,IERR) 
C        PRINT *,'DFR2FR : MATERIAU = ',(ITVL(IMAT+I-1),I=1,NMAT)
        IF( IERR.NE.0 )THEN
          CALL DSERRE(1,IERR,'DFR2FR','APPEL TBVTAB')
          GOTO 9999
        ENDIF
      ELSE
        NMAT = NMT2
      ENDIF
C
 9999 END
C
      SUBROUTINE DFR2RG(IDE1,ITRNO1,NBNMX1,NBE1,IMAT,NMT1,
     >                IDE,ITRNOE,NBNMAX,ITRTRI,NBCMAX,NOETRI,NOEMAX,NBE,
     >                MAJNOE,
     >                ITRIRG,NRGMAX,IMTREF,IMTMAX,INTMAT,INTMAX,NMT,    
     >                ITVL,NITMAX,IERR)
C     **********************************************************************
C     OBJET DFR2RG : AFFECTE LES REGIONS A PARTIR DE LA FRONTIERE
C     EN ENTREE :
C           IDE1,ITRNO1,NBNMX1,,NBE1,IMAT : LA FRONTIERE
C           IDE,ITRNOE,NBNMAX,ITRTRI,NBCMAX,NOETRI,NOEMAX,NBE : LE MAILLAGE
C           MAJNOE : NOETRI EST NECESSAIRE AU TRAITEMENT, EN REVANCHE
C                    ON PEUT SOUHAITER LE METTRE A JOUR (1) OU PAS (0)
C     EN SORTIE :
C           ITRIRG,NRGMAX,IMTREF,NMT,INTMAT,NBINMX : LES REGIONS 
C           LE MAILLAGE EST MODIFIE; LES ELEMENTS SONT TRIES DANS LE CAS
C           DE PLUSIEURS MATERIAUX
C     **********************************************************************
      INTEGER    IDE1,ITRNO1(*),NBNMX1,NBE1,IMAT(*),NMT1
      INTEGER    IDE,ITRNOE(*),NBNMAX,ITRTRI(*),NBCMAX,NOETRI(*),NOEMAX
      INTEGER    NBE,MAJNOE
      INTEGER    ITRIRG(*),NRGMAX,IMTREF(*),IMTMAX,INTMAT(*),INTMAX,NMT    
      INTEGER    ITVL(*)
      INTEGER    NITMAX,IERR
C
C     MATERIAU PAR DEFAUT : PARAMETER (DEFMAT = 1)
      INTEGER DEFMAT
      PARAMETER (DEFMAT = 1)
      INTEGER NMTMAX,PTRIRG,PMTREF,IMATCC,PNTMAT,NOEMX2,NRGREF
      INTEGER ITRAV,NITMX2,I
C 
      IERR = 0        
      ITRAV = 1                         
      NITMX2 = NITMAX            
C           =============================
C       ---- 1. CAS MONO-MATERIAU SIMPLE ----
C           =============================
      IF(( NMT1.LE.1 ).OR.(NBE1.EQ.0))THEN
C       ---- CAS MONO-MATERIAU OU PAS D'ELEMENT DE FRONTIERE ----
        NMT = 1
        IF( NMT1.EQ.1 )THEN
          IF(IMTMAX.GE.1)IMTREF(1) = IMAT(1)
        ELSE
          IF(IMTMAX.GE.1)IMTREF(1) = DEFMAT
        ENDIF
        IF(INTMAX.GE.1)INTMAT(1) = NBE
        GOTO 9999
      ENDIF
C       ---- CAS PLUSIEURS MATERIAUX POSSIBLE ----
C           ===============================
C       ---- 2. IDENTIFICATION DES REGIONS ----
C           ===============================
C      NMTMAX = NMT1
C     REMPLACE PAR : O.STAB 29.07.99, ON AUTORISE 10 CC PAR MATERIAU
      NMTMAX = NMT1*10
      IF( NRGMAX.LE.0 )THEN
        PTRIRG = ITRAV
        ITRAV  = PTRIRG + NBE
        NITMX2 = NITMAX - ITRAV
      ELSE
        IF(NRGMAX.LT.NBE)THEN
          IERR = -2
          CALL DSERRE(1,IERR,'DFR2RG','ITRIRG TROP PETIT')
          GOTO 9999
        ENDIF
      ENDIF
 210  CONTINUE
C
      PMTREF = ITRAV
      IMATCC = PMTREF + NMTMAX
      ITRAV  = NMTMAX + IMATCC
      NITMX2 = NITMAX - ITRAV
C     --- ON A BESOIN DE "ITRAV" SEULEMENT SI PLUSIEURS CC ------
      IF(NITMX2.LE.(NBE+(2*NBE1)+4))THEN
       IERR = -2
       CALL DSERRE(1,IERR,'DFR2RG',' POUR APPEL A RGRGNO')
C       CALL ESEINT(1,'TAILLE MANQUANTE ITVL :',
C     >                      (NITMX2-(NBE+(2*NBE1)+4)),1)
       GOTO 9999
      ENDIF
C
      IF( NRGMAX.GT. 0 )THEN
      CALL RGRGNO(ITRNO1,NBNMX1,NBE1,IMAT,
     >      IDE,ITRNOE,
     >      NBNMAX,ITRTRI,NBCMAX,
     >      NOETRI,NBE,ITVL(ITRAV),NITMX2,
     >      ITRIRG,ITVL(PMTREF),ITVL(IMATCC),NMT,
     >      NMTMAX,IERR)
      ELSE
      CALL RGRGNO(ITRNO1,NBNMX1,NBE1,IMAT,
     >      IDE,ITRNOE,
     >      NBNMAX,ITRTRI,NBCMAX,
     >      NOETRI,NBE,ITVL(ITRAV),NITMX2,
     >      ITVL(PTRIRG),ITVL(PMTREF),ITVL(IMATCC),NMT,
     >      NMTMAX,IERR)
      ENDIF
C     --- ON NE CONNAIT PAS LA REPARTITION EN COMPOSANTES CONNEXES ---
C      PRINT *,'NMT = ',NMT
C      PRINT *,'NMTMAX = ',NMTMAX
C      PRINT *,'REFERENCES = ',(ITVL(PMTREF+I-1),I=1,NMTMAX)
C      PRINT *,'COMPOSANTES = ',(ITVL(IMATCC+I-1),I=1,NMTMAX)

      IF((IERR .EQ. -2 ).AND.(NMT.GT.NMTMAX))THEN
          NMTMAX = NMT
          IERR = 0
          ITRAV  = PMTREF
          GOTO 210
      ENDIF
      IF( IERR .NE. 0 )THEN
        CALL DSERRE(1,IERR,'DFR2RG',' APPEL RGRGNO ')
        CALL DSERRE(1,IERR,'DFR2RG',' AFFECTATION DES MATERIAUX')        
        GO TO 9999
      ENDIF
      ITRAV = IMATCC
      NITMX2 = NITMAX - ITRAV + 1
C
C        =================================================
C     --- 3. RENUMEROTATION ELEMENTS : MATERIAUX CROISSANT ---
C        =================================================
      IF( NMT.EQ.1 )THEN
        IF( INTMAX.GT.0 )INTMAT(1) = NBE
        IF( IMTMAX.GT.0 )IMTREF(1) = ITVL(PMTREF)
        GOTO 9999
      ENDIF
C
      PNTMAT = ITRAV
      ITRAV  = NMTMAX + PNTMAT
      NOEMX2 = NOEMAX
      IF(MAJNOE.NE.1)NOEMX2 = 0
      IF( NRGMAX.GT.0 )THEN
      CALL RGCOMP(IDE,ITRNOE,NBNMAX,
     >       ITRTRI,NBCMAX,NOETRI, 
     >       NOEMX2,NBE,ITVL(ITRAV),
     >       ITRIRG,ITVL(PMTREF),NMT,
     >       ITVL(PMTREF),ITVL(PNTMAT),NRGREF,NMTMAX,IERR)
      ELSE
      CALL RGCOMP(IDE,ITRNOE,NBNMAX,
     >       ITRTRI,NBCMAX,NOETRI, 
     >       NOEMX2,NBE,ITVL(ITRAV),
     >       ITVL(PTRIRG),ITVL(PMTREF),NMT,
     >       ITVL(PMTREF),ITVL(PNTMAT),NRGREF,NMTMAX,IERR)
      ENDIF 
      IF( IERR .NE. 0 )THEN
        CALL DSERRE(1,IERR,'DFR2RG',' APPEL RGCOMP')        
        GO TO 9999
      ENDIF
C
C        =======================
C     --- 4. COPIE DES TABLEAUX ---
C        =======================
 400  CONTINUE
      IF( INTMAX.GT.0 )THEN
        IF( INTMAX.LT.NRGREF )THEN
          IERR = -2
          CALL DSERRE(1,IERR,'DFR2RG','INTMAT TROP PETIT')
          GOTO 9999
        ENDIF
        DO 410 I=1,NRGREF
          INTMAT(I) = ITVL(PNTMAT+I-1)
 410    CONTINUE
      ENDIF
C
      IF( IMTMAX.GT.0 )THEN
        IF( IMTMAX.LT.NRGREF )THEN
          IERR = -2
          CALL DSERRE(1,IERR,'DFR2RG','IMTREF TROP PETIT')
          GOTO 9999
        ENDIF
        DO 420 I=1,NRGREF
          IMTREF(I) = ITVL(PMTREF+I-1)
 420    CONTINUE
      ENDIF
C
 9999 END
C
      SUBROUTINE DRG2FR(IDE,ITRNOE,NBNMAX,ITRTRI,NBCMAX,NBE,
     >                  TRIMAT,REFMAT,NMT,
     >                  ITVL,NITMAX,
     >                  INOEFR,INOMAX,
     >                  IRRGFR,IIRGFR,NMTFR,IREMAX,
     >                  NBEFR,NBNFR,IERR)
C     **************************************************************
C     OBJET DRG2FR : EXTRAIT LA FRONTIERE (GEOMETRIQUE) D'UN MAILLAGE 
C                    (AVEC LEURS MATERIAUX)
C     EN ENTREE:
C      IDE,ITRNOE,NBNMAX,ITRTRI,NBCMAX,NBE :  LE MAILLAGE
C      TRIMAT,REFMAT,NMT :  LES REGIONS
C
C      ITVL  : TABLEAU DE TRAVAIL (ENTIER)
C      NITMAX : TAILLE DE ITVL (>= NMT+ NBEFR*2)
C
C      INOEFR:  TABLEAU A REMPLIR (ELEMENTS)  (TAILLE = NBEFR*NBNFR)
C      INOMAX:  TAILLE DU TABLEAU INOEFR
C
C      IRRGFR : TABLEAU  A REMPLIR (MATERIAUX)  
C      IIRGFR : TABLEAU  A REMPLIR (INTERVALS)  
C      IREMAX   : TAILLE DE IRRGFR ET IIRGFR (TAILLE >2*NMT)
C
C      NBNFR :  NOMBRE MAXIMUM DE SOMMETS DES ELEMENTS FRONTIERE
C               IL PEUT ETRE CONNU ET DONNE, SINON =0 ET IL SERA CALCULE
C
C     EN SORTIE: 
C      INOEFR :  LISTE DES NOEUDS DES ELEMENTS DE LA FRONTIERE
C      IIRGFR : INTERVAL DES ELEMENTS
C      IRRGFR : REFERENCE DES MATERIAUX
C      IRRGFR(IIRGFR(IEL)) :  NUMERO DE LA REGION INCIDENTE 
C               A L'ELEMENT DE FRONTIERE IEL
C               POSITIF SI LA FRONTIERE EST EXTERNE
C               NEGATIF SI LA FRONTIERE EST INTERNE
C                 -NUMERO DONNE ALORS LA REGION A GAUCHE
C      NBEFR :  NOMBRE D'ELEMENTS DE LA FRONTIERE
C      NBNFR :  NOMBRE MAXIMUM DE SOMMETS DES ELEMENTS FRONTIERE
C                =IDE SAUF EN 3D POUR LES PRISMES,PYRAMIDES,HEXA
C      IERR  :  CODE D'ERREUR 0 => OK, -2 => NCFMAX TROP PETIT
C
C     CONDITION D'APPLICATION : MAILLAGE MIXTE 1D,2D ET 
C                               ET TETRAEDRES
C     ************************************************************
      INTEGER IDE,ITRNOE(*),NBNMAX,ITRTRI(*),NBCMAX,NBE
      INTEGER TRIMAT(*),REFMAT(*),NMT
      INTEGER ITVL(*),NITMAX
      INTEGER INOEFR(*),INOMAX,IIRGFR(*),IRRGFR(*),IREMAX
      INTEGER NMTFR,NBEFR,NBNFR,IERR
C
      INTEGER IEL,I,J,K,IMAT1,IMAT2,INDNF(4),NBRN,NBNF
      INTEGER IND,IFAC,ITRMX2,NUMEL,NUMCC
      INTEGER IVOIS,IFVOIS
      INTEGER IMAT,IVMAT,IELFRT,IREFRG,NRGMAX
      INTEGER NOEMAX,NBFMAX,ITRAV
      INTEGER STRNBN,STRKSF
      EXTERNAL STRNBN,STRKSF
C
C     ---- CALCUL DE LA FRONTIERE ----
C
      IND = 1
      IFAC   = 1
      ITRMX2 = NITMAX - IFAC
C
C      CALL TMAFRT(IDE,ITRNOE,NBNMAX,ITRTRI,NBCMAX,IND,NBE,
C     >                   ITVL(IFAC),NBEFR,ITRMX2,IERR)
C      IF( IERR.NE. 0 )THEN
C        CALL DSERRE(1,IERR,'DRG2FR','APPEL TMAFRT')
C        GOTO 9999
C      ENDIF
C      --- IL AURAIT FALLU CREER LES FRONTIERES INTER-MAT : SFRICR
C
      NBEFR = 0
      DO 7 I=1,NBE
        CALL REFREG(I,TRIMAT,REFMAT,NMT,IMAT1,IERR)
        IF(IERR.NE.0)THEN
          CALL DSERRE(1,IERR,'DRG2FR','1 APPEL REFREG')
          GOTO 9999
        ENDIF
        DO 5 J=1,NBCMAX
          IVOIS = ITRTRI((I-1)*NBCMAX+J)
          IF( IVOIS .GT. I )GOTO 5
          IF( IVOIS .GT. 0 )THEN
            CALL REFREG(IVOIS,TRIMAT,REFMAT,NMT,IMAT2,IERR)
            IF(IERR.NE.0)THEN
              CALL DSERRE(1,IERR,'DRG2FR','2 APPEL REFREG')
              GOTO 9999
            ENDIF
            IF( IMAT1.NE.IMAT2 )THEN
              NBEFR = NBEFR + 1
              ITVL((NBEFR-1)*2+1+IFAC-1) = I
              ITVL((NBEFR-1)*2+2+IFAC-1) = -J
            ENDIF
          ELSE
            NBEFR = NBEFR + 1
            ITVL((NBEFR-1)*2+1+IFAC-1) = I
            ITVL((NBEFR-1)*2+2+IFAC-1) = J         
          ENDIF
    5   CONTINUE
    7 CONTINUE
C      PRINT *,'IEL14 = ',  ITVL((14-1)*2+1+IFAC-1)
C      PRINT *,'IF14 = ',   ITVL((14-1)*2+2+IFAC-1)
C
C     ---- CALCUL DES NOEUDS ET MATERIAUX ----
C
C     --- CARDINAUX ---
C
      IF( NBNFR.EQ. 0 )THEN
      DO 10 IEL=1,NBEFR
        NUMEL = ITVL((IEL-1)*2+1+IFAC-1)
        NUMCC = ITVL((IEL-1)*2+2+IFAC-1)
        NBRN = STRNBN(NUMEL,ITRNOE,NBNMAX)
        NBNF = STRKSF(IDE,NBRN,ABS(NUMCC),INDNF) 
        NBNFR = MAX(NBNFR,NBNF)
   10 CONTINUE
      ENDIF
C
      IF( NBNFR*NBEFR .GT. INOMAX )THEN
        IERR = -2
        CALL DSERRE(1,IERR,'DRG2FR',
     >   'TROP DE NOEUDS DE FRONTIERE')
C        PRINT *,'NBNFR,NBEFR =', NBNFR,NBEFR
C        PRINT *,'IOMAX =', INOMAX  
        GOTO 9999
      ENDIF        
C
C     --- LES NOEUDS ---        
C
      DO 30 IEL=1,NBEFR
        NUMEL = ITVL((IEL-1)*2+1+IFAC-1)
        NUMCC = ITVL((IEL-1)*2+2+IFAC-1)
        NBRN = STRNBN(NUMEL,ITRNOE,NBNMAX)
        NBNF = STRKSF(IDE,NBRN,ABS(NUMCC),INDNF) 
        IF( NBNF.GT.4 )THEN
          IERR = -2
          CALL DSERRE(1,IERR,'DRG2FR',
     >     'UN COTE A PLUS DE 4 NOEUDS')
          GOTO 9999
        ENDIF
        DO 20 K=1,NBNF
          INOEFR((IEL-1)*NBNFR+K)=
     >      ITRNOE((NUMEL-1)*NBNMAX+INDNF(K)) 
   20   CONTINUE 
   30 CONTINUE
C
C     --- LES MATERIAUX ---        
C
      NMTFR = 0
      IREFRG = NBEFR*2 + IFAC
      NRGMAX  = NMT*2
      IELFRT  = NRGMAX  + IREFRG
      IF( IELFRT.GT.NITMAX )THEN
          IERR = -2
          CALL DSERRE(1,IERR,'DRG2FR',
     >     'POUR LES MATERIAUX')
          GOTO 9999      
      ENDIF
C
      DO 60 IEL=1,NBEFR
        NUMEL = ITVL((IEL-1)*2+1+IFAC-1)
        NUMCC = ITVL((IEL-1)*2+2+IFAC-1)
        CALL REFREG(NUMEL,TRIMAT,REFMAT,NMT,IMAT,IERR)
        IF( IERR.NE.0 )THEN
          CALL DSERRE(1,IERR,'DRG2FR','3 APPEL REFREG')      
          GOTO 9999
        ENDIF
C
C       ---- TEST DES MATERIAUX ---
C
        IVMAT = REFMAT(IMAT)            
        IF( NUMCC.LT. 0 )
     >      IVMAT = -REFMAT(IMAT)
C        PRINT *,'NUMEL = ',NUMEL
C     >          ,' NUMCC = ',NUMCC
C     >          ,' IMAT = ',IMAT
C     >          ,' IVMAT = ',IVMAT
        IMAT = 0
        DO 35 I=1,NMTFR
          IF(IVMAT.EQ.ITVL(I+IREFRG-1))IMAT = I
   35   CONTINUE
        IF( IMAT.EQ. 0 )THEN
          NMTFR = NMTFR+1
          ITVL(NMTFR+IREFRG-1) = IVMAT
          ITVL(IEL+IELFRT-1) = IVMAT
        ELSE
          ITVL(IEL+IELFRT-1) = IVMAT         
        ENDIF
C           
C       ---- FRONTIERE INTERNE ----    
C       --- SI LE MATERIAU EST DEJA REFERENCE ON VA VOIR LE VOISIN :
C
        IF((NUMCC.LT. 0).AND.(IMAT.NE.0))THEN
C          PRINT *,'IEL = ',IEL
          IVOIS = ITRTRI((NUMEL-1)*NBCMAX-NUMCC)
C          PRINT *,'IVOIS = ',IVOIS
          CALL REFREG(IVOIS,TRIMAT,REFMAT,NMT,IMAT,IERR)
          IF( IERR.NE.0 )THEN
            CALL DSERRE(1,IERR,'DRG2FR','4 APPEL REFREG')      
            GOTO 9999
          ENDIF
C
C       ---- TEST DES MATERIAUX ---
C
C        PRINT *,'IMAT(IVOIS) = ',IMAT
        IVMAT = -REFMAT(IMAT)            
        IMAT = 0
        DO 37 I=1,NMTFR
          IF(IVMAT.EQ.ITVL(I+IREFRG-1))IMAT = I
   37   CONTINUE
        IF( IMAT.NE. 0 )GOTO 60
C
        NMTFR = NMTFR+1
        ITVL(NMTFR+IREFRG-1) = IVMAT
        ITVL(IEL+IELFRT-1) = IVMAT
C
C         --- IL FAUT INVERSER L'ORDRE DES NOEUDS ---
          CALL SESFR1(NUMEL,-NUMCC,
     >                ITRTRI,NBCMAX,IVOIS,IFVOIS)
        NBRN = STRNBN(IVOIS,ITRNOE,NBNMAX)
        NBNF = STRKSF(IDE,NBRN,ABS(IFVOIS),INDNF) 
        DO 40 K=1,NBNF
          INOEFR((IEL-1)*NBNFR+K) =
     >      ITRNOE((IVOIS-1)*NBNMAX+INDNF(K)) 
   40   CONTINUE 
        ENDIF
C
   60 CONTINUE    
C      
C     ---- RENUMEROTATION DES MATERIAUX CROISSANTS ----
C
C      PRINT *,'NOEUDS = ' 
C     > ,( (INOEFR((I-1)*NBNFR+J),J=1,NBNFR)
C     > ,'/',I=1,NBEFR)    
C      PRINT *,'NOMBRE DE MATERIAUX = ',NMTFR      
C      PRINT *,'REFERENCES MATERIAUX = ',
C     >        (ITVL(I+IREFRG-1),I=1,NMTFR)      
C      PRINT *,'ELEMENTS = ',
C     >        (ITVL(I+IELFRT-1),I=1,NBEFR)      
      NOEMAX = 0
      NBFMAX = 0
C     --- ON NE DEPASSE PAS 2*NBEFR ---
      ITRAV = IFAC
C      ITRAV = NBEFR + IELFRT
      NRGMAX = 2*NMT
C      PRINT *,'IEL14 = ',  ITVL((14-1)*2+1+IFAC-1)
C      PRINT *,'IF14 = ',   ITVL((14-1)*2+2+IFAC-1)
      CALL RGCOMP(IDE,INOEFR,NBNFR,
     >       ITVL(1),NBFMAX,ITVL(1), 
     >       NOEMAX,NBEFR,ITVL(ITRAV),
     >       ITVL(IELFRT),ITVL(IREFRG),NMTFR,
     >       IRRGFR,IIRGFR,NMTFR,NRGMAX,IERR)
C      PRINT *,'INTERVALS = ',(IIRGFR(I),I=1,NMTFR)    
C      PRINT *,'NOEUDS = ' 
C     > ,( (INOEFR((I-1)*NBNFR+J),J=1,NBNFR)
C     > ,'/',I=1,NBEFR)    
      IF( IERR.NE. 0 )THEN
        CALL DSERRE(1,IERR,'DRG2FR','APPEL RGCOMP')
        GOTO 9999
      ENDIF
C
 9999 END
C







C     *****************************************************************
C     FICHIER : DEBUG.F
C     OBJET   : VERIFICATION DES PROPRIETES DE LA STRUCTURE DES DONNEES
C               DU MAILLAGE
C     FONCT.  : 
C        SDBTRI : VERIFIE LA STRUCTURE DE DONNEES POUR LES FRONTIERES
C                   DES ELEMENTS (COHERANCE ITRTRI <-> ITRNOE)
C        SDBORI : VERIFIE L'ORIENTATION DES ELEMENTS 
C
C     AUTEUR  : O. STAB  
C     DATE    : 03.95
C     TESTS   : O.STAB 03.95
C     MODIFICATIONS :
C      AUTEUR, DATE, OBJET : O.STAB, 21.01.99, NETTOYAGE SDBTRI + EXT 3D
C
C
C     *****************************************************************
C
      SUBROUTINE SDBTRI(IDE,ITRNOE,NBNMAX,ITRTRI,NBCMAX,NOETRI,
     >                    NBE,NOEMAX,ITRACE,IERR) 
C     *****************************************************************
C     OBJET SDBTRI : VERIFIE LA STRUCTURE DES DONNEES 
C     (COHERANCE ITRTRI <-> ITRNOE, ITRNOE <-> NOETRI)
C     EN ENTREE  :  LE MAILLAGE
C        NOEMAX:  SI > 0 ON VERIFIE NOETRI
C        ITRACE  :  NIVEAU D'AFFICHAGE 0 => RIEN SAUF LES ERREURS
C                                      1 => ECHO DES TESTS EN COURS
C     EN SORTIE  :  IERR : 0 SI OK, -1 SI ERREUR
C     MODIF 21.01.99 : ON TOLERE L'ELEMENT VIDE (LES TROUS DANS LA 
C                      NUMEROTATION)
C
C     REMARQUE : ATTENTION NOETRI EST NECESSAIRE A LA VERIFICATION
C                EN REVANCHE SI NOEMAX EST NON NUL IL N'EST PAS VERIFIE !
C     *****************************************************************
      INTEGER   IDE,NBE,ITRNOE(*),NBNMAX,ITRTRI(*),NBCMAX,NOETRI(*)
      INTEGER   NOEMAX,ITRACE,IERR
C
      INTEGER   I,J,K,IT(2),IFAC(4),N(2),NF(4),NNE,NCE,NBNF,IT2,IF2
      INTEGER   KK,NF2(4),NNE2,NBNF2
      INTEGER   NBFFR,II,JJ,JJ2,ISOM(4),NBNC,IF1,IFC,ITVL(10000),NITMAX
      INTEGER   STRNBN,STRNBC,STRKSF,SFAIDE 
      EXTERNAL  STRNBN,STRNBC,STRKSF,SFAIDE 
C
      NITMAX = 10000
C
      IERR = 0
      NBFFR = 0
C        ====================================
C     --- 1. VERIFICATION NOETRI <-> ITRNOE ---
C        ====================================
      IF( NOEMAX.GT. 0 )THEN
      IF( ITRACE.GT.0)PRINT *,'VERIFICATION NOETRI <-> ITRNOE '
C     --- POUR CHAQUE ELEMENT ----------------------------------
      DO 20 I=1,NOEMAX
        K = NOETRI(I)
        IF((K.GT.NBE).OR.(K.LT.0))THEN
          PRINT *,'SDBTRI : ERREUR POSSIBLE NOETRI ',I,' = ',K
          IERR = -1
          CALL DSERRE(1,IERR,'SDBTRI',' NOETRI')
          GOTO 9999
        ENDIF
        IF( K .EQ. 0 )THEN
          PRINT *,'ATTENTION NOEUD ISOLE ',I
          GOTO 20
        ENDIF
C       --- POUR CHAQUE NOEUD DE L'ELEMENT -----------
        DO 10 J=1,NBNMAX
          IF( ITRNOE((K-1)*NBNMAX+J).EQ.I )GOTO 20
   10   CONTINUE
        PRINT *,'ERREUR NOETRI ',I,' = ',K
        PRINT *,'       ITRNOE',K,' = ',
     >          (ITRNOE((K-1)*NBNMAX+J),J=1,NBNMAX)
        IERR = -1
        CALL DSERRE(1,IERR,'SDBTRI',' NOETRI <-> ITRINOE')
        GOTO 9999       
   20 CONTINUE
      IF(ITRACE.NE.0)PRINT *,' --> OK'
      ENDIF
C        ====================================
C     --- 2. VERIFICATION ITRTRI <-> ITRNOE ---
C        ====================================
      IF( ITRACE.GT.0)PRINT *,'VERIFICATION ITRTRI <-> ITRNOE '
C
C     --- POUR CHAQUE ELEMENT ----------------------------------
C        ---------------------
      DO 100 I=1,NBE
        NNE = STRNBN(I,ITRNOE,NBNMAX)
        IF(NNE.EQ.0)THEN
          PRINT *,'ATTENTION A L ELEMENT :',I,' DE ',NNE,' NOEUDS'
          PRINT *,'NOEUDS = ',(ITRNOE((I-1)*NBNMAX+J),J=1,NBNMAX)
        ENDIF
        IF( IDE.EQ.2 )THEN
          IF((NNE.GT.4).OR.(NNE.LT.3))THEN
          PRINT *,'ATTENTION A L ELEMENT :',I,' DE ',NNE,' NOEUDS'
          PRINT *,'NOEUDS = ',(ITRNOE((I-1)*NBNMAX+J),J=1,NBNMAX)
          ENDIF
        ENDIF
        IF( IDE.EQ.3 )THEN
          IF((NNE.LT.4).OR.(NNE.GT.8))THEN
          PRINT *,'ATTENTION A L ELEMENT :',I,' DE ',NNE,' NOEUDS'
          PRINT *,'NOEUDS = ',(ITRNOE((I-1)*NBNMAX+J),J=1,NBNMAX)
          ENDIF
        ENDIF
        NCE = STRNBC(NNE,IDE)
C       --- ON PASSE A L'ELEMENT SUIVANT ---
        IF( NNE.EQ.0 )GOTO 100
C          -------------------------------
C       --- POUR CHAQUE FACE DE L'ELEMENT -----------
C          -------------------------------
        DO 90 J=1,NCE
          NBNF = STRKSF(IDE,NNE,J,NF)
          DO 80 K=1,NBNF
            NF(K) = ITRNOE((I-1)*NBNMAX+NF(K))
   80     CONTINUE
C       
C       --- ON PART DU TABLEAU DES VOISINS : ITRTRI --------
C           ELEMENT SUIVANT SUR LA FRONTIERE
          CALL SESFR1(I,J,ITRTRI,NBCMAX,IT2,IF2)
C       
C       --- ON PART DES NOEUDS DE LA FACE NF : NOETRI PUIS ITRTRI 
C
          IF( IDE.EQ.2 )THEN
C          IF( IDE.EQ.2 )THEN
C         ?? INTERET ??   <- reactive le 01/04/2003 
          CALL SFRIDE(NF,NBNF,IDE,ITRNOE,NBNMAX,ITRTRI,NBCMAX,
     >            NOETRI,NBE,ITVL,NITMAX,
     >            IT(1),IT(2),IFAC(1),IFAC(2),IERR)
          IF(IERR.NE.0)THEN
            CALL DSERRE(1,IERR,'SDBTRI',' APPEL SFRIDE')
            GOTO 9999
          ENDIF
          ELSE
C         ---- SFRIDE NE MARCHE PAS EN 3D ---------------
            IT(1)   = I
            IFAC(1) = J
            IT(2)   = IT2
            IFAC(2) = IF2
          ENDIF
C
          IF(((IT(2).NE.I).OR.(IT2.NE.IT(1))).AND.
     >       ((IT(1).NE.I).OR.(IT2.NE.IT(2))))THEN
            PRINT *,'ATTENTION : SFRIDE ET ITRTRI INCOMPATIBLES'
            PRINT *,'( ',IT(1),IT(2),' ) DIFFERENT (',I,IT2,' )'
            IERR = -1
            CALL DSERRE(1,IERR,'SDBTRI',' ITRTRI<-> ITRNOE ')
            GOTO 9999
          ENDIF
          IF((IT(1).GT.NBE).OR.(IT(2).GT.NBE))THEN
            PRINT *,'ATTENTION ',IT(1),IT(2),' SUPERIEUR A ',NBE
          ENDIF
C
C      --- ON PART DES NOEUDS DES ELEMENTS : ITRNOE --
C
        IF((IT(1).NE.0).AND.(IT(2).NE.0))THEN
          N(1) = STRNBN(IT(1),ITRNOE,NBNMAX)
          N(2) = STRNBN(IT(2),ITRNOE,NBNMAX)
          IFAC(3) = 0
          IFAC(4) = 0
          IFC = SFAIDE(ITRNOE((IT(1)-1)*NBNMAX+1),
     >        ITRNOE((IT(2)-1)*NBNMAX+1),N(1),N(2),IDE,IFAC(3),
     >        IFAC(4))
C         --------------------------------------------------
C         ON DOIT RETROUVER EGALITE DES INDICES DES FACES
C         --------------------------------------------------
          IF((IFAC(3).NE.IFAC(1)).OR.(IFAC(4).NE.IFAC(2)).OR.
     >     (ABS(ITRTRI((IT(1)-1)*NBCMAX+IFAC(1))).NE.IT(2)).OR.
     >     (ABS(ITRTRI((IT(2)-1)*NBCMAX+IFAC(2))).NE.IT(1)))THEN
           PRINT *,'ERREUR SUR LE COTE ',J,' DE ELEMENT ',I
           PRINT *,'NOEUDS = ',(ITRNOE((I-1)*NBNMAX+K),K=1,NBNMAX)
           PRINT *,'VOISINS= ',(ITRTRI((I-1)*NBCMAX+K),K=1,NBCMAX)
C         LA SUITE EST POUR LES MESSAGES :
C         --------------------------------------------------
           IF(IFAC(3).NE.IFAC(1))PRINT *,'ERREUR ',
     >     IT(1),' ADJACENT A ',IT(2),' SUR ',IFAC(1),' OU SUR ',IFAC(3)
C         --------------------------------------------------
           IF(IFAC(4).NE.IFAC(2))PRINT *,'ERREUR ',
     >     IT(1),' ADJACENT A ',IT(2),' SUR ',IFAC(2),' OU SUR ',IFAC(4)
C         --------------------------------------------------
           IF(ABS(ITRTRI((IT(1)-1)*NBCMAX+IFAC(1))).NE.IT(2))
     >     PRINT *,'ERREUR L ELEMENT ADJACENT A ',
     >     IT(1),' SUR ',IFAC(1),' EST ',
     >     ABS(ITRTRI((IT(1)-1)*NBCMAX+IFAC(1))),' OU ',IT(2) 
C         --------------------------------------------------
           IF(ABS(ITRTRI((IT(2)-1)*NBCMAX+IFAC(2))).NE.IT(1))
     >     PRINT *,'ERREUR L ELEMENT ADJACENT A ',
     >     IT(2),' SUR ',IFAC(2),' EST ',
     >     ABS(ITRTRI((IT(2)-1)*NBCMAX+IFAC(2))),' OU ',IT(1)               
C          ---- FIN DES MESSAGES ----
           IERR = -1
           CALL DSERRE(1,IERR,'SDBTRI',' ITRTRI <-> ITRNOE')
           GOTO 9999
          ENDIF
C         --------------------------------------------------
C         ON DOIT RETROUVER EGALITE DES NOEUDS NF ET NF2
C         --------------------------------------------------
          NNE2  = STRNBN(IT2,ITRNOE,NBNMAX)
          NBNF2 = STRKSF(IDE,NNE2,IF2,NF2)
          DO 180 K=1,NBNF2
            NF2(K) = ITRNOE((IT2-1)*NBNMAX+NF2(K))
  180     CONTINUE
          IF( NBNF.NE.NBNF2 )THEN
            PRINT *,'SDBTRI : LES CARD DES FACES DIFFERENT ',NBNF,NBNF2
            IERR = -1
            CALL DSERRE(1,IERR,'SDBTRI',' CARD DES FACES')
            GOTO 9999
          ENDIF
C
          DO 190 K=1,NBNF
            IF( NF(1).EQ.NF2(K) )GOTO 200
  190     CONTINUE
          PRINT *,'SDBTRI : FACES DIFFERENT ',NF(1),' INTROUVABLE'
          IERR = -1
          CALL DSERRE(1,IERR,'SDBTRI',' LES FACES')
          GOTO 9999
C
  200     CONTINUE
          KK = K
          DO 210 K=1,NBNF
            IF(NF(K).NE.NF2(KK))THEN
              PRINT *,'SDBTRI : FACES DIFFERENTES'
              IERR = -1
              CALL DSERRE(1,IERR,'SDBTRI',' LES FACES')
              GOTO 9999
            ENDIF
            KK = NBNF - MOD(NBNF+1-KK,NBNF)
  210     CONTINUE
         ELSE
C
C     --- VERIFIONS QUE NF(K) EST SUR LA FRONTIERE -----------
C        ------------------------------------------
         CALL KNUTA(NBNF,NF)
         DO 1150 II=I+1,NBE
C        --- ON TESTE TOUS LES ELEMENTS SUIVANTS ---      
           DO 1100 K=1,NBNMAX
             ISOM(K) = ITRNOE((II-1)*NBNMAX+K)
 1100      CONTINUE
           CALL KNUTA(NBNMAX,ISOM) 
           NBNC = 0    
           JJ2  = 1 
           JJ   = 1
C          ---- PAS DE FACE EN COMMUN ON PASSE AU SUIVANT -----
 1105      IF((JJ2.GT.NBNF ).OR.(JJ.GT.NBNMAX))GOTO 1150
           IF(ISOM(JJ).GT.NF(JJ2))THEN
             JJ2 = JJ2 + 1
           ELSE
             IF(ISOM(JJ).LT.NF(JJ2))THEN
               JJ = JJ + 1
             ELSE
               NBNC = NBNC+1
               JJ = JJ + 1
               JJ2 = JJ2 + 1
             ENDIF
           ENDIF
           IF( NBNC.NE.NBNF )GOTO 1105
C          ---- LA FACE NE FAIT PAS PARTIE DE LA FRONTIERE -----
           IF(NBNC.EQ.NBNF)THEN
             WRITE(*,*) 'ERREUR SUR LA FRONTIERE :'
             WRITE(*,*) 'SUR LA FACE ',J,' DE L ELEMENT ',I
             WRITE(*,*) 'IL Y A L ELEMENT : ',II
             WRITE(*,*) 'LA FACE ',NF(1),NF(2),NF(3),
     >                  ' N EST PAS SUR LA FRONTIERE'
             IFC = SFAIDE(ITRNOE((I-1)*NBNMAX+1),
     >                  ITRNOE((II-1)*NBNMAX+1), NBNMAX, NBNMAX, 
     >                   IDE, IF1, IF2 )
*            APPEL = SFAC3D
             IF(IFC.NE.0)THEN
                 WRITE(*,*)'ELEMENT ',II,' SUR FACE ',IF2
             ELSE
                 WRITE(*,*)'SFAIDE SE PLANTE AUSSI '
             ENDIF             
             IERR = -1
             CALL DSERRE(1,IERR,'SDBTRI',' ITRTRI <-> ITRNOE')
          ENDIF
C
 1150    CONTINUE
         NBFFR = NBFFR + 1
         ENDIF
C
   90   CONTINUE
  100 CONTINUE 
C
      IF((ITRACE.NE.0).AND.(IERR.EQ.0))THEN
        PRINT *,' NOMBRE DE FACES DE LA FRONTIERE = ',NBFFR
        PRINT *,' --> OK'
      ENDIF
 9999 END      
C
      SUBROUTINE SDBORI(IDE,IDIMC,ITRNOE,NBNMAX,ITRTRI,NBCMAX,
     >                    NOETRI,NBE,COORD,ITRACE,IERR) 
C     *****************************************************************
C     OBJET : VERIFIE L'ORIENTATION DES ELEMENTS 
C     EN ENTREE  :  LE MAILLAGE
C        ITRACE  :  NIVEAU D'AFFICHAGE 0 => RIEN SAUF LES ERREURS
C                                      1 => ECHO DES TESTS EN COURS
C     EN SORTIE  :  IERR : 0 SI OK, -1 SI ERREUR
C     *****************************************************************
      INTEGER   IDE,IDIMC,NBE,ITRNOE(*),NBNMAX,ITRTRI(*),NBCMAX
      INTEGER   NOETRI(*),ITRACE,IERR
      REAL      COORD(*)
C
      INTEGER    NNE,NCE,I,J
      INTEGER    STRNBN,STRNBC,GORIEN
      EXTERNAL   STRNBN,STRNBC,GORIEN
      REAL       ZERO
C      REAL     TAILLE,RIL,TTVO,TTRIL
C      EXTERNAL TTVO,TTRIL
C
C     A FAIRE : SI ZERO EST ABSOLU IL FAUDRAIT NORMALISER L'ESPACE
C     LE MIEUX SERAIT DE RELATIVISER LE TEST...
      ZERO = 1.E-6
      IERR = 0
      IF( ITRACE.NE.0)PRINT *,'SDBORI : VERIFICATION DE L ORIENTATION'
      DO 20 I=1,NBE
        NNE = STRNBN(I,ITRNOE,NBNMAX)
        NCE = STRNBC(NNE,IDE)        
C       MODIF O.STAB 12.12.97 AJOUT IDE.
        IF( GORIEN(ITRNOE((I-1)*NBNMAX+1),NCE,IDE,COORD,IDIMC,ZERO)
     >    .NE.1 )THEN
          PRINT *,'SDBORI : ERREUR SUR L ELEMENT ',I
          PRINT *,'SDBORI : NOEUDS = ',
     >           (ITRNOE((I-1)*NBNMAX+J),J=1,NBNMAX)
          IERR = -1
        ENDIF        
C
C           TAILLE = TTVO( COORD( (ITRNOE((I-1)*NBNMAX+1)-1)*IDIMC+1),
C     >                    COORD( (ITRNOE((I-1)*NBNMAX+2)-1)*IDIMC+1),
C     >                    COORD( (ITRNOE((I-1)*NBNMAX+3)-1)*IDIMC+1),
C     >                    COORD( (ITRNOE((I-1)*NBNMAX+4)-1)*IDIMC+1))
C      IF( TAILLE .LT. 1.E-3 )THEN
C        PRINT *,'SDBORI : ERREUR ',I,' VOLUME = ',TAILLE 
C        PRINT *,'SDBORI : NOEUDS = ',
C     >           (ITRNOE((I-1)*NBNMAX+J),J=1,NBNMAX)
C        IERR = -1
C      ENDIF
C           RIL = TTRIL( COORD( (ITRNOE((I-1)*NBNMAX+1)-1)*IDIMC+1),
C     >                  COORD( (ITRNOE((I-1)*NBNMAX+2)-1)*IDIMC+1),
C     >                  COORD( (ITRNOE((I-1)*NBNMAX+3)-1)*IDIMC+1),
C     >                  COORD( (ITRNOE((I-1)*NBNMAX+4)-1)*IDIMC+1))
C      IF( RIL .LT. 1.E-4 )THEN
C        PRINT *,'SDBORI : ERREUR ',I,' RIL = ',RIL 
C        PRINT *,'SDBORI : ERREUR ',I,' VOLUME = ',TAILLE 
C        PRINT *,'SDBORI : NOEUDS = ',
C     >           (ITRNOE((I-1)*NBNMAX+J),J=1,NBNMAX)
C        IERR = -1
C      ENDIF
C
   20 CONTINUE
C
      IF((ITRACE.NE.0).AND.(IERR.EQ.0))PRINT *,'SDBORI : ',NBE
     > ,' ELEMENTS > ',ZERO,' --> OK'
  999 END
C     *****************************************************************
C     MODULE  : M1 (RAFFINEMENT LINEIQUE)
C     FICHIER : M1_DENSDEF.F
C     OBJET   : DENSITE PAR DEFAUT D'UN MAILLAGE LINEIQUE
C
C     FONCT.  :
C
C       D1DSLN:   DONNE LA DENSITE PAR DEFAUT SUR DES ARETES
C
C     AUTEUR   : O. STAB
C     DATE     : 08.95
C     TESTS    : 08.95
C     MODIFICATIONS :
C       AUTEUR, DATE, OBJET : O.STAB, 12.12.97, AJOUT IDE APPEL GTAILL.
C       AUTEUR, DATE, OBJET : O.STAB, 11.08.98, SUP. DE LA STRUCTURE
C
C
C     *****************************************************************
C
C
      SUBROUTINE D1DSLN(ITYPS,RSG,
     >          ITRINO,NBNMAX,COORD,IDIMC,NBE,
     >          TSN,NTSMAX,IERR)
C     *****************************************************************
C     OBJET D1DSLN :   DONNE LA DENSITE PAR DEFAUT 
C
C     EN ENTREE: 
C      --------- DEFINITION DE L'AMORTISSEMENT --------
C      ITYPS   : TYPE DE LA PROGRESSION (GEOM. = 1, ARITH. = 2)
C      RSG     : RAPPORT MAX ENTRE 2 ELEMENTS SUCCESSIFS (GEOM.)
C                DIFFERENCE MAX "   "           "    "   (ARITH.)
C
C      --------- LE MAILLAGE ---------------------
C      ITRINO,NBNMAX : LE MAILLAGE
C      NOEMAX: SI = 0 ON NE REMPLI PAS NOETRI
C                SINON = NCOMAX
C      COORD,IDIMC : COORDONNEES DES NOEUDS
C
C      NTSMAX : TAILLE DE TSN. 
C
C      EN SORTIE :
C
C      TSN     : TABLEAU DES TAILLES SOUHAITEES
C                TSN(I) = TAILLE SOUHAITE AU NOEUD I
C      IERR    : CODE D'ERREUR 0 SI OK
C                -1 SI LES DONNEES SONT INCORRECTES
C                -2 SI TSN EST TROP PETIT
C      
C     NOUVEAU ALGORITHME : ON A PAS BESOIN DE LA STRUCTURE, ON PEUT
C     TRAITER LES ARETES DANS UN ORDRE ARBITRAIRE !
C     DU MEME COUT ON EST PLUS LIMITE A DU MONO-MATERIAU !
C     *****************************************************************
      INTEGER ITYPS
      REAL    RSG
      INTEGER NBE,ITRINO(*),NBNMAX
      REAL    COORD(*)
      INTEGER IDIMC
      REAL    TSN(*)
      INTEGER NTSMAX
      INTEGER IERR
C
      INTEGER  IT,IO,IE,J
      REAL     TIT,VSD,X
      INTEGER  IMODIF
C     TAILLE MAXI POUR INITIALISATION :  PARAMETER (TSNMAX = 1.E+38)
      REAL TSNMAX
      PARAMETER (TSNMAX = 1.E+38)
C
      IERR = 0
C        -------------------------------------
C     --- TAILLE SOUHAITE = TAILLE DES ARETES ---
C        -------------------------------------
C
      DO 10 IT=1,NBE
      IE  = ITRINO((IT-1)*NBNMAX+2)
      IO  = ITRINO((IT-1)*NBNMAX+1)
      IF((IE.GT.NTSMAX).OR.(IO.GT.NTSMAX))THEN
        IERR = -2
        CALL DSERRE(1,IERR,'D1DSLN','TABLEAU TSN TROP PETIT')
        GOTO 9999
      ENDIF
      TSN(IO) = TSNMAX
      TSN(IE) = TSNMAX
 10   CONTINUE
C
 15   CONTINUE
      IMODIF = 0
      DO 30 IT=1,NBE
      IE  = ITRINO((IT-1)*NBNMAX+2)
      IO  = ITRINO((IT-1)*NBNMAX+1)
      TIT = 0.0
      DO 20 J=1,IDIMC
        X = COORD(((IE-1)*IDIMC)+J) 
     >    - COORD(((IO-1)*IDIMC)+J)
        TIT = TIT + X*X
 20   CONTINUE
      TIT = SQRT( TIT )
C
      TSN( IE ) = MIN(TIT,TSN(IE))
      CALL SCSUPO(ITYPS,TSN(IO),RSG,TIT,VSD)      
      IF( VSD.LT.TSN(IE))THEN
        IMODIF = 1
        TSN( IE ) = VSD
      ENDIF
C
      TSN( IO ) = MIN(TIT,TSN(IO))
      CALL SCSUPO(ITYPS,TSN(IE),RSG,TIT,VSD)     
      IF( VSD.LT.TSN(IO))THEN
        IMODIF = 1
        TSN( IO ) = VSD
      ENDIF
   30 CONTINUE
      IF(IMODIF.GT.0)GOTO 15     
 9999 END
C  

C     ****************************************************************
C     MODULE   : M1 (RAFFINEMENT LINEIQUE)
C     FICHIER  : M1_DENSITE1D.F
C     OBJET    : FONCTION ANALYTIQUES DE CALCUL DE LA DENSITE
C
C     FONCT.   :
C     OBJET D1SUM : CALCUL LES PTS (SUITE MONOTONE SEGMENT) (LOCAL)
C     OBJET D1SU :  DENSITE DEFINIE PAR UNE SUITE A PARTIR D'UN OBJET (OBSOLET)
C     OBJET D1SU2 :  DENSITE DEFINIE PAR UNE SUITE A PARTIR D'UN OBJET
C     OBJET D1ISU :  DENSITE DEFINIE PAR UNE SUITE A PARTIR D'UN OBJET
C     OBJET D1SUI :   CF. D1SU MODE ITERATIF
C     OBJET D1ISUI : CALCULE LA TAILLE SOUHAITE D'UN ELEMENT (IT)
C       -------- DECOUPAGE DIRECT --------------
C
C       -------- DECOUPAGE ITERATIF ------------
C
C     AUTEUR   : O. STAB
C     DATE     : 03.95 / 06.95 / 05.98
C     TESTS    : 07.95
C     MODIFICATIONS :
C      AUTEUR, DATE, OBJET :
C
C
C     ****************************************************************
C
      SUBROUTINE D1SUM(XP1,XP2,IDIMC,ITYPS,TSP,RSG,ITYPO,
     >                          ROBJET,XPI,NBPMAX,NBPI,IERR)
C     ****************************************************************
C     OBJET D1SUM : CALCUL LES PTS (SUITE MONOTONE SEGMENT) (LOCAL)
C
C     EN ENTREE :
C         XP1     : DEBUT DU SEGMENT
C         XP2     : FIN DU SEGMENT
C         IDIMC   : DIMENSION DE L'ESPACE
C         ---------------------
C         ITYPO   : TYPE DE L'OBJET
C         ROBJET  : LA DEFINITION GEOMETRIQUE DE L'OBJET
C         ITYPS   : TYPE DE LA SUITE
C         TSP     : LA TAILLE SOUHAITE A L'OBJET
C         RSG     : RAISON DE LA SUITE GEOMETRIQUE
C         NBPMAX : TAILLE MAXI DU TABLEAU DES POINTS
C
C     EN SORTIE :
C         XPI     : COORDONNEES DES POINTS CALCULES
C         NBPI    : NOMBRE DE NOEUDS CALCULES
C     ****************************************************************
      REAL     XP1(*),XP2(*)
      INTEGER  IDIMC,ITYPS,ITYPO
      REAL     TSP,RSG,ROBJET(*),XPI(*)
      INTEGER  NBPMAX,NBPI,IERR
C
      REAL     TS1,TS2,D1,D2
      EXTERNAL SU2PO,POSUM
      REAL      ZERO
      COMMON /CSTGEO/ZERO
C
      IERR = 0
C     --- CALCUL DES DISTANCES A L'OBJET ------------------------
      CALL DIPOOB(IDIMC,XP1,ITYPO,ROBJET,D1,IERR)
      IF( IERR .NE. 0 )GOTO 888
      CALL DIPOOB(IDIMC,XP2,ITYPO,ROBJET,D2,IERR)
      IF( IERR .NE. 0 )GOTO 888
C     --- CALCUL DE LA DENSITE AUX POINTS -----------------------
      CALL SCSUPO(ITYPS,TSP,RSG,D1,TS1)
      CALL SCSUPO(ITYPS,TSP,RSG,D2,TS2)
      IF((TS2.LE.ZERO).OR.(TS1.LE.ZERO))THEN
         IERR = -1
         CALL DSERRE(1,IERR,'M1',
     >    'DANS D1SUM : TAILLE SOUHAITE NEGATIVE OU NULLE')
         GOTO 999
      ENDIF
C     --- CALCUL DE LA SUITE ------------------------------------
      CALL POSUM(XP1,XP2,IDIMC,TS1,TS2,ITYPS,
     >                    XPI,NBPMAX,NBPI,IERR)
C
  888 IF( IERR .NE. 0 )CALL DSERRE(1,IERR,'M1','DANS D1SUM')
  999 END
C
C
      SUBROUTINE D1SU2(XP1,XP2,IDIMC,ITYPS,TSP,RSG,ITYPO,ROBJET,
     >                     XPI,NBPMAX,NBPI,IERR)
C     ****************************************************************
C     OBJET D1SU2 : DENSITE DEFINIE PAR UNE SUITE A PARTIR D'UN OBJET version 19.01.2005
C              (POINT,AXE) POUR UN ELEMENT 1D (ARETE)
C     EN ENTREE :
C         -------- DEFINITION DU SEGMENT ----------------------
C         XP1     : COORDONNEES DE L'ORIGINE DU SEGMENT
C         XP2     : COORDONNEES DE L'EXTREMITE DU SEGMENT
C         IDIMC   : DIMENSION DE L'ESPACE (1 OU 2)
C         -------- DEFINITION DE LA CONCENTRATION -------------
C         ITYPO   : TYPE DE CONCENTRATION
C         ROBJET  : LA DEFINITION GEOMETRIQUE DE LA CONCENTRATION
C         ITYPS   : TYPE DE LA SUITE
C         TSP     : LA TAILLE SOUHAITE A LA CONCENTRATION
C         RSG     : RAISON DE LA SUITE GEOMETRIQUE
C         NBPMAX : NOMBRE MAXIMUM DE POINTS DANS XPI
C
C     EN SORTIE :
C         XPI     : COORDONNEES DES POINTS CALCULES
C         NBPI    : NOMBRE DE POINTS CALCULES
C         IERR    : CODE D'ERREUR
C     REMARQUE : generalise D1SU car le nombre de points sur le segment
C                peut etre = 4 dans le cas non monotone.
C     ****************************************************************
      REAL     XP1(*),XP2(*)
      INTEGER  IDIMC,ITYPS,ITYPO
      REAL     TSP,RSG,ROBJET(*),XPI(*)
      INTEGER  NBPMAX,NBPI,IERR
C
C     nombre maximum de points (de changement de densite) sur un segment
      REAL     TS1,TS2,D1,D2,DNUL(4)
      REAL     TSNUL(4),XPNUL(3*4)
      INTEGER  MONO,I
      REAL      ZERO
      COMMON /CSTGEO/ZERO
C
      IERR = 0
      MONO = 0
      CALL DIMONO(XP1,XP2,IDIMC,ITYPO,ROBJET,XPNUL,MONO,IERR)
      IF( IERR .NE. 0 )GOTO 888
      IF( MONO .NE. 0 )THEN
C          =============================
C       --- LA SUITE N'EST PAS MONOTONE ---
C          =============================
C          ------------------------------------------
C       --- CALCUL DE LA DENSITE AUX "MONO"+2 POINTS ---------
C          ------------------------------------------
        DO 10 I=1,MONO
          CALL DIPOOB(IDIMC,XPNUL((I-1)*IDIMC+1),
     >                ITYPO,ROBJET,DNUL(I),IERR)
   10   CONTINUE
        IF( IERR .NE. 0 )GOTO 888
        CALL DIPOOB(IDIMC,XP1,ITYPO,ROBJET,D1,IERR)
        IF( IERR .NE. 0 )GOTO 888
        CALL DIPOOB(IDIMC,XP2,ITYPO,ROBJET,D2,IERR)
        IF( IERR .NE. 0 )GOTO 888
        DO 20 I=1,MONO
          CALL SCSUPO(ITYPS,TSP,RSG,DNUL(I),TSNUL(I))
   20   CONTINUE
        CALL SCSUPO(ITYPS,TSP,RSG,D1,TS1)
        CALL SCSUPO(ITYPS,TSP,RSG,D2,TS2)
        IF((TS1.LE.ZERO).OR.(TS2.LE.ZERO))THEN
           IERR = -1
           CALL DSERRE(1,IERR,'D1SU2',
     >            'TAILLE SOUHAITE NEGATIVE OU NULLE')
           GOTO 999
        ENDIF
        CALL POSUNM2(XP1,XPNUL,MONO,XP2,IDIMC,TS1,TSNUL,TS2,ITYPS,
     >                      XPI,NBPMAX,NBPI,IERR)
      ELSE
C          =============================
C       --- LA SUITE EST MONOTONE       ---
C          =============================
          CALL D1SUM(XP1,XP2,IDIMC,ITYPS,TSP,RSG,ITYPO,
     >                          ROBJET,XPI,NBPMAX,NBPI,IERR)
      ENDIF
C
  888 IF( IERR .NE. 0 )CALL DSERRE(1,IERR,'D1SU','DANS D1SU')
  999 END
C
C
      SUBROUTINE D1SU(XP1,XP2,IDIMC,ITYPS,TSP,RSG,ITYPO,ROBJET,
     >                     XPI,NBPMAX,NBPI,IERR)
C     ****************************************************************
C     OBJET D1SU :  DENSITE DEFINIE PAR UNE SUITE A PARTIR D'UN OBJET (OBSOLET)
C              (POINT,AXE) POUR UN ELEMENT 1D (ARETE)
C     EN ENTREE :
C         -------- DEFINITION DU SEGMENT ----------------------
C         XP1     : COORDONNEES DE L'ORIGINE DU SEGMENT
C         XP2     : COORDONNEES DE L'EXTREMITE DU SEGMENT
C         IDIMC   : DIMENSION DE L'ESPACE (1 OU 2)
C         -------- DEFINITION DE LA CONCENTRATION -------------
C         ITYPO   : TYPE DE CONCENTRATION
C         ROBJET  : LA DEFINITION GEOMETRIQUE DE LA CONCENTRATION
C         ITYPS   : TYPE DE LA SUITE
C         TSP     : LA TAILLE SOUHAITE A LA CONCENTRATION
C         RSG     : RAISON DE LA SUITE GEOMETRIQUE
C         NBPMAX : NOMBRE MAXIMUM DE POINTS DANS XPI
C
C     EN SORTIE :
C         XPI     : COORDONNEES DES POINTS CALCULES
C         NBPI    : NOMBRE DE POINTS CALCULES
C         IERR    : CODE D'ERREUR
C     ****************************************************************
      REAL     XP1(*),XP2(*)
      INTEGER  IDIMC,ITYPS,ITYPO
      REAL     TSP,RSG,ROBJET(*),XPI(*)
      INTEGER  NBPMAX,NBPI,IERR
C
      REAL     TS1,TS2,D1,D2,DNUL
      REAL     TSNUL,XPNUL(3)
      INTEGER  MONO
      REAL      ZERO
      COMMON /CSTGEO/ZERO
C
      IERR = 0
      MONO = 1
      CALL DIMONO(XP1,XP2,IDIMC,ITYPO,ROBJET,XPNUL,MONO,IERR)
      IF( IERR .NE. 0 )GOTO 888
      IF( MONO .NE. 0 )THEN
C          =============================
C       --- LA SUITE N'EST PAS MONOTONE ---
C          =============================
C          -----------------------------------
C       --- CALCUL DE LA DENSITE AUX 3 POINTS ---------
C          -----------------------------------
        CALL DIPOOB(IDIMC,XPNUL,ITYPO,ROBJET,DNUL,IERR)
        IF( IERR .NE. 0 )GOTO 888
        CALL DIPOOB(IDIMC,XP1,ITYPO,ROBJET,D1,IERR)
        IF( IERR .NE. 0 )GOTO 888
        CALL DIPOOB(IDIMC,XP2,ITYPO,ROBJET,D2,IERR)
        IF( IERR .NE. 0 )GOTO 888
        CALL SCSUPO(ITYPS,TSP,RSG,DNUL,TSNUL)
        CALL SCSUPO(ITYPS,TSP,RSG,D1,TS1)
        CALL SCSUPO(ITYPS,TSP,RSG,D2,TS2)
        IF((TSNUL.LE.ZERO).OR.(TS1.LE.ZERO).OR.(TS2.LE.ZERO))THEN
           IERR = -1
           CALL DSERRE(1,IERR,'M1',
     >            'DANS D1SU : TAILLE SOUHAITE NEGATIVE OU NULLE')
           GOTO 999
        ENDIF
        CALL POSUNM(XP1,XPNUL,XP2,IDIMC,TS1,TSNUL,TS2,ITYPS,
     >                      XPI,NBPMAX,NBPI,IERR)
      ELSE
C          =============================
C       --- LA SUITE EST MONOTONE       ---
C          =============================
          CALL D1SUM(XP1,XP2,IDIMC,ITYPS,TSP,RSG,ITYPO,
     >                          ROBJET,XPI,NBPMAX,NBPI,IERR)
      ENDIF
C
  888 IF( IERR .NE. 0 )CALL DSERRE(1,IERR,'M1','DANS D1SU')
  999 END
C
C
      SUBROUTINE D1ISU(XP1,XP2,IDIMC,ITAB,RTAB,XPI,NBPMAX,
     >                   NBPI,IERR)
C     ****************************************************************
C     OBJET D1ISU :  DENSITE DEFINIE PAR UNE SUITE A PARTIR D'UN OBJET
C              (POINT,AXE) POUR UN ELEMENT 1D (ARETE)
C              FONCTION PARAMETRE POUR RAF1D MODE DIRECT
C              APPEL D1SU 
C     EN ENTREE :
C       --------- L'ARETE A RAFFINER -------------------
C       XP1       : COORDONNEES DU POINT ORIGINE DU SEGMENT
C       XP2       : COORDONNEES DU POINT EXTREMITE DU SEGMENT
C       IDIMC     : DIMENSION DE L'ESPACE (1 OU 2)
C       NBPMAX   : NOMBRE MAXIMUM DE POINTS DANS XPI
C
C       --------- DEFINITION DE LA CONCENTRATION ------------
C       ITAB(1)   : TYPE DE LA SUITE (1=GEOMETRIQUE, 2=ARITHEMTIQUE)
C       ITAB(2)   : TYPE DE LA CONCENTRATION  (1=POINT, 2=DROITE)
C       RTAB(1)   : RAISON DE LA SUITE GEOMETRIQUE 
C       RTAB(2)   : TAILLE SOUHAITE A LA CONCENTRATION
C       RTAB(3...): COORDONNEES DES POINTS DEFINISSANT LA GEOMETRIE 
C                   DE LA CONCENTRATION :
C                   - UN SEUL POINT SI ITAB(2) = 1
C                   - DEUX POINTS SI ITAB(2) = 2
C       
C     EN SORTIE :
C         XPI     : COORDONNEES DES POINTS CALCULES
C         NBPI    : NOMBRE DE POINTS CALCULES
C         IERR    : CODE D'ERREUR
C                    0 SI OK 
C                   -1 SI LES DONNEES SONT ERRONEES
C     ****************************************************************
      REAL      XP1(*), XP2(*)
      INTEGER   IDIMC,ITAB(*)
      REAL      RTAB(*),XPI(*)
      INTEGER   NBPMAX,NBPI,IERR
C
C      CALL D1SU(XP1,XP2,IDIMC,ITAB(1),RTAB(2),RTAB(1),
      CALL D1SU2(XP1,XP2,IDIMC,ITAB(1),RTAB(2),RTAB(1),
     >                ITAB(2),RTAB(3),XPI,NBPMAX,NBPI,IERR)
  999 END
C
C
      SUBROUTINE D1SUI(XP1,XP2,TAILEL,IDIMC,
     >                 ITYPS,TSP,RSG,
     >                 ITYPO,ROBJET,COEF,TS,IERR)
C     *****************************************************************
C     OBJET D1SUI :   CF. D1SU MODE ITERATIF
C     EN ENTREE :
C         XP1     : COORDONNEES DE L'ORIGINE DU SEGMENT
C         XP2     : COORDONNEES DE L'EXTREMITE DU SEGMENT
C         TAILEL  : TAILLE DU SEGMENT
C         IDIMC   : DIMENSION DE L'ESPACE (1 OU 2)
C         ---------------------
C         ITYPO   : TYPE DE CONCENTRATION
C         ROBJET  : LA DEFINITION GEOMETRIQUE DE LA CONCENTRATION
C         ITYPS   : TYPE DE LA SUITE
C         TSP     : LA TAILLE SOUHAITE A LA CONCENTRATION
C         RSG     : RAISON DE LA SUITE GEOMETRIQUE
C         NBPMAX : TAILLE MAXI DU TABLEAU DES POINTS
C     EN SORTIE :
C         IERR    : CODE D'ERREUR
C                    0 SI OK 
C                   -1 SI LES DONNEES SONT ERRONEES
C     REMARQUES IMPORTANTES:
C         LE DECOUPAGE EST ITERATIF : AU BARYCENTRE SI LA TAILLE 
C         SOUHAITE EST < 1.5 TAILLE REELLE
C         (LA TAILLE SOUHAITE EST EVALUEE AU BARYCENTRE)
C     ****************************************************************
      INTEGER    IDIMC,ITYPO,ITYPS
      REAL       XP1(*),XP2(*),ROBJET(*),TSP,RSG
      REAL       TAILEL
      REAL       COEF,TS
      INTEGER    IERR
C
      REAL     BARYC(3), V12(3),DBARYC
      EXTERNAL SCALVE,XNORVE
      REAL     SCALVE,XNORVE
C           ====================
C     ------ TEST AU BARYCENTRE ------
C           ====================
      CALL SOMMVE(XP2,XP1,IDIMC,V12)
      CALL MUSCVE(V12,0.5,IDIMC,BARYC)
      CALL DIPOOB(IDIMC,BARYC,ITYPO,ROBJET,DBARYC,IERR)
      IF( IERR.LT.0 )THEN
        CALL DSERRE(1,IERR,'M1','DANS D1SUI')
        GOTO 9999
      ENDIF
      CALL SCSUPO(ITYPS,TSP,RSG,DBARYC,TS)
C
      IF( TAILEL.LE.0 )THEN
        CALL DIFFVE(XP2,XP1,IDIMC,V12)
        TAILEL = XNORVE(V12,IDIMC)
      ENDIF     
      IF( TAILEL.LE.1.E-10 )THEN
        IERR = -1
        CALL DSERRE(1,IERR,'D1SUI','SEGMENT NUL')
        GOTO 9999
      ENDIF
      COEF = TS / TAILEL
C
 9999 END
C
C
      SUBROUTINE D1ISUI(IT,ITRNOE,NBNMAX,ITRTRI,NBCMAX,
     >            COORD,IDIMC,TAIREL,NBTMAX,ITAB,RTAB,COEF,TS,IERR)
C     ****************************************************************
C     OBJET D1ISUI : CALCULE LA TAILLE SOUHAITE D'UN ELEMENT (IT)
C               FONCTION PARAMETRE POUR RAF1D MODE ITERATIF
C               APPEL D1ISUI 
C     EN ENTREE :
C         --------- L'ELEMENT A RAFFINER -------------------
C         IT   : NUMERO DE L'ELEMENT A RAFFINER
C         ITRNOE,NBNMAX,ITRTRI,NBCMAX : LE MAILLAGE
C         ITRTRI,NBCMAX (INUTILISES)
C         COORD,IDIMC : COORDONNEES DANS L'ESPACE DE DIMENSION IDIMC
C         TAIREL,NBTMAX  : TAILLE REELLE DE L'ELEMENT
C         --------- DEFINITION DE LA CONCENTRATION ------------
C         ITAB(1)   : TYPE DE LA SUITE (1=GEOMETRIQUE, 2=ARITHEMTIQUE)
C         ITAB(2)   : TYPE DE LA CONCENTRATION  (1=POINT, 2=DROITE)
C         RTAB(1)   : RAISON DE LA SUITE GEOMETRIQUE 
C         RTAB(2)   : TAILLE SOUHAITE A LA CONCENTRATION
C         RTAB(3...): COORDONNEES DES POINTS DEFINISSANT LA GEOMETRIE 
C                     DE LA CONCENTRATION :
C                     - UN SEUL POINT SI ITAB(2) = 1
C                     - DEUX POINTS SI ITAB(2) = 2
C       
C     EN SORTIE :
C         TS      : TAILLE SOUHAITE POUR L'ELEMENT IT
C                   ELLE EST DONNE PAR LA CONCENTRATION (ITAB,RTAB)
C         COEF    : A * TS /  RC (RAYON DU CERCLE CIRCONSCRIT A IT)
C                   "A" EST TEL QUE 0 <= COEF <=1
C                   PLUS COEF EST PETIT PLUS ON RAFFINE
C         IERR    : CODE D'ERREUR 0 SI OK, 
C                   -1 SI TAILLE SOUHAITE EST NEGATIVE
C                      OU SI LE RAYON CIRCONSCRIT EST NUL 
C
C     NIVEAU : INTERFACE UTILISATEUR    
C     ****************************************************************
      REAL      COORD(*),TAIREL(*),COEF,TS
      INTEGER   IT,ITRNOE(*),NBNMAX,ITRTRI(*),NBCMAX,NBTMAX
      INTEGER   IDIMC,ITAB(*)
      REAL      RTAB(*)
      INTEGER   IERR
C
      INTEGER NUMP1,NUMP2
      REAL    TAILLE
C
      NUMP1 = ITRNOE((IT-1)*NBNMAX+1)
      NUMP2 = ITRNOE((IT-1)*NBNMAX+2)     
      IF( NBTMAX.LE.0 )THEN
        TAILLE = 0.0
        CALL D1SUI(COORD((NUMP1-1)*IDIMC+1),
     >             COORD((NUMP2-1)*IDIMC+1),
     >             TAILLE,IDIMC,
     >             ITAB(1),RTAB(2),RTAB(1),
     >             ITAB(2),RTAB(3),COEF,TS,IERR)
      ELSE 
        CALL D1SUI(COORD((NUMP1-1)*IDIMC+1),
     >             COORD((NUMP2-1)*IDIMC+1),
     >             TAIREL((IT-1)*NBTMAX+1),IDIMC,
     >             ITAB(1),RTAB(2),RTAB(1),
     >             ITAB(2),RTAB(3),COEF,TS,IERR)
      ENDIF
      IF( IERR.NE. 0 )
     >   CALL DSERRE(1,IERR,'D1ISUI','APPEL D1SUI')
C
 9999 END
C









C     *****************************************************************
C     MODULE  : M1 (RAFFINE MAILLAGE LINEIQUE) 
C     FICHIER : M1_RAF1D.F
C     OBJET   : RAFFINE UN MAILLAGE LINEIQUE PAR DEFAUT
C
C     FONCT.  :
C            R1ARNO  :   RAFINE UNE ARETE EN FONCTION DES TAILLES 
C                            SOUHAITEES AUX SOMMETS EXTREMITES
C            R1LIS  :   REGULARISE LA POSITION D'UN POINT DANS 
C                            UN MAILLAGE 1D
C
C            R1NO      : RAFFINE UN MAILLAGE 1D PAR LA TAILLE SOUHAITE 
C                            AUX NOEUDS
C            R1RAF    :   RAFINE PAR DEFAUT UN MAILLAGE LINEIQUE
C
C     AUTEUR   : O. STAB
C     DATE     : 03.95 / 06.95 OBSOLET ????
C     TESTS    : 07.95
C     MODIFICATIONS :
C       AUTEUR, DATE, OBJET : OBSOLET ???? 
C        O.STAB, 30.07.99, AJOUT DE NBRMAX POUR LE MULTI-REFERENCE DANS :
C                R1NO, R1ARNO, R1RAF
C        O.STAB, 10.01.05, ajout du cas sommet isole (R1ARNO et R1LIS)
C
C     *****************************************************************
C
      SUBROUTINE R1NO(ITYPS,RSG,
     >                ITRNOE,NBNMAX,ITRTRI,NBCMAX,NOETRI,NOEMAX,
     >                COORD,IDIMC,NBN,NBE,NBPMAX,NBEMAX,
C     >                IMAT,IMATMX,RTVL,NPSMAX,TSN,IERR)
     >                IMAT,NBRMAX,IMATMX,
     >                RTVL,NPSMAX,TSN,IERR)
C     **********************************************************************
C     OBJET R1NO : RAFFINE UN MAILLAGE 1D / LA TAILLE SOUHAITE AUX NOEUDS
C
C     EN ENTREE    :
C       --------- LE MAILLAGE ---------------------
C       ITRNOE,NBNMAX,ITRTRI,NBCMAX,NOETRI,NOEMAX,NBN,NBE : LE MAILLAGE
C       COORD,IDIMC: LES COORDONNEES DES NOEUDS
C       NBPMAX     : NOMBRE MAXIMUM DE POINTS
C       NBEMAX     : NOMBRE MAXIMUM D'ELEMENTS
C       IMAT       : IMAT((I-1*NBRMAX+K) = REFERENCE K DE L'ELEMENT I 
C                    (SI IMATMX > 0)
C       IMATMX      : NOMBRE DE REFERENCES
C
C       ---- DEFINITION DU RAFFINEMENT --------------
C       ITYPS    : TYPE D'AMORTISSEMENT
C       RSG      : RAISON DE L'AMORTISSEMENT
C       TSN      : TABLEAU DES TAILLES SOUHAITEES AUX NOEUDS
C
C       ---- TABLEAUX DE TRAVAIL --------------------
C       RTVL : TABLEAU DE TRAVAIL OU SONT STOQUEES LES COORDONNEES
C                  DES POINTS CALCULES SUR UNE ARETE 
C       NPSMAX : NOMBRE MAXIMUM DE POINTS GENERES SUR UNE ARETE
C
C
C     EN SORTIE    : LE MAILLAGE MODIFIE
C       NBE,NBN    : LE NOMBRE D'ARETES ET DE NOEUDS APRES GENERATION
C       IERR       : CODE D'ERREUR 
C                    0 SI OK
C                   -1 SI LES DONNEES SONT INCORRECTES
C                   -2 SI LE TABLEAU RTVL EST INSUFFISANT
C
C     **********************************************************************
      INTEGER ITYPS
      REAL    RSG
      INTEGER NBE,NBEMAX,ITRNOE(*),NBNMAX,ITRTRI(*),NBCMAX
      INTEGER IDIMC,NOETRI(*),NOEMAX,NBN,NBPMAX,NPSMAX
      INTEGER IMAT(*),NBRMAX,IMATMX
      REAL    COORD(*),RTVL(*),TSN(*)
      INTEGER IERR
C
      INTEGER IO,IE,IT,NBENEW,NBE1
      REAL    TSIO,TSIE
C
      NBE1 = NBE
      DO 10 IT=1,NBE1
        NBENEW = 0
        IO   = ITRNOE((IT-1)*NBNMAX+1)
        IE   = ITRNOE((IT-1)*NBNMAX+2)
        TSIO = TSN( IO )
        TSIE = TSN( IE )      
        CALL R1ARNO(IT,ITYPS,TSIO,TSIE,RSG,
     >          ITRNOE,NBNMAX,ITRTRI,NBCMAX,
     >          NOETRI,NOEMAX,
     >          IMAT,NBRMAX,IMATMX,
     >          COORD,IDIMC,NBN,NBE,NBPMAX,NBEMAX,
     >          RTVL,NPSMAX,NBENEW,IERR)
        IF( IERR.NE.0 )GOTO 999
   10 CONTINUE
C
  999 END          
C
      SUBROUTINE R1ARNO(IT,ITYPS,TSIO,TSIE,RSG,
     >          ITRNOE,NBNMAX,ITRTRI,NBCMAX,
     >          NOETRI,NOEMAX,
C     >          IMAT,IMATMX,
     >          IMAT,NBRMAX,IMATMX,
     >          COORD,IDIMC,NBN,NBE,NBPMAX,NBEMAX,
     >          RTVL,NRTMAX,NBENEW,IERR)
C     *****************************************************************
C     OBJET R1ARNO :   RAFINE L'ARETE EN FONCTION DE LA TAILLE SOUHAITE AUX 
C               SOMMETS
C     EN ENTREE 
C      IT       : L'ARETE A RAFFINER
C      ITYPS    : LE TYPE DE LA PROGRESSION (1=GEOM, 2= ARITH)
C      TSIO     : TAILLE SOUHAITE A L'ORIGINE DE L'ARETE
C      TSIE     : TAILLE SOUHAITE A L'EXTREMITE DE L'ARETE
C      RSG      : SI RSG > 1. (GEOM.) OU > 0. (ARITH.) 
C                 ON INTERPOLE ENTRE TSIO ET TSIE
C                 AVEC DILATATION SI POSSIBLE
C      ------------ LE MAILLAGE ----------- 
C      ITRNOE,NBNMAX,ITRTRI,NBCMAX,NOETRI,NOEMAX : LE MAILLAGE
C      NOEMAX : SI = 0 ON NE REMPLI PAS NOETRI SINON = NBPMAX
C      COORD,IDIMC,NBN : COORDONNEES DES NOEUDS
C      NBE      : LE NOMBRE D'ELEMENTS
C      NBPMAX   : NOMBRE MAXIMUM DE POINTS DANS COORD
C      NBEMAX   : NOMBRE MAXIMUM D'ELEMENTS
C      IMAT     : IMAT((I-1*NBRMAX+K) = REFERENCE K DE L'ELEMENT I 
C                    (SI IMATMX > 0)
C      IMATMX   : TAILLE DE IMAT.
C
C     EN SORTIE : LE MAILLAGE MODIFIE
C      NBENEW   : LE NOMBRE D'ARETES GENEREES
C      IERR     : CODE D'ERREUR 
C                   0 SI OK
C                  -1 SI LES DONNEES SONT INCORRECTES
C                  -2 SI LE TABLEAU RTVL EST INSUFFISANT
C     *****************************************************************
      INTEGER IT,NBE,NBEMAX,ITRNOE(*),NBNMAX,ITRTRI(*),NBCMAX
      INTEGER IDIMC,NOETRI(*),NOEMAX
      INTEGER IMAT(*),NBRMAX,IMATMX
      INTEGER NBN,NBPMAX,NBENEW,IERR
      INTEGER ITYPS,NRTMAX 
      REAL    RTVL(*),COORD(*),TSIO,TSIE,RSG
C
      INTEGER  ITD,IO,IE,I,NBPI,IENEW,INNEW,IDE,K
      REAL     TIT,TSIO2,TSIE2
      REAL     VSD, TSNUL, XPNUL(3)
C
C         --------------------------
C     ---- CALCUL DE LA PROGRESSION ----
C         --------------------------
      IERR = 0
      NBENEW = 0
      NBPI = 0
      IDE = 1
      IO  = ITRNOE((IT-1)*NBNMAX+1)
      IE  = ITRNOE((IT-1)*NBNMAX+2)
C     --- cas des aretes degenere = sommets isoles
      IF((NBNMAX.LE.1).OR.(IE.EQ.0))GOTO 9999
      IF((IE.LE.0 ).OR.(IO.LE.0))THEN
        IERR = -1
        CALL DSERRE(1,IERR,' R1ARNO ','EXTREMITES D ARETE INCORRECTS')
      ENDIF
      TSIO2 = TSIO
      TSIE2 = TSIE
C        ----------------------
C     --- AMORTISSEMENT OU PAS ---
C        ----------------------
      CALL GBARYC(ITRNOE((IT-1)*NBNMAX+1),2,COORD,IDIMC,XPNUL,IERR)
      CALL GTAILL(ITRNOE((IT-1)*NBNMAX+1),2,IDE,COORD,IDIMC,TIT,IERR)
      TIT = TIT / 2.0
C      CALL SCSUPO(ITYPS,TSIO,RSG, (TIT / 2.0),TSNUL)      
C      CALL SCSUPO(ITYPS,TSIE,RSG, (TIT / 2.0),VSD)    
C     BUG ? POURQUOI REDIVISE T-ON PAR 2 ?  
      CALL SCSUPO(ITYPS,TSIO,RSG, TIT ,TSNUL)      
      CALL SCSUPO(ITYPS,TSIE,RSG, TIT ,VSD)      
      TSNUL = MIN(TSNUL,VSD)
      IF(( TSNUL.GT.TSIO2 ).AND.(TSNUL.GT.TSIE2))THEN
C        ----------------------
C     --- AMORTISSEMENT DE RSG ---
C        ----------------------
      CALL POSUNM(COORD((IO-1)*IDIMC+1),XPNUL,COORD((IE-1)*IDIMC+1),
     >                IDIMC,TSIO2,TSNUL,TSIE2,ITYPS,
     >                RTVL,NRTMAX,NBPI,IERR)
      ELSE
C        ----------------------
C     --- PAS D'AMORTISSEMENT  ---
C        ----------------------
      CALL POSUM(COORD((IO-1)*IDIMC+1),COORD((IE-1)*IDIMC+1),IDIMC,
     >              TSIO2,TSIE2,ITYPS,RTVL,NRTMAX,NBPI,IERR)        
      ENDIF
C
      IF( IERR.NE. 0 )THEN
        CALL DSERRE(1,IERR,'R1ARNO','APPEL POSUNM OU POSUM')
        GOTO 9999
      ENDIF
C        -----------------------        
C     --- DECOUPAGE DU MAILLAGE ---   
C        -----------------------
      NBENEW = NBPI
      IF( ((NBENEW+NBE).GT.NBEMAX).OR.
     >    ((NBENEW+NBN).GT.NBPMAX) )THEN
        IERR = -2
        CALL DSERRE(1,IERR,'R1ARNO','TROP D ELEMENTS')
        GO TO 9999
      ENDIF
C
      ITD = IT
      DO 10 I=1,NBPI
        CALL S0AJNO(RTVL((I-1)*IDIMC+1),COORD,IDIMC,NBN,
     >                  NBPMAX,NOETRI,NOEMAX,INNEW,IERR)
        IF( IERR .NE. 0 )THEN
          CALL DSERRE(1,IERR,'R1ARNO','APPEL S0AJNO')
          GOTO 9999
        ENDIF
        CALL S1AJNO(ITD,INNEW,NBE,ITRNOE,NBNMAX,ITRTRI,NBCMAX,
     >                   NOETRI,NOEMAX,IENEW,IERR)
        IF( IERR .NE. 0 )THEN
          CALL DSERRE(1,IERR,'R1ARNO','APPEL S1AJNO')
          GOTO 9999
        ENDIF
C        IF( IMATMX.GT.IENEW )IMAT(IENEW) = IMAT(ITD)
C       REMPLACE PAR :
        IF( IMATMX.GT.IENEW )THEN
          DO 5 K=1,NBRMAX
            IMAT((IENEW-1)*NBRMAX+K) = IMAT((ITD-1)*NBRMAX+K)
    5     CONTINUE
        ENDIF
        ITD = IENEW
   10 CONTINUE
C
 9999 END          
C
      SUBROUTINE R1RAF(ITYPS,RSG,
     >          ITRNOE,NBNMAX,ITRTRI,NBCMAX,NOETRI,NOEMAX,
     >          COORD,IDIMC,NBN,NBE,NBPMAX,NBEMAX,NCC,
     >          IMAT,NBRMAX,IMATMX,
     >          RTVL,NRTMAX,ITVL,NITMAX,NCCMAX,IERR)
C     *****************************************************************
C     OBJET R1RAF :   RAFINE PAR DEFAUT UN MAILLAGE LINEIQUE
C               APPEL DENS1DDEF POUR LA DEFINITION DES DENSITES
C               APPEL R1NO POUR LE DECOUPAGE
C      EN ENTREE: 
C      ------------ LE MAILLAGE ----------- 
C      ITRNOE,NBNMAX,ITRTRI,NBCMAX,NOETRI,NOEMAX : LE MAILLAGE
C      NOEMAX : SI = 0 ON NE REMPLI PAS NOETRI SINON = NBPMAX
C      COORD,IDIMC,NBN : COORDONNEES DES NOEUDS
C      NBE      : LE NOMBRE D'ELEMENTS
C      NCC      : LE NOMBRE DE COMPOSANTES CONNEXES
C                  = 0 SI INCONNU.
C      NBPMAX   : NOMBRE MAXIMUM DE POINTS DANS COORD
C      NBEMAX   : NOMBRE MAXIMUM D'ELEMENTS
C       --------- LES REGIONS ---------------------
C       IMAT     : SI IMATMX == 0, PAS DE DEFINITION DE REGION
C                  SI IMATMX == 1, UNE SEULE REGION
C                : IMAT((I-1*NBRMAX+K) = REFERENCE K DE L'ELEMENT I 
C                    (SI IMATMX > 0)

C       IMATMX    : TAILLE DE IMAT = 0,1, OU NBEMAX
C
C      ---  TABLEAU DE TRAVAIL ---------------------
C      ITVL : TABLEAU DE TRAVAIL OU SONT STOQUEES LES 
C                 DIFFERENTES COMPOSANTES CONNEXES. 
C      NITMAX  : TAILLE DE ITVL
C                 SI NCC = 1 ITVL NE SERT A RIEN
C                 AU MINIMUM = NBCCMAX + 2*NBE + 3
C                 AU MAXIMUM = NBCCMAX + 2*NBE + 3*NBE
C      NCCMAX   : NOMBRE MAXIMUM DE COMPOSANTES CONNEXES
C      RTVL : TABLEAU DE TRAVAIL OU SONT STOQUEES LES COORDONNEES
C                 DES POINTS CALCULES SUR UNE ARETE 
C      NPSMAX : NOMBRE MAXIMUM DE POINTS GENERES SUR UNE ARETE

C      ---- DEFINITION DU RAFFINEMENT --------------
C      ITYPS    : TYPE D'AMORTISSEMENT
C      RSG      : RAISON DE L'AMORTISSEMENT
C
C      EN SORTIE:  LE MAILLAGE MODIFIE
C      -----------
C      NBN      : NOMBRE DE NOEUDS APRES LE RAFFINEMENT
C      NBE      : "      D'ELEMENTS APRES  "    "    "
C      IERR     : CODE D'ERREUR 0 SI OK
C                -1 SI LES DONNEES SONT INCORRECTES
C                -2 SI ITVL OU RTVL EST TROP PETIT
C
C     REMARQUES IMPORTANTES :
C     -----------------------
C      EN ENTREE LE MAILLAGE PEUT ETRE :
C      - COMPOSE DE PLUSIEURS COMPOSANTES CONNEXES ;
C      - COMPOSE DE CHAINES FERMEES OU OUVERTES ;
C      - COMPOSE D'ARETES DANS UN ESPACE DE DIMENSION 1, 2 OU 3.
C      PAR CONTRE :
C      - UN NOEUD NE DOIT APPARTENIR QU'A UNE OU DEUX ARETES  ;
C      - L'EPAISSEUR DU DOMAINE N'EST PAS PRISE EN COMPTE ;
C     *****************************************************************
      INTEGER ITYPS
      REAL    RSG
      INTEGER ITRNOE(*),NBNMAX,ITRTRI(*),NBCMAX,NOETRI(*),NOEMAX
      INTEGER IMAT(*),NBRMAX,IMATMX
      REAL    COORD(*)
      INTEGER IDIMC,NBN,NBE,NBPMAX,NBEMAX,NCC
      REAL    RTVL(*)
      INTEGER NRTMAX,ITVL(*),NITMAX,NCCMAX,IERR
C
      INTEGER ITSN,NTSMAX,IPT,NPSMAX
C        ===================================
C     --- 1. CALCUL DES DENSITES PAR DEFAUT ---
C        ===================================
      ITSN = 1
      NTSMAX = NRTMAX
      CALL D1DSLN(ITYPS,RSG,
     >          ITRNOE,NBNMAX,COORD,IDIMC,NBE,
     >          RTVL(ITSN),NTSMAX,IERR)
C     --- PLUS BESOIN DE LA STRUCTURE EN 2.0.0
C      CALL D1DS(ITYPS,RSG,
C     >        ITRNOE,NBNMAX,ITRTRI,NBCMAX,NOETRI,NOEMAX,
C     >        COORD,IDIMC,NBN,NBE,NBPMAX,NBEMAX,NCC,
C     >        ITVL,NITMAX,NCCMAX,RTVL(ITSN),NTSMAX,IERR)
      IF( IERR.NE.0 )THEN
        CALL DSERRE(1,IERR,'R1RAF','APPEL D1DSLN')
        GOTO 9999
      ENDIF
C        ===================================
C     --- 2. CALCUL DES NOEUDS              ---
C        ===================================
      IPT = NBN + ITSN
      NPSMAX = NRTMAX - IPT
      CALL R1NO(ITYPS,RSG,
     >        ITRNOE,NBNMAX,ITRTRI,NBCMAX,NOETRI,NOEMAX,
     >        COORD,IDIMC,NBN,NBE,NBPMAX,NBEMAX,
C     >        IMAT,IMATMX,
     >        IMAT,NBRMAX,IMATMX,
     >        RTVL(IPT),NPSMAX,RTVL(ITSN),IERR)
C
      IF( IERR.NE.0 )THEN
        CALL DSERRE(1,IERR,'R1RAF','APPEL R1NO')
        GOTO 9999
      ENDIF
 9999 END
C
C
      SUBROUTINE R1LIS(NUMP,ITYPS,RSG,
     >                      ITRNOE,NBNMAX,ITRTRI,NBCMAX,
     >                      NOETRI,COORD,IDIMC,DEPLAC,IERR)
C     *****************************************************************
C     OBJET R1LIS : REGULARISE LA POSITION D'UN POINT DANS UN MAILLAGE 1D
C     EN ENTREE :
C         NUMP       : LE NUMERO DU POINT A REGULARISER
C         COORD   : TABLEAU DES COORDONNEES DES POINTS
C         IDIMC   : DIMENSION DE L'ESPACE
C         ITYPS   : TYPE DE LA SUITE
C         RSG     : RAISON DE LA SUITE
C         ITRNOE,NBNMAX,ITRTRI,NBCMAX,NOETRI : LE MAILLAGE
C     EN SORTIE :
C         DEPLAC  : NORME DU DEPLACEMENT RELATIF
C         IERR    : -1 SI ERREUR 0 SI OK
C     *****************************************************************
      INTEGER NUMP,ITRNOE(*),NBNMAX,ITRTRI(*),NBCMAX,NOETRI(*)
      INTEGER IDIMC,IERR,ITYPS
      REAL    COORD(*),RSG,DEPLAC
C
      INTEGER IT2,IT,NUMP1,NUMP3
      REAL    XPN(3)
C
      IERR =0
      DEPLAC = 0.0
C     --- cas des aretes degenere = sommets isoles
      IF(NBNMAX.LE.1)GOTO 9999
      IT  = NOETRI(NUMP)
      IF( IT.LE.0 )THEN
           IERR = -1
           CALL DSERRE(1,IERR,'R1LIS',' STRUCTURE NOETRI INEXISTANTE')
           IERR = 0
           CALL DSERRE(1,IERR,'R1LIS',' SOMMET ISOLE')
           GOTO 9999
         ENDIF 
      NUMP1  = ITRNOE((IT-1)*NBNMAX+1)
      IF( NUMP1.EQ.NUMP )THEN
C        --- NUMP EST L'ORIGINE DE IT ---
         IT2 =  ITRTRI((IT-1)*NBCMAX+1)
         IF( IT2.LE.0 )THEN
           IERR = -1
           CALL DSERRE(1,IERR,'R1LIS',' STRUCTURE ITRTRI INEXISTANTE')
           GOTO 9999
         ENDIF 
         NUMP1  =  ITRNOE((IT2-1)*NBNMAX+1)
         NUMP3  =  ITRNOE((IT-1)*NBNMAX+2)
      ELSE
C        --- NUMP EST L'EXTREMITE DE IT ---
         IT2 =  ITRTRI((IT-1)*NBCMAX+2) 
         IF( IT2.LE.0 )THEN
           IERR = -1
           CALL DSERRE(1,IERR,'R1LIS',' STRUCTURE ITRTRI INEXISTANTE')
           GOTO 9999
         ENDIF 
         NUMP3  =  ITRNOE((IT2-1)*NBNMAX+2)
         NUMP1  =  ITRNOE((IT-1)*NBNMAX+1)
      ENDIF   
C     
      IF((NUMP1.LE.0 ).OR.(NUMP3.LE.0))THEN
        IERR = -1
        CALL DSERRE(1,IERR,' R1LIS ','EXTREMITES D ARETE INCORRECTS')
      ENDIF
C
      CALL LISUPO(COORD((NUMP1-1)*IDIMC+1),COORD((NUMP-1)*IDIMC+1),
     >      COORD((NUMP3-1)*IDIMC+1),IDIMC,ITYPS,RSG,XPN,DEPLAC,IERR)
      IF( IERR .NE. 0 )THEN
        CALL DSERRE(1,IERR,'R1LIS',' APPEL LISUPO')
        GOTO 9999
      ENDIF
      IF(DEPLAC.GT.0.0)CALL COPIVE(XPN,IDIMC,COORD((NUMP-1)*IDIMC+1))
 9999 END
C      
C



C     **********************************************************************
C     MODULE   : 
C     FICHIER  : RF_RAF1D.F (RF_RAF3D.F)
C     OBJET    : RAFFINEMENT DES SEGMENTS
C     FONCT.   :
C       R1DIR  : RAFINE DIRECTEMENT UNE ARETE DU MAILLAGE
C       R1RECH : RECHERCHE DE L'ELEMENT A RAFINER (ITERATIF) (LOCAL)
C       R1ITER : RAFFINE ITERATIVEMENT UN MAILLAGE EN SEGMENTS
C       R1RAFF : RAFFINE UN MAILLAGE EN SEGMENTS 2D/3D
C
C     AUTEUR   : O. STAB
C     DATE     : 15.06.98
C     TESTS    : 
C     MODIFICATIONS :
C        AUTEUR, DATE, OBJET : 
C        O.STAB, 30.07.99, AJOUT DE NBRMAX POUR LE MULTI-REFERENCE DANS :
C          R1DIR, R1ITER, R1RAFF
C        O.STAB, 25.09.2003, AJOUT WARNING MODGEN != 1 (DANS R1RAFF)
C        O.STAB, 02.02.2005, bug dans R1DIR limitation des noeuds
C
C     **********************************************************************
C
      SUBROUTINE R1DIR(MODDEF,IARD,FADEC,ITAB,RTAB,
     >          ITRNOE,NBNMAX,ITRTRI,NBCMAX,NOETRI,NOEMAX,
     >          ITBREG,NBRMAX,IRGMAX,
     >          COORD,IDIMC,NBN,NBE,NBPMAX,NBEMAX,
     >          RTVL,IRMAX,NBENEW,IERR)
C     *****************************************************************
C     OBJET R1DIR :   RAFINE DIRECTEMENT UNE ARETE DU MAILLAGE
C     EN ENTREE 
C       MODDEF    : IL Y A 3 MODES DE FONCTIONNEMENT
C        (1) LE MODE DEFAUT SIMPLE
C        (2) LE MODE CONCENTRATIONS(X,Y)
C        (3) LE MODE VALEURS NODALES
C       --------- LE DECOUPAGE -------------------
C       IARD      : NUMERO DE L'ARETE A DECOUPER
C       FADEC     : INUTILISE
C       ITAB     : PARAMETRES ENTIERS DE LA FONCTION FADEC
C       RTAB     : PARAMETRES REELS DE LA FONCTION FADEC
C
C       RTVL  : TABLEAU DE TRAVAIL TAILLE NECESSAIRE = NOMBRE MAX.
C                     DE NOEUDS RENVOYES PAR FADEC
C       IRMAX      : TAILLE MAX. DE RTVL
C       --------- LE MAILLAGE ---------------------
C       ITRNOE,NBNMAX,ITRTRI,NBCMAX,NOETRI,NOEMAX,NBN,NBE : LE MAILLAGE
C       COORD,IDIMC: LES COORDONNEES DES NOEUDS
C       NBPMAX     : NOMBRE MAXIMUM DE POINTS
C       NBEMAX     : NOMBRE MAXIMUM D'ELEMENTS
C       ITBREG     : ITBREG((I-1)*NBRMAX+K) = REFERENCE K DE L'ELEMENT I
C       IRGMAX     : TAILLE DE ITBREG
C
C     EN SORTIE    : LE MAILLAGE MODIFIE
C       NBENEW     : LE NOMBRE D'ARETES GENEREES
C       IERR       : CODE D'ERREUR 
C                    0 SI OK
C                    1 SI ON A PAS PU GENERER TOUS LES POINTS !
C                   -1 SI LES DONNEES SONT INCORRECTES
C                   -2 SI LE TABLEAU RTVL EST INSUFFISANT
C
C     REMARQUE   : POUR RETROUVER TOUS LES ELEMENTS ET NOEUDS GENERES
C                  IL SUFFIT DE REPARTIR DE IARD ET DE PARCOURIR LES
C                  NBENEW ARETES SUIVANTES
C
C     MODIFICATION : 
C        O.STAB, 30.07.99, AJOUT DE NRGMAX POUR LE MULTI-REFERENCE
C        O.STAB, 10.01.05, RETOUR POUR LES ARETES DEGENEREES (SOMMETS ISOLES)
C     *****************************************************************
      INTEGER MODDEF
      INTEGER IARD,ITAB(*)
      REAL    RTAB(*)
      INTEGER NBRMAX
      INTEGER NBE,NBEMAX,ITRNOE(*),NBNMAX,ITRTRI(*),NBCMAX
      INTEGER IDIMC,NOETRI(*),NOEMAX, ITBREG(*),IRGMAX
      INTEGER NBN,NBPMAX,IRMAX,NBENEW,IERR
      REAL    COORD(*),RTVL(*)
C
      INTEGER  IE,IORIG,IEXTR,NIAD,I,K,INNEW,IENEW
      REAL     TS1,TS2,V1(3),S12,RSGCAL
      INTEGER  ITYPS
      REAL     XNORVE
      EXTERNAL FADEC,XNORVE
C
      NBENEW = 0
      IE = IARD
      IORIG = ITRNOE((IE-1)*NBNMAX+1)
      IEXTR = ITRNOE((IE-1)*NBNMAX+2)
C     --- Ajout 10.01.2005, pour les aretes degeneree : 
      IF((IORIG.EQ.IEXTR).OR.(IEXTR.EQ.0))GOTO 9999
C         =====================================
C     ---- CALCUL DES POINTS SUR LE SEGMENT    ---------------------
C         =====================================
      GOTO (10,20,30) MODDEF
C         ---------------------------
C     --- DEFINITION DE TYPE INCONNUE ---
C         ---------------------------
      IERR = -1
      GOTO 9999 
C         ---------------------------------------------
C     --- DEFINITION PAR DEFAUT (C'EST UNE ERREUR ICI) ---
C         ---------------------------------------------
 10   CONTINUE
      IERR = -1
      GOTO 9999
C         -----------------------------
C     --- DEFINITION FONCTION SPATIALE ---
C         -----------------------------
 20   CONTINUE
C      CALL D1SU(COORD((IORIG-1)*IDIMC+1),COORD((IEXTR-1)*IDIMC+1),IDIMC,
      CALL D1SU2(COORD((IORIG-1)*IDIMC+1),
     >           COORD((IEXTR-1)*IDIMC+1),IDIMC,
     >          ITAB(1),RTAB(2),RTAB(1),ITAB(2),RTAB(3),
C     >         ITYPS,  TSP,    RSG,    ITYPO,  ROBJET,
C     >          RTVL((I-1)*IDIMC+1),NBPMAX,NIAD,IERR)
     >          RTVL,(IRMAX/IDIMC),NIAD,IERR)
      GOTO 40
C         -------------------------------
C     --- DEFINITION VALEURS AUX NOEUDS ---
C         -------------------------------
 30   CONTINUE
C     LA TAILLE SOUHAITEE EST DONNEE AUX NOEUDS.
C     ON CALCULE LES POINTS RESPECTANT SUIVANT UNE SUITE GEOMETRIQUE
      TS1 = RTAB(IORIG)
      TS2 = RTAB(IEXTR)
      ITYPS = 1
C     ---- COPIE DE POSUM ----       
      CALL DIFFVE(COORD((IEXTR-1)*IDIMC+1),
     >            COORD((IORIG-1)*IDIMC+1),IDIMC,V1)
      S12 = XNORVE(V1,IDIMC)
      CALL SU2PO(ITYPS,S12,TS1,TS2,NIAD,RSGCAL,IERR)
      IF( IERR .NE. 0 )GOTO 8888
      IF( NIAD .LE. 0 )THEN
        NIAD = 0
        GOTO 40
      ENDIF
C     --- RECALALGE DES VALEURS TS1, TS2 ---      
      CALL SCSUSE(ITYPS,S12,NIAD,RSGCAL,TS1,TS2,IERR)
      IF( IERR .NE. 0 )GOTO 8888
      IF( NIAD .GT. NBPMAX )THEN
        IERR = -2
        CALL DSERRE(1,IERR,'R1DIR','TROP DE POINTS')
        GO TO 9999
      ENDIF
      S12 = 1.0 / S12
      CALL MUSCVE(V1,S12,IDIMC,V1)
      CALL SUPTSU(COORD((IORIG-1)*IDIMC+1),
     >            V1,IDIMC,ITYPS,TS1,NIAD,RSGCAL,
c     >            RTVL((I-1)*IDIMC+1),IERR)
     >            RTVL,IERR)
C     ---- FIN DE LA COPIE DE POSUM ----       
C      CALL POSUM(COORD((IORIG-1)*IDIMC+1),
C     >           COORD((IEXTR-1)*IDIMC+1),IDIMC,
C     >           TS1,TS2,ITYPS,RTVL((I-1)*IDIMC+1),NBPMAX,NIAD,IERR)
      GOTO 40
C
 40   CONTINUE
      IF( IERR.NE.0)THEN
        CALL DSERRE(1,IERR,'R1DIR','APPEL POSUM OU D1SU')
        GOTO 9999
      ENDIF
      IF( NIAD .EQ. 0 )GOTO 9999
C         =====================================
C     ---- INSERTION DANS LE MAILLAGE LINEIQUE ---------------------
C         =====================================
      NBENEW = MIN(NIAD,NBPMAX-NBN)
      IE = IARD
      DO 50 I=1,NBENEW
         CALL S0AJNO(RTVL((I-1)*IDIMC+1),COORD,IDIMC,NBN,
     >                 NBPMAX,NOETRI,NOEMAX,INNEW,IERR)
         IF( IERR .NE. 0 )GOTO 8888 
         CALL S1AJNO(IE,INNEW,NBE,ITRNOE,NBNMAX,ITRTRI,NBCMAX,
     >                 NOETRI,NOEMAX,IENEW,IERR)
        IF( IERR .NE. 0 )GOTO 8888
C       --- LA TAILLE SOUHAITEE AU NOUVEAU NOEUD ---
C           (ELLE EST DONNE PAR LA SUITE GEOMETRIQUE)
        IF( MODDEF.EQ.3 )THEN
          CALL DIFFVE(COORD((INNEW-1)*IDIMC+1),
     >                COORD((IORIG-1)*IDIMC+1),IDIMC,V1)
          S12 = XNORVE(V1,IDIMC)
          CALL SCSUPO(ITYPS,TS1,RSGCAL,S12,TS2)
          RTAB(INNEW) = TS2
        ENDIF
C       --- HERITAGE DES MATERIAUX ---
C        IF( IENEW.LE.IRGMAX )ITBREG( IENEW ) = ITBREG( IARD )
C       REMPLACE PAR : O.STAB, 30.07.99 POUR LE MULTI-REFERENCES
C       --- HERITAGE DES REFERENCES ---
        IF( IENEW.LE.IRGMAX )THEN
          DO 45 K=1,NBRMAX
            ITBREG((IENEW-1)*NBRMAX+K) = ITBREG((IARD-1)*NBRMAX+K)
   45     CONTINUE
        ENDIF
C       --- FIN MODIF
        IE = IENEW
   50 CONTINUE
C     --- ON A PAS PU GENERER TOUS LES POINTS ---
C      IF((NIAD+NBN).GT.NBPMAX)THEN  --> bug 02.02.2005 NBN est incremente dans S0AJNO
      IF(NIAD.GT.NBENEW)THEN
         IERR = 1
         GOTO 9999
      ENDIF
C
 8888 IF( IERR .NE. 0 )CALL DSERRE(1,IERR,'R1DIR','ERREUR EN SORTIE')
 9999 END
C
C
      SUBROUTINE R1RECH(IDIMC,ITRNOE,NBNMAX,NBE,COORD,TBCOEF,
     >                      NBTMAX,IT,XPT,COEF,IERR)
C     **********************************************************************
C     OBJET R1RECH : CHERCHE L'ELEMENT LINEIQUE A RAFFINER (ITERATIF) (LOCAL)
C     EN ENTREE  :
C       COORD          : COORDONNEES DES POINTS 
C       IDIMC          : DIMENSION DE L'ESPACE
C       ITRNOE,NBNMAX  : SOMMETS DES ELEMENTS
C       NBE            : NOMBRE D'ELEMENTS
C       TBCOEF         : TABLEAU DES COEFICIENTS DE RAFFINEMENT
C       NBTMAX         : INUTILISE (GARDE LA SIGNATURE DE RFRECH)
C
C     EN SORTIE  : 
C       IT             : L'ELEMENT A REFFINER
C       XPT            : LE POINT A AJOUTER
C       COEF           : LA VALEUR DU RAFFINEMENT [0-1]
C                        PLUS COEF EST PETIT PLUS ON RAFFINE
C       IERR           : CODE D'ERREUR (INUTILISE)
C     **********************************************************************
      REAL       COORD(*),TBCOEF(*)
      INTEGER    IDIMC,ITRNOE(*),NBNMAX,NBE,NBTMAX,IT,IERR
      REAL       COEF,XPT(*)
C
      INTEGER  I,NUMP1,NUMP2
      REAL     LRCMIN,XDEMI
C
      LRCMIN = 1.0
      XDEMI = 0.5
      IT = 0
C     --- RECHERCHE DU PLUS PETIT COEF = TS/TR  ---
      DO 10 I=1,NBE 
        IF( TBCOEF(I) .LT. LRCMIN )THEN
          IT = I
          LRCMIN = TBCOEF(I)
        ENDIF
   10 CONTINUE
C
      IF( IT.EQ. 0 )THEN
        COEF = 1.
        GOTO 9999
      ENDIF
C     --- MILIEU DU SEGMENT ------------------
      NUMP1 = ITRNOE((IT-1)*NBNMAX+1)
      NUMP2 = ITRNOE((IT-1)*NBNMAX+2)
      CALL SOMMVE(COORD((NUMP1-1)*IDIMC+1),
     >            COORD((NUMP2-1)*IDIMC+1),IDIMC,XPT)
      CALL MUSCVE(XPT,XDEMI,IDIMC,XPT)
C
      COEF = LRCMIN
 9999 END
C
      SUBROUTINE R1ITER(FADEC,ITAB,RTAB,MODDEF,
     >          ITRNOE,NBNMAX,ITRTRI,NBCMAX,NOETRI,NOEMAX,
     >          ITBREG,NBRMAX,NMT,
     >          COORD,IDIMC,NBN,NBE,NBPMAX,NBEMAX,
     >          ITVL,IMAX,RTVL,IRMAX,NBENEW,IERR)
C     *****************************************************************
C     OBJET R1ITER : RAFFINE ITERATIVEMENT UN MAILLAGE LINEIQUE (APPEL FADEC)
C     EN ENTREE 
C       --------- LE DECOUPAGE -------------------
C       FADEC     : FONCTION D'EVALUATION DU DECOUPAGE ET DE
C                   CALCUL D'UN NOEUD, ELLE A LE FORMAT SUIVANT :
C   
C           FADEC(IT,ITRNOE,NBNMAX,ITRTRI,NBCMAX,
C                 COORD,IDIMC,TBCOEF,NBTMAX,ITAB,RTAB,COEF,TS,IERR)
C           CF. D2IDEF
C 
C       ITAB     : PARAMETRES ENTIERS DE LA FONCTION FADEC
C       RTAB     : PARAMETRES REELS DE LA FONCTION FADEC
C       MODDEF    : IL Y A 3 MODES DE FONCTIONNEMENT
C        (1) LE MODE DEFAUT SIMPLE
C        (2) LE MODE CONCENTRATIONS(X,Y)
C        (3) LE MODE VALEURS NODALES
C
C       --------- TABLEAUX DE TRAVAIL -------------------
C       ITVL     : TABLEAU DE TRAVAIL (???)
C       IMAX     : TAILLE DU TABLEAU DE TRAVAIL
C       RTVL     : TABLEAU DE TRAVAIL COORDONNEES + TBCOEFERES
C       IRMAX    : TAILLE DE RTVL >= ???
C       --------- LE MAILLAGE ---------------------
C       ITRNOE,NBNMAX,ITRTRI,NBCMAX,NOETRI,NOEMAX,NBN,NBE : LE MAILLAGE
C       COORD,IDIMC: LES COORDONNEES DES NOEUDS
C       NBPMAX     : NOMBRE MAXIMUM DE POINTS
C       NBEMAX     : NOMBRE MAXIMUM D'ELEMENTS
C       --------- LES REGIONS ---------------------
C       ITBREG     : SI NMT == 0, PAS DE DEFINITION DE REGION
C                    SI NMT == 1, UNE SEULE REGION
C                    SI NMT >  1, ITBREG((I-1)*NBRMAX) = REGION K DE L'ELEMENT I
C       MNT        : TAILLE DE ITBREG = 0,1*NBRMAX, OU NBEMAX*NBRMAX
C
C     EN SORTIE     : LE MAILLAGE MODIFIE
C       NBN       : LE NOMBRE DE NOEUDS = NBP + NBPNEW
C       NBE       : LE NOMBRE D'ELEMENTS = NBPNEW + NBE
C       NBENEW    : LE NOMBRE D'ELEMENTS GENEREES = NBPNEW
C       IERR      : CODE D'ERREUR
C                       2 LE NOMBRE D'ELEMENTS MAXIMUM EST ATTEINT (MEMOIRE)
C                       1 LE NOMBRE DE NOEUDS MAXIMUM (DONNE) EST ATTEINT 
C                       0 LA TAILLE SOUHAITEE EST ATTEINTE
C                      -1 TOUS LES POINTS N'ONT PAS PU ETRE AJOUTES
C                      -2 ITVL OU RTVL TROP PETIT
C     REMARQUES :
C       NBPNEW    : LE NOMBRE DE NOEUDS GENERES = NBENEW / 2
C     **********************************************************************
      INTEGER ITAB(*),MODDEF
      REAL    RTAB(*)
      INTEGER NBE,NBEMAX,ITRNOE(*),NBNMAX,ITRTRI(*),NBCMAX
      INTEGER ITVL(*),IMAX
      INTEGER IDIMC,NOETRI(*),NOEMAX,NBN,NBPMAX,IRMAX,NBENEW,IERR
      INTEGER ITBREG(*),NBRMAX,NMT
      REAL    COORD(*),RTVL(*)
      EXTERNAL FADEC
C
C     --- POUR LES STATS ---
      REAL      ZEROTR 
      PARAMETER ( ZEROTR = 1.E-30 )
C     --- VARIABLES INTERNES ---
      REAL    XPT(3)
      INTEGER IDE,NCOORD,I,IPT,ITCOEF,ICOORD,IT,IPTNEW,IENEW,K
      REAL    COEF,TS,RTVNUL(1)
      INTEGER NBTMAX,NBTNEW,ITRACE,NBRMX2
      REAL    COEFMX
C     --- RAPPORT MINI COEFMX = TS/TR = 1/1.5 ---
      DATA COEFMX/0.66666666666666666666/
C          
C          ====================================
C
C     =====          INITIALISATION            =====
C
C          ====================================
C
C     TEST DES ENTREES
C     NORMALISATION DES POINTS (PTINIT)
C     TRI DES ELEMENTS A RAFFINER
C
      NBENEW = 0      
      ITRACE = 1
C     --- ON STOQUE LE COEFFICIENT DES ELEMENTS ----
      NBTMAX = 1
C     --- MAIS PAS LA TAILLE DES SEGMENTS ---
      NBRMX2 = 0
      IERR   = 0
      IPTNEW = 0
      IDE    = 1
      NCOORD = NBN
C
C     LE NOMBRE MAXIMUM DE NOEUDS DONNE PAR L'UTILISATEUR EST ATTEINT
C     
      IF( NBN.EQ.NBPMAX )THEN
        IERR = 1
        GOTO 9999
      ENDIF
C
      IF((NBN.EQ.0).OR.(IDIMC.LT. 1).OR.(IDIMC.GT. 3))THEN
        IERR = -1
        CALL DSERRE(1,IERR,'R1ITER',' DONNEES INCORRECTES ')
C        PRINT *,'NBN,IDIMC = ',NBN,IDIMC
        GOTO 9999
      ENDIF
      IF(NBNMAX.LT.IDE)THEN
        IERR = -1
        CALL DSERRE(1,IERR,'R1ITER',' DONNEES INCOMPATIBLES ')
C        PRINT *,'NBNMAX,NBCMAX,IDE = ',NBNMAX,NBCMAX,IDE
        GOTO 9999
      ENDIF
C
      ICOORD = 1
      ITCOEF   = (IDIMC * NBPMAX)  + ICOORD
C      IF( (IRMAX-ITCOEF).LT.NBPMAX)THEN
C     MODIF 25.09.2003 : memoire mal evaluee :
      IF( (IRMAX-(ITCOEF-1)).LT.(NBPMAX+NBE*NBTMAX))THEN
        IERR = -2
        CALL DSERRE(1,IERR,'R1ITER',' TABLEAU DES REELS ')
        GOTO 9999
      ENDIF
C      CALL PTINIT(COORD,IDIMC,NBN,ZEROTR,RTVL(ICOORD),IERR)
C     --- ON NE NORMALISE PAS POUR POUVOIR DEBUGGER ---
      CALL COPIVE(COORD,(NBN*IDIMC),RTVL(ICOORD))
C        ----------------------------------------------------
C     --- CALCUL DES COEFICIENTS DES ELEMENTS ------
C        ----------------------------------------------------
      DO 20 I=1,NBE
        RTVL((I-1)*NBTMAX+ITCOEF) = 0.0
        CALL FADEC(I,ITRNOE,NBNMAX,ITRTRI,NBCMAX,
     >            RTVL(ICOORD),IDIMC,RTVNUL,NBRMX2,
     >            ITAB,RTAB,COEF,TS,IERR)
        IF( IERR .NE. 0  )THEN
          CALL DSERRE(1,IERR,'R1ITER',
     >        'APPEL FADEC (CALCUL DE LA TAILLE SOUHAITE)')          
          GOTO 9999
        ENDIF
        RTVL(I-1+ITCOEF) = COEF
   20 CONTINUE
C
      IPT = NBN 
C          
C          ====================================
C
C     ===== BOUCLE SUR LES ELEMENTS A RAFFINER  =====
C
C          ====================================
C
   30 CONTINUE
      IERR = 0
C          ------------------
C     ---- CHOIX DE L'ELEMENT  ----------------------
C          ------------------
      CALL R1RECH(IDIMC,ITRNOE,NBNMAX,
     >           NBE,RTVL(ICOORD),RTVL(ITCOEF),
     >           NBTMAX,IT,XPT,COEF,IERR)
C
        IF( IERR .NE. 0  )THEN
          CALL DSERRE(1,IERR,'R1ITER','APPEL R1RECH')          
          GOTO 9999
        ENDIF
C      IF( ITRACE.NE.0 )
C     >  PRINT *,' IT =',IT,' 2*L/RC =',COEF,' XPT = ',(XPT(J),J=1,IDIMC)
C        ------------------------------------------------          
C     ---- SORTIE DE BOUCLE : PLUS D'ELEMENTS A RAFFINER ---
C        ------------------------------------------------          
      IF((IT.EQ.0).OR.(COEF.GT.COEFMX))THEN
C     --- ON NE NORMALISE PAS POUR POUVOIR DEBUGGER ---
        IERR = 0
C        PRINT *,'NOMBRE DE NOEUD GENERES = ',NBN - NCOORD
C        PRINT *,'NOMBRE DE NOEUD TESTES = ',IPT - NCOORD
        GOTO 8888
      ENDIF
C        ----------------------------------------------------
C     --- TAILLE MINI. DES NOUVEAUX ELEMENTS                ------
C        ----------------------------------------------------
        CALL FADEC(IT,ITRNOE,NBNMAX,ITRTRI,NBCMAX,
     >            RTVL(ICOORD),IDIMC,RTVNUL,NBRMX2,
     >            ITAB,RTAB,COEF,TS,IERR)
      IF( IERR.NE.0 )THEN
        CALL DSERRE(1,IERR,'R1ITER','APPEL FADEC ')
        GOTO 9999
      ENDIF
C        ----------------------------------------------------
C     ---- INSERTION DANS LE MAILLAGE LINEIQUE               ------
C        ----------------------------------------------------
      IF(NBN+1.GT.NBPMAX)THEN
C       --- ON A ATTEIND LA LIMITE DONNEE PAR L'UTILISATEUR ---
        IERR = 1
        GOTO 8888
      ENDIF
C     --- AJOUT DU NOEUD ---
      IPT = IPT + 1
      CALL S0AJNO(XPT,RTVL(ICOORD),IDIMC,NBN,NBPMAX,
     >                NOETRI,NOEMAX,IPTNEW,IERR)  
      IF( IERR.NE.0 )THEN
        CALL DSERRE(1,IERR,'R1ITER','APPEL S0AJNO')
      ENDIF    
       CALL S1AJNO(IT,IPTNEW,NBE,ITRNOE,NBNMAX,ITRTRI,NBCMAX,
     >                 NOETRI,NOEMAX,IENEW,IERR)
C
      IF( IERR.NE.0 )THEN
        CALL DSERRE(1,IERR,'R1ITER','APPEL ARAJPO ')
        GOTO 9999
      ENDIF
C       --- L'ELEMENT NE PEUT PAS ETRE RAFFINE ---
C        ----------------------------------------------------
C     --- MISE A JOUR DES COEFICIENTS DES NOUVEAUX ELEMENTS ------
C        ----------------------------------------------------
C     AJOUT D'UNE LIGNE POUR LA MISE A JOUR DES CHAMPS POINTS
        IF(MODDEF.EQ.3)RTAB(IPTNEW) = TS
        NBENEW = NBENEW + NBTNEW
        CALL FADEC(IENEW,ITRNOE,NBNMAX,ITRTRI,NBCMAX,
     >            RTVL(ICOORD),IDIMC,RTVNUL,NBRMX2,
     >            ITAB,RTAB,COEF,TS,IERR)
      IF( IERR.NE.0 )THEN
        CALL DSERRE(1,IERR,'R1ITER','APPEL FADEC ')
        GOTO 9999
      ENDIF
        RTVL((IENEW-1)*NBTMAX+ITCOEF) = COEF
        CALL FADEC(IT,ITRNOE,NBNMAX,ITRTRI,NBCMAX,
     >            RTVL(ICOORD),IDIMC,RTVNUL,NBRMX2,
     >            ITAB,RTAB,COEF,TS,IERR)
      IF( IERR.NE.0 )THEN
        CALL DSERRE(1,IERR,'R1ITER','APPEL FADEC ')
        GOTO 9999
      ENDIF
        RTVL((IT-1)*NBTMAX+ITCOEF) = COEF
C       --- MISE A JOUR DES REGIONS ---
C        IF( NMT.GT.1)ITBREG(IENEW) = ITBREG(IT)
C       REMPLACE PAR : O.STAB, 30.07.99
        IF( NMT.GT.1)THEN
          DO 100 K=1,NBRMAX
            ITBREG((IENEW-1)*NBRMAX+K) = ITBREG((IT-1)*NBRMAX+K)
  100     CONTINUE
        ENDIF
      IF( IPTNEW .LT. NBPMAX )GO TO 30
C          
C          ====================================
C
C     =====           FIN                      =====
C
C          ====================================
C
C      PRINT *,' NOMBRE MAXIMUM DE NOEUDS GENERES',IPTNEW
C     --- ON NE NORMALISE PAS POUR POUVOIR DEBUGGER ---
      IERR = 1
C
 8888 CONTINUE
      CALL COPIVE(RTVL,(NBN*IDIMC),COORD)
C
 9999 END
C
C
C
      SUBROUTINE R1RAFF(MODDEF,MODGEN,
     >                 ITRNOE,NBNMAX,ITRTRI,NBCMAX,NOETRI,NOEMAX,
     >                 ITBREG,NBRMAX,NMT,
     >                 COORD,IDIMC,NBN,NBE,NBPMAX,NBEMAX,
     >                 FADEC,ITAB,NIADEC,RTAB,IRADEC,NFADEC,
     >                 ITVL,NITMAX,RTVL,NRTMAX,IERR)
C     **********************************************************************
C     OBJET R1RAFF : RAFFINE UN MAILLAGE LINEIQUE (APPELS R1DIR ET R1ITER)
C
C     EN ENTREE   :
C       MODDEF   : IL Y A 3 TYPES DE DEFINITIONS
C          1 LE MODE DEFAUT SIMPLE
C          2 LE MODE CONCENTRATIONS(X,Y)
C          3 LE MODE VALEURS NODALES
C       MODGEN   : IL Y A 3 MODES DE GENERATION
C          1 LE MODE DIRECT 
C          2 LE MODE ITERATIF
C          3 LE MODE ITERATIF + LISSAGE 
C
C       --------- LE MAILLAGE ---------------------
C       ITRNOE,NBNMAX,ITRTRI,NBCMAX,NOETRI,NOEMAX,NBN,NBE : LE MAILLAGE
C       COORD,IDIMC: LES COORDONNEES DES NOEUDS
C       NBPMAX     : NOMBRE MAXIMUM DE POINTS
C       NBEMAX     : NOMBRE MAXIMUM D'ELEMENTS
C
C       ---- DEFINITION DU RAFFINEMENT --------------
C       FADEC    :
C       ITAB((I-1)*NIADEC+1) : PARAMETRES ENTIERS DU IEME RAFFINEMENT
C       NIADEC  : NOMBRE MAX. DE PARAMETRES ENTIERS
C       RTAB((I-1)*NIADEC+1) : PARAMETRES REELS DU IEME RAFFINEMENT
C       IRADEC  : NOMBRE MAX. DE PARAMETRES REELS
C       NFADEC  : NOMBRE DE RAFFINEMENTS
C
C       --------- LES REGIONS ---------------------
C       ITBREG     : SI NMT == 0, PAS DE DEFINITION DE REGION
C                    SI NMT == 1, UNE SEULE REGION
C                    SI NMT >  1, ITBREG((I-1)*NBRMAX+K) = REGION K DE L'ELEMENT I
C       MNT        : TAILLE DE ITBREG = 0,1*NBRMAX, OU NBEMAX*NBRMAX
C
C       ---- TABLEAUX DE TRAVAIL --------------------
C       ITVL : SERT POUR TAJPOT                  
C       NITMAX  : TAILLE DE (6*NBADET+10) (CF. TAJPOT)
C       RTVL : TABLEAU DE REELS POUR LES CALCULS
C       NRTMAX  : TAILLE DE RTVL (8*NBNPMAX+244)
C
C     EN SORTIE     : LE MAILLAGE MODIFIE
C       NBE,NBN     : LE NOMBRE DE TRIANGLES ET DE NOEUDS APRES GENERATION
C       IERR        : 
C                        MAILLAGE CORRECT
C                      2 LE NOMBRE D'ELEMENTS MAXIMUM EST ATTEINT (MEMOIRE)
C                      1 LE NOMBRE DE NOEUDS MAXIMUM (DONNE) EST ATTEINT 
C                      0 OK
C                        MAILLAGE INCORRECT
C                     -1 SI DONNEES INCORRECTES
C                     -2 SI TABLEAUX INSUFFISANTS
C
C     MODIFICATION : O.STAB, 25.09.2003, AJOUT WARNING MODGEN != 1
C     **********************************************************************
      INTEGER    MODDEF,MODGEN
      INTEGER    NBE,NBEMAX,ITRNOE(*),NBNMAX,ITRTRI(*),NBCMAX
      INTEGER    NOETRI(*),NOEMAX,NBN,NBPMAX
      INTEGER    ITBREG(*),NBRMAX,NMT
      REAL       COORD(*)
      INTEGER    IDIMC,ITAB(*),NFADEC,NIADEC,IRADEC
      INTEGER    ITVL(*)
      REAL       RTAB(*),RTVL(*)
      INTEGER    NITMAX,NRTMAX,IERR
      EXTERNAL   FADEC
C
      INTEGER  NBENEW,I,J,NBE1,NBN1,ITYPS
      REAL     RSGMAX,DP1MAX,DP2MAX,DEPLAC,DP3MAX,DPAMAX
C
      IERR   = 0
      NBENEW = 0
C     *** ajout 25.09.2003 ***
      IF( MODGEN.NE.1)THEN
        CALL DSERRE(1,IERR,'R1RAFF',' ATTENTION MODE 2 ou 3 ')
      ENDIF
C     *** fin ajout ***
      GOTO (300,400,400) MODGEN
      IERR = -1
      GOTO 9999
C         =====================================
C      --- 1. RAFFINEMENT DIRECT               ---
C         =====================================
  300 CONTINUE
      DO 320 I=1,NFADEC
         NBE1 = NBE
C         WRITE(*,*) 'RAFIN = ',I
         DO 310 J=1,NBE1
           CALL R1DIR(MODDEF,J,FADEC,
     >          ITAB((I-1)*NIADEC+1),RTAB((I-1)*IRADEC+1),
     >          ITRNOE,NBNMAX,ITRTRI,NBCMAX,NOETRI,NOEMAX,
C     >          ITBREG,NMT,
     >          ITBREG,NBRMAX,NMT,
     >          COORD,IDIMC,NBN,NBE,NBPMAX,NBEMAX,
     >          RTVL,NRTMAX,NBENEW,IERR)
           IF( IERR.NE.0 )THEN
C             WRITE(*,*) 'ARETE = ',J
             GOTO 9999
           ENDIF
C          --- HERITAGE DU MATERIAU ---> DANS R1DIR MAINTENANT
C           IF( NMT.GT.0 )THEN
C             JS = J
C             DO 305 K=1,NBENEW
C               JS = ITRTRI((JS-1)*NBCMAX+2)
C               ITBREG(JS) = MATJ
C  305        CONTINUE
C           ENDIF
  310    CONTINUE
  320 CONTINUE
      GOTO 9999

C         =========================================
C      --- 2. RAFFINEMENT ITERATIF                 ---
C         =========================================
C
  400 CONTINUE
      NBN1 = NBN
      DO 420 I=1,NFADEC
         CALL R1ITER(FADEC,
     >            ITAB((I-1)*NIADEC+1),RTAB((I-1)*IRADEC+1),
     >            MODDEF,
     >            ITRNOE,NBNMAX,ITRTRI,NBCMAX,NOETRI,NOEMAX,
C     >            ITBREG,NMT,
     >            ITBREG,NBRMAX,NMT,
     >            COORD,IDIMC,NBN,NBE,NBPMAX,NBEMAX,
     >           ITVL,NITMAX,RTVL,NRTMAX,NBENEW,IERR)
        IF( IERR.NE.0 )GOTO 9999
  420 CONTINUE
      IF( MODGEN .NE. 3 )GOTO 9999
C         ============================
C      --- 3. AVEC REGULARISATION     ---
C         ============================
C     --- ON PREND LA DERNIERE SUITE ---
C      RSGMAX = RTAB(NFADEC*IRADEC+1)
C      DP1MAX = RTAB(NFADEC*IRADEC+2)
C      ITYPS  = ITAB(NFADEC*NIADEC+1)
C     COMMENT FAIT ON POUR TSN, DEFAUT ET MULTI CONCENTRATION ???
      RSGMAX = 1.25
C      DP1MAX = 1.E-8
C     NE CONVERGE PAS TOUJOURS !! VALEURS ABSOLUES A METTRE EN RELATIF !
      DP1MAX = 0.1
      ITYPS  = 1
      DP2MAX = 0.0
      DPAMAX = 1.E-6
C     --- C'EST LE DEPLACEMENT RELATIF MAXIMUM !!! -----
C      IF( DP1MAX.LT. 1.E-8 )DP1MAX = 1.E-8
  430 CONTINUE
      DP3MAX = DP2MAX
      DP2MAX = 0.0
      DO 440 I=NBN1+1,NBN
        CALL R1LIS(I,ITYPS,RSGMAX,ITRNOE,NBNMAX,ITRTRI,NBCMAX,
     >                  NOETRI,COORD,IDIMC,DEPLAC,IERR)
        DP2MAX = MAX(DEPLAC,DP2MAX)
        IF( IERR.NE.0 )GOTO 9999
  440 CONTINUE
C      PRINT *,'DEPLACEMENT MAX =',DP2MAX
      IF( DP2MAX .LT. DPAMAX )GOTO 9999
      IF( DP2MAX-DP3MAX / DP2MAX+DP3MAX .GT. DP1MAX )GOTO 430
C
 9999 END
C
      
      





C     **********************************************************************
C     FICHIER  : API_RAF1D.F
C     OBJET    : GENERATION ET INSERTION DES POINTS SUR UN MAILLAGE 1D
C
C     FONCT.   :
C     OBJET DS1FCT : RAFFINEMENT D'UN MAILLAGE LINEIQUE (2D,3D) MULTI-REGION
C
C     AUTEUR   : O. STAB
C     DATE     : 10.10.98
C     TESTS    :  
C     MODIFICATIONS :
C        AUTEUR, DATE, OBJET : O.STAB, 27.07.99, EXTRACTION DE DS1_NOEUD1D.F
C        O.STAB, 30.07.99, AJOUT DE NBRMAX POUR LE MULTI-REFERENCE DANS :
C          DS1FCT
C
C     **********************************************************************
C
      SUBROUTINE DS1FCT(IDE,ITRNOE,NBNMAX,ITRTRI,NBCMAX,NOETRI,NOEMAX,
     >                NBN,NBE,NCC,NBPMAX,NBEMAX,
C     >                ITRIRG,NRGMAX,IMTREF,NMT,
     >                ITRIRG,NBRMAX,NRGMAX,IMTREF,NMT,
     >                COORD,IDIMC,
     >                GRDNOE,NGRDMX,
     >                MODDEF,MODGEN,NBPNEW,
     >                IADEC,NIADEC,RADEC,NRIDEC,NFADEC,
     >                ITVL,NITMAX,RTVL,NRTMAX,ITRACE,IERR)
C     **********************************************************************
C     OBJET DS1FCT : RAFFINEMENT D'UN MAILLAGE LINEIQUE (2D,3D) MULTI-REGION
C                    IDEM DSRAFT ?
C     EN ENTREE  :
C       ---- DEFINITION DU MAILLAGE    --------------
C
C       ITRIRG : ITRIRG((I-1)*NBRMAX+K) = REFERENCE K DE L'ELEMENT I
C       NBRMAX : NOMBRE MAXIMUM DE REFERENCE POUR 1 ELEMENT
C       NRGMAX : TAILLE DE ITRIRG (OU NOMBRE MAXIMUM D'ELEMENT ?)
C       IMTREF : REFERENCE DES REGIONS
C       NMT    : NOMBRE DE REGIONS ( = TAILLE DE IMTREF)
C
C       GRDNOE : GRDNOE(I) = GRANDEUR ASSOCIEE AU NOEUD I
C       NBRDMX : TAILLE DE GRDNOE
C
C       ---- DEFINITION DU RAFFINEMENT --------------
C       IADEC((I-1)*NIADEC+1) : PARAMETRES ENTIERS DU IEME RAFFINEMENT
C       NIADEC   : NOMBRE MAX. DE PARAMETRES ENTIERS
C       RADEC((I-1)*NIADEC+1) : PARAMETRES REELS DU IEME RAFFINEMENT
C       NRIDEC   : NOMBRE MAX. DE PARAMETRES REELS
C       NFADEC   : NOMBRE DE RAFFINEMENTS
C
C       NBPNEW   : NOMBRE MAXIMUM DE POINTS A GENERER
C       MODDEF   : IL Y A 3 TYPES DE DEFINITIONS
C          1 LE MODE DEFAUT SIMPLE
C          2 LE MODE CONCENTRATIONS(X,Y)
C          3 LE MODE VALEURS NODALES
C       MODGEN   : IL Y A 3 MODES DE GENERATION
C          1 LE MODE DIRECT 
C          2 LE MODE ITERATIF
C          3 LE MODE ITERATIF + LISSAGE 
C
C       ---- TABLEAUX DE TRAVAIL --------------------
C       ITVL     : TABLEAU D'ENTIERS POUR LES CALCULS
C       NITMAX   : TAILLE DE ITVL
C       RTVL     : TABLEAU DE REELS POUR LES CALCULS
C       NRTMAX   : TAILLE DE RTVL (12 (NBP+12))
C       ITRACE   : SI > 0  ALORS ECHO DES ETAPES ET DES RESULTATS
C
C     EN SORTIE  :
C       IERR     : CODE D'ERREUR 
C           0  OK
C          -1 SI DONNEES INCORRECTES
C             MODE DE RAFFINEMENT INCONNU
C             ERREUR FICHIER OUVERTURE/FERMETURE
C             ERREUR MAILLAGE INCOMPATIBLE AVEC LE TRAITEMENT
C             ERREUR MAILLAGE INCOHERENT
C             ERREUR DE TRAITEMENT (REGIONS/RENUMEROTATION/RAFFINEMENT)
C          -2 SI TABLEAUX INSUFFISANTS
C             ITVL TROP PETIT 
C             RTVL TROP PETIT)
C             TROP DE REGIONS (>50)
C             ERREUR DE TRAITEMENT (REGIONS/RENUMEROTATION/RAFFINEMENT)
C     **********************************************************************
      INTEGER    IDE,ITRNOE(*),NBNMAX,ITRTRI(*),NBCMAX,NOETRI(*),NOEMAX
      INTEGER    NBN,NBE,NCC,NBPMAX,NBEMAX
      INTEGER    ITRIRG(*),NBRMAX,NRGMAX,IMTREF(*),NMT
      REAL       COORD(*),GRDNOE(*)
      INTEGER    IDIMC,NGRDMX
      INTEGER    ITVL(*)
      REAL       RTVL(*),RADEC(*)
      INTEGER    MODDEF,MODGEN,NBPNEW,IADEC(*),NFADEC,NIADEC,NRIDEC
      INTEGER    NITMAX,NRTMAX,ITRACE,IERR
C
      INTEGER    NCCMAX,IERTSA
      EXTERNAL   D1ISUI,DNCHPO
C
      IF( NBPNEW.EQ.0)GOTO 500
      GOTO( 100,200,300 ) MODDEF
        IERR = -1
        CALL DSERRE(1,IERR,'DS1FCT','DEFINITION DENSITE INCORRECTE')        
        GOTO 9999
C        ========================
C     --- RAFFINEMENT PAR DEFAUT ---
C        ========================
 100  CONTINUE   
C      IF(ITRACE.GT.0)
C     >    CALL ESECHA(1,'-> RAFFINEMENT PAR DEFAUT',' ')
      NCCMAX = NCC
      CALL R1RAF(IADEC(1),RADEC(2),
     >             ITRNOE,NBNMAX,ITRTRI,NBCMAX,
     >             NOETRI,NOEMAX,
     >             COORD,IDIMC,NBN,NBE,NBPMAX,NBEMAX,NCC,
C     modifier r1raf
C     >             ITRIRG,NRGMAX,
     >             ITRIRG,NBRMAX,NRGMAX,
     >             RTVL,NRTMAX,
     >             ITVL,NITMAX,NCCMAX,
     >             IERR)
      IF(IERR.LT.0)THEN 
        CALL DSERRE(1,IERR,'DS1FCT',' APPEL R1RAF')
        GOTO 9999      
      ENDIF     
      GOTO 400
C        ===========================================
C     ---    CONCENTRATIONS(X,Y) OU VALEURS NODALES  ---
C        ===========================================      
 200  CONTINUE   
C      IF(ITRACE.GT.0)
C     >    CALL ESECHA(1,'-> CONCENTRATIONS(X,Y) ',' ')
C
      CALL R1RAFF(MODDEF,MODGEN,
     >     ITRNOE,NBNMAX,ITRTRI,NBCMAX,
     >     NOETRI,NOEMAX,
C     >     ITRIRG,NRGMAX,
     >     ITRIRG,NBRMAX,NRGMAX,
     >     COORD,IDIMC,NBN,NBE,NBPMAX,NBEMAX,
     >     D1ISUI,IADEC,NIADEC,RADEC,NRIDEC,NFADEC,     
     >     ITVL,NITMAX,RTVL,NRTMAX,
     >     IERR)
      IF(IERR.LT.0)THEN 
        CALL DSERRE(1,IERR,'DS1FCT',' APPEL R1RAFF (D1ISUI)')
        GOTO 9999      
      ENDIF     
      GOTO 400
C        ===========================================
C     ---    VALEURS NODALES  ---
C        ===========================================      
 300  CONTINUE   
C      IF(ITRACE.GT.0)
C     >    CALL ESECHA(1,'-> VALEURS NODALES ',' ')
C
      CALL R1RAFF(MODDEF,MODGEN,
     >     ITRNOE,NBNMAX,ITRTRI,NBCMAX,
     >     NOETRI,NOEMAX,
C     >     ITRIRG,NRGMAX,
     >     ITRIRG,NBRMAX,NRGMAX,
     >     COORD,IDIMC,NBN,NBE,NBPMAX,NBEMAX,
     >     DNCHPO,IADEC,NIADEC,RADEC,NRIDEC,NFADEC,     
     >     ITVL,NITMAX,RTVL,NRTMAX,
     >     IERR)
      IF(IERR.LT.0)THEN 
        CALL DSERRE(1,IERR,'DS1FCT',' APPEL R1RAFF (DNCHPO)')
        GOTO 9999      
      ENDIF     
      GOTO 400
C
  400 CONTINUE
C     TAILLE SOUHAITE ATTEINTE ? (0), NOMBRE MAX ELEMENT (2), NOEUD (1) 
      IERTSA = IERR
      IERR   = 0
C       ---- LIMITATION DONNE PAR L'UTILISATEUR ---
C      IF(ITRACE.NE.0)THEN
C        IF(IERR.EQ.2)
C     >      CALL ESEINT(1,'NOMBRE MAXIMUM D ELEMENTS ATTEINT: '
C     >                  ,NBEMAX,1)
C        IF(IERR.EQ.1)
C     >      CALL ESEINT(1,'NOMBRE MAXIMUM DE NOEUDS ATTEINT: '
C     >                  ,NBPNEW,1)
C        IF(IERR.EQ.0)
C     >      CALL ESEINT(1,'TAILLE SOUHAITEE ATTEINTE: '
C     >                  ,NBN,1)
C        IERR = 0
C        CALL ESEINT(1,'NOMBRE DE NOEUDS    : ',NBN,1)
C        CALL ESEINT(1,'NOMBRE D  ELEMENTS  : ',NBE,1)
C      ENDIF
C
C        ================================================
C     --- CALCUL DES TAILLES SOUHAITEES AU NOEUDS       ---
C        ================================================
  500 CONTINUE
      IF( NGRDMX.LE.0 )GOTO 9999
C      IF( ITRACE.GT.0 )
C     >  CALL ESECHA(1,'-> CALCUL DES TAILLES SOUHAITEES',' ')
      IF( NGRDMX.LT.NBN )THEN
        IERR = -2
        CALL DSERRE(1,IERR,'DS1FCT','PLUS DE PLACE ') 
        GOTO 9999
      ENDIF
C
      GOTO( 600,700,800 ) MODDEF
C     --- RAF PAR DEFAUT
 600  CONTINUE
      CALL DNCCTB(MODDEF,IDE,ITRNOE,NBNMAX,NBE,
     >            ITRTRI,NBCMAX,
     >            0,IADEC,NIADEC,RADEC,NRIDEC,NFADEC,
     >            COORD,IDIMC,NBN,GRDNOE,IERR)
      GOTO 1000
C     --- CONCENTRATION (X,Y)
 700  CONTINUE
      CALL DNCCTB(MODDEF,IDE,ITRNOE,NBNMAX,NBE,
     >            ITRTRI,NBCMAX,
     >            D1ISUI,IADEC,NIADEC,RADEC,NRIDEC,NFADEC,
     >            COORD,IDIMC,NBN,GRDNOE,IERR)
      GOTO 1000
C     --- VALEURS NODALES 
 800  CONTINUE
      CALL DNCCTB(MODDEF,IDE,ITRNOE,NBNMAX,NBE,
     >            ITRTRI,NBCMAX,
     >            DNCHPO,IADEC,NIADEC,RADEC,NRIDEC,NFADEC,
     >            COORD,IDIMC,NBN,GRDNOE,IERR)
      GOTO 1000
C
 1000 CONTINUE
      IF( IERR.NE.0 )THEN
        CALL DSERRE(1,IERR,'DS1FCT','APPEL DNCCTB ') 
        GOTO 9999
      ENDIF
      IERR = IERTSA
C
 9999 END
C

C     **********************************************************************
C     MODULE  : TRIANGULATION DE DELAUNAY 2D
C     FICHIER : D2_DELAUNAY.F
C     OBJET   : TRIANGULATION D'UN NUAGE DE POINT
C                      RESPECTANT LE CRITERE DE DELAUNAY
C     FONCT.   :
C     OBJET TRAJPO : AJOUT D'UN POINT DANS UNE TRIANGULATION DE DELAUNAY 2D
C     OBJET TRNUPO : TRIANGULATION D'UN NUAGE DE POINTS 2D
C
C     AUTEUR   : O. STAB
C     DATE     :  
C     MODIFICATIONS :
C        AUTEUR, DATE, OBJET : 
C        O.STAB, 07.97, DISTANCE MINI D'UN POINT A LA FRONTIERE DU DOMAINE 
C        O.STAB, 10.97, V.2.0.0 
C        O.STAB, 11.97, SPCREE REMPLACE PAR SPCERC
C        o.stab, 01.02, un bug dans TRAJPO !!!!
C
C
C     **********************************************************************
C
C
      SUBROUTINE TRAJPO(IPT,ITD,ITRNOE,NBNMAX,ITRTRI,NBCMAX,
     >                    NOETRI,NBE,COORD,SPH,NBSMAX,
     >                    ITVL,NITMAX,SZERO,DFRMIN,NBTNEW,IERR)
C     **********************************************************************
C     OBJET TRAJPO : AJOUT D'UN POINT DANS UNE TRIANGULATION DE DELAUNAY 2D
C
C     EN ENTREE :
C       IPT     : L'INDICE (DANS COORD) DU POINT A AJOUTER 
C       ITD     : L'INDICE (DU TRIANGLE CONTENANT IPT 
C                 SI IL N'EST PAS CONNU : 0
C
C       ITRNOE,NBNMAX,ITRTRI,NBCMAX,NOETRI : LA TRIANGULATION
C       COORD   : COORDONNEES DES NOEUDS DE LA TRIANGULATION
C
C       SPH     : TABLEAU DES SPHERES CIRCONSCRITES AUX TRIANGLES
C       NBSMAX  : NOMBRE DE CHAMPS POUR LE CALCUL DES SPHERES (>=2)
C
C       ITVL: TABLEAU DE TRAVAIL. ON Y EMPILE SIMULTANEMENT :
C                  - LES ELEMENTS A DETRUIRE ET LEUR FRONTIERE  
C                  - LES ELEMENTS A CONSTRUIRE ET LES SOMMETS PERDUS
C       NITMAX  : TAILLE DU TABLEAU DE TRAVAIL (6*NBADET+10)
C
C       SZERO   : SURFACE MINIMUM DES TRIANGLES CREES
C                 SI ELLE EST ATTEINTE LE POINT EST REJETE
C       DFRMIN  : DISTANCE MINI D'UN POINT A LA FRONTIERE DU DOMAINE 
C                 SI ELLE EST ATTEINTE LE POINT EST REJETE
C
C     EN SORTIE : LA TRIANGULATION CONTENANT IPT (SI IERR=0) NBE = NBE+2
C       NBTNEW  : LE NOMBRE D'ELEMENTS CREES
C                 LES ELEMENTS CREES SONT LES TRIANGLES DE NUMERO 1 A NBTNEW
C       IERR    : CODE D'ERREUR 0 SI OK
C                  1 LE NOEUD N'A PAS PU ETRE AJOUTE (REJET)
C                  LA TRIANGULATION RESTE VALIDE
C                 -1 ERREUR DANS LES DONNEES
C                  LA TRIANGULATION N'EST PAS VALIDE
C                 -2 ITVL TROP PETIT
C     REMARQUE :
C       POUR UTILISER TRAJPO ET AJOUTER UN POINT A UNE TRIANGULATION
C       IL FAUT :
C       - CREER LA STRUCTURE DU MAILLAGE (CF. SMAOCR)
C       - INITIALISER SPH EN APPELANT SPHCREE POUR CHAQUE TRIANGLE
C       - AJOUTER LES COORDONNEES DU POINT A COORD.
C     **********************************************************************
      INTEGER    IPT,ITD,NBSMAX,NBTNEW
      INTEGER    ITRNOE(*),NBNMAX,ITRTRI(*),NBCMAX
      INTEGER    NOETRI(*),NBE,ITVL(*),NITMAX,IERR
      REAL       SPH(*),COORD(*),SZERO,DFRMIN
C     --- VARIABLES INTERNES ---
      INTEGER  IDE,NBC,IADETR,NADETR,NBCSTR,IACSTR,NTCMAX
      INTEGER  NBFNOE,ITRACE
      INTEGER  I,J,K, IND, IFR,NIFMAX,NBIFR,ISOMP,NBSOMP
      INTEGER  NBIFR1,IT,ITF,IT1,IFR2,NBCOL,NP, NOEMAX
      INTEGER  ISENS, IDIMC
      REAL     DISPSG
      EXTERNAL DISPSG
      INTEGER  IP(4)
      REAL     X(2),Y(2),TAILLE
      INTEGER  ITERR, ITAMPO,IPORI,IPEXT
      INTEGER  ITERR2, IAERR, IVOISI
      REAL     ZERO, HAUT
C      REAL*4   TIMED, TIMEF, TABTIME(2), ETIME
C      EXTERNAL ETIME
C
      ITRACE = 0
      IDIMC  = 2
      NBTNEW = 0
      ZERO   = 1.E-30
      IDE    = IDIMC
      NBC    = IDIMC + 1
      NOEMAX = 1
C          ====================================  
C     ---- 1. RECHERCHE DES ELEMENTS A DETRUIRE -------------------
C     LES ELEMENTS DONT LE CERCLE CIRCONSCRIT CONTIENNE LE POINT "IPT"
C     SONT MIS DANS LE TABLEAU ITVL DE "IADETR" JUSQU'A "NADETR"
C     --------------------------------------------------------------
C      TIMED = ETIME(TABTIME)
 100  CONTINUE
      IADETR   = 1
      IF( ITD.GT.0 )THEN
C     --- ON CONNAIT 1 TRIANGLE CONTENANT LE POINT : ITD ---
        ITVL(IADETR) = ITD
        NADETR = 1
        CALL RTCONN(COORD((IPT-1)*IDIMC+1),IDIMC,ITRNOE,NBNMAX,
     >              ITRTRI,NBCMAX,COORD,SPH,
     >              ITVL(IADETR),NADETR,NITMAX,ZERO,IERR)
      ELSE
C     --- ON RECHERCHE LES TRIANGLES CONTENANT LE POINT : ITD ---
        NADETR = 0
        CALL RTADET(COORD((IPT-1)*IDIMC+1),IDIMC,ITRNOE,NBNMAX,
     >              ITRTRI,NBCMAX,NBE,COORD,SPH,
     >              ITVL(IADETR),NADETR,NITMAX,ZERO,IERR)
      ENDIF
      IF(IERR .NE. 0)THEN
         IERR = -1
         CALL DSERRE(1,IERR,'TRAJPO','APPEL RTADET OU RTCONN')
         GOTO 9999
      ENDIF
      IF(NADETR.LT.1)THEN
C        --- MODIF O.STAB 27.08.97 : UN POINT HORS DU DOMAINE EST REJETE !
         IERR = 1
         CALL DSERRE(1,IERR,'TRAJPO','DANS LA RECHERCHE')
         GOTO 9999
      ENDIF
      NTCMAX = 2
C
C      TIMEF = ETIME(TABTIME)
C      TEMPSCPU(1) = TEMPSCPU(1) + TIMEF - TIMED
C
C         ======================================
C     ---- 2. FRONTIERE DES ELEMENTS A DETRUIRE -----------------------------
C         ======================================
C      TIMED = TIMEF
 200  CONTINUE
      CALL KNUTA(NADETR,ITVL(IADETR))
      DO 230 I=1,NTCMAX
        ITVL(IADETR+NADETR+I-1) = I + NBE
        DO 210 K=1,NBNMAX
          ITRNOE(((I+NBE)-1)*NBNMAX + K ) = 0
 210    CONTINUE
        DO 220 K=1,NBCMAX
          ITRTRI(((I+NBE)-1)*NBCMAX + K ) = 0
 220    CONTINUE
 230  CONTINUE
C     ---- LES ELEMENTS SONT MIS EN DEBUT  ----
      CALL NUCOMP(IDE,ITRNOE,NBNMAX,ITRTRI,NBCMAX,NOETRI,
     >            NOEMAX,(NBE+NTCMAX),ITVL(IADETR),
     >            (NADETR+NTCMAX),IERR)
      IF(IERR .NE. 0)THEN
         CALL DSERRE(1,IERR,'TRAJPO','1 APPEL NUCOMP')
         GOTO 9999
      ENDIF
      CALL SPCOMP(SPH, NBSMAX, (NBE+NTCMAX),ITVL(IADETR),
     >              (NADETR+NTCMAX),IERR)
      IF(IERR .NE. 0)THEN
         CALL DSERRE(1,IERR,'TRAJPO','APPEL SPCOMP')
         GOTO 9999
      ENDIF
C     ---- CALCUL DE LA FRONTIERE ----
      IND = 1
      IFR = IADETR + NADETR
      NBIFR = 0
      NIFMAX = NITMAX - NADETR
      CALL TMAFRT(IDE,ITRNOE,NBNMAX,ITRTRI,NBCMAX,IND,NADETR,
     >             ITVL(IFR),NBIFR,NIFMAX,IERR)
      IF( IERR .NE. 0 )THEN
        CALL DSERRE(1,IERR,'TRAJPO','APPEL TMAFRT')
        GOTO 9999
      ENDIF
C
C      TIMEF = ETIME(TABTIME)
C      TEMPSCPU(2) = TEMPSCPU(2) + TIMEF - TIMED
C
C         ====================
C     ---- 3. VERIFICATIONS   ----------------------
C         ====================
C
 300  CONTINUE
      IACSTR = IFR + ( NBIFR * 2 )
      NBCSTR = NBIFR
C
C     ---- 3.1 VERIFICATION DES CARDINAUX  ----------------------
C      T = 2 * N -A -2 D'OU NBCSTR = (NADETR+2)
C
      IF( NBCSTR .LT. (NADETR+2))THEN
        IERR = -1
        CALL DSERRE(1,IERR,'TRAJPO','UN SOMMET PERDU') 
        GOTO 900    
      ENDIF
      IF( NBCSTR .GT. (NADETR+2))THEN
        IERR = -1
        CALL DSERRE(1,IERR,'TRAJPO','PLUSIEURS COMPOSANTES CONNEXES') 
        GOTO 900    
      ENDIF
C
C     ---- 3.2 VERIFICATION DE LA GEOMETRIE  ----------------------
C
      DO 310 I=1,NBIFR
        ITVL((I-1)*NBC+IACSTR+2) = IPT
        CALL TNOFRT(IDE,ITRNOE,NBNMAX,ITVL((I-1)*2+IFR),
     >        ITVL((I-1)*2+IFR+1),ITVL((I-1)*NBC+IACSTR))
C
C      --- 3.2.1 DISTANCE D'UN POINT A LA FRONTIERE DU DOMAINE > DFRMIN
C
C       IF((DFRMIN.GT.0).AND.(ITVL((I-1)*2+IFR+1).LE.0))THEN
C      BUG 980904 :
       IVOISI = ITRTRI( (ITVL((I-1)*2+IFR) -1) * NBCMAX +
     >                   ITVL((I-1)*2+IFR+1) )
       IF( (DFRMIN.GT.0).AND.(IVOISI.LE.0) )THEN
         IPORI = ITVL((I-1)*NBC+IACSTR)
         IPEXT = ITVL((I-1)*NBC+IACSTR+1)
         HAUT = DISPSG(IDIMC,COORD((IPT-1)*IDIMC+1),
     >                     COORD((IPORI-1)*IDIMC+1),
     >                     COORD((IPEXT-1)*IDIMC+1))
C      --- POINT TROP PROCHE DE LA FRONTIERE ---
         IF( HAUT .LE. DFRMIN )THEN
           IERR = -1
           GOTO 900
         ENDIF
       ENDIF
C
C      ---- 3.2.2 SURFACE DE L'ELEMENT > SZERO ----
C
         IP(1) = (I-1)*NBC+IACSTR
         IP(2) = ITVL(IP(1))
         IP(3) = ITVL(IP(1)+1)
         IP(4) = ITVL(IP(1)+2)
         X(1) = COORD((IP(3)-1)*IDIMC+1) - COORD((IP(2)-1)*IDIMC+1)
         Y(1) = COORD((IP(3)-1)*IDIMC+2) - COORD((IP(2)-1)*IDIMC+2)
         X(2) = COORD((IP(4)-1)*IDIMC+1) - COORD((IP(3)-1)*IDIMC+1)
         Y(2) = COORD((IP(4)-1)*IDIMC+2) - COORD((IP(3)-1)*IDIMC+2)
         TAILLE = 0.5 * ( (X(1) * Y(2)) - (Y(1) * X(2)) )
         IF( TAILLE.LT.SZERO )THEN
C              ====================================
C          ---- 4.REPRISE SUR ERREUR : RECOMPACTAGE ----
C              ====================================
C
           IERR = -1
C
C          --- ON PERTURBE LE CALCUL DES SPHERES ---
C
           ITERR = ITVL((I-1)*2+IFR)
           IAERR = ITVL((I-1)*2+IFR+1)
           ITERR2 = ITRTRI((ITERR-1)*NBCMAX+IAERR)
           ITAMPO = ITRNOE(ITERR*NBNMAX)
           ITRNOE(ITERR*NBNMAX)   = ITRNOE(ITERR*NBNMAX-1)
           ITRNOE(ITERR*NBNMAX-1) = ITRNOE(ITERR*NBNMAX-2)
           ITRNOE(ITERR*NBNMAX-2) = ITAMPO
           ITAMPO = ITRTRI(ITERR*NBCMAX)
           ITRTRI(ITERR*NBCMAX)   = ITRTRI(ITERR*NBCMAX-1)
           ITRTRI(ITERR*NBCMAX-1) = ITRTRI(ITERR*NBCMAX-2)
           ITRTRI(ITERR*NBCMAX-2) = ITAMPO
C           
           CALL SPCERC(IDIMC,ITERR,ITRNOE((ITERR-1)*NBNMAX+1),
     >                 COORD,SPH((ITERR-1)*NBSMAX+1),ZERO,IERR)
C
C          --- ON PERTURBE AUSSI LE VOISIN ---
C
           IF( ITERR2.LE.0 )GOTO 900
           ITERR = ITERR2
           ITAMPO = ITRNOE(ITERR*NBNMAX)
           ITRNOE(ITERR*NBNMAX)   = ITRNOE(ITERR*NBNMAX-1)
           ITRNOE(ITERR*NBNMAX-1) = ITRNOE(ITERR*NBNMAX-2)
           ITRNOE(ITERR*NBNMAX-2) = ITAMPO
           ITAMPO = ITRTRI(ITERR*NBCMAX)
           ITRTRI(ITERR*NBCMAX)   = ITRTRI(ITERR*NBCMAX-1)
           ITRTRI(ITERR*NBCMAX-1) = ITRTRI(ITERR*NBCMAX-2)
           ITRTRI(ITERR*NBCMAX-2) = ITAMPO
C           
           CALL SPCERC(IDIMC,ITERR,ITRNOE((ITERR-1)*NBNMAX+1),
     >                 COORD,SPH((ITERR-1)*NBSMAX+1),ZERO,IERR)
           GOTO 900
         ENDIF
 310     CONTINUE
C         ================================
C     ---- 5. FRONTIERE EXTERIEUR DU TROU ---------
C         ================================
C    LES VOISINS SUR LA FRONTIERES DES ELEMENTS A DETRUIRE
C
 500  CONTINUE
      NBIFR1 = 0
      DO 530 I=1,NBIFR
        IT = ITVL((I-1)*2+IFR)
        ITF = ITVL((I-1)*2+IFR+1)
C       --- FRONTIERE INTERNE ---
        ISENS = 1
        IF( ITF.LT.0 )ISENS = -1
        IT1 = ABS(ITRTRI((IT-1)*NBCMAX+(ITF*ISENS)))
        IF( IT1.NE.0 )THEN
          DO 510 J=1,NBCMAX
            IF(ABS(ITRTRI((IT1-1)*NBCMAX+J)).EQ.IT)GO TO 520
 510      CONTINUE          
C         --- IT1 VOISIN DE IT, MAIS RECIPROQUE FAUSSE : BUG DANS LA STRUCTURE
          IERR = -1
          CALL DSERRE(1,IERR,'TRAJPO','ERREUR TROU')
          GO TO 9999
 520      NBIFR1 = NBIFR1 + 1
          ITVL((NBIFR1-1)*2+IFR)   = ABS(IT1)
          ITVL((NBIFR1-1)*2+IFR+1) = ISENS*J
         ENDIF
 530   CONTINUE
C         ============================
C     ---- 6. DESTRUCTION DES MAILLES ----------------------------
C         ============================
C
C      TIMED = ETIME(TABTIME)
 600  CONTINUE
      NBFNOE = 0
      NBSOMP = 0
      ISOMP   = IACSTR + (NBCSTR * NBC)
      DO 610 I=1,NADETR
        CALL SMADET(IDE,ITRNOE,NBNMAX,ITRTRI,NBCMAX,NBE,NOETRI,
     >              NBFNOE,I,NBC,ITVL(ISOMP+NBSOMP),NBSOMP,IERR)
        IF( IERR .NE. 0  )THEN
          CALL DSERRE(1,IERR,'TRAJPO','ERREUR DESTRUCTION')
          GOTO 9999
        ENDIF
 610  CONTINUE
      NBE = NBE - NADETR
      IF( NBSOMP.NE.0 )THEN
       IERR = -1
       CALL DSERRE(1,IERR,'TRAJPO','SOMMETS PERDUS')
       GO TO 9999
      ENDIF
C
C      TIMEF = ETIME(TABTIME)
C      TEMPSCPU(5) = TEMPSCPU(5) + TIMEF - TIMED
C         =======================================
C     ---- 7. CONSTRUCTION DES NOUVEAUX ELEMENTS -----------------
C         =======================================
C
C      TIMED = TIMEF
 700  CONTINUE
      NBFNOE = 0
      DO 730 I=1,NBCSTR
        DO 710 J=1,NBC
          ITRNOE((I-1)*NBNMAX+J)=ITVL((I-1)*NBC+IACSTR-1+J)
          ITRTRI((I-1)*NBCMAX+J)=0
 710    CONTINUE
      DO 720 J=1,(I-1)
        IF( ITRNOE((J-1)*NBNMAX+1).EQ.ITRNOE((I-1)*NBNMAX+2) )THEN
          ITRTRI((J-1)*NBCMAX+3) = I
          ITRTRI((I-1)*NBCMAX+2) = J
        ENDIF 
        IF( ITRNOE((J-1)*NBCMAX+2).EQ.ITRNOE((I-1)*NBCMAX+1) )THEN
          ITRTRI((J-1)*NBCMAX+2) = I
          ITRTRI((I-1)*NBCMAX+3) = J
        ENDIF 
 720    CONTINUE
 730  CONTINUE
      NOETRI(IPT) = 1
      DO 740 I=1,NBCSTR
        CALL SPCERC(IDIMC,I,ITRNOE((I-1)*NBNMAX+1),COORD,
     >              SPH((I-1)*NBSMAX+1),ZERO,IERR)
        IF( IERR .NE. 0  )THEN
          CALL DSERRE(1,IERR,'TRAJPO','APPEL SPCERC')
          GOTO 9999
        ENDIF
 740  CONTINUE
C
C      TIMEF = ETIME(TABTIME)
C      TEMPSCPU(6) = TEMPSCPU(6) + TIMEF - TIMED
C        ===============================
C     --- 8. INSERTION DANS LE MAILLAGE ---
C        ===============================
C
C      TIMED = TIMEF
 800  CONTINUE
      IND = 1
      IFR2 = IACSTR
      NIFMAX = NITMAX - IACSTR
      CALL TMAFRT(IDE,ITRNOE,NBNMAX,ITRTRI,NBCMAX,IND,NBCSTR,
     >             ITVL(IFR2),NBIFR,NIFMAX,IERR)
      IF( IERR .NE. 0  )THEN
        CALL DSERRE(1,IERR,'TRAJPO','FRONTIERE T CREES')      
        GOTO 9999
        ENDIF
C
C     --- MISE A JOUR DE ITRTRI -----------------
C
      CALL S2GLAR(ITVL(IFR),NBIFR1,ITVL(IFR2),NBIFR,
     >                ITRNOE,NBNMAX,ITRTRI,NBCMAX,NBCOL)
C
C     --- MISE A JOUR DE NOETRI -----------------
C
      DO 820 I=1,NBCSTR
        DO 810 J=1,NBNMAX
          NP = ITRNOE((I-1)*NBNMAX+J)
          IF( NP .NE. 0 )NOETRI(NP)=I
 810   CONTINUE
 820  CONTINUE
      NBE = NBE + NBCSTR
      NBTNEW = NBCSTR
C
C      TIMEF = ETIME(TABTIME)
C      TEMPSCPU(7) = TEMPSCPU(7) + TIMEF - TIMED
      GOTO 9999
C
C         =====================================
C     ---- 9.REPRISE SUR ERREUR : RECOMPACTAGE ----
C         =====================================
C
 900  CONTINUE
      IERR = 0
C      IF( NADETR .EQ. NBE )GO TO 9999
C     bug 21.01.2002 OS, remplace par :
      IF( NADETR .EQ. NBE )GO TO 8888
      DO 910 J=1,NADETR
             ITVL(J) = J
 910  CONTINUE
      DO 920 J=1,NTCMAX
             ITVL(NADETR+J) = NBE + J
 920  CONTINUE
      CALL NUCOMP(IDE,ITRNOE,NBNMAX,ITRTRI,NBCMAX,NOETRI,
     >                NOEMAX,(NBE+NTCMAX),ITVL(IADETR),
     >                (NADETR+NTCMAX),IERR)
      IF(IERR .NE. 0)THEN
         CALL DSERRE(1,IERR,'TRAJPO','APPEL NUCOMP')
         GOTO 9999
      ENDIF
      CALL SPCOMP(SPH, NBSMAX, (NBE+NTCMAX),ITVL(IADETR),
     >             (NADETR+NTCMAX),IERR)
      IF(IERR .NE. 0)THEN
         CALL DSERRE(1,IERR,'TRAJPO','APPEL SPCOMP')
         GOTO 9999
      ENDIF
C     ---- LE POINT N'A PAS ETE AJOUTE MAIS LE MAILLAGE RESTE VALIDE
 8888 CONTINUE
      IERR = 1
C     
 9999 END
C
C
      SUBROUTINE TRNUPO(COORD,NBN,ITRNOE,NBNMAX,ITRTRI,NBCMAX,
     >                   NOETRI,NBE,ITVL,NITMAX,RTVL,IERR)
C     **********************************************************************
C     OBJET TRNUPO : TRIANGULATION DE DELAUNAY D'UN NUAGE DE POINTS 2D
C
C     EN ENTREE  :
C       COORD    : COORDONNEES DES POINTS 
C       NBN      : NOMBRE DE POINTS 
C
C       ITVL     : TABLEAU DE TRAVAIL. ON EMPILE SUCCESSIVEMENT :
C                  LA TRIANGULATION INITIALE QUI NECESSITE : 3 * 50
C                  PUIS SIMULTANEMENT LE NOMBRE DE NOEUDS REJETES, ET
C                  LE TABLEAU DE TRAVAIL POUR TRAJPO = (6*NBADET +10)
C                  D'OU NITMAX > MAX(150,(6*NBADET+10)+NREJET)
C
C       NITMAX   : TAILLE DU TABLEAU DE TRAVAIL
C       RTVL     : TABLEAU DE TRAVAIL DE (8*NBN+244)
C
C     EN SORTIE  : LA TRIANGULATION MISE A JOUR
C
C       ITRNOE,NBNMAX,ITRTRI,NBCMAX,NOETRI : LA TRIANGULATION 
C       NBNMAX   : =3 A MOINS D'ETRE DONNE (NBNMAX != 0 EN ENTREE)
C       NBCMAX   : =3 A MOINS D'ETRE DONNE (NBCMAX != 0 EN ENTREE)
C
C       IERR     : CODE D'ERREUR
C                  -1 TRIANGULATION INCOMPLETE : TOUS LES POINTS N'ONT PAS 
C                     PU ETRE AJOUTES
C                  -2 ITVL TROP PETIT
C     **********************************************************************
      REAL       COORD(*)
      INTEGER    NBN
      INTEGER    ITRNOE(*),NBNMAX,ITRTRI(*),NBCMAX
      INTEGER    NOETRI(*),NBE,ITVL(*),NITMAX,IERR
      REAL       RTVL(*)
C     --- CONSTANTES ---
C       PARAMETER ( NBPB = NOMBRE DE POINTS BIDON (50) )    
      INTEGER   NADMAX,NBPB
      PARAMETER ( NADMAX = 50, NBPB = 50 )
      REAL      ZEROTR, SZERO
C      PARAMETER ( ZEROTR = 1.E-30, SZERO = 1.E-8 )
      PARAMETER ( ZEROTR = 1.E-30, SZERO = 1.E-16 )
C     --- VARIABLES INTERNES ---
      REAL    BOITE(4) 
      INTEGER IDIMC,IDE,NBC,NCOORD, NBFNOE, NOEMAX, ISENS
      INTEGER ITRAV,NBTRAV,I,J,IPT,ITC,IF2,NP
      INTEGER ISOMP,NBSOMP,ISPH,NTMEM,NITMX2
      INTEGER NCFMAX,NREJET,NBP,ICOORD,NPASSE
      INTEGER ITD,NBSMAX,NBTNEW
      INTEGER NOP
      REAL    DFRMIN
C
      ITRAV = 1
      NITMX2 = NITMAX
      IDIMC = 2
      NBSMAX = 3
      NBE  = 0
      IERR = 0
      IF( NBN .EQ. 0 )GOTO 9999
      IF( NBNMAX.EQ.0 )NBNMAX = 3
      IF( NBCMAX.EQ.0 )NBCMAX = 3
      IF(( NBNMAX.LT.3 ).OR.(NBCMAX.LT.3).OR.(IDIMC.NE.2))THEN
        IERR = -1
        CALL DSERRE(1,IERR,'TRNUPO','EN 2D SEULEMENT')          
        GOTO 9999
      ENDIF
C        NBE = (2*(NBN+4)) + 2 - 4
C        NTMEM =(NBE*3)+((NBE+2)*2)+(NBE*3)+((NBN*7)+NBE)
C        NBE = 2*NBN + 6
C        NTMEM = 27 * NBN
      NTMEM = MAX(150,(6*NADMAX+10))
      IF( NTMEM.GT.NITMAX )THEN
        IERR = -2
        CALL DSERRE(1,IERR,'TRNUPO','ITVL TROP PETIT')          
        GO TO 9999
      ENDIF
C         ===================
C     ---- 1. INITIALISATION -----------------------------------------
C     NORMALISATION DES POINTS (PTINIT)
C     CALCUL DU MAILLAGE INITIAL ENGLOBANT (T2INIT)
C     CALCUL DES SPHERES CIRCONSCRITES
C     ----------------------------------------------------------------
      NBE    = 0
      IDE    = IDIMC
      NBC    = IDIMC + 1
      NCOORD = NBN
      ISPH   = IDIMC * ( NBN + NBPB ) + 1
      ICOORD = 1
C      ITRI   = 1
      DO 110 I=1,IDIMC
        BOITE(I) = -1.0
        BOITE(IDIMC+I) = 1.0
 110  CONTINUE    
      CALL PTINIT(COORD,IDIMC,NBN,ZEROTR,RTVL(ICOORD),IERR)
      IF( IERR .NE. 0  )THEN
        CALL DSERRE(1,IERR,'TRNUPO','APPEL PTINIT')          
        GOTO 9999
      ENDIF
C
C     --- TRIANGULATION DE LA "BOITE D'ENCOMBREMENT" --------------------
C         ON AJOUTE NBPB POINTS "BIDON" A L'EXTERIEUR DE LA BOITE
      NCOORD  = NCOORD + NBPB
      NOEMAX  = NCOORD
C
      CALL T2ISP(BOITE,(1-NBN),NBPB,
     >           ITRNOE,NBNMAX,ITRTRI,NBCMAX,
     >           NOETRI(NBN+1),NOEMAX,NBE,
     >           RTVL((NBN*IDIMC)+ICOORD),NCOORD,IERR)
      IF( IERR .NE. 0  )THEN
        CALL DSERRE(1,IERR,'TRNUPO','APPEL T2ISP')          
        GOTO 9999
      ENDIF
C     ---- TRANSLATION DES NBPT POINT EN FIN ----
      DO 120 I=1,(NBE*NBNMAX)
        ITRNOE(I) = ITRNOE(I) + NBN
 120  CONTINUE
      DO 130 I=1,NBE
        CALL SPCERC(IDIMC,I,ITRNOE((I-1)*NBNMAX+1),RTVL(ICOORD),
     >              RTVL((I-1)*NBSMAX+ISPH),ZEROTR,IERR)
        IF( IERR .NE. 0  )THEN
          CALL DSERRE(1,IERR,'TRNUPO','APPEL SPCERC')          
          GOTO 9999
        ENDIF
 130  CONTINUE
      NCFMAX = IDE
C         ====================
C     ---- 2. AJOUT DES NOEUDS ----------------------------------------
C         ====================
C     
      IPT = 2
      NPASSE = 0
      DO 210 I=IPT,NBN
        ITVL(I)=I
 210  CONTINUE
C
      ITD = 0
      NBP = NBN
      NREJET = 0
 220  CONTINUE
      IERR = 0
      DFRMIN = 0.0
      ITRAV  = NBP + 1
      NITMX2 = NITMAX - ITRAV + 1
      CALL TRAJPO(ITVL(IPT),ITD,ITRNOE,NBNMAX,ITRTRI,
     >           NBCMAX,NOETRI,NBE,RTVL(ICOORD),RTVL(ISPH),
     >           NBSMAX,ITVL(ITRAV),NITMX2,SZERO,
     >           DFRMIN,NBTNEW,IERR)
C
      IF( IERR.NE.0 )THEN
C        ----- PERMUTATION : EN FIN -------
         NREJET = NREJET + 1
         ITVL(NREJET) = ITVL(IPT)
      ENDIF
      IPT = IPT+1
      IF( IPT .LE. NBP )GO TO 220
C     -------- ON PASSE AU REJETES ---------
C     -------- TOUS LES POINTS REJETES -----
      IF( NREJET .GE. NBP )THEN
      IF( NPASSE .LT. 10 )THEN
        NPASSE = NPASSE + 1
        NBP = NREJET
        IPT = 1
        NREJET = 0
        IERR = 0
        GOTO 220
      ELSE
        IERR = -1
        CALL DSERRE(1,IERR,'TRNUPO','BOUCLE REJET')
        IERR = 0
        GO TO 310
      ENDIF
      ENDIF
C
      IF( NREJET .NE. 0 )THEN
        NPASSE = 0
        NBP = NREJET
        IPT = 1
        NREJET = 0
        GO TO 220
      ENDIF
C         ===================================
C     ---- 3. DESTRUCTION DES ELEMENTS BIDON --------------------------
C         ===================================
C
 310  CONTINUE
      ISENS = 1
      NBFNOE = 1
      DO 330 I=1,NBPB
        NP = NBN + I
 320    CALL SESFR2(NP,ISENS,IDE,ITRNOE,NBNMAX,ITRTRI,
     >                NBCMAX,NOETRI,ITC,IF2)
C       --- DE LA PREMIERE ARETE DE FRONTIERE ---
        IF( ITC.EQ. 0 )GO TO 330
        IF( ITRTRI((ITC-1)*NBCMAX+IF2)  .NE. 0 )THEN
          IERR = -1
          CALL DSERRE(1,IERR,'TRNUPO','DESTRUCTION FINALE')
          GO TO 9999
        ENDIF        
C     --- L'ELEMENT EST MIS A LA FIN : PERMUTE ITC ET NBE ---------
      CALL NUPERM(IDE,ITRNOE,NBNMAX,ITRTRI,NBCMAX,NOETRI,
     >              NBFNOE,NBE,ITC,NBE,IERR)
      IF( IERR .NE. 0  )THEN
          CALL DSERRE(1,IERR,'TRNUPO','APPEL NUPERM')
         GO TO 9999
       ENDIF
C     --- LE DERNIER ELEMENT EST DETRUIT --------------------------
      ISOMP = 1
      NBSOMP = 0
      CALL SMADET(IDE,ITRNOE,NBNMAX,ITRTRI,NBCMAX,NBE,NOETRI,
     >           NBFNOE,NBE,NBC,ITVL(ISOMP),NBSOMP,IERR)
      NBE = NBE-1
      IF( IERR .NE. 0  )THEN
C          IERR = -1
          CALL DSERRE(1,IERR,'TRNUPO','APPEL SMADET')
         GO TO 9999
       ENDIF
      IF( NBSOMP .EQ. 0 )GO TO 320
C     --- LE NOEUD (NBN + I) EST DECONNECTE ----------------------
 330  CONTINUE
C     --- MISE A JOUR DE NOETRI : O(3*NBE) ---
      DO 350 I=1,NBE
        DO 340 J=1,3
           NOP = ITRNOE((I-1)*NBNMAX+J)
           IF((NOP.GT.NBN).OR.(NOP.LE.0))THEN
             IERR = -1
             CALL DSERRE(1,IERR,'TRNUPO','STRUCTURE NON CORRECTE')
             GOTO 9999
           ENDIF
           NOETRI(NOP) = I
 340    CONTINUE    
 350  CONTINUE
C
C     ---- MODIF 04.97 :
C
      IF( NREJET.NE. 0 )IERR = -1    
C
 9999 END


C     *******************************************************************
C     FICHIER  : D2_EVAL.F
C     OBJET    : EVALUATION DES MAILLAGES 2D 
C
C     FONCT.   :
C     OBJET STTREV : EVALUE UN MAILLAGE TRIANGULAIRE 2D / 3D
C
C     AUTEUR   : O. STAB
C     DATE     : 07.95
C     TESTS    : 07.95
C     MODIFICATIONS :
C      AUTEUR, DATE, OBJET : O.STAB, 08.97, RESTRUCTURATION
C      AUTEUR, DATE, OBJET : O.STAB, 10.97, INTEGRATION V.2.0.0
C      AUTEUR, DATE, OBJET : O.STAB, 11.97, RESTRUCTURATION
C      AUTEUR, DATE, OBJET : O.STAB, 02.03, AJOUT SONBAR,SOANGL,SOANAR
C
C     REMARQUE : les fonctions SONBAR,SOANGL,SOANAR ne servent pas qu'a l'evaluation
C                Attention elles n'existent pas encore en 3D !
C     REMARQUE : Il faudra remplacer STTREV par la nouvelle version 
C                VOIR prog/ev_grandeur.f
C     *******************************************************************
C
      FUNCTION SONBAR (ISO,COORD,IDIMC,NBN,
     >                ISOMFR,NBTRSO,ITBASO,IERR)
C     **********************************************************************
C     OBJET SONBAR : RENVOI LE NOMBRE D'ARETE AU SOMMET
C      EN ENTREE :
C          ISOMFR : 1 si le sommet appartient a la frontiere
C                   0 sinon
C          NBTRSO : nombre de triangles incidents a ISOMM
C                   le nombre de sommets = NBTRSO + ISOMFR
C          ITABSO : Tableau des sommets connectes a ISOMM (dans l'ordre)
C                   si ISOMFR=0 ITABSE(i) est ferme
C                   si ISOMFR=1 ITBASE(i) est ouvert
C     REMARQUE : VOIR S2SOTR
C     **********************************************************************
      REAL SONBAR 
      INTEGER ISO,IDIMC,NBN
      REAL    COORD(*)
      INTEGER ISOMFR,NBTRSO,ITBASO(*)
      INTEGER IERR
C
      SONBAR = 1.0 * (NBTRSO+ISOMFR)
 9999 END
C
      FUNCTION SOANGL(ISO,COORD,IDIMC,NBN,
     >                ISOMFR,NBTRSO,ITBASO,IERR)
C     **********************************************************************
C     OBJET SOANGL : RENVOI L'ANGLE (2D) AU SOMMET
C      EN ENTREE :
C          ISOMFR : 1 si le sommet appartient a la frontiere
C                   0 sinon
C          NBTRSO : nombre de triangles incidents a ISOMM
C                   le nombre de sommets = NBTRSO + ISOMFR
C          ITABSO : Tableau des sommets connectes a ISOMM (dans l'ordre)
C                   si ISOMFR=0 ITABSE(i) est ferme
C                   si ISOMFR=1 ITBASE(i) est ouvert
C     REMARQUE : VOIR S2SOTR
C     **********************************************************************
      REAL SOANGL
      INTEGER ISO,IDIMC,NBN
      REAL    COORD(*)
      INTEGER ISOMFR,NBTRSO,ITBASO(*)
      INTEGER IERR
C
      EXTERNAL TRAGSO
      REAL     TRAGSO
C         --- calcul des angles ---
      IF( ISOMFR.EQ.0 )THEN
          SOANGL = 360
      ELSE
C          --- angle entre la premiere et la derniere arete
          SOANGL =  TRAGSO(
     >         COORD((ISO-1)*IDIMC+1),
     >         COORD((ITBASO(1)-1)*IDIMC+1), 
     >         COORD((ITBASO(NBTRSO+ISOMFR)-1)*IDIMC+1),IDIMC)
      ENDIF
 9999 END
C
      FUNCTION SOANAR(ISO,COORD,IDIMC,NBN,
     >                ISOMFR,NBTRSO,ITBASO,IERR)
C     **********************************************************************
C     OBJET SOANAR : RENVOI LE RAPPORT ANGLE/NBELEM
C      EN ENTREE :
C          ISOMFR : 1 si le sommet appartient a la frontiere
C                   0 sinon
C          NBTRSO : nombre de triangles incidents a ISOMM
C                   le nombre de sommets = NBTRSO + ISOMFR
C          ITABSO : Tableau des sommets connectes a ISOMM (dans l'ordre)
C                   si ISOMFR=0 ITABSE(i) est ferme
C                   si ISOMFR=1 ITBASE(i) est ouvert
C     REMARQUE : VOIR S2SOTR
C     **********************************************************************
      REAL SOANAR
      INTEGER ISO,IDIMC,NBN
      REAL    COORD(*)
      INTEGER ISOMFR,NBTRSO,ITBASO(*)
      INTEGER IERR
C
      EXTERNAL SOANGL
      REAL SOANGL
C
      REAL ANGLE, FNBARE
C      FNBARE = 1.0 * (NBTRSO+ISOMFR)
      FNBARE = 1.0 * NBTRSO
      ANGLE = SOANGL(ISO,COORD,IDIMC,NBN,ISOMFR,NBTRSO,ITBASO,IERR)
      SOANAR = ANGLE / FNBARE 
C     Prendre la valeur absolue de la difference avec 60 degrees !!!
 9999 END
C
C
      SUBROUTINE STTREV(IDE,ITRNOE,NBNMAX,ITRTRI,NBCMAX,NOETRI,NOEMAX,
     >          COORD,IDIMC,NBN,NBE,
     >          ITVL,IMAX,RTVL,IRMAX,IERR)
C     *****************************************************************
C     OBJET STTREV :   EVALUE UN MAILLAGE TRIANGULAIRE 2D / 3D
C     EN ENTREE 
C       ITVL  : TABLEAU DE TRAVAIL (6*NBADET+10)
C       IMAX      : TAILLE DU TABLEAU DE TRAVAIL
C       RTVL  : TABLEAU DE TRAVAIL COORDONNEES + SPHERES
C       IRMAX      : TAILLE DE RTVL >= 3*(3*NBNPTMAX-2*NBN+NBE) 
C       --------- LE MAILLAGE ---------------------
C       ITRNOE,NBNMAX,ITRTRI,NBCMAX,NOETRI,NOEMAX,NBN,NBE : LE MAILLAGE
C       COORD,IDIMC: LES COORDONNEES DES NOEUDS
C
C     EN SORTIE   : UNE EVALUATION
C       IERR      : CODE D'ERREUR
C                      -1 TOUS LES POINTS N'ONT PAS PU ETRE AJOUTES
C                      -2 ITVL OU RTVL TROP PETIT
C     REMARQUES :
C       NBPNEW    : LE NOMBRE DE NOEUDS GENERES = NBENEW / 2
C     **********************************************************************
      INTEGER IDE,NBE,ITRNOE(*),NBNMAX,ITRTRI(*),NBCMAX
      INTEGER ITVL(*),IMAX,IDIMC,NOETRI(*),NOEMAX,NBN,IRMAX,IERR
      REAL    COORD(*),RTVL(*)
C
      EXTERNAL TRSURF,TRRIL2,TRLSL2,TRLRC2 
      REAL     TRSURF,TRRIL2,TRLSL2,TRLRC2 
      REAL     RSUFMN,RSUFMX,RSUFTO
      INTEGER  ISUFMN,ISUFMX,NBESUF
      REAL     RRILMN,RRILMX,RRILTO
      INTEGER  IRILMN,IRILMX,NBERIL
      REAL     RLSLMN,RLSLMX,RLSLTO
      INTEGER  ILSLMN,ILSLMX,NBELSL
      REAL     RLRCMN,RLRCMX,RLRCTO
      INTEGER  ILRCMN,ILRCMX,NBELRC
      REAL SUFMIN,SUFMAX,RILMIN,RILMAX,LSLMIN,LSLMAX,LRCMIN,LRCMAX
C
      EXTERNAL TRLAG2
      REAL     TRLAG2
      INTEGER  ILAGMN,ILAGMX,NBELAG
      REAL     LAGMIN,LAGMAX,RLAGMN,RLAGMX,RLAGTO
      REAL     RAD2DG,DG2RAD
C
      SUFMIN = 0.0
      SUFMAX = 0.0
      RILMIN = 0.0
      RILMAX = 0.2
      LSLMIN = 0.0
      LSLMAX = 0.2
      LRCMIN = 0.0
      LRCMAX = 0.2
C
      RAD2DG = 180.0 / 3.14159265
      DG2RAD =  3.14159265 / 180.0
      LAGMIN = 0.0
      LAGMAX = SIN( 20.0 * DG2RAD )
C
C           ============
C       ---- CALCUL SUF ----
C           ============
C
      CALL EVFCTT(ITRNOE,NBNMAX,TRSURF,
     >          COORD,IDIMC,NBN,NBE,
     >          SUFMIN,SUFMAX,NBESUF,
     >          RSUFMN,ISUFMN,RSUFMX,ISUFMX,RSUFTO,IERR)
C        
C           ============
C       ---- CALCUL RIL ----
C           ============
C
      CALL EVFCTT(ITRNOE,NBNMAX,TRRIL2,
     >          COORD,IDIMC,NBN,NBE,
     >          RILMIN,RILMAX,NBERIL,
     >          RRILMN,IRILMN,RRILMX,IRILMX,RRILTO,IERR)
C
C           ============
C       ---- CALCUL LMIN / LMAX -----
C           ============
C
      CALL EVFCTT(ITRNOE,NBNMAX,TRLSL2,
     >          COORD,IDIMC,NBN,NBE,
     >          LSLMIN,LSLMAX,NBELSL,
     >          RLSLMN,ILSLMN,RLSLMX,ILSLMX,RLSLTO,IERR)
C
C           ============
C       ---- CALCUL L/RC -----
C           ============
C
      CALL EVFCTT(ITRNOE,NBNMAX,TRLRC2,
     >          COORD,IDIMC,NBN,NBE,
     >          LRCMIN,LRCMAX,NBELRC,
     >          RLRCMN,ILRCMN,RLRCMX,ILRCMX,RLRCTO,IERR)
C
C           ===============
C       ---- CALCUL ANGLE  -----
C           ===============
C
      CALL EVFCTT(ITRNOE,NBNMAX,TRLAG2,
     >          COORD,IDIMC,NBN,NBE,
     >          LAGMIN,LAGMAX,NBELAG,
     >          RLAGMN,ILAGMN,RLAGMX,ILAGMX,RLAGTO,IERR)
C
      RLAGMN = ASIN( RLAGMN ) * RAD2DG
      RLAGMX = ASIN( RLAGMX ) * RAD2DG 
C      PRINT *,' RLAGTO = ', RLAGTO
      RLAGTO = ASIN( RLAGTO / NBE ) * RAD2DG 
      LAGMAX = ASIN( LAGMAX ) * RAD2DG 
C
C          ===========
C     ----- AFFICHAGE ---------
C          ===========
        WRITE(*,*) 'SURFACE TOTALE = ',RSUFTO
        WRITE(*,*) '------------- MINIMUM ------------------'
        WRITE(*,*) 'RIL EST MINIMUM SUR ',IRILMN,' = ',RRILMN
        WRITE(*,*) 'LL  EST MINIMUM SUR ',ILSLMN,' = ',RLSLMN
        WRITE(*,*) 'LRC EST MINIMUM SUR ',ILRCMN,' = ',RLRCMN
        WRITE(*,*) 'AGM EST MINIMUM SUR ',ILAGMN,' = ',RLAGMN
C
        WRITE(*,*) '------------- MOYENNE ------------------'
        WRITE(*,*) 'SUF MOYEN ',RSUFTO / NBE
        WRITE(*,*) 'RIL MOYEN ',RRILTO / NBE
        WRITE(*,*) 'LL  MOYEN ',RLSLTO / NBE
        WRITE(*,*) 'LRC MOYEN ',RLRCTO / NBE
        WRITE(*,*) 'AGM MOYEN ',RLAGTO  
C
        WRITE(*,*) '------------- MAXIMUM ------------------'
        WRITE(*,*) 'RIL EST MAXIMUM SUR ',IRILMX,' = ',RRILMX
        WRITE(*,*) 'LL  EST MAXIMUM SUR ',ILSLMX,' = ',RLSLMX
        WRITE(*,*) 'LRC EST MAXIMUM SUR ',ILRCMX,' = ',RLRCMX
        WRITE(*,*) 'AGM EST MAXIMUM SUR ',ILAGMX,' = ',RLAGMX
C
        WRITE(*,*) '------------- CARDINAUX ----------------'
        WRITE(*,*) NBERIL,' ELEMENTS ONT UN RIL < ',RILMAX
        WRITE(*,*) NBELSL,' ELEMENTS ONT UN LSL < ',LSLMAX
        WRITE(*,*) NBELRC,' ELEMENTS ONT UN LRC < ',LRCMAX
        WRITE(*,*) NBELAG,' ELEMENTS ONT UN AGM < ',LAGMAX
        WRITE(*,*) '----------------------------------------'
C
 9999 END
C      
C     **********************************************************************
C     MODULE  : M2 (TRIANGULATION DE DELAUNAY 2D)
C     FICHIER : M2_POINT.F
C     OBJET    :  QUELQUES CALCULS ELEMENTAIRES SUR DES NUAGES DE POINTS
C                       
C     FONCT.   :
C       POBTEN : CALCUL LA BOITE D'ENCOMBREMENT D'UN NUAGE DE POINTS
C       PTINIT    : INITIALISATION D'UN NUAGE DE POINTS (CF PTNORM)
C       PTNORM    : NORMALISATION D'UN NUAGE DE POINTS [-1.00:+1.00]
C
C     AUTEUR   : O. STAB
C     DATE     : 03.95
C     MODIFICATIONS :
C        AUTEUR, DATE, OBJET :
C
C
C     **********************************************************************
C
      SUBROUTINE POBTEN(COORD,IDIMC,NBN,BOITE)
C     **********************************************************************
C     OBJET : CALCUL LA BOITE D'ENCOMBREMENT D'UN NUAGE DE POINTS
C     EN ENTREE   :
C          COORD    : TABLEAU DES COORDONNEES DES POINTS
C         IDIMC   : DIMENSION DE L'ESPACE
C         NBN    : NOMBRE DE POINTS
C     EN SORTIE   :
C         BOITE    : LA BOITE D'ENCOMBREMENT (POINT MINI, POINT MAXI )
C     **********************************************************************
      REAL       COORD(*)
      INTEGER    IDIMC, NBN
      REAL       BOITE(2*IDIMC)
C
      INTEGER I,J
C
      DO 10 I=1,IDIMC
          BOITE(I)      = COORD(I)
          BOITE(IDIMC+I) = COORD(I)
   10 CONTINUE
C
      DO 30 I=2,NBN
        DO 20 J=1,IDIMC
          BOITE(J)      = MIN(BOITE(J)     ,COORD((I-1)*IDIMC+J))
          BOITE(IDIMC+J) = MAX(BOITE(IDIMC+J),COORD((I-1)*IDIMC+J))
   20 CONTINUE
   30 CONTINUE
C
  999 END
C
      SUBROUTINE PTNORM(COORD,BOITE,IDIMC,NBN,ZERO,COORDN,IERR)
C     **********************************************************************
C     OBJET : NORMALISATION D'UN NUAGE DE POINTS ENTRE [-1.00:+1.00]
C     EN ENTREE   :
C         COORD  : TABLEAU DES COORDONNEES DES POINTS
C         BOITE  : BOITE D'ENCOMBREMENT
C         IDIMC   : DIMENSION DE L'ESPACE
C         NBN    : NOMBRE DE POINTS
C         ZERO   : ZERO
C     EN SORTIE   :
C         COORDN   : COORDONNEES NORMALISEES
C     **********************************************************************
      REAL       COORD(*),BOITE(*),ZERO
      INTEGER    IDIMC, NBN
      REAL       COORDN(*)
      INTEGER    IERR
C
      INTEGER I,J
      REAL    XC(3),COEF
C
      COEF = 0.0
      DO 40 I=1,IDIMC
        XC(I) = (BOITE(I) + BOITE(IDIMC+I)) / 2.0
        COEF = MAX(COEF,(BOITE(IDIMC+I) - BOITE(I)))
   40 CONTINUE
C
      IF( COEF .LE. ZERO )THEN
        IERR = -1
        GOTO 999
      ENDIF
      COEF = 2.0 / COEF
C
      DO 50 I=1,IDIMC
      IF( COEF*(BOITE(IDIMC+I) - BOITE(I)) .LE. ZERO )THEN
        IERR = -1
        GOTO 999
      ENDIF
   50 CONTINUE
C
      DO 70 I=1,NBN
        DO 60 J=1,IDIMC
          COORDN((I-1)*IDIMC+J) = (COORD((I-1)*IDIMC+J) - XC(J)) * COEF
   60   CONTINUE
   70 CONTINUE    
C   
  999 END
C
C
      SUBROUTINE PTINIT(COORD,IDIMC,NBN,ZERO,COORDN,IERR)
C     **********************************************************************
C     OBJET : INITIALISATION D'UN NUAGE DE POINTS
C     EN ENTREE   :
C         COORD  : TABLEAU DES COORDONNEES DES POINTS
C         IDIMC   : DIMENSION DE L'ESPACE
C         NBN    : NOMBRE DE POINTS
C         ZERO   : ZERO
C     EN SORTIE   :
C         COORDN   : COORDONNEES NORMALISEES
C     **********************************************************************
      REAL       COORD(*),ZERO
      INTEGER    IDIMC, NBN
      REAL       COORDN(*)
      INTEGER    IERR
C
      REAL    BOITE(6)
C
      CALL POBTEN(COORD,IDIMC,NBN,BOITE)
      CALL PTNORM(COORD,BOITE,IDIMC,NBN,ZERO,COORDN,IERR)  
  999 END
C
C     **********************************************************************
C     MODULE  : M2 (TRIANGULATION DE DELAUNAY 2D)
C     FICHIER : M2_RECHERCHE.F
C     OBJET    : RECHERCHE PAR PARCOURS DANS UNE TRIANGULATION
C     FONCT.   :
C       RTCONN : RECHERCHE DES TRIANGLES CONNEXES "NON-DELAUNAY" 
C       RTADET    : RECHERCHE DES TRIANGLES A DETRUIRE (IE "NON-DELAUNAY") 
C                     A L'AJOUT D'UN POINT
C 
C     AUTEUR   : O. STAB
C     DATE     : 03.95
C     MODIFICATIONS :
C        AUTEUR, DATE, OBJET :
C
C   
C     **********************************************************************
C
      SUBROUTINE RTCONN(XYZPT,IDIMC,ITRNOE,NBNMAX,ITRTRI,NBCMAX,
     >                     COORD,SPH,IADET,NBADET,NADMAX,ZERO,IERR)
C     **********************************************************************
C     OBJET : RECHERCHE DES TRIANGLES CONNEXES "NON-DELAUNAY" 
C     EN ENTREE   :
C        XYZPT : COORDONNEES DU POINT AJOUTE
C        IDIMC  : DIMENSION DE L'ESPACE
C        ITRNOE,NBNMAX,ITRTRI,NBCMAX,COORD : LA TRIANGULATION
C        SPH   : LES SPHERES CIRCONSCRITES AUX TRIANGLES
C        IADET,NBADET : L'ENSEMBLE DES ELEMENTS "NON-DELAUNAY" 
C                (IE A DETRUIRE) ; EN ENTREE IL DOIT CONTENIR 1 ELEMENT.
C        NBADET: NOMBRE D'ELEMENTS A DETRUIRE
C        NBADETMNAX : TAILLE DU TABLEAU IADET 
C     EN SORTIE   :
C        IADET    : TABLEAU DES TRIANGLES "NON-DELAUNAY"
C        NBADET   : NOMBRE DE TRIANGLES "  "    "   "
C     **********************************************************************
      REAL       XYZPT(*)
      INTEGER    IDIMC
      INTEGER    ITRNOE(*),NBNMAX,ITRTRI(*),NBCMAX
      INTEGER    IADET(*),NBADET,NADMAX,IERR
      REAL       COORD(*),SPH(*),ZERO
C
C   
C     --- POUR LE DEBUG ---
C
C      COMMON /DEBUG/ ITRACE, ITEST, IERROR, IMESS
C      INTEGER       ITRACE, ITEST, IERROR
C      CHARACTER*256 IMESS
C     ---------------------------------------------------------------------
C     --- POUR LES STATS ---
C
      COMMON /STATS/ ICARD(100)
      INTEGER       ICARD
C     ---------------------------------------------------------------------
C     --- VARIABLES INTERNES ---
      INTEGER   J,K,NT,IPTDS, NBTRA, IVOIS, IT, ITRA, NBC
      INTEGER  SPPOIN
      EXTERNAL SPPOIN
C
      IERR = 0
      NBC = IDIMC+1
      IF( NBADET.NE.1 )THEN
        IERR = -1
        GOTO 999
      ENDIF
C
      NBTRA = 0
      ITRA  = 2
C      
      IT = IADET(1)
      DO 3 J=1,NBC
        IVOIS = ITRTRI((IT-1)*NBCMAX+J)
        IF( IVOIS .LE. 0 )GOTO 3
        IADET(ITRA + NBTRA) = IVOIS
        NBTRA = NBTRA + 1
    3 CONTINUE      
C
C     ON BOUCLE TANTQUE ITRAVAIL N'EST PAS VIDE
C     ----------------------------------------
    5 IF( NBTRA .EQ. 0 )GOTO 999
      IT     = IADET(ITRA)
      NBTRA  = NBTRA-1 
      ITRA = ITRA + 1 
      NT =ITRNOE((IT-1)*NBNMAX+1+IDIMC)
      IF( NT.EQ. 0 )GOTO 5
      IPTDS = SPPOIN(IDIMC,COORD((NT-1)*IDIMC+1),XYZPT,
     >       SPH((IT-1)*(IDIMC+1)+1),ZERO)
        IF( IPTDS.EQ.1 )THEN
C         ---------------------------
C         LE TRIANGLE EST A DETRUIRE
C         ---------------------------
          NBADET = NBADET+1
          IF(NBADET.GT.NADMAX)THEN
            IERR = -2
            GO TO 999
          ENDIF
          IADET(NBADET)= IT
C         ------------------------------------------
C         ON MET LES VOISINS A TRAITER DANS ITRAVAIL
C         ------------------------------------------
          DO 20 J=1,NBC
            IVOIS = ITRTRI((IT-1)*NBCMAX+J)
            IF( IVOIS .LE. 0 )GOTO 20
            DO 10 K=1,NBADET
              IF( IVOIS.EQ.IADET(K) )GOTO 20
   10       CONTINUE
C           --- LE VOISIN EST DEJA A TRAITER : BUG6 ---
C           EN 3D POSSIBLE - EN 2D => ON PERD UN SOMMET
C           -------------------------------------------
            DO 15 K=1,NBTRA
              IF( IVOIS.EQ.IADET(ITRA+K-1) )GOTO 20
   15       CONTINUE
C
            IF((NBTRA+ITRA).GT.NADMAX)THEN
              IERR = -2
              GO TO 999
            ENDIF
            IADET(ITRA + NBTRA) = IVOIS
            NBTRA = NBTRA + 1
   20     CONTINUE
        ENDIF
        GOTO 5
  999 END
C
      SUBROUTINE RTADET(XYZPT,IDIMC,ITRNOE,NBNMAX,ITRTRI,NBCMAX,
     >                     NBE,COORD,SPH,
     >                     IADET,NBADET,NADMAX,ZERO,IERR)
C     **********************************************************************
C     OBJET : RECHERCHE DES TRIANGLES A DETRUIRE (IE "NON-DELAUNAY") 
C             A L'AJOUT D'UN POINT
C     EN ENTREE   :
C        XYZPT : COORDONNEES DU POINT AJOUTE
C        IDIMC  : DIMENSION DE L'ESPACE
C        ITRNOE,NBNMAX,ITRTRI,NBCMAX,NBE,COORD : LA TRIANGULATION
C        SPH   : LES SPHERES CIRCONSCRITES AUX TRIANGLES
C        NBADETMNAX : TAILLE DU TABLEAU IADET 
C        ZERO  : PRECISION DU TEST "POINT DANS SPHERE"
C     EN SORTIE   :
C        IADET    : TABLEAU DES TRIANGLES "NON-DELAUNAY"
C        NBADET   : NOMBRE DE TRIANGLES "  "    "   "
C     **********************************************************************
      REAL       XYZPT(*)
      INTEGER    IDIMC
      INTEGER    ITRNOE(*),NBNMAX,ITRTRI(*),NBCMAX
      INTEGER    NBE,IADET(*),NBADET,NADMAX,IERR
      REAL       COORD(*),SPH(*),ZERO
C
C   
C     --- POUR LE DEBUG ---
C
C      COMMON /DEBUG/ ITRACE, ITEST, IERROR, IMESS
C      INTEGER       ITRACE, ITEST, IERROR
C      CHARACTER*256 IMESS
C     ---------------------------------------------------------------------
C     --- POUR LES STATS ---
C
      COMMON /STATS/ ICARD(100)
      INTEGER       ICARD
C     ---------------------------------------------------------------------
C     --- VARIABLES INTERNES ---
      INTEGER   I,NT,IPTDS,IPTDSC,IPTDS2,ITRACE
      REAL      SPHC(4)
      INTEGER  SPPOIN, SPPOI2,SPCIRC
      EXTERNAL SPPOIN, SPPOI2,SPCIRC
C
      ITRACE = 0
      IERR = 0
      NBADET = 0
      DO 30 I=1,NBE
C     ----- ON PREND LE DERNIER NOEUD ---
        NT =ITRNOE((I-1)*NBNMAX+1+IDIMC)
        IF ( NT.EQ. 0 ) GO TO 30
        IPTDS = SPPOIN(IDIMC,COORD((NT-1)*IDIMC+1),XYZPT,
     >       SPH((I-1)*(IDIMC+1)+1),ZERO)
C
C       ---- POUR LE DEBUG ----
C
      IF( ITRACE .GT. 0 )THEN
        IPTDS2 = SPPOI2(IDIMC,COORD((NT-1)*IDIMC+1),XYZPT,
     >       SPH((I-1)*(IDIMC+1)+1),ZERO)
        IF( IPTDS2.NE.IPTDS )THEN
          ICARD(1) = ICARD(1) + 1
C            PRINT *,'DIFFERENCE DE CALCUL'
C            PRINT *,'SPPOI2 = ',IPTDS2,' SPPOIN = ',IPTDS
C            PRINT *, (SPHC(J),J=1,3)
            IPTDS = SPPOIN(IDIMC,COORD((NT-1)*IDIMC+1),XYZPT,
     >       SPH((I-1)*(IDIMC+1)+1),ZERO)
            IPTDS2 = SPPOI2(IDIMC,COORD((NT-1)*IDIMC+1),XYZPT,
     >       SPH((I-1)*(IDIMC+1)+1),ZERO)
        ENDIF
C
        IPTDSC=SPCIRC(ITRNOE((I-1)*NBNMAX+1),COORD,SPHC,ZERO)
        IPTDSC=SPPOIN(IDIMC,COORD((NT-1)*IDIMC+1),XYZPT,
     >         SPHC(1),ZERO)
        IF(( SPHC(1).NE. SPH((I-1)*(IDIMC+1)+1)).OR.
     >     ( SPHC(2).NE. SPH((I-1)*(IDIMC+1)+2)).OR.
     >     ( SPHC(3).NE. SPH((I-1)*(IDIMC+1)+3)))THEN
C          PRINT *,'ERREUR SUR LA SPHERE'
C          PRINT *, (SPH((I-1)*(IDIMC+1)+J),J=1,3)
C          PRINT *, (SPHC(J),J=1,3)
        ENDIF
        ENDIF
C       ------------------------
        IF( IPTDS.EQ.1 )THEN
          IADET(1) = I
          NBADET = 1
          CALL RTCONN(XYZPT,IDIMC,ITRNOE,NBNMAX,ITRTRI,NBCMAX,
     >                   COORD,SPH,IADET,NBADET,NADMAX,ZERO,IERR)
          GOTO 999
        ENDIF
C
   30 CONTINUE
  999 END
C     **********************************************************************
C     MODULE  : M2 (TRIANGULATION DE DELAUNAY 2D)
C     FICHIER  : M2_SCULPT.F
C     OBJET    : DETERMINE LE PLEIN ET LE VIDE DANS UNE TRIANGULATION
C
C      SCULPT : SCULPT DETERMINE LE PLEIN ET LE VIDE A PARTIR 
C                  DE FRONTIERES DONNEES
C
C     FONCT.   :
C
C     AUTEUR   : O. STAB
C     DATE     : 03.95
C     MODIFICATIONS :
C        AUTEUR, DATE, OBJET : 
C        O.STAB / 20.11.95 / BUG_12 CORRECTION DE SCULPT
C        O.STAB / 03.11.97 / BUG_41 CORRECTION DE SCMAT
C        O.STAB / 26.01.99 / GENERALISATION 3D (CHG SFRIDE,SFRICR)
C
C
C     **********************************************************************
C
      SUBROUTINE SCRGCC(IT,IREGIO,IDE,ITRTRI,NBCMAX,NBE,
     >                 ITVL,IMAT,NBEMAT,IERR)
C     **********************************************************************
C     OBJET SCRGCC : ASSOCIE UN NUMERO DE REGION AUX ELEMENTS DE LA CC A IT
C                    (COMPOSANTE CONNEXE A IT)
C        IREGIO : NUMERO DE LA REGION (DOIT ETRE NON-NUL)
C        ITVL   : TABLEAU DE TRAVAIL = NBE + PILE (APPEL TMA1CC)
C     EN SORTIE :
C        IMAT   : SI I CONNEXE A IT ALORS IMAT(I) = IREGIO 
C        NBEMAT : NOMBRE D'ELEMENTS AFFECTE DU REGION 
C     **********************************************************************
      INTEGER IT,IREGIO,IDE,ITRTRI(*),NBCMAX,NBE
      INTEGER ITVL(*),IMAT(*),NBEMAT,IERR
C
      INTEGER ICON,ITRAV,NBTRAV,IND,I
C
      IERR   = 0
      NBEMAT = 0
      ICON   = 1
C     --- ON A AU MAXIMUM NBE ELEMENTS CONNEXES AVEC IT ---
      ITRAV  = NBE + ICON
      NBTRAV = NBE
      IND    = 1
      CALL TMA1CC(IDE,ITRTRI,NBCMAX,IND,NBE,
     >      IT,ITVL(ITRAV),IMAT,NBTRAV,
     >      ITVL(ICON),NBEMAT,IERR)
      IF( IERR.NE. 0 )THEN
        CALL DSERRE(1,IERR,'SCRGCC',' APPEL TMA1CC ')
        GOTO 999
      ENDIF
C      PRINT *,NBEMAT,' DE IREGIO = ',IREGIO
      DO 10 I=1,NBEMAT
        IMAT(ITVL(I-1+ICON)) = IREGIO
C        PRINT *,ITVL(I-1+ICON)
   10 CONTINUE   
  999 END
C
      SUBROUTINE SCMAT(IFR,NBNIFR,NBIFR,
     >                 IDE,ITRNOE,NBNMAX,ITRTRI,NBCMAX,
     >                 NOETRI,NBE,ITVL,NITMAX,
     >                 IMAT,NPLEIN,NCREUX,IERR)
C     **********************************************************************
C     OBJET SCMAT : DETERMINE LE PLEIN (1) ET LE CREUX (-1) 
C                   A PARTIR DE FRONTIERES DONNEES
C     EN ENTREE  :
C       IFR      : LES ELEMENTS DES FRONTIERES
C       NBIFR    : NOMBRE D'ELEMENTS FRONTIERE
C
C       ITVL : TABLEAU DE TRAVAIL = NBE + PILE (APPEL TMA1CC)
C       NITMAX     : TAILLE DU TABLEAU DE TRAVAIL
C
C     EN SORTIE  : 
C       IMAT     : IMAT(I) = 1 SI L'ELEMENT EST PLEIN
C                                 -1 SI "    "  "  "  CREUX
C       NPLEIN  : NOMBRE DE COMPOSANTES CONNEXES PLEINES
C       NCREUX  : NOMBRE DE COMPOSANTES CONNEXES CREUSES
C       IERR     : CODE D'ERREUR
C                -1 UN ELEMENT FRONTIERE DE IFR N'EXISTE PAS
C                -2 ITVL TROP PETIT
C     **********************************************************************
      INTEGER    IFR(*),NBIFR,NBNIFR,IDE
      INTEGER    ITRNOE(*),NBNMAX,ITRTRI(*),NBCMAX
      INTEGER    NOETRI(*),NBE,ITVL(*),NITMAX,IMAT(*)
      INTEGER    NPLEIN,NCREUX,IERR
C
      INTEGER NBVUE,IT1,IT2,I1,I2,NBEMAT,IREGIO,I,J
      INTEGER NBNE,NBCE
      INTEGER STRNBN,STRNBC
      EXTERNAL STRNBN,STRNBC
C        ===================
C     --- 1. INITIALISATION ----
C        ===================
      NPLEIN = 0
      NCREUX = 0
      IERR = -1
      DO 10 I=1,NBIFR
        CALL SFRICR(IFR((I-1)*NBNIFR+1),NBNIFR,IDE,
     >               ITRNOE,NBNMAX,ITRTRI,NBCMAX,
     >               NOETRI,NBE,ITVL,NITMAX,IERR)
      IF( IERR.NE. 0 )THEN
        CALL DSERRE(1,IERR,'SCMAT',' APPEL SFRICR ')
C        PRINT *,'L ARETE N EXISTE PAS : ',IFR((I-1)*NBNIFR+1),
C     >                                    IFR((I-1)*NBNIFR+2)
C        PRINT *,'NOETRI(O) : ',NOETRI(IFR((I-1)*NBNIFR+1))
C        PRINT *,'NOETRI(E) : ',NOETRI(IFR((I-1)*NBNIFR+2))
        GOTO 9999
      ENDIF   
   10 CONTINUE
      DO 20 I=1,NBE
        IMAT(I) = 0
   20 CONTINUE   
      IERR = 0
C        ====================================================
C     --- 2. RECHERCHE DES FRONTIERES DONNEES NON RECONNUES ----
C         SI UNE DES REGIONS EST CONNUE, L'AUTRE L'EST AUSSI
C        ====================================================      
C
      NBVUE = 0
      I = 0      
   30 I = MOD(I,NBIFR)+1
        CALL SFRIDE(IFR((I-1)*NBNIFR+1),NBNIFR,IDE,
     >               ITRNOE,NBNMAX,ITRTRI,NBCMAX,
     >               NOETRI,NBE,ITVL,NITMAX,
     >               IT1,IT2,I1,I2,IERR)
      IF(IERR.NE.0)THEN
        CALL DSERRE(1,IERR,'SCMAT','APPEL SFRIDE')
        GOTO 9999
      ENDIF
      NBEMAT = 0
C     ----- FRONTIERE DONNEE EST SUR LA FRONTIERE REELLE ---------
      IF(IT1.EQ.0)THEN
        IF(IMAT(IT2).EQ.0)THEN
         IREGIO = 1
         NPLEIN = NPLEIN + 1
         CALL SCRGCC(IT2,IREGIO,IDE,ITRTRI,NBCMAX,NBE,
     >                 ITVL,IMAT,NBEMAT,IERR)
         IF(IERR.NE.0)THEN
           CALL DSERRE(1,IERR,'SCMAT',' 1 APPEL SCRGCC ')
           GOTO 9999
         ENDIF
        ENDIF
        GOTO 40
      ENDIF
      IF(IT2.EQ.0)THEN
        IF(IMAT(IT1).EQ.0)THEN
         IREGIO = 1
         NPLEIN = NPLEIN + 1
         CALL SCRGCC(IT1,IREGIO,IDE,ITRTRI,NBCMAX,NBE,
     >                 ITVL,IMAT,NBEMAT,IERR)
         IF(IERR.NE.0)THEN
           CALL DSERRE(1,IERR,'SCMAT',' 2 APPEL SCRGCC ')
           GOTO 9999
         ENDIF
        ENDIF
        GOTO 40
      ENDIF
C     ----- FRONTIERE DONNEE EST A L'INTERIEUR ---------
      IF((IMAT(IT2).EQ.0).AND.
     >   (IMAT(IT1).EQ.0))GOTO 40
      IF((IMAT(IT2).NE.0).AND.
     >   (IMAT(IT1).NE.0))GOTO 40
      IF(IMAT(IT1).EQ.0)THEN
        IREGIO = - IMAT(IT2)
        IF( IREGIO .EQ. 1 )THEN
          NPLEIN = NPLEIN + 1
        ELSE 
          NCREUX = NCREUX + 1
        ENDIF
        CALL SCRGCC(IT1,IREGIO,IDE,ITRTRI,NBCMAX,NBE,
     >                 ITVL,IMAT,NBEMAT,IERR)
         IF(IERR.NE.0)THEN
           CALL DSERRE(1,IERR,'SCMAT',' 3 APPEL SCRGCC ')
           GOTO 9999
         ENDIF
        GOTO 40
      ENDIF
      IF(IMAT(IT2).EQ.0)THEN
        IREGIO = - IMAT(IT1)
        IF( IREGIO .EQ. 1 )THEN
          NPLEIN = NPLEIN + 1
        ELSE 
          NCREUX = NCREUX + 1
        ENDIF
        CALL SCRGCC(IT2,IREGIO,IDE,ITRTRI,NBCMAX,NBE,
     >                 ITVL,IMAT,NBEMAT,IERR)
         IF(IERR.NE.0)THEN
           CALL DSERRE(1,IERR,'SCMAT',' 4 APPEL SCRGCC ')
           GOTO 9999
         ENDIF
        GOTO 40
      ENDIF
C      
C
   40 NBVUE = NBEMAT + NBVUE
C     --- FIN : ON A ATTRIBUE UN MAT. A TOUS LES ELEMENTS ----
      IF( NBVUE.EQ.NBE )GOTO 9999
C     --- CAS PARTICULIER : ON N'A PAS PU ATTRIBUER UN IREGIO ---
      IF(( NBVUE.EQ.0 ).AND.(I.EQ.NBIFR))GOTO 50
C     --- BOUCLE : ON A PAS VU TOUS LES ELEMENTS ---
      IF( NBVUE.NE.NBE )GOTO 30
C
C        =====================================================
C     --- 3. CAS PARTICULIER :
C         LA FRONTIERE DONNEE EST TOTALEMENT A L'INTERIEUR
C         => RECHERCHE D'UN ELEMENT DE LA FRONTIERE DU CONVEXE  
C        =====================================================
   50 IREGIO = -1
      DO 70 I=1,NBE
        NBNE = STRNBN(I,ITRNOE,NBNMAX)
        NBCE = STRNBC(NBNE,IDE)
        DO 60 J=1,NBCE
          IF( ITRTRI((I-1)*NBCMAX+J).EQ.0 )GOTO 80
   60   CONTINUE
   70 CONTINUE
      NCREUX = NCREUX + 1
   80 CALL SCRGCC(I,IREGIO,IDE,ITRTRI,NBCMAX,NBE,
     >                 ITVL,IMAT,NBEMAT,IERR)
      IF(IERR.NE.0)THEN
         CALL DSERRE(1,IERR,'SCMAT',' 5 APPEL SCRGCC ')
         GOTO 9999
      ENDIF
C     ---- BUG_41 : O.STAB, 03.NOV.97 : ON OUBLIAIT D'INCREMENTER NBVUE !
      NBVUE = NBEMAT + NBVUE
      GOTO 30
C
 9999 END      
C
C
C
C
      SUBROUTINE SCULPT(IFR,NBNIFR,NBIFR,
     >                     IDE,ITRNOE,NBNMAX,ITRTRI,NBCMAX,
     >                     NOETRI,NBE,ITVL,NITMAX,NCC,IERR)
C     **********************************************************************
C     OBJET SCULPT : DETRUIT LES ELEMENTS EXTERIEURS A UNE FRONTIERE DONNEE
C     EN ENTREE  :
C       IFR      : LES ELEMENTS DES FRONTIERES
C       NBIFR    : NOMBRE D'ELEMENTS FRONTIERE
C
C       ITVL : TABLEAU DE TRAVAIL = 2 * NBE + PILE (APPEL TMA1CC)
C       NITMAX      : TAILLE DU TABLEAU DE TRAVAIL
C
C     EN SORTIE  : LA TRIANGULATION MISE A JOUR
C       ITRNOE,NBNMAX : NOEUDS DES ELEMENTS    "   "   "  "
C       ITRTRI,NBCMAX : ELEMENTS VOISINS       
C       NOETRI         : UN DES ELEMENTS INCIDENT A UN POINT
C       NCC            : NOMBRE DE COMPOSANTES CONNEXES
C       IERR           : CODE D'ERREUR
C                        -1 UN ELEMENT FRONTIERE DE IFR N'EXISTE PAS
C                        -2 ITVL OU RTRAVAIL TROP PETIT
C     **********************************************************************
      INTEGER    IFR(*),NBIFR,NBNIFR,IDE
      INTEGER    ITRNOE(*),NBNMAX,ITRTRI(*),NBCMAX
      INTEGER    NOETRI(*),NBE,ITVL(*),NITMAX,NCC,IERR
C
      INTEGER IMAT,ITRAV,NITMX2
      INTEGER ICREUX,NCREUX,NCCREU
      INTEGER NBSOMP,ISOMP,NBFNOE,I,J,IP,NOEMAX
C        =======================================
C     --- 1. AFFECTATION DES PLEIN ET DES CREUX ----
C        =======================================
      NCC = 1
      IERR = 0
      IF( NBIFR.EQ. 0)GOTO 999
      IMAT  = 1
      ITRAV = IMAT + NBE
      NITMX2 = NITMAX - ITRAV + 1
      IF( NITMX2.LT. (2*NBE))THEN
        IERR = -2
        CALL DSERRE(1,IERR,'SCULPT',' TROP D ELEMENTS')
        GOTO 999
      ENDIF
C
      CALL SCMAT(IFR,NBNIFR,NBIFR,
     >           IDE,ITRNOE,NBNMAX,ITRTRI,NBCMAX,
     >           NOETRI,NBE,ITVL(ITRAV),NITMX2,
     >           ITVL(IMAT),NCC,NCCREU,IERR)
      IF( IERR.NE. 0 )THEN
        CALL DSERRE(1,IERR,'SCULPT',' APPEL SCMAT')
        GOTO 999
      ENDIF
      NCREUX = 0
      ICREUX = IMAT
      DO 10 I=1,NBE
        IF( ITVL(I-1+IMAT).EQ.-1 )THEN
          NCREUX = NCREUX + 1
          ITVL(NCREUX-1+ICREUX) = I
        ENDIF
   10 CONTINUE
C        ==================================
C     --- 2. DESTRUCTION DES ELEMENTS CREUX ----
C        ==================================
C
C     --- 2.1 DECONNECTION DES NOEUDS NOETRI(IP)=0 ----
      NOEMAX = 0
C     --- BUG_12 CORRIGE LE 20.11.95 O.STAB ---------
      DO 25 I=1,NCREUX
        DO 20 J=1,NBNMAX
           IP = ITRNOE((ITVL(ICREUX-1+I)-1)*NBNMAX+J)
           IF(IP.NE.0)NOETRI(IP) = 0
   20   CONTINUE 
   25 CONTINUE   
C     --- 2.2 COMPRESSION AU DEBUT ---
      CALL ENSTRI(ITVL(ICREUX),NCREUX)
      CALL NUCOMP(IDE,ITRNOE,NBNMAX,ITRTRI,NBCMAX,NOETRI,
     >            NOEMAX,NBE,ITVL(ICREUX),NCREUX,IERR)
      IF(IERR .NE. 0)THEN
         CALL DSERRE(1,IERR,'SCULPT','APPEL NUCOMP')
         GOTO 999
      ENDIF
C
C     --- POUR LE DEBUG ---
C      CALL DEBSTRF1(IDE,ITRNOE,NBNMAX,ITRTRI,NBCMAX,NOETRI,
C     >              NBE,NOEMAX,ITRACE,IERR) 
C      IF( IERR .NE. 0 )THEN
C        CALL DSERRE(1,IERR,'SCULPT',' NUCOMP')        
C        GO TO 999
C      ENDIF
C     --- 2.3 DESTRUCTION ---
      NBFNOE  = 0
      NBSOMP  = 0
      ISOMP   = IMAT
      DO 30 I=1,NCREUX
        CALL SMADET(IDE,ITRNOE,NBNMAX,ITRTRI,NBCMAX,NBE,NOETRI,
     >          NBFNOE,I,NBCMAX,ITVL(ISOMP+NBSOMP),NBSOMP,IERR)
        IF( IERR .NE. 0  )THEN
          CALL DSERRE(1,IERR,'SCULPT','APPEL SMADET')
          GOTO 999
        ENDIF
   30 CONTINUE
C     --- BUG_12 CORRIGE LE 20.11.95 O.STAB ---------
      DO 40 I=1,MIN(NCREUX,NBE-NCREUX)
        CALL NUPERM(IDE,ITRNOE,NBNMAX,ITRTRI,NBCMAX,NOETRI,
     >                NOEMAX,NBE,I,(NBE+1-I),IERR)
        IF( IERR .NE. 0  )THEN
          CALL DSERRE(1,IERR,'SCULPT','APPEL NUPERM')
          GOTO 999
        ENDIF
   40 CONTINUE
      NBE = NBE - NCREUX
C     --- POUR LE DEBUG ---
C      CALL DEBSTRF1(IDE,ITRNOE,NBNMAX,ITRTRI,NBCMAX,NOETRI,
C     >              NBE-I,NOEMAX,ITRACE,IERR) 
C      IF( IERR .NE. 0 )THEN
C        CALL DSERRE(1,IERR,'SCULPT',' NUCOMP')        
C        GO TO 999
C      ENDIF
C
      IF( NBSOMP.NE.0 )THEN
       IERR = -1
       CALL DSERRE(1,IERR,'SCULPT','SOMMETS PERDUS')
C       PRINT *, (ITVL(ISOMP),I=1,NBSOMP)
       GO TO 999
      ENDIF
C        ==================================
C     --- MISE A JOUR DE NOETRI : O(3*NBE) ---
C        ==================================
      DO 70 I=1,NBE
        DO 60 J=1,NBNMAX
           IP = ITRNOE((I-1)*NBNMAX+J)
           IF(IP.NE.0)NOETRI(IP) = I
   60   CONTINUE    
   70 CONTINUE    
C      
C
  999 END      
C
C     **********************************************************************
C     MODULE  : M2 (TRIANGULATION DE DELAUNAY 2D)
C     FICHIER : D2_SPH2D.F
C     OBJET    : GESTION DES SPHERES CIRCONSCRITES (CAS 2D)
C     FONCT.   :
C     OBJET SPCERC : CREER LA SPHERE CIRCONSCRITE AU TRIANGLE
C      SPPOIN : LE POINT EST-IL DANS LA SPHERE ?
C
C     AUTEUR   : O. STAB - S.M. TIJANI
C     DATE     : 03.95
C     MODIFICATIONS :
C      AUTEUR, DATE, OBJET : O.STAB, 13.11.97, RESTRUCTURATION 
C                            SPCERC REMPLACE SPCREE, 
C                            SPPERM ET SPCOMP VONT DANS ST_SPH.F
C
C
C     **********************************************************************
C
      SUBROUTINE SPCERC(IDIMC,ISPH,ITRI,COORD,SPH,ZERO,IERR)
C     **********************************************************************
C     OBJET SPCERC : CREER LA SPHERE CIRCONSCRITE AU TRIANGLE
C     EN ENTREE :
C        IDIMC : DIMENSION DE L'ESPACE
C        ISPH : NUMERO DU TRIANGLE
C        ITRI : LES SOMMETS DU TRIANGLE
C        COORD: TABLEAU DES COORDONNEES DES POINTS
C        SPH  : TABLEAU DES SPHERES
C        ZERO :
C     EN SORTIE:
C        SPH  : TABLEAU DES SPHERES AUQUEL A ETE AJOUTE CELLE CREEE
C        IERR : CODE D'ERREUR -1 SI LE TRIANGLE EST PLAT
C
C     **********************************************************************
      INTEGER IDIMC
      INTEGER ITRI(*),ISPH,IERR
      REAL    COORD(*),SPH(*),ZERO
C
      REAL X1,Y1,X2,Y2,D1,D2,D
C      REAL S,V
C      INTEGER I,K
C
C      IF( IDIMC .NE. 2 )THEN
C        IERR = -1
C        GOTO 9999
C      ENDIF
C
      SPH(1)=0.
      SPH(2)=0.
C      SPH(3)=0.
      X1=COORD((ITRI(1)-1)*IDIMC+1) - COORD((ITRI(3)-1)*IDIMC+1)
      Y1=COORD((ITRI(1)-1)*IDIMC+2) - COORD((ITRI(3)-1)*IDIMC+2)
      X2=COORD((ITRI(2)-1)*IDIMC+1) - COORD((ITRI(3)-1)*IDIMC+1)
      Y2=COORD((ITRI(2)-1)*IDIMC+2) - COORD((ITRI(3)-1)*IDIMC+2)
      D1=X1**2+Y1**2
      D2=X2**2+Y2**2
      D=X2*Y1-X1*Y2
      IF(ABS(D).LE.ZERO)THEN
        IERR = -1
        GO TO 9999
      ENDIF
      SPH(1)=(Y1*D2-Y2*D1)/D
      SPH(2)=(X2*D1-X1*D2)/D
      IERR = 0
C      SPH(3)=SPH(1)**2+SPH(2)**2
C
C     --- POUR TESTER LE CALCUL :
C
C      DO 20 I=1,3
C      S = 0.0
C      DO 10 K=1,2
C        V = COORD((ITRI(I)-1)*2+K) - COORD((ITRI(3)-1)*2+K)
C        S = S + V * ( SPH(K) - V )
C     10 CONTINUE
C      PRINT '(F22.20)',S
C     20 CONTINUE
C
 9999 END
C
      FUNCTION SPCIRC(ITRI,COORD,SPHERE,ZERO)
C     **********************************************************************
C     OBJET SPCIRC : CALCULE LE CERCLE CIRCONSCRIT A UN TRIANGLE
C     EN ENTREE :
C        ITRID  : NUMERO DES NOEUDS DU TRIANGLE
C        COORD  : COORDONNEES DES NOEUDS
C        ZERO   : PRECISION ( 2* SURFACE MINI. DES TRIANGLES)
C     EN SORTIE :
C        SPHERE : VECTEUR DIAMETRE DU CERCLE 
C                 LE VECTEUR A POUR ORIGINE LE 3IEME POINT DU TRIANGLE
C     RENVOI : -1 SI LA SURFACE DU TRIANGLE EST INFERIEUR A "ZERO"/2
C               0 SINON 
C      ---- > OBSOLET REMPLACE PAR SPCERC !
C     **********************************************************************
      INTEGER SPCIRC
      INTEGER ITRI(3)
      REAL    COORD(*),SPHERE(3),ZERO
C
      REAL X1,Y1,X2,Y2,D1,D2,D
C      REAL S,V
C      INTEGER I,K
C
      SPCIRC = 0
      SPHERE(1)=0.
      SPHERE(2)=0.
C      SPHERE(3)=0.
      X1=COORD( ( ITRI(1) - 1 ) *2 +1 ) -COORD( ( ITRI(3) -1 ) * 2+1 )
      Y1=COORD( ( ITRI(1) - 1 ) *2 +2 ) -COORD( ( ITRI(3) -1 ) * 2+2 )
      X2=COORD( ( ITRI(2) - 1 ) *2 +1 ) -COORD( ( ITRI(3) -1 ) * 2+1 )
      Y2=COORD( ( ITRI(2) - 1 ) *2 +2 ) -COORD( ( ITRI(3) -1 ) * 2+2 )
      D1=X1**2+Y1**2
      D2=X2**2+Y2**2
      D=X2*Y1-X1*Y2
      IF(ABS(D).LE.ZERO)THEN
        SPCIRC = -1
        GO TO 999
      ENDIF
      SPHERE(1)=(Y1*D2-Y2*D1)/D
      SPHERE(2)=(X2*D1-X1*D2)/D
C      SPHERE(3)=SPHERE(1)**2+SPHERE(2)**2
C
C     --- POUR TESTER LE CALCUL :
C
C      DO 20 I=1,3
C      S = 0.0
C      DO 10 K=1,2
C        V = COORD((ITRI(I)-1)*2+K) - COORD((ITRI(3)-1)*2+K)
C        S = S + V * ( SPHERE(K) - V )
C     10 CONTINUE
C      PRINT '(F22.20)',S
C     20 CONTINUE
  999 END
C
      FUNCTION  SPPOI2(IDIMC,U,POINT,BOULE,ZERO)
C     **********************************************************************
C     LE POINT EST-IL A L'EXTERIEUR DU DISQUE OU DE LA BOULE ?
C     EN ENTREE:
C       IDIMC  : DIMENSION DE L'ESPACE
C       POINT : COORDONNEES DU POINT A TESTER
C       BOULE : VECTEUR DIAMETRE DE LA BOULE (CF SPCIRC)
C       U     : LE POINT DE LA BOULE QUI A SERVIT A SON CALCUL(CF SPCIRC)
C       ZERO  :
C     EN SORTIE : 1 SI "POINT" EST DANS "BOULE", O SINON
C      ---- > OBSOLET
C     **********************************************************************
      INTEGER SPPOI2
      INTEGER IDIMC
      REAL    U(*),POINT(*),BOULE(*),ZERO
C
      REAL V(3),FAC,BV,V2
      INTEGER I
      REAL     SPSCVE
      EXTERNAL SPSCVE
C
      FAC=0.999
      SPPOI2=0
C     ---- BUG_36 : O.STAB, 17.10.97, BOULE(IDIMC+1) N'EST PAS FORCEMENT
C         INITIALISE (VOIR SPCIRC)
C      IF(BOULE(IDIMC+1).LE.ZERO) RETURN
      DO 10 I=1,IDIMC
        V(I)= POINT(I)-U(I)
   10 CONTINUE
      BV = FAC*SPSCVE(BOULE,V,IDIMC)
      V2 = SPSCVE(V,V,IDIMC)
      IF( BV.LT.V2 )RETURN
C     --- DANS SPHERE ---
      SPPOI2=1
      END
C
C
      FUNCTION  SPPOIN(IDIMC,U,POINT,SPHERE,ZERO)
C     **********************************************************************
C     OBJET : LE POINT EST-IL DANS LA SPHERE ?
C     EN ENTREE:
C       IDIMC  : DIMENSION DE L'ESPACE
C       POINT : COORDONNEES DU POINT A TESTER
C       SPHERE : VECTEUR DIAMETRE DE LA SPHERE (CF SPCIRC)
C       U     : LE POINT DE LA SPHERE QUI A SERVIT A SON CALCUL(CF SPCIRC)
C     EN SORTIE : 1 SI "POINT" EST DANS "SPHERE", O SINON
C     **********************************************************************
      INTEGER SPPOIN
      INTEGER IDIMC
      REAL    U(*),POINT(*),SPHERE(*),ZERO
C
      REAL V,FAC,S
      INTEGER I
C      DATA FAC /.999/
      DATA FAC /.999999999/
C
      S = 0.0
      SPPOIN=0
      DO 10 I=1,IDIMC
        V = POINT(I)-U(I)
        S = S + V * ( (FAC*SPHERE(I)) - V )
   10 CONTINUE
      IF( S.LT.ZERO )RETURN
C     --- DANS SPHERE ---
      SPPOIN=1
      END
C
C
      FUNCTION SPSCVE(V1,V2,IDIMC)
C     **********************************************************************
C     OBJET : SCALXUTL = V1(L)*V2(1) + V1(2)*V2(2) + ... + V1(N)*V2(N)
C      ---- > OBSOLET
C     **********************************************************************
      REAL SPSCVE
      INTEGER IDIMC
      REAL    V1(*),V2(*)
C
      INTEGER I
C
      SPSCVE = 0.
      IF(IDIMC.LE.0) RETURN
      DO 10 I=1,IDIMC
        SPSCVE = SPSCVE + V1(I)*V2(I)
   10 CONTINUE
      END
C     **********************************************************************
C     MODULE  : M2 (TRIANGULATION DE DELAUNAY 2D)
C     FICHIER : M2_TRIANGULATION.F
C     OBJET    : TRIANGULATION INITIALES DE FORMES ELEMENTAIRES 
C                CONTENANT UNE BOITE ET RESPECTANT DELAUNAY
C     FONCT.   :
C      T2INIT  : TRIANGULATION INITIALE AVEC UN POINT INTERIEUR
C      T2IBT : TRIANGULATION D'UN CARRE CONTENANT LA BOITE
C      T2ITR   : UN TRIANGLE CONTENANT LA BOITE
C      T2ISP: TRIANGULATION D'UN CERCLE AVEC UN POINT INTERIEUR
C
C     AUTEUR   : O. STAB
C     DATE     : 03.95
C     MODIFICATIONS :
C      AUTEUR, DATE, OBJET :
C
C
C     **********************************************************************
C
      SUBROUTINE T2IBT(BOITE,ITRNOE,NBE,COORD,NBN)
C     **********************************************************************
C     OBJET T2IBT : TRIANGULATION D'UN CARRE CONTENANT LA BOITE
C     EN ENTREE  :
C        BOITE   :  LA BOITE QUE DOIT CONTENIR LE MAILLAGE
C     EN SORTIE  :
C        ITRNOE    :  LA DEFINITION DES TRIANGLES (LEURS POINTS)
C        NBE     :  LE NOMBRE D'ELEMENTS
C        COORD   :  TABLEAU DES COORDONNEES
C        NBN     :  NOMBRE DE POINTS DE LA TRIANGULATION INITIALE
C     **********************************************************************
      REAL       BOITE(4),COORD(*)
      INTEGER    NBN,ITRNOE(*),NBE
C
      REAL     R, CTR(2), COEF
      INTEGER I
C
      NBN = -1
      NBE = -1
C
      R = 0.0
      DO 10 I=1,2
        CTR(I) = (BOITE(2+I) + BOITE(I)) / 2.
        R = MAX(R,(BOITE(2+I) - BOITE(I)))
   10 CONTINUE
C      COEF = SQRT(2.) * 50.
      COEF = 2.
C
      COORD(1) = CTR(1) - R * COEF
      COORD(2) = CTR(2) - R * COEF
C
      COORD(3) = CTR(1) + R * COEF
      COORD(4) = CTR(2) - R * COEF
C
      COORD(5) = CTR(1) + R * COEF
      COORD(6) = CTR(2) + R * COEF
C
      COORD(7) = CTR(1) - R * COEF
      COORD(8) = CTR(2) + R * COEF
C
      ITRNOE(1) = 1
      ITRNOE(2) = 2
      ITRNOE(3) = 3
      ITRNOE(4) = 3
      ITRNOE(5) = 4
      ITRNOE(6) = 1
C
      NBN = 4
      NBE = 2
C
      END
C
C
      SUBROUTINE T2ITR(BOITE,ITRNOE,NBE,COORD,NBN)
C     **********************************************************************
C     OBJET T2ITR : UN TRIANGLE CONTENANT LA BOITE
C     EN ENTREE  :
C        BOITE   :  LA BOITE QUE DOIT CONTENIR LE MAILLAGE
C     EN SORTIE  :
C        ITRNOE    :  LA DEFINITION DES TRIANGLES (LEURS POINTS)
C        NBE     :  LE NOMBRE D'ELEMENTS
C        COORD   :  TABLEAU DES COORDONNEES
C        NBN     :  NOMBRE DE POINTS DE LA TRIANGULATION INITIALE
C     **********************************************************************
      REAL       BOITE(4),COORD(*)
      INTEGER    NBN,ITRNOE(*),NBE
C
      INTEGER I
C
      COORD(1) = -SQRT(3.)/2.
      COORD(2) = -0.5
C
      COORD(3) = SQRT(3.)/2.
      COORD(4) = -0.5
C
      COORD(5) = 0.
      COORD(6) = 1.
C
      DO 10 I=1,6
        COORD(I) = 50. * COORD(I)
   10 CONTINUE
C
      ITRNOE(1) = 1
      ITRNOE(2) = 2
      ITRNOE(3) = 3
C
      NBN = 3
      NBE = 1
C
      END
C
C
      SUBROUTINE T2ISP(BOITE,NUM,NBPT,
     >                 ITRNOE,NBNMAX,ITRTRI,NBCMAX,NOETRI,NOEMAX,NBE,
     >                 COORD,NCOORD,IERR)
C     **********************************************************************
C     OBJET T2ISP : TRIANGULATION D'UN CERCLE AVEC UN POINT INTERIEUR
C     EN ENTREE  :
C        BOITE   :  LA BOITE QUE DOIT CONTENIR LE MAILLAGE
C        NUM     :  NUMERO D'UN POINT A L'INTERIEUR DE LA BOITE
C     EN SORTIE  :
C        ITRNOE    :  LA DEFINITION DES TRIANGLES (LEURS POINTS)
C        NBE     :  LE NOMBRE D'ELEMENTS
C        COORD   :  TABLEAU DES COORDONNEES
C        NBN     :  NOMBRE DE POINTS DE LA TRIANGULATION INITIALE
C     **********************************************************************
      REAL       BOITE(4)
      INTEGER    NUM,NBPT
      INTEGER    ITRNOE(*),NBNMAX,ITRTRI(*),NBCMAX,NOETRI(*),NOEMAX,NBE
      REAL       COORD(*)
      INTEGER    NCOORD,IERR
C
      REAL     R, COEF
      INTEGER  I
      REAL     DTETA, TETA, RPI
      PARAMETER ( RPI = 3.14159265358979323846 )
C
C
      IERR = 0
      NBE = 0
      COEF = 2.
      IF( NCOORD.LT.NBPT )THEN
        IERR = -2
        GOTO 9999
      ENDIF
C
C     --- GEOMETRIE ---
      R = 0.0
      DO 10 I=1,2
        R = MAX(R,(BOITE(2+I) - BOITE(I)))
   10 CONTINUE
C     --- pour l'enseignement :
C      R = R * 200.
      IF( NBPT .LT. 3 )THEN
        IERR = -1
        CALL DSERRE(1,IERR,'T2ISP','IL FAUT 3 POINTS')
        GOTO 9999
      ENDIF
      DTETA = (2 * RPI) / NBPT 
      DO 20 I=1,NBPT 
        TETA = (I-1) * DTETA
        COORD((I-1)*2+1) = COEF * R * COS(TETA)
        COORD((I-1)*2+2) = COEF * R * SIN(TETA)
   20 CONTINUE 
      IF( NBNMAX.GE. 3 )THEN
      DO 30 I=1,NBPT
        ITRNOE((I-1)*NBNMAX+1) = NUM
        ITRNOE((I-1)*NBNMAX+2) = I
        ITRNOE((I-1)*NBNMAX+3) = I+1      
   30 CONTINUE 
      ITRNOE((NBPT-1)*NBNMAX+3) = 1 
      NBE = NBPT
      ELSE
      NBE = 0
      ENDIF     
C     --- STRUCTURE DE DONNEES ---
      IF( NBCMAX.GE.3 )THEN
      DO 110 I=1,NBPT
        ITRTRI((I-1)*NBCMAX+1) = I-1
        ITRTRI((I-1)*NBCMAX+2) = 0
        ITRTRI((I-1)*NBCMAX+3) = I+1   
 110  CONTINUE
      ITRTRI(1) = NBE
      ITRTRI((NBPT-1)*NBCMAX+3) = 1
      ENDIF
C
      IF( NOEMAX.GE.NBPT )THEN
      DO 120 I=1,NBPT
        NOETRI(I) = I
 120  CONTINUE
      ENDIF
C
 9999 END         
C
C
      SUBROUTINE T2INIT(BOITE,NUM,ITRNOE,NBE,COORD,NBN)
C     **********************************************************************
C     OBJET T2INIT : TRIANGULATION INITIALE AVEC UN POINT INTERIEUR
C     EN ENTREE  :
C        BOITE   :  LA BOITE QUE DOIT CONTENIR LE MAILLAGE
C        NUM     :  NUMERO D'UN POINT A L'INTERIEUR DE LA BOITE
C     EN SORTIE  :
C        ITRNOE    :  LA DEFINITION DES TRIANGLES (LEURS POINTS)
C        NBE     :  LE NOMBRE D'ELEMENTS
C        COORD   :  TABLEAU DES COORDONNEES
C        NBN     :  NOMBRE DE POINTS DE LA TRIANGULATION INITIALE
C     **********************************************************************
      REAL       BOITE(4),COORD(*)
      INTEGER    NUM, NBN
      INTEGER    ITRNOE(*),NBE
C
      INTEGER IPOLY
C
      IPOLY = 1
      GOTO(10,20,30) IPOLY
C     CALL T2ISP(BOITE,NUM,ITRNOE,NBE,COORD,NBN)
 10   GOTO 999
   20 CALL T2IBT(BOITE,ITRNOE,NBE,COORD,NBN)
      GOTO 999
   30 CALL T2ITR(BOITE,ITRNOE,NBE,COORD,NBN)
  999 END
C





C     *****************************************************************
C     MODULE  : M3 (RESPECT D'UNE ARETE)
C     FICHIER : M3_INTER2D.F
C     OBJET   : INTERSECTION D'UN SEGMENT AVEC UN MAILLAGE 
C               TRIANGULAIRE 2D
C     FONCT.  : 
C       TRITSE: CALCULE LES ELEMENTS INTERSECTANT UN SEGMENT 
C       TRDBSE : TRIANGLE AU DEPART D'UN SEGMENT
C
C     AUTEUR  : O. STAB
C     DATE    : 03.95
C     MODIFICATIONS :
C      AUTEUR, DATE, OBJET :
C      O.STAB, 28.03.97, BUG_14 TRITSE DEPASSEMENT DU TABLEAU INTER
C
C
C     *****************************************************************
C 
      SUBROUTINE TRITSE(NN,ITRNOE,NBNMAX,ITRTRI,NBCMAX,
     >                   NOETRI,NBE,COORD,INTER,NINTER)
C     *************************************************************
C     OBJET TRITSE : DETECTE LES ELEMENTS INTERSECTANT UN SEGMENT 
C
C     EN ENTREE: 
C        NN() : LES INDICES DES NOEUDS DU SEGMENT
C
C        ITRTRI,NBNMAX,ITRNOE,NBCMAX,NOETRI,NBE,COORD : LE MAILLAGE
C
C        NINTER : TAILLE DU TABLEAU INTER
C
C     EN SORTIE: 
C        INTER  :  TABLEAU DES ELEMENTS INTERSECTANT NN
C                  ILS SONT ORDONNEES DE NN(1) VERS NN(2)
C        NINTER:  NOMBRE D'ELEMENTS INTERSECTANT NN
C                  -1 SI LE SEGMENT EST EXTERIEUR OU PASSE PAR UN NOEUD
C                  -2 SI INTER(NINTER) TROP PETIT
C     NIVEAU  : MODULE
C     *****************************************************************
      INTEGER   NN(*),ITRNOE(*),NBNMAX,ITRTRI(*),NBCMAX
      INTEGER   NOETRI(*),NBE,INTER(*),NINTER
      REAL      COORD(*)
C
      REAL      XN(4), DROITE(3), PZERO, X(3),Y(3)
      INTEGER   NLO(3),NBNN,IDE,IDIMC,NBN,I,IT1,IT2,I1,I2,IERR
      INTEGER   ITD,IAD,ITF,IAF,ITS,IARET(3),NBA,ISOM(3),NBS,NS
      INTEGER   NINMAX,ITVL(1),NITMAX
C
      NITMAX = 1 
      NINMAX = NINTER
      NINTER = 0
      IDE = 2
      NBNN = 2
      IDIMC = 2
      NBN = 3
      CALL SFRI2D(NN,NBNN,IDE,ITRNOE,NBNMAX,ITRTRI,NBCMAX,
     >            NOETRI,NBE,ITVL,NITMAX,IT1,IT2,I1,I2,IERR)
      IF(IERR.NE.0)THEN
        CALL DSERRE(1,IERR,'TRITSE','APPEL SFRI2D')
        GOTO 9999
      ENDIF
C      
      IF((IT1.NE.0).OR.(IT2.NE.0))GO TO 9999
C
C     --- LE SEGMENT N'EST PAS RESPECTE ---
C
      NLO(1) = NN(1)
      NLO(2) = NN(2)
      NLO(3) = NN(1)
C
C     --- RECHERCHE DU TRIANGLE DE DEPART ---
C
      CALL TRDBSE(NLO,ITRNOE,NBNMAX,ITRTRI,NBCMAX,
     >                   NOETRI,COORD,ITD,IAD)
C
      IF(ITD.EQ.0)THEN
C       --- on teste si l'un des noeuds n'est pas connecte !
        IT1=NOETRI(NN(1))
        IT2=NOETRI(NN(2))
        IF((IT1.LT.1 ).OR.(IT2.LT.1))THEN
          CALL DSERRE(1,IERR,'TRITSE','POINT DE FRONTIERE NON CONNECTE')
        ELSE
C         l'arete est geometriquement hors du maillage
          XN(1)=COORD((NN(1)-1)*IDIMC+1)
          XN(2)=COORD((NN(1)-1)*IDIMC+2)
          XN(3)=COORD((NN(2)-1)*IDIMC+1)
          XN(4)=COORD((NN(2)-1)*IDIMC+2)
          CALL DSERRE(1,IERR,'TRITSE','FRONTIERE HORS DU MAILLAGE')
        ENDIF
        IERR=-1
        CALL DSERRE(1,IERR,'TRITSE','1 APPEL TRDBSE')
        GOTO 888
      ENDIF
C
      NINTER=NINTER+1
C     ----- BUG_14 : 28.03.97 O.STAB ---
      IF( NINTER.GT. NINMAX )THEN
        NINTER = -2
        CALL DSERRE(1,IERR,'TRITSE','1 TROP D INTERSECTIONS')
        GOTO 9999
      ENDIF
      INTER(NINTER)= ITD
C
C     --- RECHERCHE DU TRIANGLE D'ARRIVEE ---
C
      CALL TRDBSE(NLO(2),ITRNOE,NBNMAX,ITRTRI,NBCMAX,
     >                   NOETRI,COORD,ITF,IAF)     
      IF(ITF.EQ.0)THEN
        IERR=-1
        CALL DSERRE(1,IERR,'TRITSE','2 APPEL TRDBSE')
        GOTO 888
      ENDIF
C     -----------------------------------------
      DO 5 I=1,IDIMC
        XN(I)     = COORD((NN(1)-1)*IDIMC+I)
        XN(IDIMC+I)= COORD((NN(2)-1)*IDIMC+I)
   5  CONTINUE
      PZERO = 1.E-10 *((XN(3)-XN(1))**2 + (XN(4)-XN(2))**2)
C      CALL G2DDRO2P( XN, DROITE ) REMPLACE PAR O.STAB
      CALL DR2PO( COORD((NN(1)-1)*IDIMC+1),
     >                COORD((NN(2)-1)*IDIMC+1),DROITE,IERR)
      IF(IERR.NE.0)THEN
        CALL DSERRE(1,IERR,'TRITSE','1 APPEL DR2PO')
        GOTO 888
      ENDIF
C     -----------------------------------------      
      ITS = ITRTRI((ITD-1)*NBCMAX+IAD)
C     --------------------------------------------
   10 IF( ITS .EQ. ITF )GO TO 90
      NINTER=NINTER+1
C     ----- BUG_14 : 28.03.97 O.STAB ---
      IF( NINTER.GT. NINMAX )THEN
        NINTER = -2
        GOTO 9999
      ENDIF
      INTER(NINTER)= ITS
      DO 20 I=1,NBN
        NS = ITRNOE((ITS-1)*NBNMAX+I)
        X(I)  = COORD((NS-1)*IDIMC+1)
        Y(I)  = COORD((NS-1)*IDIMC+2)
   20 CONTINUE
      CALL INDRPO(X,Y,NBN,DROITE,PZERO,NBA,IARET,NBS,ISOM)
      IF( NBA .NE.2 )GOTO 888
      IF( ITRTRI((ITS-1)*NBCMAX+IARET(1)).EQ.INTER(NINTER-1))THEN
        ITS = ITRTRI((ITS-1)*NBCMAX+IARET(2))
      ELSE
        ITS = ITRTRI((ITS-1)*NBCMAX+IARET(1))
      ENDIF
      GO TO 10
C     --- ON A FINI ---
   90 NINTER=NINTER+1
C     ----- BUG_14 : 28.03.97 O.STAB ---
      IF( NINTER.GT. NINMAX )THEN
        NINTER = -2
        CALL DSERRE(1,IERR,'TRITSE','2 TROP D INTERSECTIONS')
        GOTO 9999
      ENDIF
      INTER(NINTER)= ITF
      GOTO 9999
  888 NINTER= -1
C
 9999 END
C    
C      
      SUBROUTINE TRDBSE(NN,ITRNOE,NBNMAX,ITRTRI,NBCMAX,
     >                   NOETRI,COORD,ITP,IAR)
C     ******************************************************     
C     OBJET :  SELECTIONNE LE TRIANGLE INCIDENT A UN NOEUD
C              ET QUI INTERSECTE UNE DEMI-DROITE PARTANT 
C              DE CE NOEUD
C     EN ENTREE: 
C        NN() : LES INDICES DES NOEUDS DU SEGMENT
C     EN SORTIE: 
C        ITP  :  LE TRIANGLE INTERSECTANT NN
C        IAR  :  L'INDICE DE L'ARETE DE ITP INTERSECTEE PAR NN
C     NIVEAU  : FICHIER
C     ********************************************************
      INTEGER   NN(*),ITRNOE(*),NBNMAX,ITRTRI(*),NBCMAX
      INTEGER   NOETRI(*),ITP,IAR
      REAL      COORD(*)
C
      REAL      XN(4), DROITE(3), PZERO, X(2),Y(2),S1,S2
      INTEGER   IDE,IDIMC,I
      INTEGER   ITPDEB,ISENS,IARDEB,N1,N2,IERR
C 
C     --- LE SEGMENT N'EST PAS RESPECTE ---
      IERR = 0
      IDIMC = 2
      IDE = 2
      DO 10 I=1,IDIMC
        XN(I)      = COORD((NN(1)-1)*IDIMC+I)
        XN(IDIMC+I)= COORD((NN(2)-1)*IDIMC+I)
   10 CONTINUE
      PZERO = 1.E-10 *((XN(3)-XN(1))**2 + (XN(4)-XN(2))**2)
C      CALL G2DDRO2P( XN, DROITE ) REMPLACE PAR O.STAB
      CALL DR2PO( COORD((NN(1)-1)*IDIMC+1),
     >            COORD((NN(2)-1)*IDIMC+1),DROITE,IERR)
      IF( IERR.NE.0 )THEN
        CALL DSERRE(1,IERR,'TRDBSE','APPEL DR2PO')
        GO TO 999
      ENDIF
C      
C     --- RECHERCHE DE L'ELEMENT DE DEPART ---
C     --------------------------------------------
      ISENS = 1
      CALL SESFR2(NN,ISENS,IDE,ITRNOE,NBNMAX,ITRTRI,
     >                     NBCMAX,NOETRI,ITP,IAR)
C     --- LE SOMMET NN(1) EST ISOLE ?!
      IF((IAR.EQ.-1).OR.(ITP.EQ.0))THEN
        IERR=-1
        CALL DSERRE(1,IERR,'TRDBSE','1 APPEL SESFR2')
        GO TO 999
      ENDIF
      ITPDEB = ITP
      IARDEB = IAR
C      
C     --- TEST D'INTERSECTION : L'ARETE OPPOSEE ---
C
   20 I = IAR
      N2 = ITRNOE((ITP-1)*NBNMAX+I)     
      X(2) = COORD((N2-1)*IDIMC + 1)
      Y(2) = COORD((N2-1)*IDIMC + 2)
      I = MOD(I,3)+1
      I = MOD(I,3)+1 
      N1 = ITRNOE((ITP-1)*NBNMAX+I)    
      X(1) = COORD((N1-1)*IDIMC + 1)
      Y(1) = COORD((N1-1)*IDIMC + 2)
C
      S1 = DROITE(1)*X(1)+DROITE(2)*Y(1)+DROITE(3)
      S2 = DROITE(1)*X(2)+DROITE(2)*Y(2)+DROITE(3)
      IF(((S1.GT. PZERO).AND.(S2.LT.-PZERO)).OR.
     >   ((S1.LT.-PZERO).AND.(S2.GT. PZERO)))THEN
C        --- VERIFICATION DU COTE : PRSCAL > 0---
         S1 = ((X(1)-XN(1))*(XN(4)-XN(2))) -
     >        ((Y(1)-XN(2))*(XN(3)-XN(1)))
         S2 = ((X(1)-XN(1))*(Y(2)-Y(1))) -
     >        ((Y(1)-XN(2))*(X(2)-X(1)))     
         IF( (S1*S2).GT.PZERO )THEN
         IAR = I
         GOTO 999
         ENDIF
      ENDIF
C     --- ON PASSE AU TRIANGLE SUIVANT --- 
      IAR = MOD(IAR,NBCMAX)+1  
      CALL SESFR1(ITP,IAR,ITRTRI,NBCMAX,ITP,IAR)
      IF((ITP.NE.ITPDEB ).AND.(ITP.NE.0))GOTO 20    
C     -- on a pas trouve d'intersection => ERREUR !!!
      ITP = 0
      IAR = 0
      IERR=-1
      CALL DSERRE(1,IERR,'TRDBSE','1 APPEL SESFR2')
  999 END             

C     *****************************************************************
C     MODULE  : M3 (RESPECT D'UNE ARETE)
C     FICHIER : M3_RESPECT.F
C     OBJET   : FORCE LE RESPECT DES ARETES FRONTIERE DANS UN MAILLAGE 
C               TRIANGULAIRE 2D
C     FONCT.  : 
C       RF2RAR : IMPOSE LE RESPECTER D'UNE ARETE A UN MAILLAGE 
C       RF2FAR : FORCE LE MAILLAGE A RESPECTER UNE ARETE 
C
C     AUTEUR  : O. STAB
C     DATE    : 03.95
C     TEST    : 07.95
C     MODIFICATIONS :
C      AUTEUR, DATE, OBJET :
C      O.STAB BUG1 DANS RF2FAR
C      O.STAB, 28.03.97, BUG_14 RF2RAR RETOUR CODE D'ERREUR (TRITSE)
C      O.STAB, 28.04.97, SUPPRESSION TRPLS2 (DEPLACEE)
C            AJOUT TRRILF (DEPLACE), AJOUT DE 2 PARAMETRES 
C            D'ENTREE POUR TRPLS2,TRRILF : RDONFR, IDIMC 
C
C     *****************************************************************
C
      FUNCTION TRRILF(P1,P2,P3,IDIMC,RDONFR)
C     *****************************************************************
C     QUALITE DU TRIANGLE : RAYON DU CERCLE INSCRIT SUR ARETE LA PLUS
C     LONGUE. 
C     RIL = SURFACE / (DEMI PERIMETRE * ARETE LA PLUS LONGUE)
C     *****************************************************************
      INTEGER IDIMC
      REAL P1(*),P2(*),P3(*),RDONFR(*)
C
      REAL TRRILF
      REAL       XV(3),YV(3),S,D,DMAX
      INTEGER    I
C
      TRRILF = 0.0
      XV(1) = P2(1) - P1(1) 
      YV(1) = P2(2) - P1(2) 
      XV(2) = P3(1) - P2(1) 
      YV(2) = P3(2) - P2(2) 
      XV(3) = P1(1) - P3(1) 
      YV(3) = P1(2) - P3(2) 
      S = (XV(1) *  YV(2)) - ( XV(2) * YV(1) )   
      IF( S.LT.0.0 )GOTO 999
      DMAX = 0.0
      DO 10 I=1,3
        D = XV(I)**2 + YV(I)**2
        IF( D .GT. DMAX )DMAX = D
   10 CONTINUE 
      TRRILF = ( S / DMAX )    
  999 END
C
C      
      SUBROUTINE RF2RAR(NN,ITRNOE,NBNMAX,ITRTRI,NBCMAX,
     >                    NOETRI,NBE,COORD,
     >                    ITVL,NTIMAX,RTVL,NTRMAX,
     >                    NBENEW,IERR)
C     *****************************************************************
C     OBJET : IMPOSE LE RESPECTER D'UNE ARETE A UN MAILLAGE TRIANGULAIRE
C
C     EN ENTREE: 
C        NN()    :  LES INDICES DES NOEUDS DE L'ARETE
C
C        ITRTRI,NBNMAX,ITRNOE,NBCMAX,NOETRI,NBE,COORD : LE MAILLAGE
C
C        ITVL   :  TABLEAU DE TRAVAIL (ENTIERS)
C        NTIMAX :  TAILLE DU TABLEAU ITVL
C        RTVL   :  TABLEAU DE TRAVAIL (REELS)
C
C        NTRMAX :  TAILLE DU TABLEAU RTVL
C          AU MINIMUM = 9 * NINTER + 10
C          AU MAXIMUM = (NBR MAX D'ELEMENTS EN 1 NOEUD + 1) *
C                        NUMERO MAXI DU NOEUD DANS ITRNOE
C
C     EN SORTIE: LE MAILLAGE MODIFIE SI NECESSAIRE.
C
C        NBENEW: LE NOMBRE DE TRIANGLES MODIFIES
C                ILS ONT LES NUMERO 1 A NBENEW
C
C        IERR  :  0 SI OK
C          -1 SI L'ARETE EST EXTERIEURE OU PASSE PAR UN NOEUD
C          -2 SI LE NOMBRE DE TRIANGLES INTERSECTES EST TROP GRAND
C             PEUT ETRE ITVL EST TROP PETIT
C     *****************************************************************
      INTEGER   NN(*),ITRNOE(*),NBNMAX,ITRTRI(*),NBCMAX
      INTEGER   NOETRI(*),NBE,ITVL(*),NTIMAX,NTRMAX
      REAL      COORD(*), RTVL(*)
      INTEGER   NBENEW,IERR
C
      INTEGER   NINTER,ITRAV,INTER,IDIMC
C        =================================================
C     --- 1. CALCUL DES TRIANGLES INTERSECTANT LE SEGMENT ---
C        =================================================
C     ITVL = | INTER |
C                 NINTER    
C 
      IDIMC = 2
      IERR = 0
      INTER = 1
      NINTER = NTIMAX
      CALL TRITSE(NN,ITRNOE,NBNMAX,ITRTRI,NBCMAX,
     >               NOETRI,NBE,COORD,ITVL(INTER),NINTER)
      NBENEW = NINTER
      IF( NINTER .EQ. 0 ) GO TO 999
C     ---- BUG_14 O.STAB 28.03.97 ----
      IF( NINTER .LT. 0 )THEN
       IERR = NINTER
       CALL DSERRE(1,IERR,'RF2RAR',' APPEL TRITSE')       
       GOTO 999
      ENDIF
C              ====================
C       ------- 2.FORCAGE OPTIMUM  ----------
C              ====================
        ITRAV = NINTER + INTER
        CALL RF2FAR(NN,ITVL(INTER),NINTER, 
     >                ITRNOE,NBNMAX,ITRTRI,NBCMAX,
     >                NOETRI,NBE,COORD,ITVL(ITRAV),
     >                (NTIMAX-NINTER),RTVL,NTRMAX,IERR)
C       
      IF( IERR .NE. 0  )THEN
        CALL DSERRE(1,IERR,'RF2RAR',' APPEL RF2FAR')       
        GOTO 999
      ENDIF
  999 END
C
C
      SUBROUTINE RF2FAR(NN,INTER, NINTER, 
     >                  ITRNOE,NBNMAX,ITRTRI,NBCMAX,
     >                  NOETRI,NBE,COORD,
     >                  ITVL,NTIMAX,RTVL,NTRMAX,IERR)
C     *****************************************************************
C     OBJET : FORCE LE MAILLAGE A RESPECTER UNE ARETE 
C
C     EN ENTREE: 
C      NN()    :  LES INDICES DES NOEUDS DE L'ARETE
C      INTER   :  TABLEAU DES ELEMENTS INTERSECTANTS NN()
C      NINTER  :  NBRE D'ELEMENTS DE INTER
C                 AU MINIMUM = 8 * NINTER + 10
C                 AU MAXIMUM = (NBR MAX D'ELEMENTS EN 1 NOEUD + 1) *
C                 (NUMERO MAXI DES NOEUDS DES ELEMENTS DE INTER)
C
C      ITVL    :  TABLEAU DE TRAVAIL (ENTIERS)
C      NTIMAX  :  TAILLE DU TABLEAU ITVL
C      RTVL    :  TABLEAU DE TRAVAIL (REELS)
C      NTRMAX  :  TAILLE DU TABLEAU RTVL
C
C     EN SORTIE: LE MAILLAGE MODIFIE SI NECESSAIRE.
C      IERR    : 0 SI OK
C          -1 SI LES DONNEES SONT ERRONEES
C             NN(1) OU NN(2) N'APPARTIENNT PAS AUX ELEMENTS DE INTER
C          -2 SI ITVL EST TROP PETIT
C     REMARQUE : ATTENTION LES MAILLES DE INTER SONT RENUMEROTEE DE 
C                1 A CARD(INTER), ITRNOE,ITRTRI...SONT MODIFIES !!!
C     *****************************************************************
      INTEGER   NN(*),INTER(*),NINTER,ITRNOE(*),NBNMAX
      INTEGER   ITRTRI(*),NBCMAX,NOETRI(*),NBE
      INTEGER   ITVL(*),NTIMAX,NTRMAX,IERR
      REAL      COORD(*), RTVL(*)
C
      REAL      TRRILF
      EXTERNAL  TRRILF
C
      INTEGER   IDE,I,NBN,NBC,NBIFR,NBIFR1,IND,IFR
      INTEGER   NIFMAX
      INTEGER   IT,IF,IT1,J, NOEUD, IFR2, NBCOL, NOEMAX
      INTEGER   IPOLY,NBPP,IPOLY1,NBPP1,IPOLY2,NBPP2
      INTEGER   INOE,ITRI,ITRAV,NBTRAV
      INTEGER   NBFNOE, N, ISOMP, NBSOMP, NCC
      INTEGER   ITRIP1, ITRIP2, ITI, ITR, NTIMX, NTRMX
      INTEGER   NBIFR2
      REAL      QTMIN1, QTMIN2
      REAL      RDONFR(1)
      INTEGER   IDIMC
C
      IDIMC = 2
      IDE   = 2
      IERR  = 0
      IF(NTIMAX.LT.(8*NINTER+10))THEN
         IERR = -2
         GO TO 999
      ENDIF
C         ====================================================
C     --- 1. COMPRESSION DU MAILLAGE ET CALCUL DE LA FRONTIERE
C         ====================================================
C
C     ITVL = |  IFR  |
C                 2*NBIFR
C
      CALL ENSTRI(INTER,NINTER)
      NOEMAX = 1
      CALL NUCOMP(IDE,ITRNOE,NBNMAX,ITRTRI,NBCMAX,NOETRI,
     >             NOEMAX,NBE,INTER,NINTER,IERR)
      IF( IERR .NE. 0  )THEN
        CALL DSERRE(1,IERR,'RF2FAR',' APPEL NUCOMP')       
        GOTO 999
      ENDIF
C
C      PRINT *,' ELEMENTS A DETRUIRE '
C      PRINT *,' ',((ITRNOE((I-1)*3+J),J=1,3),I=1,NINTER)
C
      IND = 1
      IFR = 1
      NBIFR = 0
      NIFMAX = NTIMAX
      CALL TMAFRT(IDE,ITRNOE,NBNMAX,ITRTRI,NBCMAX,IND,NINTER,
     >                   ITVL(IFR),NBIFR,NIFMAX,IERR)
C
C      PRINT *,' FRONTIERE '
C      PRINT *,' ',((ITVL((I-1)*2+IFR-1+J),J=1,2),I=1,NBIFR)
      IF( IERR .NE. 0  )THEN
        CALL DSERRE(1,IERR,'RF2FAR',' APPEL TMAFRT')       
        GOTO 999
      ENDIF
      IF( NBIFR .NE. (NINTER+2)  )THEN
        CALL DSERRE(1,IERR,'RF2FAR',' CARDINAL POLYGONE ?')       
        GOTO 999
      ENDIF
C          ========================================= 
C     --- 2. CREATION DES 2 POLYGONES A TRIANGULER. -----
C          =========================================
C     ITVL = |  IFR |   INOE  |  ITRI   | IPOLY
C                2*NBIFR NBN*NBIFR NBC*NBIFR
C
      NBN = 2
      NBC = 2
      NBIFR = NINTER + 2 
C
C     --- 2.1 CREATION DU MAILLAGE LINEIQUE ---
C         ----------------------------------
C     LE NOMBRE DE PARAMETRES DE SFRCRE A CHANGE ??? O.STAB 07.95
C     >              ITRTRI,NBCMAX,NOETRI,NBE,ITVL(ITRAV),NBTRAV,
C
      INOE   = ( 2 * NBIFR ) + 1
      ITRI   = ( NBN * NBIFR ) + INOE
      ITRAV  = ( NBC * NBIFR ) + ITRI
C     --- ECONOMIE DE FNOETRI --
      NBTRAV = (NBC + 1) * NBIFR
      NBFNOE = 0
      NCC = 0
      CALL SFRCRE(IDE,ITVL(IFR),NBIFR,ITRNOE,NBNMAX,
     >              ITVL(ITRAV),NBTRAV,
     >              ITVL(INOE),NBN,ITVL(ITRI),NBC,NBIFR,
     >              ITVL(1),NBFNOE,NCC,IERR)
C      PRINT *,' FRONTIERE '
C      PRINT *,' ',((ITVL((I-1)*2+INOE-1+J),J=1,2),I=1,NBIFR)
      IF( IERR .NE. 0  )THEN
        CALL DSERRE(1,IERR,'RF2FAR',' APPEL SFRCRE')       
        GOTO 999
      ENDIF
C      PRINT *,' NBIFR, NCC = ',NBIFR,NCC
C      IF((NBIFR .NE. NBIFR2).OR.(NCC.NE.1))THEN
C        CALL DSERRE(1,IERR,'RF2FAR',' FRONTIERE NON POLYGONALE')       
C        GOTO 999
C      ENDIF
C
C     ---- 2.2 FRONTIERE EXTERIEURE ---------
C         --------------------------
      NBIFR1 = 0
      DO 30 I=1,NBIFR
        IT = ITVL((I-1)*2+IFR)
        IF = ITVL((I-1)*2+IFR+1)
        IT1 = ITRTRI((IT-1)*NBCMAX+IF)
        IF( IT1.NE.0 )THEN
          DO 10 J=1,NBCMAX
            IF( ITRTRI((IT1-1)*NBCMAX+J).EQ.IT )GO TO 20
   10     CONTINUE
          IERR = -1
          GO TO 999
   20     NBIFR1 = NBIFR1 + 1
          ITVL((NBIFR1-1)*2+IFR) = IT1
          ITVL((NBIFR1-1)*2+IFR+1) = J
        ENDIF 
   30 CONTINUE
C
C     ---- DESTRUCTION DES MAILLES SANS MISE A JOUR DE NOETRI ----
C      MODIF O.STAB 18.08.95 DEPLACE APRES LE CALCUL 
C      => PERMET UN RETOUR EN ARRIERE EN CAS D'ERREUR
C
C      N = 3
C      NBSOMP = 0
C      ISOMP = 1
C      DO 40 I=1,NINTER
C        CALL SMADET(IDE,ITRNOE,NBNMAX,ITRTRI,NBCMAX,NBE,NOETRI,
C     >                   NBFNOE,I,N,ITVL(ISOMP),NBSOMP,IERR)
C        IF( IERR .NE. 0  )GOTO 999
C     40 CONTINUE  
C
C     --- 2.3 CONSTRUCTION DU POLYGONE ---
C         -----------------------------
C     BUG1 : IPOLY = ITRI + ( NBC * NBIFR ) + 1
C     REMPLACE PAR :
      IPOLY = (6* NBIFR) + MAX(1,NBIFR-4)
      CALL ARTOPL(ITVL(INOE),2,ITVL(ITRI),2,
     >             ITVL(IPOLY),NBPP)
C      PRINT *,' POLYGONE  RESULTANT '
C      PRINT *,' ',(ITVL(IPOLY+I),I=0,(NBPP-1))
C      PRINT *,' ORIGINE, EXTREMITE = ',NN(1),NN(2)
      IF( NBPP .LE. 3  )THEN
        IERR = -1
        CALL DSERRE(1,IERR,'RF2FAR',
     >      ' POLYGONE A MOINS DE 4 COTES')       
        GOTO 999
      ENDIF
C
C
C       --- 2.4 DECOUPAGE DU POLYGONE ---
C          ---------------------------
C     ITVL = | IFR |   XXXXX     | IPOLY1 | IPOLY2 | IPOLY
C                2*NBIFR NINTER * 3   NBIFR   NBIFR   NBIFR
C
C       ON STOQUE D'ABORD LA FRONTIERE PUIS LA TRIANGULATION
C       PUIS ENFIN LES POLYGONES
C
        IPOLY1 = (2 * NBIFR) + (NINTER * 3 ) + 1
C       IPOLY1 CONTIENT AU MAX NBPP COTES (NBPP = NBIFR)
C        IPOLY2 = IPOLY1 + NBPP - 1
        IPOLY2 = IPOLY1 + NBIFR - 1
C       DANS LE PIRE CAS C'EST IPOLY2 QUI CONTIENT NBPP COTES
        CALL SPLIPL(ITVL(IPOLY),NBPP,NN,ITVL(IPOLY1),NBPP1,
     >                 ITVL(IPOLY2),NBPP2,IERR)      
        IF(IERR.NE.0)THEN    
C        PRINT *,' POLYGONE  RESULTANT '
C        PRINT *,' ',(ITVL(IPOLY+I),I=0,(NBPP-1))
C        PRINT *,' POLYGONE  1 '
C        PRINT *,' ',(ITVL(IPOLY1+I),I=0,(NBPP1-1))
C        PRINT *,' POLYGONE  2 '
C        PRINT *,' ',(ITVL(IPOLY2+I),I=0,(NBPP2-1))
          CALL DSERRE(1,IERR,'RF2FAR',' APPEL SPLIPL')       
          GOTO 999
        ENDIF
C
C             ===========================
C     -------- 3. TRIANGULATION DU TROU  ------------------
C             ===========================
C     ITVL = |NBIFR|  ITRIP1  |  ITRIP2   | IPOLY1 | IPOLY2 |
C                              NINTER * 3          NBIFR   NBIFR
C
        ITRIP1 = ( 2 * NBIFR ) + 1
        ITRIP2 = ( 3 *(NBPP1-2) ) + ITRIP1
        ITR    = 1
        NTRMX  = NTRMAX
        ITI    = IPOLY2 + NBIFR
        NTIMX  = NTIMAX - ITI
C        
        CALL TRPLS2(COORD,IDIMC,ITVL(IPOLY1),NBPP1,
     >              ITVL(ITI),NTIMX,RTVL(ITR),NTRMX,
     >              ITVL(ITRIP1),TRRILF,QTMIN1,RDONFR,IERR)
        IF(IERR.NE.0)THEN    
          CALL DSERRE(1,IERR,'RF2FAR',' PREMIER APPEL TRPLS2')       
          GOTO 999
        ENDIF
C
        CALL TRPLS2(COORD,IDIMC,ITVL(IPOLY2),NBPP2,
     >              ITVL(ITI),NTIMX,RTVL(ITR),NTRMX,
     >              ITVL(ITRIP2),TRRILF,QTMIN2,RDONFR,IERR)
        IF(IERR.NE.0)THEN    
          CALL DSERRE(1,IERR,'RF2FAR',' DEUXIEME APPEL TRPLS2')       
          GOTO 999
        ENDIF
C        PRINT *,'QUALITE T1   QUALITE T2 ' 
C        PRINT  '(F7.6,F7.6)',QTMIN1,QTMIN2
C
C         =======================================================
C     ---- 4. DESTRUCTION DES MAILLES SANS MISE A JOUR DE NOETRI ----
C         =======================================================
      N = 3
      NBSOMP = 0
      ISOMP = 1
      DO 50 I=1,NINTER
        CALL SMADET(IDE,ITRNOE,NBNMAX,ITRTRI,NBCMAX,NBE,NOETRI,
     >                   NBFNOE,I,N,ITVL(ISOMP),NBSOMP,IERR)
        IF( IERR .NE. 0  )THEN
           CALL DSERRE(1,IERR,'RF2FAR',' APPEL SMADET')       
           GOTO 999
        ENDIF
   50 CONTINUE  
C         =================================
C     --- 5. CREATION DU NOUVEAU MAILLAGE ---      
C         =================================
      NBFNOE = 0
C     --- ON LIBERE LES IPOLYS ---
      ITRAV  = IPOLY1
      NBTRAV = NTIMAX - ITRAV + 1
      CALL SMACRE(IDE,ITVL(ITRIP1),NINTER,0,
     >             ITRNOE,NBNMAX,ITRTRI,NBCMAX,NOETRI,NBFNOE,
     >             ITVL(ITRAV),NBTRAV,IERR)
      IF( IERR .NE. 0  )THEN
        CALL DSERRE(1,IERR,'RF2FAR',' APPEL SMACRE')       
        GOTO 999
      ENDIF
C     --- POUR LE DEBUG -------
C      PRINT *,'TABLEAU DES NOEUDS '
C      PRINT *,((ITRNOE((I-1)*NBNMAX+J),J=1,NBNMAX),I=1,NINTER)
C      PRINT *,'TABLEAU DES VOISINS '
C      PRINT *,((ITRTRI((I-1)*NBCMAX+J),J=1,NBCMAX),I=1,NINTER)
C
C     --- COLLAGE DES FRONTIERES ---
C
      IND = 1
C     --- ON LIBERE LA TRIANGULATION ---
      IFR2 = ITRIP1
      NIFMAX = NTIMAX - ITRIP1
      CALL TMAFRT(IDE,ITRNOE,NBNMAX,ITRTRI,NBCMAX,IND,NINTER,
     >                   ITVL(IFR2),NBIFR,NIFMAX,IERR)
      IF( IERR .NE. 0  )THEN
           CALL DSERRE(1,IERR,'RF2FAR',' APPEL TMAFRT')       
           GOTO 999
         ENDIF
C
C     --- MISE A JOUR DE ITRTRI -----------------
C
      CALL S2GLAR(ITVL(IFR),NBIFR1,ITVL(IFR2),NBIFR,
     >                 ITRNOE,NBNMAX,ITRTRI,NBCMAX,NBCOL)
C
C     --- MISE A JOUR DE NOETRI -----------------
C
      DO 90 I=1,NINTER
        DO 80 J=1,NBNMAX
          NOEUD = ITRNOE((I-1)*NBNMAX+J)
          IF( NOEUD .NE. 0 )NOETRI(NOEUD)=I
   80   CONTINUE
   90 CONTINUE
  999 END
C
C     *****************************************************************
C     MODULE  : M3 (RESPECT D'UNE ARETE)
C     FICHIER : M3_TRIPO.F
C     OBJET   : CALCUL DE LA MEILLEURE TRIANGULATION D'UN POLYGONE 
C               SIMPLE
C     FONCT.  : 
C        TRPLS2  : ALLOCATION ET APPEL A TRPLSI
C        TRPLSI  : CALCULE LA TRIANGULATION D'UN POLYGONE SIMPLE 
C                QUI MAXIMISE LA VALEUR MINIMUM D'UN CRITERE DONNE 
C
C     AUTEUR  : O. STAB
C     DATE    : 03.95
C     MODIFICATIONS :
C      AUTEUR, DATE, OBJET : STAB, 25.04.97, BUG_21 DANS TRPLSI 
C      AUTEUR, DATE, OBJET : STAB, 28.04.97, AJOUT TRPLS2 (DEPLACEE)
C            SUPPRESSION TRRILF (DEPLACE), AJOUT D'UN PARAMETRE 
C            D'ENTREE POUR TRPLS2 ET TRPLSI :RDONFR 
C
C     *****************************************************************
C
      SUBROUTINE TRPLS2(X,IDIMC,IPOLYG,NCP,
     >                  ITVL,NTIMAX,RTVL,NTRMAX,
     >                  ITRPOL,FCRMIN,QTMIN,RDONFR,IERR)
C     *****************************************************************
C     OBJET TRPLS2 : ALLOCATION ET APPEL A TRPLSI
C
C     EN ENTREE :
C        X     : COORDONNEES DES POINTS DU POLYGONE
C        IDIMC : DIMENSION DE L'ESPACE DES COORDONNEES
C        IPOLYG : NUMERO DES NOEUDS DU POLYGONE 
C        NCP   : NOMBRE DE POINT DU POLYGONE
C        FCRMIN: FONCTION RENVOYANT LA VALEUR DU CRITERE
C                FUNCTION REAL FCRMIN(P1,P2,P3,IDIMC,RDONFR)
C                INTEGER IDIMC : DIMENSION DES COORDONNEES DU POLY
C                REAL P1(*),P2(*),P3(*),RDONFR(*)
C                OU P1,P2,P3 SONT LES COORDONNEES DES POINTS 
C                DU TRIANGLE, RDONFR(*) D'AUTRES DONNEES
C        QTMIN : VALEUR MINIMUM DU CRITERE
C        RDONFR: DONNEES REELLES POUR LA FONCTION "FCRMIN"
C
C        ITVL  : TABLEAU DE TRAVAIL DE TAILLE NTIMAX
C        RTVL  : TABLEAU DE TRAVAIL DE TAILLE NTRMAX
C
C     EN SORTIE :
C        ITRPOL: TRIANGULATION RESULANTE
C                 ITRPOL((I-1)*3+1) PREMIER NOEUD DU TRIANGLE I
C                 ITRPOL((I-1)*3+2) DEUXIEME NOEUD DU TRIANGLE I
C                 ITRPOL((I-1)*3+3) TROISIEME NOEUD DU TRIANGLE I
C        QTMIN  : VALEUR MINIMUM DE FCRMIN SUR ITRPOL
C        IERR   : 0 SI TOUT EST OK
C                -1 SI QTMIN N'A PAS PU ETRE ATTEINT
C                -2 SI UN PROBLEME DE TAILLE MEMOIRE
C     *****************************************************************
      REAL    X(*),QTMIN
      INTEGER IDIMC,IPOLYG(*),NCP,ITVL(*),NTIMAX,NTRMAX
      REAL    RTVL(*),RDONFR(*)
      INTEGER ITRPOL(*),IERR
C
C     NPMAX : LE NOMBRE MAXIMUM DE POLYGONES EMPILES
C     NCMAX : LE NOMBRE MAXIMUM DE COTE DU POLYGONE
C      PARAMETER (NPMAX = 1000,NCMAX = 20, IDIMC = 2)
C
      REAL      FCRMIN
      EXTERNAL  FCRMIN
      INTEGER   IND,ICARD,JT,IFD,IFG,IT,ITM,IPERE
      INTEGER   ITPOLY,ITRIA,ITRMIN,IQTRIA,IQMIN
      INTEGER   NPMAX,NCMAX
C
      NCMAX = NCP
      NPMAX = (NTIMAX - 3*(NCMAX-2)) / (2*(2*NCMAX+1))
C      WRITE (*,*) '---- LE RESPECT D ARETE ----'
C      WRITE (*,*) 'COTES DU POLYGONE NCP =',NCP
C      WRITE (*,*) 'PLACE DISPONIBLE NTIMAX =',NTIMAX
C      WRITE (*,*) 'TAILLE DE LA PILE NPMAX =',NPMAX
C
      NPMAX = MIN( (NTRMAX / 2),NPMAX )
C      WRITE (*,*) 'TAILLE DE LA PILE POUR LE RESPECT D ARETE =',NPMAX
      IF((NPMAX.LE.0).OR.(NTRMAX.LT.(2*NCMAX)))THEN
        IERR = -2
        GOTO 999
      ENDIF
C     --- ALLOCATION DE TOUS LES TABLEAUX ---
      IND   = 1
      ICARD = NPMAX + IND
      JT    = NPMAX + ICARD
      IFD   = NPMAX + JT
      IFG   = NPMAX + IFD
      IT    = NPMAX + IFG
      ITM   = NPMAX + IT
      IPERE = NPMAX + ITM
      ITPOLY= NPMAX + IPERE
      ITRIA = (NPMAX*NCMAX) + ITPOLY
      ITRMIN= ((NCMAX-2)*3) + ITRIA
C     ITRMIN((NCMAX-2)*3*NPMAX)      
C
      IQTRIA= 1
      IQMIN = NPMAX + IQTRIA
C     IQMIN(NPMAX)
C
      CALL TRPLSI(X,IDIMC,IPOLYG,NCP,
     >            ITVL(IND),ITVL(ICARD),ITVL(JT),ITVL(IFD),
     >            ITVL(IFG),ITVL(IT),ITVL(ITM),ITVL(IPERE),
     >            ITVL(ITPOLY),ITVL(ITRIA),
     >            ITVL(ITRMIN),
     >            RTVL(IQTRIA),RTVL(IQMIN),NPMAX,NCMAX,        
     >            ITRPOL,FCRMIN,QTMIN,RDONFR,IERR)
C
  999 END
C      
C
      SUBROUTINE TRPLSI(X,IDIMC,IPOLYG,NCP,
     >            IND,ICARD,JT,IFD,
     >            IFG,IT,ITM,IPERE,
     >            ITPOLY,ITRIA,
     >            ITRMIN,
     >            QTRIA,QMIN,NPMAX,NCMAX,        
     >            ITRPOL,FCRMIN,QTMIN,RDONFR,IERR)
C     *****************************************************************
C     OBJET TRPLSI: TRIANGULATION MAXIMISANT UN CRITERE DONNE
C
C     EN ENTREE :
C     ----------
C        X     : COORDONNEES DES POINTS DU POLYGONE
C        IDIMC : DIMENSION DE L'ESPACE DES COORDONNEES
C        IPOLYG: NUMERO DES NOEUDS DU POLYGONE SIMPLE (DEF. SHAMOS)
C        NCP   : NOMBRE DE POINT DU POLYGONE
C        FCRMIN: FONCTION RENVOYANT LA VALEUR DU CRITERE
C                FUNCTION REAL FCRMIN(P1,P2,P3,IDIMC,RDONFR)
C                INTEGER IDIMC : DIMENSION DES COORDONNEES DU POLY
C                REAL P1(*),P2(*),P3(*),RDONFR(*)
C                OU P1,P2,P3 SONT LES COORDONNEES DES POINTS 
C                DU TRIANGLE, RDONFR(*) D'AUTRES DONNEES
C        QTMIN : VALEUR MINIMUM DU CRITERE
C        RDONFR: DONNEES REELLES POUR LA FONCTION "FCRMIN"
C
C     LES TABLEAUX DE TRAVAIL POUR LES POLYGONES
C     ------------------------------------------
C     IND,ICARD,JT,IFG,IFD,IT,ITM : TABLEAUX DE NPMAX D'ENTIERS, NPMAX 
C            EST LE NOMBRE MAXIMUM DE POLYGONE EMPILES (VOIR REMARQUE).
C 
C     QTRIA,QMIN : TABLEAUX DE NPMAX REELS, NPMAX EST LE NOMBRE 
C                  MAXIMUM DE POLYGONE EMPILES.    
C
C     ITPOLY : TABLEAU DE NPMAX*M ENTIERS, NPMAX EST LE NOMBRE MAXIMUM 
C              DE POLYGONE EMPILES. M LE NOMBRE MOYEN
C              DE NOEUDS PAR POLYGONE (M<NCMAX).
C
C     ITRIA  :
C     ITRMIN : TABLEAU DE NPMAX*(M-2)*3 ENTIERS, NPMAX EST LE NOMBRE 
C               MAXIMUM DE POLYGONE EMPILES. M LE NOMBRE 
C               MOYEN DE NOEUDS PAR POLYGONE (M<NCMAX). 
C
C     NCMAX : LE NOMBRE MAXIMUM DE COTE DU POLYGONE
C     NPMAX : LE NOMBRE MAXIMUM DE POLYGONES EMPILES (VOIR REMARQUE).
C
C
C     EN SORTIE :
C     -----------
C        ITRPOL:  UNE DES TRIANGULATIONS MAXIMISANT LA VALEUR MINIMUM 
C                 DU CRITERE.
C                 ITRPOL((I-1)*3+1),ITRPOL((I-1)*3+2),ITRPOL((I-1)*3+3) 
C                 LES TROIS NOEUDDS DU TRIANGLE I
C        QTMIN  : VALEUR MINIMUM DE FCRMIN SUR ITRPOL
C        IERR   : 0 SI TOUT EST OK
C                -1 SI QTMIN N'A PAS PU ETRE ATTEINT
C                -2 SI UN PROBLEME DE TAILLE MEMOIRE
C
C     *****************************************************************
C
C     REMARQUES :
C     -----------
C     NOMBRE MAXIMUM DE POLYGONES EMPILES :
C     -------------------------------------
C     POUR UN POLY DE N COTE = 2*(N-2) POLYGONES
C     DONT UN FILS PEUT AVOIR N-1 COTE.
C     DANS LE PIRE CAS NPMAX = (NCMAX-2)! 
C
C     NCMAX = 5  => 5 TRIANGULATIONS POSSIBLES
C     NCMAX = 10 => 1430 TRIANGULATIONS POSSIBLES
C     NCMAX = 14 => 208012 TRIANGULATIONS POSSIBLES
C     NCMAX = 20 => 477638700 TRIANGULATIONS POSSIBLES
C
C     DANS LE  PIRE CAS (QUI DEPEND DE LA FONCTION D'EVALUATION),
C     LA COMPLEXITE EN PLACE ET TEMPS EST EXPONENTIELLE ! 
C     PAR CONTRE, DANS LE CAS GENERAL LE RESULTAT EST ACCEPTABLE : 
C     POUR UN POLYGONE 14 COTES :  1939 POLYGONES TESTES, 
C                                  54 POLYGONES EMPILES 
C                                  208012 TRIANGULATIONS POSSIBLES.
C
C     PRINCIPE : VOIR DOC DE CONCEPTION DE DELOS
C     ----------
C
C     ALGORITHME : RECURSIF
C     ------------
C       POUR UN POLYGONE, ON CHOISI UN TRIANGLE (1,2,J) LE DECOUPANT EN 2.
C       ON DESCENT SUR LE FILS DROIT...QUAND LE FILS DROIT = 0 ON 
C       RETOURNE SUR LE FILS GAUCHE PUIS SUR LE PERE. ON OBTIENT 
C       AINSI LA MEILLEUR TRIANGULATION DU POLYGONE CONTENANT LE 
C       TRIANGLE. ON PASSE A UN AUTRE TRIANGLE.
C
C     STRUCTURE DES DONNEES :
C     -----------------------
C     ARBRE DE RECCURSION :
C     ---------------------
C     IPI       : NUMERO DU POLYGONE COURANT (DANS LA PILE)
C     IPERE(IPI): NUMERO DU POLYGONE PERE
C     IFG(IPI)  : NUMERO DU POLYGONE FILS GAUCHE
C     IFD(IPI)  : NUMERO DU POLYGONE FILS DROIT 
C                 LE PARCOURS FAIT QUE IFG(IPI) = IPI+1, 
C                 IFD(IPI) =IPI+2 SI ILS EXISTENT.
C
C     LES POLYGONES
C     --------------
C     ITPOLY    : TABLEAU OU SONT DECRITS LES POLYGONES 
C                 (LA LISTE DES INDICES DES NOEUDS)
C                 ATTENTION TOUS LES FILS GAUCHES PARATGENT LEURS DONNEES
C                 DANS ITPOLY (NE PAS DESALLOUER : BUG_21)
C     IND(IPI)  : ADRESSE DU DEBUT DU POLYGONE "IPI" DANS "ITPOLY"
C     ICARD(IPI): NOMBRE DE COTES DU POLYGONE "IPI" 
C
C     JT(IPI)   : INDICE J DES TRIANGLES (1,2,J) DEJA TESTES 
C                 (POUR LA DECOMPOSITION)
C     ITRIA(IPI): NOEUDS DU TRIANGLE DE DECOMPOSITION   
C     QTRIA(IPI): QUALITE DU TRIANGLE DE DECOMPOSITION   
C
C     LES TRIANGULATIONS
C     -------------------
C     ITRMIN    : TABLEAU OU SONT DECRITES LES TRIANGULATIONS
C     QMIN(IPI) : QUALITE MINI DEJA ATTEINTE POUR UNE TRIANGULATION DE IPI
C     IT(IPI)   : ADRESSE DE LA TRIANGULATION COURANTE DE IPI
C                 LE NB DE TRIANGLES = ICARD(IPI) - 2
C     ITM(IPI)  : ADRESSE DE LA TRIANGULATION MINI DE IPI
C
C     GESTION MEMOIRE :
C     -----------------
C     LIBTL : PREMIERE PLACE LIBRE DANS ITPOLY
C     LIBTR : "      "   "   "     "    ITRMIN
C     LIBPL : "      "   "   "     "    LES TABLEAUX DES POLY (IND...)
C
C     *****************************************************************
      REAL    X(*),QTMIN
      INTEGER IDIMC,IPOLYG(*),NCP,ITRPOL(*),IERR
      REAL    FCRMIN,RDONFR(*)
      EXTERNAL FCRMIN
      INTEGER   NPMAX,NCMAX
C
C     ---- LES TABLEAUX DE TRAVAIL ----
C
      INTEGER   IND(*),ICARD(*),JT(*),IFD(*)
      INTEGER   IFG(*),IT(*),ITM(*),IPERE(*)
      INTEGER   ITPOLY(*),ITRIA(*)
      INTEGER   ITRMIN(*)
      REAL      QTRIA(*),QMIN(*)  
C
C     ---- VARIABLES  LOCALES ----
C
C      INTEGER IDIMC
C      PARAMETER (IDIMC = 2)
      INTEGER NBP,II,I,J,K,N,ITP,IPI,LIBTL,LIBTR,LIBPL
      INTEGER LPLMAX,NPTEST
C
      IF( NCP .GT. NCMAX )GO TO 888
C      
      NPTEST = 0
      LPLMAX = 0
      IERR = 0
      NBP = 1
      LIBPL = 2
      IND(1)   = 1
      ICARD(1)  = NCP
      JT(1)    = 1
      IFD(1)    = -1
      IFG(1)    = -1
      QTRIA(1) = 0.0
      QMIN(1)  = -1.0
      IT(1)  = 1
      ITM(1) = 1
      IPERE(1) = 0
      DO 5 I=1,NCP
        ITPOLY(I) = IPOLYG(I)
    5 CONTINUE
      ITPOLY(NCP+1) = IPOLYG(1)
      LIBTL = NCP+1
      LIBTR = (NCP-2)*3
C      
C        ===============================================
C     --- 1. BOUCLE SUR LES POLYGONES ---
C        ===============================================
C
C     NBP : NOMBRE DE POLYGONES = NUMERO DU DERNIER POLYGONE
C     IPI : POLYGONE COURANT
C     ITP : ADRESSE DU POLY DANS ITPOLY
C
C
   10 IPI  = NBP
      ITP = IND(IPI)
      N   = ICARD(IPI)
      J   = JT(IPI)
      I   = IT(IPI)
C     ------- POUR LE DEBUG ----------
C        PRINT *,' ITPOLY(1)',
C     >            (ITPOLY(II),II=1,NCP)
      LPLMAX = MAX(LIBPL,LPLMAX)
      NPTEST = NPTEST + 1
C
C        ----------------------------------
C     --- ON A 1 TRIANGULATION DU POLY IPI ---
C        ----------------------------------
C
      IF((IFD(IPI).NE.-1).AND.(IFG(IPI).NE.-1))THEN
        IF(IFD(IPI).NE.0)
     >    QTRIA(IPI)=MIN(QMIN(IFD(IPI)),QTRIA(IPI))
        IF(IFG(IPI).NE.0)
     >    QTRIA(IPI)=MIN(QMIN(IFG(IPI)),QTRIA(IPI))
C
C     --- ON A TROUVER UNE MEILLEURE TRIANGULATION ---
C        ------------------------------------------
C       ON FUSIONNE LE TRIANGLE, LA TRIANGULATION DU SAG, 
C       ET LA TRIANGULATION DU SAD. 
C
        IF(QTRIA(IPI) .GT. QMIN(IPI) )THEN
          K = ITM(IPI)-1
          DO 15 II=1,3
            ITRMIN(K+II) = ITRIA((I-1)*3+II)
   15     CONTINUE
          IF(IFG(IPI).NE.0)THEN
          K = ITM(IPI) + 2
          DO 16 II=1,(ICARD(IFG(IPI))-2)*3  
           ITRMIN(K+II)=ITRMIN(ITM(IFG(IPI))-1+II)          
   16     CONTINUE
          ENDIF
C
          IF(IFD(IPI).NE.0)THEN
          IF(IFG(IPI).NE.0)THEN
            K = ITM(IPI) + 2 + (ICARD(IFG(IPI))-2)*3
          ELSE
            K = ITM(IPI) + 2
          ENDIF
          DO 17 II=1,(ICARD(IFD(IPI))-2)*3   
           ITRMIN(K+II)=ITRMIN(ITM(IFD(IPI))-1+II)          
   17     CONTINUE
          ENDIF
          QMIN(IPI) = QTRIA(IPI)
C     --- POUR LE DEBUG ----
C      PRINT *,'---------------------------------------'
C      PRINT *,' TRIANGULATION RETENUE POUR LE POLYGON ',IPI
C      PRINT *,' PERE DE ',IFG(IPI),' ET ',IFD(IPI)
C      PRINT *,' ',(ITRMIN(ITM(IPI)-1+II),II=1,((N-2)*3))
C      PRINT *,' QMIN ',QMIN(IPI)
C      PRINT *,' POLY = ',(ITPOLY(IND(IPI)+II-1),II=1,(ICARD(IPI)))
C      PRINT *,'---------------------------------------'
        ELSE
C      PRINT *,'---------------------------------------'
C      PRINT *,' TRIANGULATION NON RETENUE POUR LE POLYGON ',IPI
C      PRINT *,' PERE DE ',IFG(IPI),' ET ',IFD(IPI)
C      PRINT *,' S APPUYANT SUR = ',(ITRIA((I-1)*3+II),II=1,3)
C      PRINT *,  QTRIA(IPI),' < ',QMIN(IPI)
C      PRINT *,' POLY = ',(ITPOLY(IND(IPI)+II-1),II=1,(ICARD(IPI)))
C      PRINT *,'---------------------------------------'        
        ENDIF
      ENDIF
C
C        ===============================================
C     --- 2. BOUCLE SUR LES TRIANGULATIONS D'UN POLYGONE
C        ===============================================
C
C     ON PASSE AU TRIANGLE : ITP,IPT+1,J
C
   20 J=J+1
      IF( J.GE.N )THEN
C
C        --------------------------------------------
C     --- ON A TOUTES LES TRIANGULATIONS DU POLY IPI ---
C        --------------------------------------------
C
        IF( IPERE(NBP).EQ.0 )THEN
C
C         --- ON EST A LA RACINE : ON A FINI ---        
C            --------------------------------
C
          DO 25 II=1,(ICARD(1)-2)*3
            ITRPOL(II) = ITRMIN(ITM(1)-1+II)            
   25     CONTINUE
          QTMIN = QMIN(1)
C         --- POUR LE DEBUG -------------------------------
C        PRINT *,' ITPOLY(IPI)',IPI,' = ',
C     >            (ITPOLY(ITP+II-1),II=1,N)
C        PRINT *,' FILS D,G = ',IFD(IPI),IFG(IPI)
C          PRINT *,' ITRPOL(IPI)',IPI,' = ',
C     >              (ITRPOL(II),II=1,((N-2)*3))
C          PRINT *,(ITRPOL(II),II=1,((N-2)*3))
C          PRINT *,' NOMBRE DE POLYS TESTES : ',NPTEST
C          PRINT *,' NOMBRE MAX DE POLYS EMPILES : ',LPLMAX
          GO TO 999
        ENDIF
C
C        PRINT *,' ITPOLY(IPI)',IPI,' = ',
C     >            (ITPOLY(ITP+II-1),II=1,N)
C        PRINT *,' FILS D,G = ',IFD(IPI),IFG(IPI)
C     
C         --- ON CONTINUE LE PARCOURS ---        
C            ------------------------
C
        IF((IFD(IPERE(IPI)).EQ.IPI).AND.
     >     (IFG(IPERE(IPI)).NE.0))THEN
C
C       --- ON VIENT DU SAD (FILS DROIT) ---
C       --- ON VA VISITER LE SAG (FILS GAUCHE) ---
C            --------------------------------
C
           NBP  = IFG(IPERE(IPI))   
           IF( LIBPL.GT.(IPI+1))THEN
C            --- ON LIBERE LES FILS DU FILS DROIT ---
             LIBPL = IPI+1   
             LIBTR = ITM(IPI+1)
C             PRINT *,'LIBPL = ',LIBPL
C             PRINT *,'LIBTR = ',LIBTR
C             PRINT *,'LIBTL = ',LIBTL
           ENDIF
        ELSE
C
C       --- BUG_21 : O.STAB 25.04.97 -------------------------------
C           CAS SAG=0 PAS ENVISAGE : LIBTL = IND(IPI+2)
C           LIBTL PRENAIT DONC UNE MAUVAISE VALEUR (CELLE D'UN SAD) 
C           QUE L'ON NE DOIT JAMAIS DESALLOUER (LIBTL) !
C        
C       --- ON A FINI SAG ET SAD : ON REMONTE (AU PERE) ---
C          ---------------------------------------------
C
           NBP = IPERE(IPI)
C
           IF(IFG(IPERE(IPI)).EQ.0)THEN
C       --- ON VIENT DU SAD (FILS DROIT)  ET LE SAG = 0 ---
C        PRINT *,'ON VIENT DU SAD (FILS DROIT)  ET LE SAG = 0 '
           IF( LIBPL.GT.(IPI+1))THEN
C            --- ON LIBERE LES FILS DU FILS DROIT ---
             LIBPL = IPI+1   
             LIBTR = ITM(IPI+1)
           ENDIF
           ENDIF
           IF(IFG(IPERE(IPI)).EQ.IPI)THEN
C       --- ON VIENT DU SAG (FILS GAUCHE) : ON A DEJA VISITE LE SAD ---
C        PRINT *,'ON VIENT DU SAG (FILS GAUCHE) '
           IF( LIBPL.GT.(IPI+2))THEN
C            --- ON LIBERE LES FILS DU FILS GAUCHE---
C               PRINT *,'IND = ',(IND(II),II=1,LIBPL-1)
C               PRINT *,'IPERE(IPI) = ',IPERE(IPI)
C               PRINT *,'IFD(IPERE(IPI)) = ',IFD(IPERE(IPI))
C               PRINT *,'IFG(IPERE(IPI)) = ',IFG(IPERE(IPI))
             LIBPL = IPI+2
             LIBTR = ITM(IPI+2)
             LIBTL = IND(IPI+2)
C             PRINT *,'LIBPL = ',LIBPL
C             PRINT *,'LIBTR = ',LIBTR
C             IF( LIBTL.LT.NCP )THEN
C               PRINT *,'++++++++++++++++++++++++++++++++++++'
C               PRINT *,'IPI = ',IPI
C               PRINT *,'IPERE(IPI) = ',IPERE(IPI)
C               PRINT *,'IFD(IPERE(IPI)) = ',IFD(IPERE(IPI))
C               PRINT *,'IFG(IPERE(IPI)) = ',IFG(IPERE(IPI))
C               PRINT *,'LIBTL = IND(IPI+2)',LIBTL
C               PRINT *,'LIBPL = ',LIBPL
C               PRINT *,'LIBTR = ',LIBTR
C             ENDIF
           ENDIF
           ENDIF
        ENDIF
C
C       --- ON A FINI LE PARCOURS DE L'ARBRE DU POLY NBP ---
C
        GO TO 10
      ENDIF
C
C         ==============================================
C     --- ON CALCULE TOUTES LES TRIANGULATIONS CONTENANT
C                LE TRIANGLE ITP,ITP+1,ITP+J
C         ==============================================
C
      QTRIA(IPI) = FCRMIN(X((ITPOLY(ITP  )-1)*IDIMC+1),
     >                   X((ITPOLY(ITP+1)-1)*IDIMC+1),
     >                   X((ITPOLY(ITP+J)-1)*IDIMC+1),
     >                   IDIMC,RDONFR)
C     --------- POUR LE DEBUG -------------
C      PRINT *,'POLYGON ',IPI,' ',IND(IPI),' ',ICARD(IPI),
C     >  ' TRIANGLE ',ITPOLY(ITP),' ',(ITPOLY(ITP+1)),
C     >  ' ',(ITPOLY(ITP+J)),' RIL = ',QTRIA(IPI)
C
C     --- ON A PAS MIEUX : ON PASSE AU TRIANGLE SUIVANT (J=J+1) ---
C
      IF( QTRIA(IPI) .LE. QMIN(IPI) ) GO TO 20
C
      ITRIA((I-1)*3+1) = ITPOLY(ITP)
      ITRIA((I-1)*3+2) = ITPOLY(ITP+1)
      ITRIA((I-1)*3+3) = ITPOLY(ITP+J)
C
C        --------------------------
C     --- ON STOQUE LE FILS GAUCHE ---
C         ITPOLY = IPT+J,.....,IPT
C        --------------------------
C
      IF( (N-J+1) .GT. 2 )THEN
C     --- ON DESCEND SUR LE FILS GAUCHE ---
        IF( LIBPL .EQ. NPMAX )GO TO 888
        NBP = LIBPL
        IND(NBP)  = LIBTL
        ICARD(NBP) = N-J+1 
        IFG(NBP)   = -1
        IFD(NBP)   = -1
        IPERE(NBP) = IPI
        JT(NBP)   = 1
        IT(NBP)   = I+1+J-2
        ITM(NBP)  = LIBTR
        QMIN(NBP) = QMIN(IPI)
        QTRIA(NBP)= 0.0
        IFG(IPI) = NBP
C       --- 
        IF( ((NPMAX*NCMAX)-LIBTL) .LT. (N-J+1) )GO TO 888
C        PRINT *,' LIBTL,N,J = ',LIBTL,N,J
        DO 30 II=0,(N-(J+1))
         ITPOLY(LIBTL+II) = ITPOLY(ITP+J+II)
   30   CONTINUE
        ITPOLY(LIBTL+N-J) = ITPOLY(ITP)   
        LIBTL =  LIBTL + ICARD(NBP)  
C        PRINT *,' LIBTL =  LIBTL + ICARD(NBP) ',LIBTL  
        IF(((NPMAX*NCMAX)-LIBTR).LT.((ICARD(NBP)-2)*3))GO TO 888
        LIBTR =  LIBTR + ((ICARD(NBP)-2)*3)
        LIBPL = LIBPL + 1 
      ELSE 
        IFG(IPI) = 0        
      ENDIF
C
C        --------------------------
C     --- ON STOQUE LE FILS DROIT ---
C         ITPOLY = IPT+1,.....,IPT+J
C        --------------------------
C
      IF( J .GE. 3 )THEN
C     --- ON DESCEND SUR LE FILS DROIT ---
        IF( LIBPL .EQ. NPMAX )GO TO 888
        NBP = LIBPL
        IND(NBP) = ITP+1
        ICARD(NBP) = J 
        IFG(NBP)   = -1
        IFD(NBP)   = -1
        IPERE(NBP) = IPI
        JT(NBP)   = 1
        IT(NBP)   = I+1
        ITM(NBP)  = LIBTR
        QMIN(NBP) = QMIN(IPI)  
        QTRIA(NBP)= 0.0               
        IFD(IPI)  = NBP
        IF(((NPMAX*NCMAX)-LIBTR).LT.((ICARD(NBP)-2)*3))GO TO 888
        LIBTR =  LIBTR + ((ICARD(NBP)-2)*3)
        LIBPL = LIBPL + 1 
      ELSE 
        IFD(IPI) = 0        
      ENDIF
C      
      JT(IPI) = J  
C
C     --- ON TRAITE DANS L'ORDRE : IFD, IFG, IPERE
C 
      GOTO 10
C  
  888 IERR = -2   
C      
  999 END


C     **********************************************************************
C     MODULE   : M4 (RAFFINEMENT D'UN MAILLAGE TRIANGULAIRE)
C     FICHIER  : M4_DENSITE2D.F
C     OBJET    : CALCUL DE LA DENSITE POUR RAFFINER 
C                UNE TRIANGULATION DE DELAUNAY
C     FONCT.   :
C      D2SUI   :  TAILLE SOUHAITE / SUITE DEFINIE EN UN OBJET
C      D2ISUI  :  CF D2SUI - FONCTION PARAMETRE
C
C     AUTEUR   : O. STAB
C     DATE     : 07.95
C     TESTS    : 08.95
C     MODIFICATIONS :
C        AUTEUR, DATE, OBJET : O.STAB, 19.06.98, BUG PROBABLE DANS LE CALCUL
C           DE LA TAILLE SOUHAITEE. A VERIFIER !!!
C
C     REMARQUES : UN TRIANGLE EQUILATERAL : ARETE = SQRT(3)*RC
C                 IL SEMBLE QUE L'ON AI DEFINI LA TAILLE D'UN TRIANGLE
C                 COMME : TT = SQRT(3) RC
C          
C     **********************************************************************
C
C
      SUBROUTINE D2SUI(XP1,XP2,XP3,XPC,VDIA,IDIMC,
     >                        ITYPS,TSP,RSG,
     >                        ITYPO,ROBJET,COEF,TS,IERR)
C     *****************************************************************
C     OBJET :   TAILLE SOUHAITE POUR UN TRIANGLE / CONCENTRATION DONNEE
C
C     EN ENTREE :
C         XP1,XP2,XP3 : LES TROIS POINT DU TRIANGLE (INUTILISES)
C         XPC     : UN POINT SUR LE CERCLE
C         VDIA    : LE VECTEUR DIAMETRE PARTANT DE CE POINT
C         IDIMC   : DIMENSION DE L'ESPACE
C         ---------------------
C         ITYPO   : TYPE DE CONCENTRATION
C         ROBJET  : LA DEFINITION GEOMETRIQUE DE LA CONCENTRATION 
C         ITYPS   : TYPE DE LA SUITE
C         TSP     : LA TAILLE SOUHAITE A L'OBJET
C         RSG     : RAISON DE LA SUITE GEOMETRIQUE
C
C     EN SORTIE :
C         TS      : TAILLE SOUHAITE POUR LE TRIANGLE XP1,XP2,XP3
C                   ELLE EST CALCULEE AVEC LA CONCENTRATION  
C         COEF    : A * TS / RC (RAYON DU CERCLE CIRCONSCRIT A IT)
C                   "A" EST TEL QUE 0 <= COEF <=1
C                   PLUS COEF EST PETIT PLUS ON RAFFINE
C         IERR    : CODE D'ERREUR 0 SI OK, 
C                   -1 SI TAILLE SOUHAITE EST NEGATIVE
C                      OU SI LE RAYON CIRCONSCRIT EST NUL
C     REMARQUE :
C       LA TAILLE SOUHAITE EST EVALUEE AU CENTRE DU CERCLE 
C
C     NIVEAU : INTERFACE UTILISATEUR    
C     *****************************************************************
      INTEGER    IDIMC,ITYPO,ITYPS
      REAL       XP1(*),XP2(*),XP3(*)
      REAL       XPC(*),VDIA(*),ROBJET(*),TSP,RSG,COEF,TS
      INTEGER    IERR
C
      REAL     BARYC(3), VDD(3),DBARYC, TSBARY, DIAM, RC
      EXTERNAL XNORVE, NULLVE
      REAL     XNORVE
      INTEGER  NULLVE
C      
      REAL      COEF3, XDEMI
C     --- COEF3 = 1/SQRT(3) ------------
      DATA COEF3/.57735026918962576451/
      XDEMI = 0.5
      IERR = -1
C           ==================================================
C     ------ TAILLE SOUHAITE AU CENTRE DE LA BOULE / DIAMETRE ------
C           ==================================================
      CALL MUSCVE(VDIA,XDEMI,IDIMC,VDD)
      CALL SOMMVE(XPC,VDD,IDIMC,BARYC)
      CALL DIPOOB(IDIMC,BARYC,ITYPO,ROBJET,DBARYC,IERR)
      IF( IERR .NE. 0 ) THEN
        CALL DSERRE(1,IERR,'D2ISUI','APPEL DIPOOB')
        GOTO 999
      ENDIF
      CALL SCSUPO(ITYPS,TSP,RSG,DBARYC,TSBARY)
C     --- MODIF O.STAB 19.06.98 BUG PROBABLE ?!
C      TSBARY = TSBARY * COEF3
      IF( TSBARY.LE. 0.0 ) THEN
        IERR = -1
        CALL DSERRE(1,IERR,'D2ISUI','TAILLE SOUHAITEE NEGATIVE')
        GOTO 999
      ENDIF
      DIAM  = XNORVE(VDIA,IDIMC)
      RC = DIAM * 0.5
      IF( NULLVE(RC,1) .NE. 0 )THEN
        IERR = -1
        CALL DSERRE(1,IERR,'D2ISUI','DIAMETRE NUL')
        GOTO 999
      ENDIF
C     --- MODIF O.STAB 19.06.98 BUG PROBABLE ?!
C      COEF = TSBARY / RC
      COEF = COEF3 * TSBARY / RC
      TS = TSBARY
      IERR = 0
  999 END
C
C
      SUBROUTINE D2ISUI(IT,ITRNOE,NBNMAX,ITRTRI,NBCMAX,
     >            COORD,IDIMC,SPH,NBSMAX,ITAB,RTAB,COEF,TS,IERR)
C     ****************************************************************
C     OBJET :   CALCULE LA TAILLE SOUHAITE / CONCENTRATION DONNEE
C               FONCTION PARAMETRE POUR RAF2D MODE ITERATIF
C               APPEL D2SUI 
C     EN ENTREE :
C         --------- L'ELEMENT A RAFFINER -------------------
C         IT   : NUMERO DE L'ELEMENT A RAFFINER
C         ITRNOE,NBNMAX,ITRTRI,NBCMAX : LE MAILLAGE
C         ITRTRI,NBCMAX (INUTILISES)
C         COORD,IDIMC : COORDONNEES DANS L'ESPACE DE DIMENSION IDIMC
C         SPH,NBSMAX  : VECTEUR DIAMETRE DES SPHERES CIRCONSCRITES
C         --------- DEFINITION DE LA CONCENTRATION ------------
C         ITAB(1)   : TYPE DE LA SUITE (1=GEOMETRIQUE, 2=ARITHEMTIQUE)
C         ITAB(2)   : TYPE DE LA CONCENTRATION  (1=POINT, 2=DROITE)
C         RTAB(1)   : RAISON DE LA SUITE GEOMETRIQUE 
C         RTAB(2)   : TAILLE SOUHAITE A LA CONCENTRATION
C         RTAB(3...): COORDONNEES DES POINTS DEFINISSANT LA GEOMETRIE 
C                     DE LA CONCENTRATION :
C                     - UN SEUL POINT SI ITAB(2) = 1
C                     - DEUX POINTS SI ITAB(2) = 2
C       
C     EN SORTIE :
C         TS      : TAILLE SOUHAITE POUR L'ELEMENT IT
C                   ELLE EST DONNE PAR LA CONCENTRATION (ITAB,RTAB)
C         COEF    : A * TS /  RC (RAYON DU CERCLE CIRCONSCRIT A IT)
C                   "A" EST TEL QUE 0 <= COEF <=1
C                   PLUS COEF EST PETIT PLUS ON RAFFINE
C         IERR    : CODE D'ERREUR 0 SI OK, 
C                   -1 SI TAILLE SOUHAITE EST NEGATIVE
C                      OU SI LE RAYON CIRCONSCRIT EST NUL 
C
C     NIVEAU : INTERFACE UTILISATEUR    
C     ****************************************************************
      REAL      COORD(*),SPH(*),COEF,TS
      INTEGER   IT,ITRNOE(*),NBNMAX,ITRTRI(*),NBCMAX,NBSMAX
      INTEGER   IDIMC,ITAB(*)
      REAL      RTAB(*)
      INTEGER   IERR
C
      INTEGER NUMP1,NUMP2,NUMP3
C
        NUMP1 = ITRNOE((IT-1)*NBNMAX+1)
        NUMP2 = ITRNOE((IT-1)*NBNMAX+2)      
        NUMP3 = ITRNOE((IT-1)*NBNMAX+3)      
        CALL D2SUI(COORD((NUMP1-1)*IDIMC+1),
     >                  COORD((NUMP2-1)*IDIMC+1),
     >                  COORD((NUMP3-1)*IDIMC+1),
     >                  COORD((NUMP3-1)*IDIMC+1),
     >                  SPH((IT-1)*NBSMAX+1),IDIMC,
     >                  ITAB(1),RTAB(2),RTAB(1),
     >                  ITAB(2),RTAB(3),COEF,TS,IERR)
C
  999 END
C
C     *****************************************************************
C     MODULE  : API LIBRAIRIE DELOS
C     FICHIER : API_TRIANGULATION.F
C     OBJET   : TRIANGULATION DE DELAUNAY D'UN DOMAINE POLYGONAL
C
C     FONCT.  :
C     OBJET DSTRIA : TRIANGULE UN DOMAINE 2D (AVEC ARETES IMPOSES)
C     OBJET GNTRIA : TRIANGULE UN DOMAINE PSEUDO-PLAN ET MULTI-REGION
C
C     AUTEUR  : O.STAB
C     DATE    : 21.07.99
C     MODIFICATIONS :
C        AUTEUR, DATE, OBJET : O.STAB, 27.07.99, EXTRACTION DE DSTRIA2.F
C                              ET SUPPRESSION DES E/S.
C        O.STAB, 17.09.2002, 2 BUG DANS L'ALLOCATION DES TABLEAUX (APPEL DSTRIA)
C     *****************************************************************
C
      SUBROUTINE DSTRIA(IDE1,ITRNO1,NBNMX1,NBN1,NBE1,
     >                IFREEL,NFREEL,
     >                COORD,IDIMC,
     >                IDE,ITRNOE,NBNMAX,ITRTRI,NBCMAX,NOETRI,NOEMAX,
     >                NBN,NBE,NCC,NBPMAX,NBEMAX,
     >                ITVL,NITMAX,RTVL,NRTMAX,ITRACE,IERR)
C     **********************************************************************
C     OBJET DSTRIA : TRIANGULE UN DOMAINE 2D (AVEC ARETES IMPOSES)
C
C     EN ENTREE  :
C     ----------- FRONTIERE DU DOMAINE A MAILLER -----------
C       ITRNO1 : NOEUDS DES ELEMENTS DE LA FRONTIERE
C       NBNMX1 : NOMBRE DE NOEUDS PAR ELEMENT
C       NBE1   : NOMBRE D'ELEMENTS
C       NBN1   : NOMBRE DE NOEUDS
C       IFREEL,NFREEL ???
C       COORD : COORDONNEES DES NOEUDS
C       NBPMAX : NOMBRE MAXIMUM DE POINTS (DANS COORD)
C       NBEMAX : NOMBRE MAXIMUM D'ELEMENT (DANS LE MAILLAGE)
C
C       ITRACE   : DESUET !
C
C     EN SORTIE  :
C     ----------- LE MAILLAGE TRIANGULAIRE ------------------
C       IDE,ITRNOE,NBNMAX,ITRTRI,NBCMAX,NOETRI,NOEMAX,NBN,NBE,NCC :
C
C       IERR     : CODE D'ERREUR 
C                   0 : OK, LE MAILLAGE EST VALIDE
C                  -1 : UNE ERREUR EST SURVENUE (DONNEES INCORRECTE)
C                  -2 : PAS ASSEZ DE MEMOIRE (LE MAILLAGE N'EST PAS GENERE)
C     **********************************************************************
      INTEGER    IDE1,ITRNO1(*),NBNMX1,NBN1,NBE1
      INTEGER    IFREEL,NFREEL
      REAL       COORD(*)
      INTEGER    IDIMC
      INTEGER    IDE,ITRNOE(*),NBNMAX,ITRTRI(*),NBCMAX,NOETRI(*),NOEMAX
      INTEGER    NBN,NBE,NCC,NBPMAX,NBEMAX
      INTEGER    ITVL(*)
      REAL       RTVL(*)
      INTEGER    NITMAX,NRTMAX,ITRACE,IERR
C
      INTEGER ITRAV,NITMX2,IRTRAV,NRTMX2,I
      INTEGER NBARET,IERRI,NBENEW,NBARFR
C
      ITRAV = 1
      IRTRAV = 1
      NITMX2 = NITMAX - ITRAV + 1
      NRTMX2 = NRTMAX - IRTRAV + 1
C
C         =====================================
C     ---- 1. TRIANGULATION DU NUAGE DE POINTS ----
C         =====================================
C      IF(ITRACE.GT.0)CALL ESECHA(1,'-> TRIANGULATION DU CONVEXE',' ')
      IDE    = IDIMC
      NBNMAX = IDE + 1
      NBCMAX = NBNMAX
      NBN    = NBN1
      CALL TRNUPO(COORD,NBN,ITRNOE,
     >     NBNMAX,ITRTRI,NBCMAX,NOETRI,NBE,
     >     ITVL(ITRAV),NITMX2,RTVL(IRTRAV),IERR)
      IF(IERR.NE.0)THEN
        CALL DSERRE(1,IERR,'DSTRIA',' APPEL TRNUPO')
        CALL DSERRE(1,IERR,'LA TRIANGULATION ',
     >              ' POINTS CONFONDUS PROBABLEMENT')
        GOTO 9999
      ENDIF
C      IF( ITRACE.GT.0 )THEN
C          CALL ESEINT(1,'NOMBRE DE NOEUDS    : ',NBN,1)
C          CALL ESEINT(1,'NOMBRE DE TRIANGLES : ',NBE,1)
C      ENDIF
C     --- POUR LE DEBUG ---
C      CALL SDBTRI(IDE,ITRNOE,NBNMAX,ITRTRI,
C     >            NBCMAX,NOETRI,NBE,
C     >            NBN,ITRACE,IERR) 
C      IF( IERR .NE. 0 )THEN
C        CALL DSERRE(1,IERR,'SDBTRI','APRES TRNUPO')        
C        GO TO 9999
C      ENDIF
C
C         ==================================
C     ---  2.  FORCAGE DES ARETES FRONTIERES  ---
C         ==================================
 100  CONTINUE
      IF( NBE1.EQ. 0 )GOTO 9999
C      IF(ITRACE.GT.0)CALL ESECHA(1,'-> RESPECT DE LA FRONTIERE',' ')
C
      IERRI = 0
      NBARET = NBE1
      NBARFR = 0
      DO 110 I=1,NBARET
        CALL RF2RAR(ITRNO1((I-1)*NBNMX1+1),
     >             ITRNOE,NBNMAX,
     >             ITRTRI,NBCMAX,NOETRI,NBE,
     >             COORD,ITVL(ITRAV),NITMX2,
     >             RTVL(IRTRAV),NRTMX2,
     >             NBENEW,IERR)
C     --- POUR LE DEBUG ---
C      CALL SDBTRI(IDE,ITRNOE,NBNMAX,ITRTRI,
C     >            NBCMAX,NOETRI,NBE,
C     >            NBN,ITRACE,IERR) 
      IF( IERR .NE. 0 )THEN
        CALL DSERRE(1,IERR,'DSTRIA',' APPEL RF2RAR')
C        CALL DSERRE(1,IERR,'FRONTIERE ',
C     >    ' FRONTIERE CROISEE ?')        
C        CALL ESEINT(1,'ERREUR POUR L ARETE : ',I,1)
        IERRI = IERR
        IERR = 0
      ENDIF
      IF(NBENEW.GT. 0 )NBARFR = NBARFR + 1
 110  CONTINUE
C
      IF(IERRI.NE.0)THEN
        CALL DSERRE(1,IERRI,'DSTRIA',' APPEL RF2RAR')  
        IERR = IERRI
        GOTO 9999
      ENDIF
C      IF(ITRACE.GT.0)THEN
C        IF(NBARFR.GT.0)THEN
C          CALL ESEINT(1,'NOMBRE D ARETES FORCEES : ',NBARFR,1) 
C        ELSE 
C          CALL ESECHA(1,'LA TRIANGULATION RESPECTE DELAUNAY',' ')
C        ENDIF
C      ENDIF
C
C         ================================================
C     ---  4. DESTRUCTION DES ELEMENTS EXTERIEURS : SCULPT  ---
C         ================================================
 300  CONTINUE
C      IF(ITRACE.GT.0)CALL ESECHA(1,
C     > '-> DESTRUCTION DES ELEMENTS EXTERIEURS',' ')
C
      CALL SCULPT(ITRNO1((IFREEL-1)*NBNMX1+1),NBNMX1,NFREEL,
     >             IDE,ITRNOE,NBNMAX,
     >             ITRTRI,NBCMAX,NOETRI,
     >             NBE,ITVL(ITRAV),NITMX2,NCC,IERR)
C
C     --- POUR LE DEBUG ---
C      CALL SDBTRI(IDE,ITRNOE,NBNMAX,ITRTRI,
C     >            NBCMAX,NOETRI,NBE,
C     >            NBN,ITRACE,IERR) 
      IF( IERR .NE. 0 )THEN
        CALL DSERRE(1,IERR,'DSTRIA',' APPEL SCULPT')
        CALL DSERRE(1,IERR,' LE DOMAINE',
     >              ' FRONTIERE INCORRECTE')        
        GO TO 9999
      ENDIF
C
C        =========================================
C     --- 4. INSERTION DES FRONTIERES INTERIEURES  ---
C        =========================================
 400  CONTINUE
C     AJOUT 26.01.99
      ITRAV = 1
      NITMX2 = NITMAX
      DO 410 I=1,NBE1
        CALL SFRICR(ITRNO1((I-1)*NBNMX1+1),NBNMX1,
     >       IDE,ITRNOE,NBNMAX,ITRTRI,NBCMAX,
     >       NOETRI,NBE,ITVL(ITRAV),NITMX2,IERR)
        IF( IERR.NE. 0 )THEN
          CALL DSERRE(1,IERR,'DSTRIA',' APPEL SFRICR')
          IERR = 0  
C  il faudrait des messages !!! et pouvoir continuer
C          GOTO 9999
        ENDIF
 410  CONTINUE
C
 9999 END
C
C
      SUBROUTINE GNTRIA(IDE1,IARETE,NBNMX1,NBN1,NBARET,
     >                  COORDO,IDIMC,
     >                  IMTRF1,INTMA1,NMT1,
C    --- EN SORTIE :
     >                  IDE,ITRNOE,NBNMAX,
     >                  NBN,NBE,NCC,NBPMAX,NBEMAX,
     >                  IMTREF,NMTREF,INTMAT,INTMAX,NMT,
     >                  ITVL,NITMAX,RTVL,NRTMAX,ITRACE,IERR)
C     **********************************************************************
C     OBJET GNTRIA : TRIANGULE UN DOMAINE PSEUDO-PLAN ET MULTI-REGION
C                    APPEL DSTRIA + PROJECTION + GESTION DES REGIONS
C     EN ENTREE   :
C
C       NMTREF : TAILLE DE IMTREF
C       INTMAX : TAILLE DE INTMAX
C
C       ITVL : TABLEAU D'ENTIERS POUR LES CALCULS
C       NITMAX  : TAILLE DE ITVL
C       RTVL : TABLEAU DE REELS POUR LES CALCULS
C       NRTMAX  : TAILLE DE RTVL (12 (NBP+12))
C       ITRACE   : DESUET !
C     EN SORTIE   :
C       IERR     : CODE D'ERREUR -1 SI DONNEES INCORRECTES
C                                -2 SI TABLEAUX INSUFFISANTS
C     **********************************************************************
      INTEGER IDE1,IARETE(*),NBNMX1,NBN1,NBARET
      REAL    COORDO(*)
      INTEGER IDIMC,IMTRF1(*),INTMA1(*),NMT1
      INTEGER IDE,ITRNOE(*),NBNMAX
      INTEGER NBN,NBE,NCC,NBPMAX,NBEMAX
      INTEGER IMTREF(*),NMTREF,INTMAT(*),INTMAX,NMT
      INTEGER ITVL(*)  
      REAL    RTVL(*)
      INTEGER NITMAX,NRTMAX,ITRACE,IERR
C
C     --- VARIABLES INTERNES ---
      INTEGER NBCMAX
      INTEGER ITRTRI,NOETRI,NOEMAX
      INTEGER ITRIRG,NRGMAX,IMAT,NMAT,NR1MAX
      INTEGER IFREEL,NFREEL
      INTEGER ITRAV,IRTRAV,NITMX2,NRTMX2,MAJNOE
C     ---- MODIF POUR LA PROJECTION ---
      INTEGER IDIMC2,ICOO2D,IORIG,IMATT,IND1,IND2,IPOINT(1),NPOINT
      INTEGER I,J
C     --- NOM DE REGION PAR DEFAUT 
      INTEGER MATDEF
      PARAMETER (MATDEF = 1 )
C
      ITRAV  = 1
      IRTRAV = 1
      NITMX2 = NITMAX - ITRAV + 1
      NRTMX2 = NRTMAX - IRTRAV + 1
C        ===========================
C     --- 1. FRONTIERE DES DOMAINES  ---
C        ===========================
      IMAT   = ITRAV
C     ---- AU CAS OU IL N'Y A PAS DE REGION ----
      ITRAV  = IMAT + MAX(2*NBARET, 1)
      NITMX2 = NITMAX - ITRAV + 1
C
      NR1MAX = 0
      CALL DFR2FR(IDE1,IARETE,NBNMX1,NBARET,
     >            ITVL(ITRAV),NR1MAX,
     >            IMTRF1,NMT1,INTMA1,NMT1,
     >            ITVL(IMAT),IFREEL,NFREEL,NMAT,
     >            ITVL(ITRAV),NITMX2,IERR)
      NMT1 = NMAT
C
      IF( IERR.NE.0 )THEN
        CALL DSERRE(1,IERR,'GNTRIA','APPEL DFR2FR')        
        GOTO 9999
      ENDIF 
C     ---- LE REGION PAR DEFAUT EST "1" ----
      IF( NBARET.EQ. 0 )THEN
         ITVL(IMAT) = MATDEF
         NMT1 = 1
      ENDIF
C         ====================================================
C     ---- 0. PROJECTION SUR LE PLAN DES MOINDRES CARRES SI 3D ---
C         ====================================================
      IDIMC2 = 2
      IF(IDIMC.EQ.3 )THEN
        ICOO2D = IRTRAV
        IORIG  = ICOO2D + NBPMAX*IDIMC2
        IMATT  = IORIG  + 3
        IRTRAV = IMATT  + 9
C        NRTMX2 = NITMAX - IRTRAV  , BUG 080699:
        NRTMX2 = NRTMAX - IRTRAV
        IND1   = 1
        IND2   = NBN1
        IPOINT(1) = 0
        NPOINT = 0
        CALL RPPNCR(IPOINT,NPOINT,IND1,IND2,
     >              COORDO,IDIMC,
     >              ITVL(ITRAV),NITMX2,RTVL(IRTRAV),NRTMX2,
     >              RTVL(IORIG),RTVL(IMATT),RTVL(ICOO2D),IDIMC2,IERR)
C      ---- POUR LE DEBUG ----
       PRINT *,'GNTRIA: ORIG = ',RTVL(IORIG),RTVL(IORIG+1),RTVL(IORIG+2)        
       DO 998 I=1,MIN(NBN1,10)
        PRINT *,(RTVL((I-1)*IDIMC2+ICOO2D+J-1),J=1,IDIMC2)
  998  CONTINUE
        IF( IERR.NE.0 )THEN
          CALL DSERRE(1,IERR,'GNTRIA','APPEL RPPNCR')
          GOTO 9999
        ENDIF
        IRTRAV = IORIG
C        NITMX2 = NITMAX - IRTRAV BUG 080699 :
C        NRTMX2 = NITMAX - IRTRAV 2ieme BUG !!!! 01.07.99 OS
        NRTMX2 = NRTMAX - IRTRAV
      ENDIF
C        ----------------
C     --- 2.1 ALLOCATION ---
C        ----------------
C     ITVL = |IARETE|IMAT| ITRNOE | ITRTRI | NOETRI | ITRAV
C                             NBEMAX*3  NBEMAX*3  NBPMAX    310
C                                                         TRNUPO
C      IDE = IDIMC BUG 080699 :
C      IDE = IDE1 + 1  BUG 17.09.2002
      IDE = 2
      NBNMAX = IDE + 1
      NBCMAX = NBNMAX
      NBE = 0
C      ITRTRI = ITRAV  + (NBEMAX * NBNMAX)  BUG 17.09.2002
      ITRTRI = ITRAV 
      NOETRI = ITRTRI + (NBEMAX * NBCMAX)
      ITRAV  = NOETRI + NBPMAX
      NITMX2 = NITMAX - ITRAV
C        --------------------------------------------
C     --- 2.2 CALCUL DE LA TRIANGULATION DE DELAUNAY ---
C        --------------------------------------------
C     --- LA GESTION DES REGIONS EST A L'EXTERIEUR DE DSTRIA ---
C      NRGMAX = 0
C      NMTREF = 0      BUG 02.07.99
C      ITRIRG = 1
      IF(IDIMC.EQ.3)THEN
      CALL DSTRIA(IDE1,IARETE,NBNMX1,NBN1,NBARET,
     >            IFREEL,NFREEL,
     >            RTVL(ICOO2D),IDIMC2,
     >            IDE,ITRNOE,NBNMAX,
     >            ITVL(ITRTRI),NBCMAX,ITVL(NOETRI),NOEMAX,
     >            NBN,NBE,NCC,NBPMAX,NBEMAX,
     >            ITVL(ITRAV),NITMX2,RTVL(IRTRAV),NRTMX2,ITRACE,IERR)
      ELSE
      CALL DSTRIA(IDE1,IARETE,NBNMX1,NBN1,NBARET,
     >            IFREEL,NFREEL,
     >            COORDO,IDIMC2,
     >            IDE,ITRNOE,NBNMAX,
     >            ITVL(ITRTRI),NBCMAX,ITVL(NOETRI),NOEMAX,
     >            NBN,NBE,NCC,NBPMAX,NBEMAX,
     >            ITVL(ITRAV),NITMX2,RTVL(IRTRAV),NRTMX2,ITRACE,IERR)
      ENDIF
C
      IF( IERR.NE. 0)THEN
        CALL DSERRE(1,IERR,'GNTRIA','APPEL A DSTRIA')
        GOTO 9999
      ENDIF
C        =========================================
C     --- 5. AFFECTATION DES REGIONS   ---
C        =========================================
      ITRIRG = ITRAV
      NRGMAX = NBE
      ITRAV  = ITRIRG + NRGMAX
      NITMX2 = NITMAX - ITRAV
      MAJNOE = 0
      CALL DFR2RG(IDE1,IARETE,NBNMX1,NBARET,
     >            ITVL(IMAT),NMT1,
     >            IDE,ITRNOE,NBNMAX,
     >            ITVL(ITRTRI),NBCMAX,ITVL(NOETRI),NOEMAX,NBE,
     >            MAJNOE,
     >            ITVL(ITRIRG),NRGMAX,IMTREF,NMTREF,
     >            INTMAT,INTMAX,NMT,     
     >            ITVL(ITRAV),NITMX2,IERR)
C
      IF( IERR.NE. 0)THEN
        CALL DSERRE(1,IERR,'GNTRIA','APPEL A DFR2RG')
        GOTO 9999
      ENDIF
C            
 9999 END


C     *****************************************************************
C     MODULE  : 
C     FICHIER : API_MESH.F (anciennement DSG_NEW.f)
C     OBJET   : MAILLAGE EN TRIANGLE D'UN DOMAINE SURFACIQUE (MULTI-REGION)
C               fonction appellees de Delos
C
C     FONCT.  :
C     OBJET DSTRAF : TRIANGULATION ET RAFFINEMENT D'UN DOMAINE PLAN (2D ou 3D) MONO-REGION
C     OBJET RGARET : EXTRAIT LES ARETES D'UNE REGION
C     OBJET RGRAFT : MAILLAGE ET RAFFINEMENT DE LA REGION IREGIO, 
C
C     AUTEUR  : O.STAB
C     DATE    : 21.07.99
C     MODIFICATIONS :
C        AUTEUR, DATE, OBJET : O.STAB, 05.03.2001 CORRECTION BUG DS RGRAFT
C        AUTEUR, DATE, OBJET : O.STAB, 07.06.2001 CORRECTION "BUG" DS RGARET
C     
C     A FAIRE : DSTRAF ET RGRAFT SONT A DESCENDRE DANS DELOS API_MESH.F...
C     *****************************************************************
C
      SUBROUTINE DSTRAF(IDE1,IARETE,NBNMX1,NBN1,NBARET,
     >                  IDE,ITRNOE,NBNMAX,ITRTRI,NBCMAX,NOETRI,NOEMAX,
     >                NBN,NBE,NCC,NBPMAX,NBEMAX,
     >                COORD,IDIMC,
     >                GRDNOE,NGRDMX,
     >                MODDEF,MODGEN,NBPNEW,
     >                IADEC,NIADEC,RADEC,NRIDEC,NFADEC,
     >                ITVL,NITMAX,RTVL,NRTMAX,ITRACE,IERR)
C     **********************************************************************
C     OBJET DSTRAF : TRIANGULATION ET RAFFINEMENT D'UN DOMAINE PLAN (2D ou 3D) MONO-REGION
C
C     EN ENTREE :
C       --- LE MAILLAGE LINEIQUE ---
C       IDE1,IARETE,NBNMX1,NBN1,NBARET : LE MAILLAGE LINEIQUE
C       COORD,IDIMC : LES POINTS DU MAILLAGE LINEIQUE
C
C       ---- DEFINITION DU RAFFINEMENT --------------
C       MODDEF   : IL Y A 3 TYPES DE DEFINITIONS
C          1 LE MODE DEFAUT SIMPLE
C          2 LE MODE CONCENTRATIONS(X,Y)
C          3 LE MODE VALEURS NODALES
C       MODGEN   : IL Y A 3 MODES DE GENERATION
C          1 LE MODE DIRECT 
C          2 LE MODE ITERATIF
C          3 LE MODE ITERATIF + LISSAGE 
C       NBPNEW   : NOMBRE MAXIMUM DE POINTS A GENERER
C
C       IADEC((I-1)*NIADEC+1) : PARAMETRES ENTIERS DU IEME RAFFINEMENT
C       NIADEC   : NOMBRE MAX. DE PARAMETRES ENTIERS
C       RADEC((I-1)*NIADEC+1) : PARAMETRES REELS DU IEME RAFFINEMENT
C       NRIDEC   : NOMBRE MAX. DE PARAMETRES REELS
C       NFADEC   : NOMBRE DE RAFFINEMENTS
C
C     EN SORTIE : 
C       ---- LIMITATION DONNE PAR L'UTILISATEUR ---
C       IERR = 2 : NOMBRE MAXIMUM D ELEMENTS ATTEINT: 
C       IERR = 1 : NOMBRE MAXIMUM DE NOEUDS ATTEINT: 
C       IERR = 0 : TAILLE SOUHAITEE ATTEINTE (FRONTIERE): '
C
C     REMARQUE : APPEL DSTRIA ET DSRAFT 
C
C     LIMITATIONS : CONCENTRATIONS PONCTUELLES ET AXIALES 
C                   LES POINTS AJOUTES SONT DANS LE PLAN DES MOINDRES CARRES
C     **********************************************************************
      INTEGER    IDE1,IARETE(*),NBNMX1,NBN1,NBARET
      INTEGER    IDE,ITRNOE(*),NBNMAX,ITRTRI(*),NBCMAX,NOETRI(*),NOEMAX
      INTEGER    NBN,NBE,NCC,NBPMAX,NBEMAX
      REAL       COORD(*),GRDNOE(*)
      INTEGER    IDIMC,NGRDMX
      INTEGER    ITVL(*)
      REAL       RTVL(*),RADEC(*)
      INTEGER    MODDEF,MODGEN,NBPNEW,IADEC(*),NFADEC,NIADEC,NRIDEC
      INTEGER    NITMAX,NRTMAX,ITRACE,IERR
C     ---- MODIF POUR LA PROJECTION ---
      INTEGER IDIMC2,ICOO2D,IORIG,IMATT,IND1,IND2,IPOINT(1),NPOINT
      INTEGER I,J
C
      INTEGER ITRAV,NITMX2,IRTRAV,NRTMX2
      INTEGER IUN,NMT2
      INTEGER NDECMX
      INTEGER INODE,NBN2
C
      INTEGER IFREEL,NFREEL
C
      INODE = 0
      IUN = 1
      ITRAV = 1
      NITMX2 = NITMAX
      IRTRAV = 1
      NRTMX2 = NRTMAX
C     --- PAS DE FRONTIERE INTERIEUR A PRIORI ! ---
      IFREEL = 1
      NFREEL = NBARET
C
      INODE = 0
C        -------------------
C     --- CAS D'UN DOMAINE 3D ---
C        -------------------
      IF( IDIMC.EQ.3 )THEN
C     ---- PROJECTION SUR LE PLAN DES MOINDRES CARRES SI 3D ---
        IDIMC2 = 2
        ICOO2D = IRTRAV
        IORIG  = ICOO2D + NBPMAX*IDIMC2
        IMATT  = IORIG  + 3
        IRTRAV = IMATT  + 9
        NRTMX2 = NRTMAX - IRTRAV
        IND1   = 1
        IND2   = NBN1
        IPOINT(1) = 0
        NPOINT = 0
        CALL RPPNCR(IPOINT,NPOINT,IND1,IND2,
     >              COORD,IDIMC,
     >              ITVL(ITRAV),NITMX2,RTVL(IRTRAV),NRTMX2,
     >              RTVL(IORIG),RTVL(IMATT),RTVL(ICOO2D),IDIMC2,IERR)
C      ---- POUR LE DEBUG ----
C      ORIG : NOUVELLE ORIGINE
C      IMATT : MATRICE 3x3 DE PASSAGE DANS LE NOUVEAU REPERE
C       PRINT *,'DSTRAF: ORIG = ',RTVL(IORIG),RTVL(IORIG+1),RTVL(IORIG+2)        
C       DO 60 I=1,MIN(NBN,10)
C        PRINT *,(RTVL((I-1)*IDIMC2+ICOO2D+J-1),J=1,IDIMC2)
C   60  CONTINUE
        IF( IERR.NE.0 )THEN
          CALL DSERRE(1,IERR,'DSTRAF','APPEL RPPNCR')
          GOTO 9999
        ENDIF
C     --- ATTENTION NE RIEN LIBERER CA SERT PLUS LOIN !!!
C        IRTRAV = IORIG
C        NRTMX2 = NRTMAX - IRTRAV
C      ENDIF
C... a integrer
      CALL DSTRIA(IDE1,IARETE,NBNMX1,NBN1,NBARET,
     >            IFREEL,NFREEL,
     >            RTVL(ICOO2D),IDIMC2,
     >            IDE,ITRNOE,NBNMAX,
     >            ITRTRI,NBCMAX,NOETRI,NOEMAX,
     >            NBN,NBE,NCC,NBPMAX,NBEMAX,
     >            ITVL(ITRAV),NITMX2,RTVL(IRTRAV),NRTMX2,ITRACE,IERR)
        IF( IERR.NE.0 )THEN
          CALL DSERRE(1,IERR,'DSTRAF','APPEL DSTRIA')
          GOTO 9999
        ENDIF
C
C     --- ATTENTION LES CONCENTRATIONS PONCTUELLE ET AXIALES NE PASSERONT PAS EN 3D
C
      NBN2 = NBN
      CALL DSRAFT(IDE,ITRNOE,NBNMAX,ITRTRI,NBCMAX,
     >            NOETRI,NOEMAX,
     >             NBN2,NBE,NCC,NBPMAX,NBEMAX,
     >             RTVL(ICOO2D),IDIMC2,
     >             GRDNOE,NGRDMX,
     >             MODDEF,MODGEN,NBPNEW,
     >             IADEC,NIADEC,RADEC,NRIDEC,NFADEC,
     >             ITVL(ITRAV),NITMX2,RTVL(IRTRAV),NRTMX2,ITRACE,IERR)
C
C       ---- LIMITATION DONNE PAR L'UTILISATEUR ---
C       IERR = 2 : NOMBRE MAXIMUM D ELEMENTS ATTEINT: 
C       IERR = 1 : NOMBRE MAXIMUM DE NOEUDS ATTEINT: 
C       IERR = 0 : TAILLE SOUHAITEE ATTEINTE (FRONTIERE): '
        IF( IERR.LT.0 )THEN
          CALL DSERRE(1,IERR,'DSTRAF','APPEL DSRAFT')
          GOTO 9999
        ENDIF
C        PRINT *,'APRES DSRAFT INODE = ',IERR
        INODE = IERR
        IERR = 0
C     --- INTERPOLATION DES POINTS CALCULES 2D -> 3D
C      YMAT(3,3) = RTVL(IMAT)
C      CALL M33INV(YMATT,XMATT,IERR)
      CALL M33INV(RTVL(IMATT),RTVL(IMATT),IERR)
      IF( IERR.NE. 0 )THEN
          CALL DSERRE(1,IERR,'GNRAFT','APPEL M33INV')
          GOTO 9999
        ENDIF
C
C      PRINT *,'ON PROJETE LES POINTS GENERES ',NBN2-NBN
      DO 70 I=(NBN+1),NBN2
C     --- LES POINTS GENERES SERONT SUR LE PLAN MOYEN
        COORD((I-1)*IDIMC+1) = RTVL((I-1)*IDIMC2+ICOO2D)
        COORD((I-1)*IDIMC+2) = RTVL((I-1)*IDIMC2+ICOO2D+1)
        COORD((I-1)*IDIMC+3) = 0.0
C        CALL SOMMVE(COORD((I-1)*IDIMC+1),RTVL(IORIG),IDIMC,
C     >              COORD((I-1)*IDIMC+1))
        CALL  M33APP(RTVL(IMATT),COORD((I-1)*IDIMC+1),IDIMC,IUN,
     >               RTVL(IRTRAV),COORD((I-1)*IDIMC+1)) 
        CALL SOMMVE(COORD((I-1)*IDIMC+1),RTVL(IORIG),IDIMC,
     >              COORD((I-1)*IDIMC+1))
   70 CONTINUE
      NBN = NBN2  
C
      ELSE
C        -------------------
C     --- CAS D'UN DOMAINE 2D ---
C        -------------------
C
C... a integrer
      CALL DSTRIA(IDE1,IARETE,NBNMX1,NBN1,NBARET,
     >            IFREEL,NFREEL,
     >            COORD,IDIMC,
     >            IDE,ITRNOE,NBNMAX,
     >            ITRTRI,NBCMAX,NOETRI,NOEMAX,
     >            NBN,NBE,NCC,NBPMAX,NBEMAX,
     >            ITVL(ITRAV),NITMX2,RTVL(IRTRAV),NRTMX2,ITRACE,IERR)
C
        IF( IERR.NE.0 )THEN
          CALL DSERRE(1,IERR,'DSTRAF','APPEL DSTRIA')
          GOTO 9999
        ENDIF
C
      CALL DSRAFT(IDE,ITRNOE,NBNMAX,ITRTRI,NBCMAX,
     >            NOETRI,NOEMAX,
     >             NBN,NBE,NCC,NBPMAX,NBEMAX,
     >             COORD,IDIMC,
     >             GRDNOE,NGRDMX,
     >             MODDEF,MODGEN,NBPNEW,
     >             IADEC,NIADEC,RADEC,NRIDEC,NFADEC,
     >             ITVL(ITRAV),NITMX2,RTVL(IRTRAV),NRTMX2,ITRACE,IERR)
C
        IF( IERR.LT.0 )THEN
          CALL DSERRE(1,IERR,'DSTRAF','APPEL DSRAFT')
          GOTO 9999
        ENDIF
C        PRINT *,'APRES DSRAFT INODE = ',IERR
        INODE = IERR
        IERR = 0
      ENDIF
C
      IERR = INODE
C
 9999 END
C

C     --- SEPARATION DE CHAQUE REGION !

C
      SUBROUTINE RGARET(IDE1,IARETE,NBNMX1,NBN1,NBARET,
     >                  IAR2RG,NBRGMX,IREGIO,
     >                  ISOMRG,NBSORG,NSOMAX,IARERG,NBARRG,NARMAX,
     >                  ITVL,NITMAX,RTVL,NRTMAX,ITRACE,IERR)
C     **********************************************************************
C     OBJET RGARET : EXTRAIT LES ARETES D'UNE REGION
C     EN ENTREE :
C       IDE1,IARETE,NBNMX1,NBN1,NBARET : LE MAILLAGE LINEIQUE
C
C       NBRGMX : NOMBRE MAXIMUM DE REGIONS INCIDENTES A UNE ARETE
C       IAR2RG((I-1*NBRGMX+J) : Jeme REGION INCIDENTE A L'ARETE I
C       IREGIO : NUMERO DE LA REGION RECHERCHEE 
C
C     EN SORTIE : 
C       ISOMRG : TABLEAU DES SOMMETS DE LA REGION
C       IARERG : TABLEAU DES ARETES DE LA FRONTIERE DE LA REGION
C     **********************************************************************
      INTEGER    IDE1,IARETE(*),NBNMX1,NBN1,NBARET
      INTEGER    IAR2RG(*),NBRGMX,IREGIO
      INTEGER    ISOMRG(*),NBSORG,NSOMAX,IARERG(*),NBARRG,NARMAX
      INTEGER    ITVL(*)
      REAL       RTVL(*)
      INTEGER    NITMAX,NRTMAX,ITRACE,IERR
C
      INTEGER I,J
C
      NBSORG = 0
      NBARRG = 0
      DO 100 I=1,NBARET
C        IF((IAR2RG((I-1)*2+1).EQ.IREGIO ).OR.
C     >     (IAR2RG((I-1)*2+2).EQ.IREGIO))THEN
        DO 50 J=1,NBRGMX
        IF(IAR2RG((I-1)*NBRGMX+J).EQ.IREGIO )THEN
C          --- COPIE DES SOMMETS ET DE L'ARETE
C           IF((NBSORG+2.GT.NSOMAX).OR.(NBARRG+1.GT.NARMAX))THEN
           IF((NBSORG+2.GT.NSOMAX*2).OR.(NBARRG+1.GT.NARMAX))THEN
             IERR = -2
             GOTO 9999
           ENDIF
           NBSORG = NBSORG+1
           ISOMRG(NBSORG)=IARETE((I-1)*NBNMX1+1)
C          --- ajout 10.01.2005 pour les sommets isoles
           IF(( IARETE((I-1)*NBNMX1+2).EQ.0 ).OR.(NBNMX1.EQ.1))GOTO 100
           NBSORG = NBSORG+1
           ISOMRG(NBSORG)=IARETE((I-1)*NBNMX1+2)
           NBARRG = NBARRG+1
           IARERG((NBARRG-1)*2+1)=IARETE((I-1)*NBNMX1+1)
           IARERG((NBARRG-1)*2+2)=IARETE((I-1)*NBNMX1+2)
C          ON POURRAIT FAIRE UN GOTO 100
C          MODIF 07.06.2001 O.STAB : NE STOQUE QU'UNE SEULE FACE 
C          (EVITE UN PLANTAGE QUAND LA FACE EST REPETEE !)
           GOTO 100
           ENDIF
   50    CONTINUE
  100   CONTINUE
C     --- ON TRIE LES SOMMETS
C      CALL TBVTAB(ITABRG,NBE,ITVL,IREFRG,NBREF,
C     >                      NREFMX,IERR)
C      RENVOI LES VALEURS DISTINCTES ET TRIEES D'UN TABLEAU, 
C             TRIEES DANS L'ORDRE CROISSANT       
      CALL TBVTAB(ISOMRG,NBSORG,ITVL,ISOMRG,NBSORG,NSOMAX,IERR)
      IF(IERR.NE.0)THEN
        CALL DSERRE(1,IERR,'RGARET','APPEL TBVTAB')
        GOTO 9999
        ENDIF
C      
 9999 END
C
C
C
      SUBROUTINE RGRAFT(IDE1,IARETE,NBNMX1,NBN1,NBARET,
C     >                  IAR2RG,IREGIO,
     >                  IAR2RG,NBRGMX,IREGIO,
C
     >                  IDE,ITRNOE,NBNMAX,
C     INUTILE POUR L'INSTANT : ITRTRI,NBCMAX,NOETRI,NOEMAX,
     >                  NBN,NBE,NCC,NBPMAX,NBEMAX,
     >                  COORD,IDIMC,
C
     >                  GRDNOE,NGRDMX,
     >                  MODDEF,MODGEN,NBPNEW,
     >                  IADEC,NIADEC,RADEC,NRIDEC,NFADEC,
     >                  ITVL,NITMAX,RTVL,NRTMAX,ITRACE,IERR)
C     **********************************************************************
C     OBJET RGRAFT : MAILLAGE  ET RAFFINEMENT DE LA REGION IREGIO, 
C                    AVEC AJOUT AU MAILLAGE EXISTANT
C
C     EN ENTREE :
C       --- LE MAILLAGE LINEIQUE ---
C       IDE1,IARETE,NBNMX1,NBN1,NBARET : LE MAILLAGE LINEIQUE
C       IAR2RG,NBRGMX : REGIONS INCIDENTES AUX ARETES
C       COORD,IDIMC : LES POINTS DU MAILLAGE LINEIQUE
C
C       --- LE RAFFINEMENT SOUHAITE ---
C       MODDEF,MODGEN,NBPNEW,
C       IADEC,NIADEC,RADEC,NRIDEC,NFADEC,
C
C     EN SORTIE : 
C       ---- LIMITATION DONNE PAR L'UTILISATEUR ---
C       IERR = 2 : NOMBRE MAXIMUM D ELEMENTS ATTEINT: 
C       IERR = 1 : NOMBRE MAXIMUM DE NOEUDS ATTEINT: 
C       IERR = 0 : TAILLE SOUHAITEE ATTEINTE (FRONTIERE): 

C     LIMITATIONS : CONCENTRATIONS PONCTUELLES ET AXIALES 
C                   LES POINTS AJOUTES SONT DANS LE PLAN DES MOINDRES CARRES
C     REMARQUE :
C       CUMULE DSTRIA ET DSRAFT POUR UNE REGION DONNE: IREGIO 
C       TRIANGULATION D'UN DOMAINE SURFACIQUE (PAS FORCEMENT PLAN)
C       ET RAFFINEMENT (CAS MULTI-MATERIAUX)
C     **********************************************************************
      INTEGER IDE1,IARETE(*),NBNMX1,NBN1,NBARET
      INTEGER IAR2RG(*),NBRGMX,IREGIO
      INTEGER IDE,ITRNOE(*),NBNMAX
C     ITRTRI(*),NBCMAX,NOETRI(*),NOEMAX
      INTEGER NBN,NBE,NCC,NBPMAX,NBEMAX
      REAL    COORD(*)
      INTEGER IDIMC
      REAL    GRDNOE(*)
      INTEGER NGRDMX
      INTEGER MODDEF,MODGEN,NBPNEW
      INTEGER IADEC(*),NIADEC
      REAL    RADEC(*)
      INTEGER NRIDEC,NFADEC
      REAL    RTVL(*)
      INTEGER ITVL(*),NITMAX,NRTMAX,ITRACE,IERR
C     --- VARIABLES LOCALES ---
      INTEGER I,J,K,NBSORG,NBARRG
      INTEGER ITRAV,IRTRAV,NITMX2,NRTMX2
      INTEGER ISOMRG,NSOMRG,NSOMAX,IARERG,NARMAX
      INTEGER ICOOM,OLDNUM,INEWNU,NEWNUM,IARMA,NBETR
      INTEGER IGRDMX,NBGRD,IRADEC,NRADEC,NBTSN,NBTSMX
      INTEGER PSTRUC,PITRRG,TSN,ICOEF,IDIMG,NBPMX2,NBEMX2
      INTEGER IRGNOE,IRGTRI,IRGNOT,NOEMX2,NBNRG,NBERG,NCCRG
      INTEGER NBNMX3,NBCMX3
      INTEGER NBPTOT,INODE
      INTEGER NUMNOD,NEWNOD
C
*     pour tester la memoire :
      ITVL(NITMAX-1) = 0
*
      INODE = 0
      ITRAV = 1
      IRTRAV = 1
      NRTMX2 = NRTMAX - IRTRAV+1
C
      ISOMRG = ITRAV
C      NSOMAX = NBN1  BUG OS16.08.99 :
      NSOMAX = NBN1*2
      IARERG = ISOMRG+NSOMAX
      NARMAX = NBARET
      ITRAV =  IARERG + 2*NARMAX
      NITMX2 = NITMAX - ITRAV+1
C
        NBSORG = 0
        NBARRG = 0
        CALL RGARET(IDE1,IARETE,NBNMX1,NBN1,NBARET,
C     >              IAR2RG,IREGIO,
     >              IAR2RG,NBRGMX,IREGIO,
     >              ITVL(ISOMRG),NBSORG,NSOMAX,
     >              ITVL(IARERG),NBARRG,NARMAX,
     >              ITVL(ITRAV),NITMX2,RTVL(IRTRAV),NRTMX2,ITRACE,IERR)
        IF(IERR.NE.0)THEN 
          CALL DSERRE(1,IERR,' RGRAFT','APPEL A RGARET')
          GOTO 9999
        ENDIF
C          ====================================
C       --- ETAPE 1. EXTRACTION D'UN MAILLAGE  ---
C          ====================================
C
C       --- RENUMEROTATION DES NOEUDS DE LA REGION
C
        INEWNU = ITRAV
        ITRAV  = INEWNU + NBN1
        NITMX2 = NITMAX - ITRAV
        IF( NITMX2.LT.0 )THEN
          IERR = -2
          CALL DSERRE(1,IERR,' RGRAFT','ENTIERS POUR INEWNU')
          GOTO 9999
        ENDIF
        DO 5 I=1,NBSORG
          OLDNUM = ITVL(I-1+ISOMRG)
          ITVL((OLDNUM-1)+INEWNU) = I
    5   CONTINUE
C
C       --- EXTRACTION ET COPIE DES COORDONNEES DES NOEUDS DE LA REGION
C
        ICOOM  = IRTRAV
C        IRTRAV = NBSORG*IDIMC + ICOOM     
        IRTRAV = NBPMAX*IDIMC + ICOOM     
        NRTMX2 = NRTMAX - IRTRAV
        IF( NRTMX2.LT.0 )THEN
          IERR = -2
          CALL DSERRE(1,IERR,' RGRAFT','REELS POUR ICOOM')
          GOTO 9999
        ENDIF
        DO 20 I=1,NBSORG
          OLDNUM = ITVL(I-1+ISOMRG)
          NEWNUM = ITVL((OLDNUM-1)+INEWNU)
          DO 10 J=1,IDIMC
            RTVL((NEWNUM-1)*IDIMC+ICOOM-1+J) = COORD((OLDNUM-1)*IDIMC+J)
   10     CONTINUE
   20   CONTINUE
C
C       --- EXTRACTION ET COPIE DES TS DES NOEUDS DE LA REGION
C
        IF( MODDEF.EQ.3 )THEN
          NRADEC = NBSORG
          NBTSN  = 1
C          PRINT *,'CONCENTRATION NODALE NRIDEC,NFADEC = ',NRIDEC,NFADEC
          IRADEC = IRTRAV
          IRTRAV = IRADEC + NBPMAX*NBTSN
          NRTMX2 = NRTMAX - IRTRAV+1
        IF( NITMX2.LT.0 )THEN
          IERR = -2
          CALL DSERRE(1,IERR,' RGRAFT','ENTIERS POUR IRADEC')
          GOTO 9999
        ENDIF
          DO 52 I=1,NBSORG
            OLDNUM = ITVL(I-1+ISOMRG)
            NEWNUM = ITVL((OLDNUM-1)+INEWNU)
            DO 51 J=1,NBTSN
              RTVL((NEWNUM-1)*NBTSN+IRADEC-1+J) = 
     >            RADEC((OLDNUM-1)*NBTSN+J)
   51       CONTINUE
   52     CONTINUE
        ENDIF
C
C       --- EXTRACTION ET COPIE DES GRANDEURS DES NOEUDS DE LA REGION
C
        IGRDMX = -1
        IF( NGRDMX.NE.0 )THEN
          NBGRD = 1
C          PRINT *,' GRANDEURS DES NOEUDS NGRDMX= ',NGRDMX
          IGRDMX = IRTRAV
          IRTRAV = IGRDMX + NBPMAX*NBGRD
          NRTMX2 = NRTMAX - IRTRAV+1
        IF( NITMX2.LT.0 )THEN
          IERR = -2
          CALL DSERRE(1,IERR,' RGRAFT','ENTIERS POUR IGRDMX')
          GOTO 9999
        ENDIF
          DO 54 I=1,NBSORG
            OLDNUM = ITVL(I-1+ISOMRG)
            NEWNUM = ITVL((OLDNUM-1)+INEWNU)
            DO 53 J=1,NBGRD
              RTVL((NEWNUM-1)*NBGRD+IGRDMX-1+J) = 
     >            GRDNOE((OLDNUM-1)*NBGRD+J)
   53       CONTINUE
   54     CONTINUE
        ENDIF
C
C       --- EXTRACTION ET COPIE DES ARETES DE LA REGION
C
        IARMA = ITRAV 
        ITRAV = IARMA + 2*NBARRG
        NITMX2 = NITMAX - ITRAV
        IF( NITMX2.LT.0 )THEN
          IERR = -2
          CALL DSERRE(1,IERR,' RGRAFT','ENTIERS POUR IARMA')
          GOTO 9999
        ENDIF
        DO 60 I=1,NBARRG
          OLDNUM = ITVL((I-1)*NBNMX1+IARERG)
          NEWNUM  = ITVL((OLDNUM-1)+INEWNU)
          ITVL((I-1)*2+IARMA)  = NEWNUM
          OLDNUM = ITVL((I-1)*NBNMX1+IARERG+1)
          NEWNUM  = ITVL((OLDNUM-1)+INEWNU)
          ITVL((I-1)*2+IARMA+1)= NEWNUM
   60   CONTINUE
C          ===========================================
C      --- ETAPE 2 : CALCUL DU MAILLAGE DE LA REGION  ---
C          ===========================================
C
C     --- ALLOCATION : CALCUL DE NBPMX2, NBEMX2
        NBETR = 2*NBARRG
        PSTRUC = 1
        PITRRG = 0
        TSN = 0
        ICOEF = 0
C       ON PREND LA PLACE QUE L'ON A
        NBPTOT = -1
C        CALL DS4MAX(IDIMC,NMT,NBN,NBE,NBPTOT,
        CALL DS4MAX(IDIMC,1,NBSORG,NBETR,NBPTOT,
     >              PSTRUC,PITRRG,TSN,ICOEF,IDIMG,NITMX2,
     >              NRTMX2,NBPMX2,NBEMX2,IERR)
        IF(IERR.NE.0)THEN 
          CALL DSERRE(1,IERR,' RGRAFT','1 APPEL A DS4MAX')
          GOTO 9999
        ENDIF
C       ON NE DOIT PAS DEPASSER NBPMAX !!!
        IF( NBPMX2.GT.NBPMAX )THEN
          CALL DS4MAX(IDIMC,1,NBSORG,NBETR,NBPMAX,
     >              PSTRUC,PITRRG,TSN,ICOEF,IDIMG,NITMX2,
     >              NRTMX2,NBPMX2,NBEMX2,IERR)
          IF(IERR.NE.0)THEN 
            CALL DSERRE(1,IERR,' RGRAFT','2 APPEL A DS4MAX')
            GOTO 9999
          ENDIF
        ENDIF  
C
        IF(ITRACE.GT.1 )THEN
          CALL ESEINT(1,'NOMBRE MAXIMUM DE NOEUDS  : ',NBPMX2,1)
          CALL ESEINT(1,'NOMBRE MAXIMUM D ELEMENTS : ',NBEMX2,1)
       ENDIF
C
          NBNMX3 = 3
          NBCMX3 = 3
        IRGNOE = ITRAV
        IRGTRI = NBNMX3*NBEMX2 + IRGNOE 
        IRGNOT = NBCMX3*NBEMX2 + IRGTRI
        NOEMX2 = NBPMX2
        ITRAV  = NOEMX2 + IRGNOT
C       MODIF O.STAB 05.03.2001 : BUG ajout ligne suivante
        NITMX2 = NITMAX - ITRAV
        NBNRG = 0
        NBERG = 0
        NCCRG = 0
        IF( MODDEF.EQ.3 )THEN
C       CALL DSTRAF(IDE1,IARETE,NBNMX1,NBN1,NBARET,
        CALL DSTRAF(IDE1,ITVL(IARMA),2,NBSORG,NBARRG,
C     >            IDE,ITRNOE,NBNMAX,ITRTRI,NBCMAX,NOETRI,NOEMAX,
     >            IDE,ITVL(IRGNOE),NBNMX3,ITVL(IRGTRI),NBCMX3,
     >            ITVL(IRGNOT),NOEMX2,
     >            NBNRG,NBERG,NCCRG,NBPMX2,NBEMX2,
     >            RTVL(ICOOM),IDIMC,
C     >            GRDNOE,NGRDMX,
     >            RTVL(IGRDMX),NGRDMX,
     >            MODDEF,MODGEN,NBPNEW,
C     >            IADEC,NIADEC,RADEC,NRIDEC,NFADEC,
     >            IADEC,NIADEC,RTVL(IRADEC),NRADEC,NFADEC,
     >            ITVL(ITRAV),NITMX2,RTVL(IRTRAV),NRTMX2,ITRACE,IERR)
        ELSE
        CALL DSTRAF(IDE1,ITVL(IARMA),2,NBSORG,NBARRG,
C     >            IDE,ITRNOE,NBNMAX,ITRTRI,NBCMAX,NOETRI,NOEMAX,
     >            IDE,ITVL(IRGNOE),NBNMX3,ITVL(IRGTRI),NBCMX3,
     >            ITVL(IRGNOT),NOEMX2,
     >            NBNRG,NBERG,NCCRG,NBPMX2,NBEMX2,
     >            RTVL(ICOOM),IDIMC,
C     >            GRDNOE,NGRDMX,
     >            RTVL(IGRDMX),NGRDMX,
     >            MODDEF,MODGEN,NBPNEW,
     >            IADEC,NIADEC,RADEC,NRIDEC,NFADEC,
C     >            IADEC,NIADEC,RTVL(IRADEC),NRADEC,NFADEC,
     >            ITVL(ITRAV),NITMX2,RTVL(IRTRAV),NRTMX2,ITRACE,IERR)
        ENDIF
C
        IF(IERR.LT.0)THEN 
          CALL DSERRE(1,IERR,' RGRAFT','APPEL A DSTRAF')
          GOTO 9999
        ENDIF
C       ---- LIMITATION DONNE PAR L'UTILISATEUR ---
C       IERR = 2 : NOMBRE MAXIMUM D ELEMENTS ATTEINT: 
C       IERR = 1 : NOMBRE MAXIMUM DE NOEUDS ATTEINT: 
C       IERR = 0 : TAILLE SOUHAITEE ATTEINTE (FRONTIERE): 
C        PRINT *,'APRES DSRAF : INODE = ',IERR
        INODE = IERR
        IERR = 0
C          ========================================================
C      --- ETAPE 3 : INSERTION DU RESULTAT DANS LE MAILLAGE GLOBAL ---
C          ========================================================
C
C       --- ON ATTRIBUT DES NUMEROS AUX NOUVEAUX NOEUDS :
C           NBSORG A NBNRG  --> NBN A NBN+(NBNRG-NBSORG)
C
        NEWNOD = ITRAV
        ITRAV  = NEWNOD + (NBNRG-NBSORG)
        NITMX2 = NITMAX - ITRAV
        IF( NITMX2.LT.0 )THEN
          IERR = -2
          CALL DSERRE(1,IERR,' RGRAFT','POUR LES NOUVEAUX NOEUDS')
          GOTO 9999
        ENDIF
C       ATTENTION NBN PEUT ETRE PLUS GRAND QUE NBSORG=FRT DU DOMAINE
        DO 70 I=1,(NBNRG-NBSORG)
           NBN = NBN + 1
           ITVL(NEWNOD+I-1)= NBN
   70   CONTINUE
C
C       --- ON EMPILE LES COORDONNEES DES NOUVEAUX NOEUDS 
C     
        IF( NBPMAX.LT.NBN )THEN
          IERR = -2
          CALL DSERRE(1,IERR,' RGRAFT','COORD POUR LES NOUVEAUX NOEUDS')
          GOTO 9999
        ENDIF
        DO 90 I=1,(NBNRG-NBSORG)        
          NUMNOD = ITVL(NEWNOD+I-1)
          DO 80 J=1,IDIMC
            COORD((NUMNOD-1)*IDIMC+J)=RTVL((I+NBSORG-1)*IDIMC+ICOOM+J-1)
   80     CONTINUE
   90   CONTINUE
C
C       --- ON EMPILE LES GRANDEURS DES NOUVEAUX NOEUDS 
C    
      IF( NGRDMX.NE.0 )THEN 
        IF( NGRDMX.LT.NBN )THEN
         IERR = -2
         CALL DSERRE(1,IERR,' RGRAFT','GRDNOE POUR LES NOUVEAUX NOEUDS')
         GOTO 9999
        ENDIF
        DO 91 I=1,(NBNRG-NBSORG)        
          NUMNOD = ITVL(NEWNOD+I-1)
          DO 81 J=1,NBGRD
          GRDNOE((NUMNOD-1)*NBGRD+J)=RTVL((I+NBSORG-1)*NBGRD+IGRDMX+J-1)
   81   CONTINUE
   91 CONTINUE
      ENDIF
C
C       --- ON EMPILE LES TS AUX NOUVEAUX NOEUDS 
C     
      IF( MODDEF.EQ.3 )THEN 
        NBTSN = 1
        NBTSMX = NBPMAX
C       SI TOUT EST BIEN FAIT !
        IF( NBTSMX.LT.NBN )THEN
         IERR = -2
         CALL DSERRE(1,IERR,' RGRAFT','RADEC POUR LES NOUVEAUX NOEUDS')
         GOTO 9999
        ENDIF
        DO 92 I=1,(NBNRG-NBSORG)        
          NUMNOD = ITVL(NEWNOD+I-1)
          DO 82 J=1,NBTSN
         RADEC((NUMNOD-1)*NBTSN+J)=RTVL((I+NBSORG-1)*NBTSN+IRADEC+J-1)
   82  CONTINUE
   92 CONTINUE
      ENDIF
C
C       --- ON EMPILE LES ELEMENTS AVEC LES ANCIENS NUMEROS DE NOEUDS ---
C
        DO 110 I=1,NBERG
          DO 100 J=1,NBNMAX
            NEWNUM = ITVL((I-1)*3+IRGNOE-1+J)
            IF( NEWNUM.GT.NBSORG )THEN
              ITRNOE((I+NBE-1)*NBNMAX+J)= ITVL((NEWNUM-NBSORG-1)+NEWNOD)
            ELSE
              ITRNOE((I+NBE-1)*NBNMAX+J)= ITVL((NEWNUM-1)+ISOMRG)
            ENDIF
  100     CONTINUE
  110   CONTINUE
        NBE = NBE + NBERG
C
        IERR = INODE
C
 9999   END





C     **********************************************************************
C     FICHIER  : API_RAFFINE.F
C     OBJET    : GENERATION ET INSERTION DES POINTS SUR UNE TRIANGULATION
C
C     FONCT.   :
C     OBJET DSRAFT : RAFFINE UNE TRIANGULATION plane ET TAILLE SOUHAITE AUX NOEUDS
C     OBJET GNRAFT : RAFFINE UNE TRIANGULATION (surface 3D) MULTI-REGIONS
C
C     AUTEUR   : O. STAB
C     DATE     : 10.10.98
C     TESTS    :  
C     MODIFICATIONS :
C        AUTEUR, DATE, OBJET : O.STAB, 27.07.99, EXTRACTION DE DS4_NOEUD2D.F
C                              ET SUPPRESSION DES E/S.
C                              O.STAB, 19.06.2001, GNRAFT (ERREUR ET MESSAGE)
C                              POUR LE MULTI-MAT EN 3D.
C                              O.STAB, 02.02.2005, DSRAFT limitation des noeuds
C     **********************************************************************
C
C
      SUBROUTINE DSRAFT(IDE,ITRNOE,NBNMAX,ITRTRI,NBCMAX,NOETRI,NOEMAX,
     >                NBN,NBE,NCC,NBPMAX,NBEMAX,
     >                COORD,IDIMC,
     >                GRDNOE,NGRDMX,
     >                MODDEF,MODGEN,NBPNEW,
     >                IADEC,NIADEC,RADEC,NRIDEC,NFADEC,
     >                ITVL,NITMAX,RTVL,NRTMAX,ITRACE,IERR)
C     **********************************************************************
C     OBJET DSRAFT : RAFFINE UNE TRIANGULATION plane ET TAILLE SOUHAITE AUX NOEUDS
C                    APPEL RFRAFF PUIS DNCCTB
C
C     EN ENTREE :
C          --- le maillage (avec la structure de donnees) mais pas de region ---
C          IDE,ITRNOE,NBNMX,ITRTRI,NBCMAX,NOETRI,NBE : la triangulation existante
C          COORD,IDIMC,NBN : coordonnee des points
C          --- donnees aux noeuds ---
C          GRDNOE,NGRDMX : grandeurs aux noeuds
C          --- la densite ---
C          MODDEF,MODGEN,NBPNEW :
C          IADEC,NIADEC,RADEC,NRIDEC,NFADEC :
C
C     EN SORTIE :
C       ---- LIMITATIONS DONNEES PAR L'UTILISATEUR ---
C       IERR = 2 : NOMBRE MAXIMUM D ELEMENTS ATTEINT: 
C       IERR = 1 : NOMBRE MAXIMUM DE NOEUDS ATTEINT: 
C       IERR = 0 : TAILLE SOUHAITEE ATTEINTE (FRONTIERE): '
C
C     REMARQUE :    IDEM DS1FCT (AUX SIGNATURES DE RFRAFF PRES)
C     ATTENTION CONTRAIREMENT A DS1FCT LES REGIONS NE SONT PAS MAINTENUS !
C     ATTENTION NBPNEW n'est pas correctement gere : seul le cas = 0 est traite !!!
C     **********************************************************************
      INTEGER    IDE,ITRNOE(*),NBNMAX,ITRTRI(*),NBCMAX,NOETRI(*),NOEMAX
      INTEGER    NBN,NBE,NCC,NBPMAX,NBEMAX
      REAL       COORD(*),GRDNOE(*)
      INTEGER    IDIMC,NGRDMX
      INTEGER    ITVL(*)
      REAL       RTVL(*),RADEC(*)
      INTEGER    MODDEF,MODGEN,NBPNEW,IADEC(*),NFADEC,NIADEC,NRIDEC
      INTEGER    NITMAX,NRTMAX,ITRACE,IERR
C
      INTEGER    NCCMAX,IERTSA,NBPMX2
      EXTERNAL   D2ISUI,DNCHPO
C
      IERTSA = 0
      IF( NBPNEW.EQ.0)GOTO 500
C     --- ajout 02.02.2005
      NBPMX2 = MIN(NBPMAX,NBPNEW+NBN)
      GOTO( 100,200,300 ) MODDEF
        IERR = -1
        CALL DSERRE(1,IERR,'DSRAFT','DEFINITION DENSITE INCORRECTE')        
        GOTO 9999
C        ========================
C     --- RAFFINEMENT PAR DEFAUT ---
C        ========================
 100  CONTINUE   
      CALL RFRAFF(MODDEF,
C     >     MODGEN,
     >     ITRNOE,NBNMAX,ITRTRI,NBCMAX,
     >     NOETRI,NOEMAX,
C     >     ITRIRG,NRGMAX,
     >     COORD,IDIMC,NBN,NBE,NBPMX2,NBEMAX,
     >     0,IADEC,NIADEC,RADEC,NRIDEC,NFADEC,     
     >     ITVL,NITMAX,RTVL,NRTMAX,
     >     IERR)
      IF(IERR.LT.0)THEN 
        CALL DSERRE(1,IERR,'DSRAFT',' APPEL RFRAFF')
        GOTO 9999      
      ENDIF     
      GOTO 400
C        ===========================================
C     ---    CONCENTRATIONS(X,Y) OU VALEURS NODALES  ---
C        ===========================================      
 200  CONTINUE   
      CALL RFRAFF(MODDEF,
C     >     MODGEN,
     >     ITRNOE,NBNMAX,ITRTRI,NBCMAX,
     >     NOETRI,NOEMAX,
C     >     ITRIRG,NRGMAX,
     >     COORD,IDIMC,NBN,NBE,NBPMX2,NBEMAX,
     >     D2ISUI,IADEC,NIADEC,RADEC,NRIDEC,NFADEC,     
     >     ITVL,NITMAX,RTVL,NRTMAX,
     >     IERR)
      IF(IERR.LT.0)THEN 
        CALL DSERRE(1,IERR,'DSRAFT',' APPEL RFRAFF (D2ISUI)')
        GOTO 9999      
      ENDIF     
      GOTO 400
C        ===========================================
C     ---    VALEURS NODALES  ---
C        ===========================================      
 300  CONTINUE   
      CALL RFRAFF(MODDEF,
C     >     MODGEN,
     >     ITRNOE,NBNMAX,ITRTRI,NBCMAX,
     >     NOETRI,NOEMAX,
C     >     ITRIRG,NRGMAX,
     >     COORD,IDIMC,NBN,NBE,NBPMX2,NBEMAX,
     >     DNCHPO,IADEC,NIADEC,RADEC,NRIDEC,NFADEC,     
     >     ITVL,NITMAX,RTVL,NRTMAX,
     >     IERR)
      IF(IERR.LT.0)THEN 
        CALL DSERRE(1,IERR,'DSRAFT',' APPEL RFRAFF (DNCHPO)')
        GOTO 9999      
      ENDIF 
      GOTO 400
C
  400 CONTINUE
C     TAILLE SOUHAITE ATTEINTE ? (0), NOMBRE MAX ELEMENT (2), NOEUD (1) 
      IERTSA = IERR
      IERR = 0

C
C        ================================================
C     --- CALCUL DES TAILLES SOUHAITEES AU NOEUDS       ---
C        ================================================
  500 CONTINUE
      IERR = 0
      IF( NGRDMX.LE.0 )GOTO 8000
      IF( NGRDMX.LT.NBN )THEN
        IERR = -2
        CALL DSERRE(1,IERR,'DSRAFT','PLUS DE PLACE ') 
        GOTO 9999
      ENDIF
C
      GOTO( 600,700,800 ) MODDEF
C     --- RAF PAR DEFAUT
 600  CONTINUE
      CALL DNCCTB(MODDEF,IDE,ITRNOE,NBNMAX,NBE,
     >            ITRTRI,NBCMAX,
     >            0,IADEC,NIADEC,RADEC,NRIDEC,NFADEC,
     >            COORD,IDIMC,NBN,GRDNOE,IERR)
      GOTO 1000
C     --- CONCENTRATION (X,Y)
 700  CONTINUE
      CALL DNCCTB(MODDEF,IDE,ITRNOE,NBNMAX,NBE,
     >            ITRTRI,NBCMAX,
     >            D2ISUI,IADEC,NIADEC,RADEC,NRIDEC,NFADEC,
     >            COORD,IDIMC,NBN,GRDNOE,IERR)
      GOTO 1000
C     --- VALEURS NODALES 
 800  CONTINUE
      CALL DNCCTB(MODDEF,IDE,ITRNOE,NBNMAX,NBE,
     >            ITRTRI,NBCMAX,
     >            DNCHPO,IADEC,NIADEC,RADEC,NRIDEC,NFADEC,
     >            COORD,IDIMC,NBN,GRDNOE,IERR)
      GOTO 1000
C
 1000 CONTINUE
      IF( IERR.NE.0 )THEN
        CALL DSERRE(1,IERR,'DSRAFT','APPEL DNCCTB ') 
        GOTO 9999
      ENDIF
C     --- FIN ---
 8000 CONTINUE
      IERR = IERTSA
C
 9999 END
C
C
      SUBROUTINE GNRAFT(IDE,ITRNOE,NBNMAX,ITRTRI,NBCMAX,NOETRI,NOEMAX,
     >                NBN,NBE,NCC,NBPMAX,NBEMAX,
     >                COORD,IDIMC,
C     --- AJOUT POUR LES MATERIAUX :
     >                ITRIRG,NRGMAX,IMTREF,NMT,INTMAT,NMTCC,
     >                GRDNOE,NGRDMX,
     >                MODDEF,MODGEN,NBPNEW,
     >                IADEC,NIADEC,RADEC,NRIDEC,NFADEC,
     >                ITVL,NITMAX,RTVL,NRTMAX,ITRACE,IERR)
C     **********************************************************************
C     OBJET GNRAFT : RAFFINE UNE TRIANGULATION (2D,3D) MULTI-REGIONS
C                    creation de la structure de donnees ITRTRI,NOETRI
C                    APPEL DSRAFT
C     EN ENTREE : 
C          ---- la triangulation initiale ---
C          IDE,ITRNOE,NBNMX,NBCMAX,NBE : la triangulation existante
C          COORD,IDIMC,NBN : coordonnee des points
C          ITRIRG,NRGMAX,IMTREF,NMT,INTMAT,NMTCC : les regions
C          --- la densite ---
C          MODDEF,MODGEN,NBPNEW :
C          IADEC,NIADEC,RADEC,NRIDEC,NFADEC :
C
C     EN SORTIE :
C          --- la triangulation mise a jour et la structure de donnees ---
C
C     REMARQUE :               
C          APPEL DSRAFT
C     **********************************************************************
      INTEGER    IDE,ITRNOE(*),NBNMAX,ITRTRI(*),NBCMAX,NOETRI(*),NOEMAX
      INTEGER    NBN,NBE,NCC,NBPMAX,NBEMAX
      REAL       COORD(*),GRDNOE(*)
      INTEGER    IDIMC,NGRDMX
      INTEGER    ITRIRG(*),NRGMAX,IMTREF(*),NMT,INTMAT(*),NMTCC
      INTEGER    ITVL(*)
      REAL       RTVL(*),RADEC(*)
      INTEGER    MODDEF,MODGEN,NBPNEW,IADEC(*),NFADEC,NIADEC,NRIDEC
      INTEGER    NITMAX,NRTMAX,ITRACE,IERR
C     ---- MODIF POUR LA PROJECTION ---
      INTEGER IDIMC2,ICOO2D,IORIG,IMATT,IND1,IND2,IPOINT(1),NPOINT
      INTEGER I,J
C
      INTEGER ITRAV,NITMX2,IRTRAV,NRTMX2
      INTEGER IUN,NMT2
      INTEGER NDECMX
      INTEGER IFR,NBNIFR,NBIFR,IMATFR,NFRMAX,IDE1,NMT1,MAJNOE
      INTEGER INODE,NBN2
      INTEGER INTMAX,IMTMAX
C
      IUN = 1
      ITRAV = 1
      NITMX2 = NITMAX
      IRTRAV = 1
      NRTMX2 = NRTMAX
C         =====================================================
C     --- 1. CREATION DE LA STRUCTURE DE DONNEES ---
C         =====================================================
      CALL SMAOCR(IDE,ITRNOE,NBE,COORD,NBN,IDIMC,
     >            ITRNOE,NBNMAX,ITRTRI,
     >            NBCMAX,NOETRI,NOEMAX,
     >            ITVL(ITRAV),NITMX2,NCC,IERR)
      IF( IERR.NE.0 )THEN
        CALL DSERRE(1,IERR,'GNRAFT',' APPEL SMAOCR')        
        GOTO 9999
      ENDIF 
C      IF( ITRACE.NE.0 )
C     >   CALL ESEINT(1,'NOMBRE DE COMPOSANTES CONNEXES : ',NCC,1)
C         =====================================================
C     --- 2. EXTRACTION DES REGIONS       
C         ON EXTRAIT LES ARETES DE LA FRONTIERE ( ITVL(IFR))
C         ET LES REGIONS INCIDENTS ( ITVL(IMATFR) )
C         =====================================================
C     --- CAS MONO-REGION --
      NBIFR = 0
      IMATFR = ITRAV
      ITRAV = ITRAV + 1
C
      ITVL(IMATFR) = IMTREF(1)
      NMTCC = 1
C
      IF( NMT.GT. 1 )THEN
C     --- ATTENTION NE FONCTIONNE QUE POUR LE 2D :
        IF( IDE.EQ.3 )THEN
          IERR = -3
          CALL DSERRE(1,IERR,'GNRAFT',' PAS IMPLEMENTE EN 3D!')        
          GOTO 9999
        ENDIF
C     --- CAS POLY-REGION ---
C      IF(ITRACE.GT.0)
C     >  CALL ESECHA(1,'-> SAUVEGARDE DES REGIONS',' ')
C
      CALL TBIT2V(INTMAT,IMTREF,NMT,ITRIRG,
     >                NBE,IERR)
      IF( IERR.NE.0 )THEN
        CALL DSERRE(1,IERR,'GNRAFT',' APPEL TBIT2V')        
        GOTO 9999
      ENDIF
C
      NBNIFR  = 2
      CALL RGNORG(IDE,ITRNOE,NBNMAX,ITRTRI,
     >         NBCMAX,NBE,ITRIRG,NMT,0,NBIFR,
     >         0,NBNIFR,0,0,IERR)
      IF( IERR.NE.-2 )THEN
        CALL DSERRE(1,IERR,'GNRAFT',' APPEL RGNORG')        
        GOTO 9999
      ENDIF
C      PRINT *,'ON A :',NBIFR,' ARETES DE FRONTIERE'
C
      IERR   = 0
      NFRMAX = NBIFR
      IFR    = ITRAV
      IMATFR = (NBNIFR * NFRMAX) + IFR
      ITRAV  = IMATFR + (2*NBIFR)
      NITMX2 = NITMAX - ITRAV
C
      CALL RGNORG(IDE,ITRNOE,NBNMAX,ITRTRI,
     >         NBCMAX,NBE,ITRIRG,NMT,ITVL(IFR),NBIFR,
     >         NFRMAX,NBNIFR,ITVL(IMATFR),NFRMAX,IERR)
C
      IF( IERR.NE.0 )THEN
        CALL DSERRE(1,IERR,'GNRAFT',' APPEL RGNORG')        
        GOTO 9999
      ENDIF
C      IF( ITRACE.NE.0 )
C     >     CALL ESEINT(1,'NOMBRE D ARETES DE FRONTIERE : ',NBIFR,1)
C
C     --- IL FAUT LIBERER ITRIRG EN COMPRIMANT IFR ET IMATFR ---
C     --- INSERTION DES FRONTIERES INTERIEURES ---
C

C     AJOUT ITVL,NITMX2 : 26.01.99
      DO 10 I=1,NBIFR
        CALL SFRICR(ITVL((I-1)*NBNIFR+IFR),2,IDE,
     >       ITRNOE,NBNMAX,ITRTRI,NBCMAX,
     >       NOETRI,NBE,ITVL(ITRAV),NITMX2,IERR)
      IF( IERR.NE. 0 )THEN
        CALL DSERRE(1,IERR,'GNRAFT',' APPEL SFRICR')        
        GOTO 9999
      ENDIF
   10 CONTINUE
      ENDIF
C     --- POUR LE DEBUG ---
C        ===============
C      CALL SDBTRI(IDE,ITRNOE,NBNMAX,ITRTRI,NBCMAX,NOETRI,
C     >                    NBE,NBN,ITRACE,IERR) 
C      IF( IERR.NE. 0 )THEN
C        CALL DSERRE(1,IERR,'GNRAFT',' APPEL SDBTRI 1')        
C        GOTO 9999
C      ENDIF
C
C         ========================================
C     --- 3. GENERATION DES NOEUDS DANS LE PLAN ET 
C            INSERTION DANS LA TRIANGULATION       ---
C         ========================================
C
   50 CONTINUE
C
C      ITBDEN = IRTRAV
C      NDENMX = NBPMAX
C      IRTRAV = ITBDEN + NDENMX
C      NRTMX2 = NRTMAX - IRTRAV + 1
      INODE = 0
C      IF( IDIMC.EQ.3 )THEN
      IF((IDIMC.EQ.3 ).AND.(IDE.EQ.2))THEN
C     ---- PROJECTION SUR LE PLAN DES MOINDRES CARRES SI 3D ---
      IDIMC2 = 2
      IF(IDIMC.EQ.3 )THEN
        ICOO2D = IRTRAV
        IORIG  = ICOO2D + NBPMAX*IDIMC2
        IMATT  = IORIG  + 3
        IRTRAV = IMATT  + 9
C        NRTMX2 = NITMAX - IRTRAV  , BUG 080699:
        NRTMX2 = NRTMAX - IRTRAV
        IND1   = 1
        IND2   = NBN
        IPOINT(1) = 0
        NPOINT = 0
        CALL RPPNCR(IPOINT,NPOINT,IND1,IND2,
     >              COORD,IDIMC,
     >              ITVL(ITRAV),NITMX2,RTVL(IRTRAV),NRTMX2,
     >              RTVL(IORIG),RTVL(IMATT),RTVL(ICOO2D),IDIMC2,IERR)
C      ---- POUR LE DEBUG ----
C      ORIG : NOUVELLE ORIGINE
C      IMATT : MATRICE 3x3 DE PASSAGE DANS LE NOUVEAU REPERE
C       PRINT *,'GNRAFT: ORIG = ',RTVL(IORIG),RTVL(IORIG+1),RTVL(IORIG+2)        
C       DO 60 I=1,MIN(NBN,10)
C        PRINT *,(RTVL((I-1)*IDIMC2+ICOO2D+J-1),J=1,IDIMC2)
C   60  CONTINUE
        IF( IERR.NE.0 )THEN
          CALL DSERRE(1,IERR,'GNRAFT','APPEL RPPNCR')
          GOTO 9999
        ENDIF
C     --- ATTENTION NE RIEN LIBERER CA SERT PLUS LOIN !!!
C        IRTRAV = IORIG
C        NRTMX2 = NRTMAX - IRTRAV
      ENDIF
C
      NBN2 = NBN
      CALL DSRAFT(IDE,ITRNOE,NBNMAX,ITRTRI,NBCMAX,
     >            NOETRI,NOEMAX,
     >             NBN2,NBE,NCC,NBPMAX,NBEMAX,
C     >                ITRIRG,NRGMAX,IMTREF,NMT,
     >             RTVL(ICOO2D),IDIMC2,
     >             GRDNOE,NGRDMX,
C     >             RTVL(ITBDEN),NDENMX,
     >             MODDEF,MODGEN,NBPNEW,
     >             IADEC,NIADEC,RADEC,NRIDEC,NFADEC,
     >             ITVL(ITRAV),NITMX2,RTVL(IRTRAV),NRTMX2,ITRACE,INODE)
C     --- INTERPOLATION DES POINTS CALCULES 2D -> 3D
C      YMAT(3,3) = RTVL(IMAT)
C      CALL M33INV(YMATT,XMATT,IERR)
      CALL M33INV(RTVL(IMATT),RTVL(IMATT),IERR)
      IF( IERR.NE. 0 )THEN
          CALL DSERRE(1,IERR,'GNRAFT','APPEL M33INV')
          GOTO 9999
        ENDIF
C
C      PRINT *,'ON PROJETE LES POINTS GENERES ',NBN2-NBN
      DO 70 I=(NBN+1),NBN2
C     --- LES POINTS GENERES SERONT SUR LE PLAN MOYEN
        COORD((I-1)*IDIMC+1) = RTVL((I-1)*IDIMC2+ICOO2D)
        COORD((I-1)*IDIMC+2) = RTVL((I-1)*IDIMC2+ICOO2D+1)
        COORD((I-1)*IDIMC+3) = 0.0
C        CALL SOMMVE(COORD((I-1)*IDIMC+1),RTVL(IORIG),IDIMC,
C     >              COORD((I-1)*IDIMC+1))
        CALL  M33APP(RTVL(IMATT),COORD((I-1)*IDIMC+1),IDIMC,IUN,
     >               RTVL(IRTRAV),COORD((I-1)*IDIMC+1)) 
        CALL SOMMVE(COORD((I-1)*IDIMC+1),RTVL(IORIG),IDIMC,
     >              COORD((I-1)*IDIMC+1))
   70 CONTINUE
      NBN = NBN2  
C
      ELSE
      CALL DSRAFT(IDE,ITRNOE,NBNMAX,ITRTRI,NBCMAX,
     >            NOETRI,NOEMAX,
     >             NBN,NBE,NCC,NBPMAX,NBEMAX,
C     >                ITRIRG,NRGMAX,IMTREF,NMT,
     >             COORD,IDIMC,
     >             GRDNOE,NGRDMX,
C     >             RTVL(ITBDEN),NDENMX,
     >             MODDEF,MODGEN,NBPNEW,
     >             IADEC,NIADEC,RADEC,NRIDEC,NFADEC,
     >             ITVL(ITRAV),NITMX2,RTVL(IRTRAV),NRTMX2,ITRACE,INODE)
      ENDIF
C
      IF(IERR.LT.0)THEN 
        CALL DSERRE(1,IERR,'GNRAFT',' APPEL DSRAFT')
        GOTO 9999      
      ENDIF     
C     --- POUR LE DEBUG ---
C        ===============
C      CALL SDBTRI(IDE,ITRNOE,NBNMAX,ITRTRI,NBCMAX,NOETRI,
C     >                    NBE,NBN,ITRACE,IERR) 
C      IF( IERR.NE. 0 )THEN
C        CALL DSERRE(1,IERR,'GNRAFT',' APPEL SDBTRI 2')        
C        GOTO 9999
C      ENDIF
C
C         ==================================
C     --- 3.2. AFFECTATION DES REGIONS       ---
C         ==================================
C
      INTMAT(1) = NBE
      IF( NMT.GT.1 )THEN
C      IF(ITRACE.GT.0)
C     >  CALL ESECHA(1,'-> HERITAGE DES REGIONS',' ET RENUMEROTATION')
C
      NBNIFR = 2
C     --- C'EST UN NOUVEAU ITRIRG !!!
      IDE1 = IDE - 1
      NMT1 = NMT
      MAJNOE = 0
      IMTMAX = NMT
      INTMAX = NMT
      CALL DFR2RG(IDE1,ITVL(IFR),NBNIFR,NBIFR,ITVL(IMATFR),NMT1,
     >            IDE,ITRNOE,NBNMAX,ITRTRI,NBCMAX,
     >            NOETRI,NOEMAX,NBE,
     >            MAJNOE,
     >            ITRIRG,NRGMAX,IMTREF,IMTMAX,
     >            INTMAT,INTMAX,NMTCC,    
     >            ITVL(ITRAV),NITMX2,IERR)
C
      IF( IERR .NE. 0 )THEN
        CALL DSERRE(1,IERR,'GNRAFT','APPEL DFR2RG')        
        GO TO 9999
      ENDIF
      ENDIF
C      IF((ITRACE.GT. 0 ).AND.(NMTCC.GT.1))THEN
C        CALL ESEINT(1,
C     >     'NOMBRE DE REGIONS     : ',NMTCC,1)
C        CALL ESEINT(1,
C     >     'REFERENCE DES REGIONS : ',IMTREF,NMTCC)
C        CALL ESEINT(1,
C     >     'NUMEROS DES ELEMENTS  : ',INTMAT,NMTCC)
C      ENDIF
C
      IERR = INODE
C
 9999 END
C
C     *****************************************************************
C     MODULE  : M6 (EXTRACTION D'UN MAILLAGE 2D)
C     FICHIER : M6_REQUETE.F
C     OBJET   : REQUETES SUR UN MAILLAGE POUR LES ELEMENTS FINIS
C
C               LA SYNTAXE D'UNE REQUETE : 
C                  (NOMBRE DE NOEUDS,N1...NM,REF,+/-REGION)
C
C               LE RESULTAT D'UNE REQUETE EST MIS DANS UN ENSEMBLE
C               DE LA FORME : REF, TYPE, ELEMENTS = { (E,I) }
C               AVEC (E,I)  : E = ELEMENT, 
C                             I = ADRESSE RELATIVE DE L'ENTITE DANS 
C                                 L'ELEMENT
C     FONCT.  :
C
C        --- 3 REQUETES ELEMENTAIRES --- 
C
C        RQ2AR : L'ENSEMBLE DES ARETES DE LA FRONTIERE 
C                     DE LA REGION DONNEE ENTRE N1 ET N2
C
C        RQELNO : L'ENSEMBLE DES ELEMENTS DE LA REGION DONNEE 
C                     S'APPUYANT SUR LE NOEUD DONNE
C
C        RQELRG    : LES ELEMENTS DE LA REGION DONNEE (MAT)
C
C     AUTEUR  : O. STAB
C     DATE    : 02.96
C     TESTS   : 
C     MODIFICATIONS :
C      AUTEUR, DATE, OBJET : O.STAB, 17.08.98, AJOUT RQ2ENS
C                            O.STAB, 09.03.05, modif REQ2D, type ensemble cree = -1 
C
C
C     *****************************************************************
C
C
      SUBROUTINE RQ2GAR(N1,N2,MATG,
     >                    ITRNOE,NBNMAX,ITRTRI,NBCMAX,NOETRI,
     >                    IMAT,
     >                    IELEMS,NBELE,NELMAX,IERR)
C     *****************************************************
C     OBJET RQ2GAR : FRONTIERE ENTRE 2 NOEUDS DE LA FRONTIERE 
C             D'UN MATERIAU (2D)
C     EN ENTREE:
C        N1,N2 : LES 2 NOEUDS (SUR LA FRONTIERE DE MAT)
C        MATG : REFERENCE DU MATERIAU 
C                A GAUCHE DE LA FRONTIERE SI POSITIF
C                OU A DROITE SI NEGATIF
C        ITRNOE,...NOETRI,IMAT : LE MAILLAGE
C        IELEMS   : TABLEAU RESULTAT (FRONTIERE)
C        NELMAX : NOMBRE MAXIMUM D'ELEMENTS FRONTIERE =
C                   TAILLE DU TABLEAU / 2                 
C        NNOE  : TABLEAU RESULTAT (LISTE DES NOEUDS)
C        NBNNOEMAX : NOMBRE MAXIMUM DE NOEUD = TAILLE DU TABLEAU  
C
C     EN SORTIE : 
C        IELEMS    : FRONTIERE TRIEE DE N1 VERS N2 (DOUBLET = (E,A))
C                 E = ELEMENT DE MATERIAU "MATG"
C                 A = NUMERO RELATIF DE L'ARETE DE E
C        NBELE  : NOMBRE D'ELEMENT DE LA FRONTIERE
C        IERR   : -1 SI N1 ET N2 NE SONT PAS SUR LA FRONTIERE DE MAT
C     REMARQUES :
C       - LA FRONTIERE D'UN MEME MATERIAU DOIT ETRE REGULIERE
C       EN TOUT NOEUD DE LA FRONTIERE DE MAT IL N'Y A QUE 2 
C       ARETES INCIDENTES 
C     ******************************************************
      INTEGER   N1,N2,MATG
      INTEGER   ITRNOE(*),NBNMAX,ITRTRI(*),NBCMAX,NOETRI(*),IMAT(*)
      INTEGER   IELEMS(*), NBELE,NELMAX
      INTEGER   IERR
C
      INTEGER NI,ITD,IT,IT2,IARD,IAR,IAR2
      INTEGER IDE,ISENS,ISOM,NBNE,IARS
      EXTERNAL STRNBN
      INTEGER  STRNBN
C
      IERR = -1
      NBELE = 0
      IF(( N1.LE. 0 ).OR.( N2.LE. 0 ))GOTO 999
C
      ISENS = 1
      IDE = 2     
      NI = N1
      NBNE = NBCMAX
C
C     --- ON TOURNE AUTOUR DE N1 DANS LE SENS DIRECT ---
C         DES QUE L'ON TROUVE MATG ON S'ARRETE
C
C     === BOUCLE SUR LES NOEUDS ===
C
    5 CALL SESFR2(NI,ISENS,IDE,ITRNOE,NBNMAX,ITRTRI,
     >                     NBCMAX,NOETRI,IT,IAR)
C     --- ERREUR : N1 EST ISOLE ---
      IF( IT.EQ. 0 )GOTO 999
      ITD  = IT
      IARD = IAR
C
C     === BOUCLE SUR LES ARETES D'UN NOEUD ===
C
   10 IF( NBNMAX.NE.3 )NBNE = STRNBN(IT,ITRNOE,NBNMAX)
      IARS = MOD(IAR,NBNE)+1
      CALL SESFR1(IT,IARS,ITRTRI,NBCMAX,IT2,IAR2)
C
C     --- LE MATERIAU EST A GAUCHE ---
C
      IF((IMAT(IT).EQ.MATG).AND.
     >   ((IT2.EQ.0).OR.(IMAT(IT2).NE.MATG)))GOTO 20    
C
C     --- ERREUR : ON A PAS TROUVE "MATG" SUR N1 ---
      IF(( IT2.EQ.ITD ).AND.( IAR2.EQ.IARD ))GOTO 999
      IF(  IT2.EQ. 0 )GOTO 999
C     --- ON PASSE AU SUIVANT ---
      IT  = IT2
      IAR = IAR2
      GOTO 10
C
C     ---- ON A TROUVE UNE ARETE ---
C
   20 NBELE = NBELE+1
      IF( NBELE.LE.NELMAX )THEN
        IELEMS((NBELE-1)*2+1) = IT
        IELEMS((NBELE-1)*2+2) = IARS
      ENDIF
      ISOM = MOD(IARS,NBNE)+1
      NI = ITRNOE((IT-1)*NBNMAX+ISOM)
      IF( NI.EQ.N2 )GOTO 30
      IF( NI.EQ.N1) GOTO 999
      GOTO 5
C
C     --- ON A TROUVE N2 ---
C
   30 IERR = 0
C
      IF((NELMAX.GT.0).AND.(NELMAX.LT.NBELE))IERR=-2
C      
  999 END
C
C
      SUBROUTINE RQ2AR(N1,N2,MAT,
     >       ITRNOE,NBNMAX,ITRTRI,NBCMAX,NOETRI,IMAT,
     >       IELEMS,NBELE,NELMAX,IERR)
C     *****************************************************
C     OBJET RQ2AR : REQUETE SUR LA FRONTIERE DES MAILLES D'ATTRIBUT 
C             DONNE
C     EN ENTREE:
C        ------------ LOCALISATION --------------
C        N1,N2 : LES 2 NOEUDS (SUR LA FRONTIERE DE MAT)
C        MATG : REFERENCE DU MATERIAU 
C                A GAUCHE DE LA FRONTIERE SI POSITIF
C                OU A DROITE SI NEGATIF
C
C        ------------ MAILLAGE  -----------------
C        ITRNOE,...NOETRI,IMAT : LE MAILLAGE
C
C        ------------ L'ENSEMBLE ----------------
C        IDENS    : DIMENSION DES ELEMENTS DE L'ENSEMBLE
C        IELEMS     : TABLEAU DES ELEMENTS DE L'ENSEMBLE
C        NELMAX : NOMBRE MAXIMUM D'ELEMENTS DANS IELEMS  
C
C     EN SORTIE : 
C        IELEMS   : TABLEAU DES ELEMENTS DE L'ENSEMBLE
C        NBELE  : NOMBRE D'ELEMENTS DANS IELEMS  
C        IERR   : -1 
C                 -2 
C                 -3
C     REMARQUES :
C       - LA FRONTIERE D'UN MEME MATERIAU DOIT ETRE REGULIERE
C       EN TOUT NOEUD DE LA FRONTIERE DE MAT IL N'Y A QUE 2 
C       ARETES INCIDENTES 
C     ******************************************************
      INTEGER   N1,N2,MAT
      INTEGER   ITRNOE(*),NBNMAX,ITRTRI(*),NBCMAX,NOETRI(*)
      INTEGER   IMAT(*)
      INTEGER   IELEMS(*),NBELE,NELMAX,IERR
C
      INTEGER ITAMPO,I
C
      IERR = 0
      IF( MAT.LT. 0) THEN
C
C       --- "MATERIAU" A DROITE ---
C          =====================
        CALL RQ2GAR(N2,N1,-MAT,
     >            ITRNOE,NBNMAX,ITRTRI,NBCMAX,NOETRI,IMAT,
     >            IELEMS,NBELE,NELMAX,IERR)
        IF( IERR.NE.0 )GOTO 999
C       --- PERMUTATION : ATTENTION C'EST DES DOUBLETS ---
        DO 10 I=1,(NBELE/2)
          ITAMPO = IELEMS((I-1)*2+1)
          IELEMS((I-1)*2+1) = IELEMS((NBELE-I)*2+1)          
          IELEMS((NBELE-I)*2+1) = ITAMPO
          ITAMPO = IELEMS((I-1)*2+2)
          IELEMS((I-1)*2+2) = IELEMS((NBELE-I)*2+2)          
          IELEMS((NBELE-I)*2+2) = ITAMPO
   10   CONTINUE
C
C       --- "MATERIAU" A GAUCHE ---
C          =====================
      ELSE
        CALL RQ2GAR(N1,N2,MAT,
     >            ITRNOE,NBNMAX,ITRTRI,NBCMAX,NOETRI,IMAT,
     >            IELEMS,NBELE,NELMAX,IERR)
        IF( IERR.NE.0 )GOTO 999
      ENDIF 
C
  999 END
C  
C
C
      SUBROUTINE RQELNO(N1,MAT,
     >       ITRNOE,NBNMAX,ITRTRI,NBCMAX,NOETRI,IMAT,
     >       IELEMS,NBELE,NELMAX,IERR)
C     *****************************************************
C     OBJET RQELNO : REQUETE SUR LES NOEUDS
C             
C     EN ENTREE:
C        N1  : LE NOEUD RECHERCHE
C        MAT : VALEUR DU MATERIAU DES ELEMENTS RECHERCHES         
C
C        ------------ MAILLAGE  -----------------
C        IDE  : DIMENSION DU MAILLAGE
C        ITRNOE,...NOETRI,IMAT : LE MAILLAGE
C
C        ------------ L'ENSEMBLE ----------------
C        IELEMS     : TABLEAU DES ELEMENTS DE L'ENSEMBLE
C        NELMAX : NOMBRE MAXIMUM D'ELEMENTS DANS IELEMS  
C
C     EN SORTIE : 
C        IELEMS   : TABLEAU DE DOUBLETS (E,N)
C                 
C        NBELE  : NOMBRE D'ELEMENTS DANS IELEMS  
C        IERR   : -1 
C                 -2 
C                 -3
C     REMARQUES :
C       - LA FRONTIERE D'UN MEME MATERIAU DOIT ETRE REGULIERE
C       EN TOUT NOEUD DE LA FRONTIERE DE MAT IL N'Y A QUE 2 
C       ARETES INCIDENTES 
C     ******************************************************
      INTEGER   N1,MAT
      INTEGER   ITRNOE(*),NBNMAX,ITRTRI(*),NBCMAX,NOETRI(*)
      INTEGER   IMAT(*)
      INTEGER   IELEMS(*),NBELE,NELMAX,IERR
C
      INTEGER  ISENS,IT,ITD,IAR,IARS,J,NBNE,IDE
      EXTERNAL STRNBN
      INTEGER  STRNBN
C
      ISENS = 1
      NBELE = 0
      IERR  = 0
      IDE = 2
C
C     --- ON TOURNE AUTOUR DE N1 DANS LE SENS DIRECT ---
C         DES QUE L'ON TROUVE MAT ON S'ARRETE
C
    5 CALL SESFR2(N1,ISENS,IDE,ITRNOE,NBNMAX,ITRTRI,
     >                     NBCMAX,NOETRI,IT,IAR)
C     --- ERREUR : N1 EST ISOLE ---
      IF( IT.EQ. 0 )GOTO 999
      ITD  = IT
C        ===================================
C     --- BOUCLE SUR LES ARETES DU NOEUD N1 ---
C        ===================================
   10 IF((MAT.EQ.0).OR.(IMAT(IT).EQ.MAT))THEN
C
C       --- ON AJOUTE UN ELEMENT A L'ENSEMBLE ---
C
        NBELE = NBELE + 1
        IF( NBELE.GE.NELMAX )THEN
          IERR = -2
          GOTO 999
        ENDIF
        IELEMS((NBELE-1)*2+1) = IT
C       --- IL FAUT RETROUVER LE NOEUD N1 ---
        DO 20 J=1,NBNMAX
          IF( ITRNOE((IT-1)*NBNMAX+J).EQ.N1 )
     >       IELEMS((NBELE-1)*2+2) = J
   20   CONTINUE
      ENDIF
C
C     --- ON PASSE AU SUIVANT ---
C
      NBNE = 3
      IF( NBNMAX.NE.3 )NBNE = STRNBN(IT,ITRNOE,NBNMAX)
      IARS = MOD(IAR,NBNE)+1
      CALL SESFR1(IT,IARS,ITRTRI,NBCMAX,IT,IAR)
C
C     --- ERREUR : ON A PAS TROUVE "MAT" SUR N1 ---
      IF(( IT.EQ.ITD ).OR.( IT.EQ. 0 ))GOTO 999
      GOTO 10
C
  999 END
C
C
C
      SUBROUTINE RQELRG(MAT,IMAT,NBE,
     >                   IELEMS,NBELE,NELMAX,IERR)
C     *****************************************************
C     OBJET RQELRG : REQUETES SUR LES ELEMENTS D'UN MAILLAGE D'UN
C             MATERIAU DONNE 
C     EN ENTREE :
C       MAT  : LE MATERIAU SOUHAITE
C       IMAT : TABLEAU DES MATERIAUX DES ELEMENTS
C              IMAT(I) = MATERIAU DE L'ELEMENT I
C       NBE  : NOMBRE D'ELEMENT DU MAILLAGE
C
C       IELEMS : TABLEAU A REMPLIR
C       NELMAX : NOMBRE MAXIMUM DE DOUBLET DANS IELEMS 
C
C     EN SORTIE :
C       IELEMS : TABLEAU DE DOUBLET (E,0) DES ELEMENTS DE
C                  MATERIAU DONNE : IMAT(E) = MAT
C       NBELE    : NOMBRE DE DOUBLETS
C       IERR     : -2, IELEMS TROP PETIT
C     *****************************************************
      INTEGER MAT,IMAT(*),NBE
      INTEGER IELEMS(*),NBELE,NELMAX,IERR
C
      INTEGER J
C
      NBELE = 0
      DO 10 J=1,NBE
        IF( IMAT(J).EQ.MAT )THEN
          NBELE = NBELE + 1
          IF( NBELE.GE.NELMAX )THEN
            IERR =-2
            GOTO 999
          ENDIF
          IELEMS((NBELE-1)*2+1) = J
          IELEMS((NBELE-1)*2+2) = 0
        ENDIF            
   10 CONTINUE
  999 END

C
      SUBROUTINE REQ2D(NOEREQ,MAXRQ,IRGRQ,IRFRQ,NBREQ,
     >       IDE,ITRNOE,NBNMAX,ITRTRI,NBCMAX,NOETRI,NBE,IMAT,
     >       ITVL,
     > IELEMS,MAXELE,IENS,ITYEN,IRFENS,NBENS,IERR )
C     *****************************************************
C     OBJET REQ2D : REQUETES SUR UN MAILLAGE 2D. 
C             SYNTAXE :  (NOEUD...) (+/- MAT) REF
C              
C     EN ENTREE:
C        ---- LES REQUETES ----
C        NOEREQ     : NOEUDS DE CHAQUE REQUETES
C        MAXRQ  : NOMBRE MAXIMUM DE NOEUDS PAR REQUETE    
C        IRGRQ    : MATERIAU ASSOCIE A LA REQUETE        
C        IRFRQ    : REFERENCE DE L'ENSEMBLE ASSOCIE A LA 
C                     REQUETE
C        NBREQ      : NOMBRE DE REQUETES
C        ---- LE MAILLAGE ----
C        ITRNOE,...NOETRI,IMAT : LE MAILLAGE
C
C        ITVL : TABLEAU DE TRAVAIL DE "NBREQ" ENTIERS
C
C     EN SORTIE : 
C        IENS     : ADRESSE DES ENSEMBLES (DANS IELEMS)
C            ADRESSE DU DERNIER ELEMENT DE CHAQUE ENSEMBLE 
C            TAILLE DE IENS <= NBREQ.
C        ITYEN  : TYPE DES ENSEMBLES (FRONTIERE OU ELEMENT)                   
C        IRFENS  : REFERENCE (OU NUMERO) DE L'ENSEMBLE
C                   (C'EST LA REFERENCE DE LA REQUETE).
C        NBENS    : <= NBREQ (LE RESULTAT DE PLUSIEURS REQUETES 
C                   PEUT ETRE MIS DANS UN MEME ENSEMBLE)
C
C        IELEMS : TABLEAU DES ELEMENTS DES ENSEMBLES 
C        MAXELE: TAILLE MAXIMUM DE IELEMS (EN ENTREE)
C
C        IERR   : -1 SI UNE REQUETE EST INCORRECTE
C                 -2 SI IELEMS EST TROP PETIT
C     REMARQUES :
C       - LA FRONTIERE D'UN MEME MATERIAU DOIT ETRE REGULIERE
C       EN TOUT NOEUD DE LA FRONTIERE DE MAT IL N'Y A QUE 2 
C       ARETES INCIDENTES 
C
C       - LES REQUETES SONT TRAITEES DANS L'ORDRE DES REFERENCES
C       CROISSANTES.
C     ******************************************************
      INTEGER   NOEREQ(*),MAXRQ,IRGRQ(*),IRFRQ(*),NBREQ
      INTEGER   IDE,ITRNOE(*),NBNMAX,ITRTRI(*),NBCMAX
      INTEGER   NOETRI(*),NBE,IMAT(*),ITVL(*)
      INTEGER   IELEMS(*), MAXELE
      INTEGER   IENS(*),ITYEN(*),IRFENS(*), NBENS, IERR 
C
      INTEGER   IRFENP,IIENS,I,J,NB,II,NOE(4),ITYPE
      INTEGER   NBELE,NELMAX
      INTEGER   IORDRE
C
      IERR = -3
      IF( IDE.NE.2 )GOTO 999
      IERR = -1
      IF( MAXRQ.GT.2 )GOTO 999
C        =============================================
C     --- 1. TRIER LES REQUETES SUIVANT L'ORDRE DES   ---
C            REFERENCES CROISSANTES
C        =============================================
      IORDRE = 1
      CALL KNUTP(NBREQ,ITVL(IORDRE),IRFRQ)
C        ==========================
C     --- 2. REALISER LES REQUETES ---
C        ==========================
      IRFENP  = 0
      NBENS = 0
      IIENS = 0
      DO 200 I=1,NBREQ
C          ------------------------------    
C       --- 2.1 DEFINITION DE L'ENSEMBLE ---
C          ------------------------------
        II = ITVL(IORDRE+I-1)
C       --- CREATION D'UN ENSEMBLE ---
C          ------------------------
        IF( IRFRQ(II).NE.IRFENP )THEN
          NBENS = NBENS + 1
          IRFENS(NBENS) = IRFRQ(II)
C          ITYEN(NBENS) = 0
          ITYEN(NBENS) = -1
          IRFENP = IRFRQ(II)
        ENDIF
C       --- TYPE DE L'ENSEMBLE ---
C          --------------------
        NB = MAXRQ
        DO 100 J=MAXRQ,1,-1
          NOE(J) =NOEREQ((II-1)*MAXRQ+J)
          IF( NOE(J).EQ.0 ) NB = (J-1)
  100   CONTINUE
        IERR = -1
        GOTO( 110,120,130,140 ) (NB+1)
          CALL DSERRE(1,IERR,'REQ2D',' REQUETE INCONNUE')
          GOTO 999
C         --- RECHERCHE DES MAILLES (2D/3D)---
 110      CONTINUE
          ITYPE = IDE
          GOTO 150
C         --- RECHERCHE DES NOEUDS
 120      CONTINUE
          ITYPE = 0
          GOTO 150
C         --- RECHERCHE DES ARETES ---
 130      CONTINUE
          IF( IDE.LT.2 )THEN
            CALL DSERRE(1,IERR,'REQ2D',' NBR NOEUD > ELEMENTS')
            GOTO 999
          ENDIF
          ITYPE = 1
          GOTO 150
C          --- RECHERCHE DES FACES ---
 140      CONTINUE
          IF(IDE.LT.3)THEN
            CALL DSERRE(1,IERR,'REQ2D',' NBR NOEUD > ELEMENTS')
            GOTO 999
          ENDIF
          ITYPE = 2
          GOTO 150
C
 150    CONTINUE
C       --- ON VERIFIE LES TYPES DES REQUETES --- 
C          -----------------------------------         
C        IF(ITYEN(NBENS).NE.0)THEN
C       creation : -1 (modif 09.03.2005)
        IF(ITYEN(NBENS).NE.-1)THEN
          IF(ITYEN(NBENS).NE.ITYPE)THEN
            CALL DSERRE(1,IERR,'REQ2D',' MELANGE DE TYPE INTERDIT')
            GOTO 999
          ENDIF
        ELSE
          ITYEN(NBENS) = ITYPE
        ENDIF
        IERR = 0
C       IIENS DONNE LE NOMBRE D'ELEMENT DANS IELEMS
        NELMAX = ( MAXELE - IIENS ) / 2
        NBELE = 0
        
C          -----------------------        
C       --- 2.2 REQUETE SOMMET ---
C          -----------------------
        IF( ITYPE.EQ.0 )THEN 
           CALL RQELNO(NOE(1),IRGRQ(II),
     >      ITRNOE,NBNMAX,ITRTRI,NBCMAX,NOETRI,IMAT,
     >      IELEMS((2*IIENS)+1),NBELE,NELMAX,IERR)
        
        ELSE
C          -----------------------        
C       --- 2.3 REQUETE ARETE  ---
C          -----------------------
        IF( IDE.GT.ITYPE )THEN 
          CALL RQ2AR(NOE(1),NOE(2),IRGRQ(II),
     >     ITRNOE,NBNMAX,ITRTRI,NBCMAX,NOETRI,IMAT,
     >     IELEMS((2*IIENS)+1),NBELE,NELMAX,IERR)
C
        ELSE 
C        ---------------------
C     --- 2.4 REQUETE ELEMENT ---
C        ---------------------
        IF( IDE.EQ.ITYPE )THEN
          CALL RQELRG(IRGRQ(II),IMAT,NBE,
     >    IELEMS((2*IIENS)+1),NBELE,NELMAX,IERR)
      ELSE 
        IERR = -1
      ENDIF
      ENDIF
      ENDIF
      IF( IERR.NE. 0 )THEN
        CALL DSERRE(1,IERR,'REQ2D',' APPEL REQUETES ELEMENTAIRES')
        GOTO 999
      ENDIF
      IIENS = IIENS + NBELE
      IENS(NBENS) = IIENS 
  200 CONTINUE
C
  999 END
C      
C
      SUBROUTINE RQ2ENS(IDE,ITRNOE,NBNMAX,NBE,NBN,INTMAT,IREGIO,NMT,
     >                   NOEREQ,NBMXRQ,IMATRQ,IREFRQ,NBREQ,
     >                   IELENS,NBMXEL,IENS,ITYPEN,IREFEN,NBENS,
     >                   ITVL,NITMAX,RTVL,NRTMAX,IERR)
C     **********************************************************************
C     OBJET RQ2ENS : REQUETES SUR UN MAILLAGE 2D
C
C     EN ENTREE   :
C       ------------- LE MAILLAGE ------------------
C       IDE,ITRNOE,NBNMAX,NBE,NBE,INTMAT,IREGIO,NMT
C
C       ------------- LES REQUETES -----------------
C       NOEREQ,NBMXRQ,IMATRQ,IREFRQ,NBREQ
C
C       ---- TABLEAUX DE TRAVAIL --------------------
C       ITVL : TABLEAU D'ENTIERS POUR LES CALCULS
C       NITMAX  : TAILLE DE ITVL
C                   NBE*NBCMAX -> ITRTRI
C                 + NBN        -> NOETRI
C                 + NBE        -> IMAT
C                 + [NBREQ,2*NBN]   -> POUR ITRAV
C                 --------------
C                 (NBCMAX+1)*NBE + NBN*3 -> TOTAL MINIMUM CONSEILLE
C
C     EN SORTIE   :
C       --- DES ENSEMBLES ---------------------------
C       IELENS,NBMXEL,IENS,ITYPEN,IREFEN,NBENS
C       IERR     : CODE D'ERREUR 
C           0  OK
C          -1 SI DONNEES INCORRECTES
C          -2 SI TABLEAUX INSUFFISANTS
C             ITVL TROP PETIT 
C             RTVL TROP PETIT)
C             TROP DE MATERIAUX (>50)
C     **********************************************************************
      INTEGER IDE,ITRNOE(*),NBNMAX,NBE,NBN,INTMAT(*),IREGIO(*),NMT
      INTEGER NOEREQ(*),NBMXRQ,IMATRQ(*),IREFRQ(*),NBREQ
      INTEGER IELENS(*),NBMXEL,IENS(*),ITYPEN(*),IREFEN(*),NBENS
      INTEGER ITVL(*),NITMAX,NRTMAX,IERR
      REAL    RTVL(*)
C     --- VARIABLES INTERNES ---
      INTEGER ITRTRI,NOETRI,ITRAV,NBCMAX,IDIMC,ICOORD
      INTEGER NITMX2,I,NCC,NBNOMX
      INTEGER IMAT
C
C        =========================================
C     --- 2. CREATION DE LA STRUCTURE DE DONNEES  ---
C        =========================================
C
C        =======================
C     --- 2.1. ALLOCATION       ---
C        =======================
C
      NBCMAX = NBNMAX
C
      ICOORD  = 1
      ITRTRI  = 1
      NOETRI  = ITRTRI + (NBE * NBCMAX)
      ITRAV   = NOETRI + NBN
      NITMX2 = NITMAX - ITRAV
      NBNOMX = NBN
C
      IF(NITMX2.LT.0)THEN
        IERR = -2
        CALL DSERRE(1,IERR,'RQ2ENS',
     >                   ' TABLEAUX DE TRAVAIL TROP PETITS')        
        GOTO 999
      ENDIF    
C
      CALL SMAOCR(IDE,ITRNOE,NBE,RTVL(ICOORD),
     >            NBN,IDIMC,
     >            ITRNOE,NBNMAX,ITVL(ITRTRI),
     >            NBCMAX,ITVL(NOETRI),NBNOMX,
     >            ITVL(ITRAV),NITMX2,NCC,IERR)
      IF( IERR.NE.0 )THEN
        CALL DSERRE(1,IERR,'RQ2ENS',' APPEL SMAOCR')        
        GOTO 999
      ENDIF
C        =======================
C     --- TABLEAU DES MATERIAUX ---
C        =======================
      IMAT   = NOETRI + NBN
      CALL  TBIT2V(INTMAT,IREGIO,NMT,ITVL(IMAT),NBE,IERR)      
      IF( IERR.NE.0 )THEN
        CALL DSERRE(1,IERR,'RQ2ENS',' APPEL TBIT2V')        
        GOTO 999
      ENDIF
C      
C        ============================
C     --- 3. REQUETES SUR LE MAILLAGE ---
C        ============================
C     --- REQUETES ---
C        -----------------------
      ITRAV = IMAT + NBE
      CALL REQ2D(NOEREQ,NBMXRQ,IMATRQ,IREFRQ,NBREQ,
     >       IDE,ITRNOE,NBNMAX,
     >       ITVL(ITRTRI),NBCMAX,ITVL(NOETRI),NBE,
     >       ITVL(IMAT),
     >       ITVL(ITRAV),
     > IELENS,NBMXEL,IENS,ITYPEN,IREFEN,NBENS,IERR )
C
      IF( IERR.NE.0 )THEN
        CALL DSERRE(1,IERR,'RQ2ENS',' APPEL REQ2D')        
        GOTO 999
      ENDIF
C
  999 END      
C



C     **********************************************************************
C     MODULE   : 
C     FICHIER  : 3D_UNDEF.F 
C     OBJET    : DECLARATION DES APPELS AU 3D
C     FONCT.   :
C
C     AUTEUR   : O. STAB
C     DATE     : 
C     TESTS    : 
C     MODIFICATIONS :
C        AUTEUR, DATE, OBJET : 
C
C
C     **********************************************************************
      SUBROUTINE SFRI3D_NEW(NN,NBNN,
     >                  IDE,ITRNOE,NBNMAX,ITRTRI,NBCMAX,
     >                  NOETRI,NBE,ITVL,NITMAX,
     >                  IT1,IT2,I1,I2,IERR)
C     *************************************************************
C     OBJET SFRI3D : ELEMENTS SUR LA FACE NN (VOIR SFRIDE)
C        
C     EN ENTREE:
C      NN     :  TABLEAU DES SOMMETS DE L'ELEMENT FRONTIERE
C      NBNN   :  NOMBRE DE SOMMETS
C      IDE    :  DIMENSION DES ELEMENTS DU MAILLAGE
C      NBE    :  NOMBRE D'ELEMENTS DU MAILLAGE
C
C     EN SORTIE: 
C      IT1 :  L'ELEMENT QUI CONTIENT LA FACE NN(1),NN(2),NN(3)
C       I1 :  L'INDICE DE LA FACE DANS IT1
C      IT2 :  L'ELEMENT QUI CONTIENT LA FACE NN(3),NN(2),NN(1)
C       I2 :  L'INDICE DE LA FACE DANS IT1
C     REMARQUE : 3D SEULEMENT 
C                NE PREND PAS EN COMPTE LES FRONTIERES INTERNES
C     *************************************************************
      INTEGER   NN(*),NBNN,IDE,ITRNOE(*),NBNMAX,ITRTRI(*),NBCMAX
      INTEGER   NOETRI(*),NBE,ITVL(*),NITMAX
      INTEGER   IT1,IT2,I1,I2,IERR
C
      IERR = -3
 9999 END
C
      FUNCTION TTVO_AJETER(P1,P2,P3,P4)
C     *****************************************************************
C     *****************************************************************
      REAL TTVO
      REAL P1(*),P2(*),P3(*),P4(*)
C
      TTVO = 0.
 9999 END
C 
      SUBROUTINE TTAJPO(IPT,ITD,ITRNOE,NBNMAX,NBEMAX,ITRTRI,NBCMAX,
     >                    NOETRI,NBE,COORD,SPH,NBSMAX,
     >                    ITVL,IMAX,SZERO,DFRMIN,MODERR,NBTNEW,IERR)
C     **********************************************************************
C     **********************************************************************
      INTEGER    IPT,ITD,NBSMAX,NBTNEW
      INTEGER    ITRNOE(*),NBNMAX,NBEMAX,ITRTRI(*),NBCMAX
      INTEGER    NOETRI(*),NBE,ITVL(*),IMAX,MODERR      
      REAL       SPH(*),COORD(*),SZERO,DFRMIN
      INTEGER    IERR
C 
      IERR = -3
 9999 END
C
       SUBROUTINE SPSPHE(IDIMC,I,ITRI,COORD,SPHERE,ZERO,IERR)
C     **********************************************************************
C     **********************************************************************
      INTEGER ITRI(4),IDIMC,I,IERR
      REAL    COORD(*),SPHERE(4),ZERO
C
      IERR = -3
 9999 END
C
C
      SUBROUTINE STTTEV(IDE,ITRNOE,NBNMAX,ITRTRI,NBCMAX,NOETRI,NOEMAX,
     >          COORD,IDIMC,NBN,NBE,
     >          ITVL,IMAX,RTVL,IRMAX,IERR)
C     *****************************************************************
C     **********************************************************************
      INTEGER IDE,NBE,ITRNOE(*),NBNMAX,ITRTRI(*),NBCMAX
      INTEGER ITVL(*),IMAX,IDIMC,NOETRI(*),NOEMAX,NBN,IRMAX,IERR
      REAL    COORD(*),RTVL(*)
C
      IERR = -3
 9999 END        
C     **********************************************************************
C     MODULE  : 
C     FICHIER : SP_SPH.F
C     OBJET    : GESTION DES SPHERES CIRCONSCRITES (CAS 2D ET 3D)
C     FONCT.   :
C     OBJET SPCREE : CREER LA SPHERE CIRCONSCRITE AU SIMPLEXE
C
C     AUTEUR   : O. STAB 
C     DATE     : 03.95
C     MODIFICATIONS :
C      AUTEUR, DATE, OBJET : O.STAB, 13.11.97, RESTRUCTURATION 
C
C
C     **********************************************************************
C
      SUBROUTINE  SPCREE(IDIMC,ISPH,ITRI,COORD,SPH,ZERO,IERR)
C     **********************************************************************
C     OBJET SPCREE : CREER LA SPHERE CIRCONSCRITE AU SIMPLEXE
C     EN ENTREE :
C        IDIMC : DIMENSION DE L'ESPACE
C        ISPH : NUMERO DU TRIANGLE
C        ITRI : LES SOMMETS DU TRIANGLE
C        COORD: TABLEAU DES COORDONNEES DES POINTS
C        SPH  : TABLEAU DES SPHERES
C        ZERO :
C     EN SORTIE:
C        SPH  : TABLEAU DES SPHERES AUQUEL A ETE AJOUTE CELLE CREEE
C        IERR : CODE D'ERREUR -1 SI LE TRIANGLE EST PLAT
C
C     **********************************************************************
      INTEGER IDIMC
      INTEGER ITRI(*),ISPH,IERR
      REAL    COORD(*),SPH(*),ZERO
C
C      INTEGER  SPCIRC
C      EXTERNAL SPCIRC
C
      IF( IDIMC .EQ. 2 )THEN
C        IERR = SPCIRC(ITRI,COORD,SPH((ISPH-1)*3+1),ZERO)
        CALL SPCERC(IDIMC,ISPH,ITRI,COORD,SPH((ISPH-1)*3+1),ZERO,IERR)
      ELSE
      IF( IDIMC .EQ. 3 )THEN
        CALL SPSPHE(IDIMC,ISPH,ITRI,COORD,SPH((ISPH-1)*4+1),ZERO,IERR)
      ELSE
        IERR = -1
      ENDIF
      ENDIF
      END
C
C     **********************************************************************
C     MODULE   :  (RAFFINEMENT D'UN MAILLAGE TRIANGULAIRE)
C     FICHIER  : D3_DENSDEF.F
C     OBJET    : CALCUL DE LA DENSITE POUR RAFFINER 
C                UNE TRIANGULATION DE DELAUNAY
C     FONCT.   :
C     OBJET DNARMN : LONGUEUR DE L'ARETE LA PLUS COURTE (ARETE,TRIANGLE,TETRA)
C     OBJET DNARET : LONGUEUR DE L'ARETE LA PLUS LONGUE (ARETE,TRIANGLE,TETRA)
C     OBJET DNTSDF : TAILLE SOUHAITE PAR DEFAUT 
C     OBJET DNIDEF : CF DNTSDF - FONCTION PARAMETRE
C     OBJET DNCHPO : TAILLE SOUHAITE / CONCENTRATION CHAMPS DE POINTS
C     OBJET DNVERI : VERIFICATION DES DENSITES DONNEES - A TESTER -
C     OBJET DNCCTB : CALCUL DES DENSITES DONNEES AUX NOEUDS
C
C     AUTEUR   : O. STAB
C     DATE     : 
C     TESTS    : 
C     MODIFICATIONS :
C        AUTEUR, DATE, OBJET :
C
C
C     **********************************************************************
C
C
      SUBROUTINE DNARMN(IDE,NUMP,COORD,IDIMC,DLONGU)
C     *****************************************************************
C     OBJET DNARMN : LONGUEUR DE L'ARETE LA PLUS COURTE 
C     *****************************************************************
      INTEGER  IDE,NUMP(*),IDIMC
      REAL     COORD(*)
      REAL     DLONGU
C
      EXTERNAL XNORVE
      REAL     XNORVE
      REAL V(3),D
      INTEGER I,II
C     ---- BUG_34 : O.STAB 17.10.97, COORD ETAIT DECLARE ENTIER ----
C
      CALL DIFFVE(COORD((NUMP(1)-1)*IDIMC+1),
     >            COORD((NUMP(2)-1)*IDIMC+1),IDIMC,V)
      DLONGU = XNORVE(V,IDIMC)
C     --- CAS D'UNE ARETE ---
      IF( IDE.EQ. 1 )GOTO 9999
      DO 20 I=2,3
        II = MOD(I,3)+1
        CALL DIFFVE(COORD((NUMP(I)-1)*IDIMC+1),
     >              COORD((NUMP(II)-1)*IDIMC+1),IDIMC,V)
        D = XNORVE(V,IDIMC)
        DLONGU = MIN( D, DLONGU )
  20  CONTINUE
C     --- CAS D'UN TRIANGLE ---
      IF( IDE.EQ.2 )GOTO 9999
C     --- CAS D'UN TETRAEDRE ---
      II = 4
      DO 30 I=1,3
          CALL DIFFVE(COORD((NUMP(I)-1)*IDIMC+1),
     >              COORD((NUMP(II)-1)*IDIMC+1),IDIMC,V)
          D = XNORVE(V,IDIMC)
          DLONGU = MIN( D, DLONGU )
  30  CONTINUE
C
 9999 END
C
C
      SUBROUTINE DNARMX(IDE,NUMP,COORD,IDIMC,DLONGU)
C     *****************************************************************
C     OBJET DNARET : LONGUEUR DE L'ARETE LA PLUS LONGUE  
C     *****************************************************************
      INTEGER  IDE,NUMP(*),IDIMC
      REAL     COORD(*)
      REAL     DLONGU
C
      EXTERNAL XNORVE
      REAL     XNORVE
      REAL V(3),D
      INTEGER I,II
C     ---- BUG_34 : O.STAB 17.10.97, COORD ETAIT DECLARE ENTIER ----
C
      CALL DIFFVE(COORD((NUMP(1)-1)*IDIMC+1),
     >            COORD((NUMP(2)-1)*IDIMC+1),IDIMC,V)
      DLONGU = XNORVE(V,IDIMC)
C     --- CAS D'UNE ARETE ---
      IF( IDE.EQ. 1 )GOTO 9999
      DO 20 I=2,3
        II = MOD(I,3)+1
        CALL DIFFVE(COORD((NUMP(I)-1)*IDIMC+1),
     >              COORD((NUMP(II)-1)*IDIMC+1),IDIMC,V)
        D = XNORVE(V,IDIMC)
        DLONGU = MAX( D, DLONGU )
  20  CONTINUE
C     --- CAS D'UN TRIANGLE ---
      IF( IDE.EQ.2 )GOTO 9999
C     --- CAS D'UN TETRAEDRE ---
        II = 4
        DO 30 I=1,3
          CALL DIFFVE(COORD((NUMP(I)-1)*IDIMC+1),
     >              COORD((NUMP(II)-1)*IDIMC+1),IDIMC,V)
          D = XNORVE(V,IDIMC)
          DLONGU = MAX( D, DLONGU )
  30    CONTINUE
C
 9999 END
C
C
C
      SUBROUTINE DNTSDF(NUMP,IDIMC,COORD,VDIA,COEF,TS,IERR)
C     *****************************************************************
C     OBJET DNTSDF : TAILLE SOUHAITE PAR DEFAUT 
C               (LA TAILLE SOUHAITE EST EVALUEE AU CENTRE D'UNE BOULE)
C     EN ENTREE :
C         VDIA    : LE VECTEUR DIAMETRE PARTANT DE XPC
C         IDIMC   : DIMENSION DE L'ESPACE
C     EN SORTIE :
C         TS      : TAILLE SOUHAITE POUR LE TRIANGLE
C                   = LONGUEUR DE SA PLUS PETITE ARETE
C         COEF    : TS / RC
C                   RC EST LE RAYON DU CERCLE CIRCONSCRIT
C                   PLUS COEF EST PETIT PLUS ON RAFFINE
C         IERR    : CODE D'ERREUR 0 SI OK,
C                   -1 SI LE RAYON CIRCONSCRIT EST NUL
C     NIVEAU : FICHIER
C     *****************************************************************
      INTEGER    NUMP(*),IDIMC
      REAL       COORD(*)
      REAL       VDIA(*),COEF,TS
      INTEGER    IERR
C
      INTEGER  IDE
      REAL     DMIN,DIAM2,RC
      EXTERNAL XNORVE,SCALVE,NULLVE
      REAL     XNORVE,SCALVE
      INTEGER  NULLVE
C     
      IERR = -1 
      IDE  = IDIMC
      CALL DNARMN(IDE,NUMP,COORD,IDIMC,DMIN)
      DIAM2 = SCALVE(VDIA,VDIA,IDIMC)
      RC    = SQRT(DIAM2) / 2.0
C      PRINT *,'DANS DNIDEF : RC = ',RC
      IF( NULLVE(RC,1) .NE. 0 )GOTO 9999
      COEF = DMIN / RC
      TS = DMIN
C      PRINT *,'DANS DNIDEF : COEF = ',COEF
C      PRINT *,'DANS DNIDEF : TS = ',TS
      IERR = 0
 9999 END
C
C
C
      SUBROUTINE DNIDEF(IT,ITRNOE,NBNMAX,ITRTRI,NBCMAX,
     >            COORD,IDIMC,SPH,NBSMAX,ITAB,RTAB,COEF,TS,IERR)
C     ****************************************************************
C     OBJET DNIDEF : CF DNTSDF - FONCTION PARAMETRE
C     EN ENTREE :
C         --------- L'ELEMENT A RAFFINER -------------------
C         IT   : NUMERO DE L'ELEMENT A RAFFINER
C         ITRNOE,NBNMAX,ITRTRI,NBCMAX : LE MAILLAGE
C         COORD,IDIMC : COORDONNEES DANS L'ESPACE DE DIMENSION IDIMC
C         SPH,NBSMAX  : VECTEUR DIAMETRE DES SPHERES CIRCONSCRITES
C         --------- LE POINT DE CONCENTRATION ------------
C         ITAB() , RTAB()  : INUTILISES
C     EN SORTIE :
C         TS      : TAILLE SOUHAITE POUR L'ELEMENT IT 
C                   LONGUEUR DE SA PLUS PETITE ARETE
C         COEF    : TS / RC
C                   RC EST LE RAYON DU CERCLE CIRCONSCRIT
C                   PLUS COEF EST PETIT PLUS ON RAFFINE
C         IERR    : CODE D'ERREUR 0 SI OK,
C                   -1 SI LE RAYON CIRCONSCRIT A IT EST NUL
C     NIVEAU : MODULE
C     ****************************************************************
      REAL      COORD(*),SPH(*),COEF,TS
      INTEGER   IT,ITRNOE(*),NBNMAX,ITRTRI(*),NBCMAX,NBSMAX
      INTEGER   IDIMC,ITAB(*)
      REAL      RTAB(*)
      INTEGER   IERR
C
      CALL DNTSDF(ITRNOE((IT-1)*NBNMAX+1),IDIMC,COORD,
     >            SPH((IT-1)*NBSMAX+1),COEF,TS,IERR)
C   
 9999 END
C
      SUBROUTINE DNCHPO(IT,ITRNOE,NBNMAX,ITRTRI,NBCMAX,
     >            COORD,IDIMC,SPH,NBSMAX,ITAB,RTAB,COEF,TS,IERR)
C     ****************************************************************
C     OBJET DNCHPO : TAILLE SOUHAITE A L'ELEMENT / CHAMPS DE VALEURS
C                    FONCTION PARAMETRE 
C
C     EN ENTREE :
C         --------- L'ELEMENT A RAFFINER -------------------
C         IT   : NUMERO DE L'ELEMENT A RAFFINER
C         ITRNOE,NBNMAX,ITRTRI,NBCMAX : LE MAILLAGE
C         ITRTRI,NBCMAX (INUTILISES)
C         COORD,IDIMC : COORDONNEES DANS L'ESPACE DE DIMENSION IDIMC
C         SPH,NBSMAX  : VECTEUR DIAMETRE DES SPHERES CIRCONSCRITES
C         RTAB(1)     :  TAILLE SOUHAITEE AU NOEUD 1 
C         RTAB(2)     : TAILLE SOUHAITEE AU NOEUD 2
C         RTAB(3...)  : ....
C       
C     EN SORTIE :
C         TS      : TAILLE SOUHAITE POUR L'ELEMENT IT
C                   ELLE EST DONNE PAR LA CONCENTRATION (ITAB,RTAB)
C         COEF    : A * TS /  RC (RAYON DU CERCLE CIRCONSCRIT A IT)
C                   "A" EST TEL QUE 0 <= COEF <=1
C                   PLUS COEF EST PETIT PLUS ON RAFFINE
C         IERR    : CODE D'ERREUR 0 SI OK, 
C                   -1 SI TAILLE SOUHAITE EST NEGATIVE
C                      OU SI LE RAYON CIRCONSCRIT EST NUL 
C
C     NIVEAU : INTERFACE UTILISATEUR    
C     ****************************************************************
      REAL      COORD(*),SPH(*),COEF,TS
      INTEGER   IT,ITRNOE(*),NBNMAX,ITRTRI(*),NBCMAX,NBSMAX
      INTEGER   IDIMC,ITAB(*)
      REAL      RTAB(*)
      INTEGER   IERR
C
      REAL     DMAX,TSD,TSP,ZERO
      INTEGER  I,J,IMOY,NBNE,IDE
      EXTERNAL XNORVE
      REAL     XNORVE
      INTEGER  STRNBN 
      EXTERNAL STRNBN
      PARAMETER (ZERO = 1.E-05)
C
      IMOY = 1
C     ---- ATTENTION MARCHE POUR DES SIMPLEXES SEULEMENT ---
C      NBNE = IDIMC+1
      NBNE = STRNBN(IT,ITRNOE,NBNMAX)
      IDE = NBNE - 1
      GOTO(100,200,300,400,500) IMOY
C
C     ---- MOYENNE ARITHMETIQUE ----
C
  100 CONTINUE
      TS = 0.0
      DO 110 I=1,NBNE
        TS = RTAB(ITRNOE((IT-1)*NBNMAX+I)) + TS
  110 CONTINUE
      TS = TS / NBNE
      GOTO 1000
C
C     ---- MOYENNE GEOMETRIQUE ----
C
  200 CONTINUE
      TS = 1.0
      DO 210 I=1,NBNE
C        PRINT *,' TS(SOMMET) = ',RTAB(ITRNOE((IT-1)*NBNMAX+I))
        TS = RTAB(ITRNOE((IT-1)*NBNMAX+I)) * TS
  210 CONTINUE
C     ---- CALCUL APPROCHE DE LA RACINE NIEME :
      TSP = TS
      TS = TS**(1.0/NBNE)
C      TS = 0.43429 * EXP(LOG(TS)/(NBNE*0.43429))
C      PRINT *,'RACINE ',NBNE,' IEME DE ',TSP,' = ',TS
C      PRINT *,'TSP = TS^3 ',TSP,' = ',(TS*TS*TS)
      GOTO 1000
C
C     ---- MOYENNE HARMONIQUE ----
C
  300 CONTINUE
      TS = 1.0
      DO 310 I=1,NBNE
        TS = RTAB(ITRNOE((IT-1)*NBNMAX+I)) * TS
  310 CONTINUE
      TSD = 0.0
      DO 330 I=1,NBNE
      TSP = 1.0
      DO 320 J=1,NBNE
      IF( I.NE.J )
     >   TSP = RTAB(ITRNOE((IT-1)*NBNMAX+J)) * TSP
  320 CONTINUE
      TSD = TSD + TSP
  330 CONTINUE
      TS = NBNE * TS /  TSD
      GOTO 1000
C
C     ---- MOYENNE DES CARRES ----
C
  400 CONTINUE
      TS = 0.0
      DO 410 I=1,NBNE
        TS = RTAB(ITRNOE((IT-1)*NBNMAX+I))**2 + TS
  410 CONTINUE
      TS = (TS / NBNE)**0.5
      GOTO 1000
C
C     ---- MOYENNE DES CUBES ----
C
  500 CONTINUE
      TS = 0.0
      DO 510 I=1,NBNE
        TS = RTAB(ITRNOE((IT-1)*NBNMAX+I))**3 + TS
  510 CONTINUE
      TS = (TS / NBNE)**(1.0/3.0)
      GOTO 1000
C
 1000 CONTINUE
      CALL DNARMX(IDE,ITRNOE((IT-1)*NBNMAX+1),COORD,IDIMC,DMAX)
C
      IF( DMAX.LE.ZERO )THEN
        IERR = -1
        CALL DSERRE(1,IERR,'DNCHPO','ARETE DE LONGUEUR NULLE')
        GOTO 9999
      ENDIF      
      COEF = TS / DMAX
      IERR = 0
C      WRITE (6,*) 'TS = ',TS,
C     >            ' DMAX = ',DMAX,' COEF = ',COEF
C
 9999 END
C
      SUBROUTINE DNCCTB(IMODE,IDE,ITRNOE,NBNMAX,NBE,ITRTRI,NBCMAX,
     >                 FADEC,ITAB,NIADEC,RTAB,IRADEC,NFADEC,
     >                 COORD,IDIMC,NBN,RTBDEN,IERR)
C     **********************************************************************
C     OBJET DNCCTB : CALCUL DES DENSITES DONNEES AUX NOEUDS
C     EN ENTREE :
C         --------- LE MAILLAGE -------------------
C         ITRNOE,NBNMAX,ITRTRI,NBCMAX : LE MAILLAGE
C         COORD,IDIMC : COORDONNEES DANS L'ESPACE DE DIMENSION IDIMC
C       ---- DEFINITION DU RAFFINEMENT --------------
C       FADEC    :
C       ITAB((I-1)*NIADEC+1) : PARAMETRES ENTIERS DU IEME RAFFINEMENT
C       NIADEC  : NOMBRE MAX. DE PARAMETRES ENTIERS
C       RTAB((I-1)*NIADEC+1) : PARAMETRES REELS DU IEME RAFFINEMENT
C       IRADEC  : NOMBRE MAX. DE PARAMETRES REELS
C       NFADEC  : NOMBRE DE RAFFINEMENTS
C
C     EN SORTIE :
C         RTBDEN  : TABLEAU DES DENSITES AUX NOEUDS (>= NBN)
C         IERR    : CODE D'ERREUR 0 SI OK,
C                   -1 SI DENSITE LA EST INCORRECTE
C
C     REMARQUE : ON TESTE QUE LA DENSITE AUX POINTS > 0.0
C     **********************************************************************
      REAL      COORD(*)
      INTEGER   IMODE,IDE,ITRNOE(*),NBE,NBN,NBNMAX
      INTEGER   ITRTRI(*),NBCMAX,IDIMC
      INTEGER   ITAB(*),NFADEC,NIADEC,IRADEC
      REAL      RTAB(*),RTBDEN(*)
      EXTERNAL   FADEC
      INTEGER   IERR
C
      REAL    ZERO,REAMAX,DLONGU,DISTAN,TS
      REAL    COEF,VDIA(3)
      INTEGER INO,IEL,I
C
      ZERO = 1.E-05
      REAMAX = 1.E+38
C      VDIA(1) = ZERO
C      VDIA(2) = ZERO
C      VDIA(3) = ZERO
C      PRINT *,'IMODE = ',IMODE
      GOTO( 100,200,300,400 ) IMODE
C
C     ---- TS = ARETE LA PLUS PETITE ----
C
  100 CONTINUE
C     ------- PAS DE DEFINITION : LA PLUS PETITE ARETE !  ---------
      DO 105 INO=1,NBN
        RTBDEN(INO) = REAMAX
 105  CONTINUE
      DO 110 IEL=1,NBE
         CALL DNARMN(IDE,ITRNOE((IEL-1)*NBNMAX+1),COORD,IDIMC,DLONGU)
         IF( DLONGU.LT.ZERO )THEN
           IERR = -1
           CALL DSERRE(1,IERR,'DNCCTB','DENSITE NEGATIVE OU NULLE !')
C           CALL ESEINT(1,' ELEMENT PLAT = ',IEL,1)
           GOTO 9999
         ENDIF
         DO 107 I=1,(IDE+1)
           INO = ITRNOE((IEL-1)*NBNMAX+I) 
           RTBDEN(INO) = MIN(DLONGU,RTBDEN(INO))
 107     CONTINUE
  110 CONTINUE
      GOTO 500
C
C     ---- CONCENTRATIONS PONCTUELLES ET LINEIQUES ----
C
  200 CONTINUE
      IF(IDE.EQ.3) THEN
        IERR = -3
        CALL DSERRE(1,IERR,'DNCCTB','N EXISTE PAS EN 3D')
        GOTO 9999
      ENDIF
      DO 220 INO=1,NBN
C      PRINT *,' CALCUL DE TS POUR LE NOEUD ',INO
      RTBDEN(INO) = REAMAX
      DO 210 I=1,NFADEC
C        UN POINT N'EST PAS UN ELEMENT !!!
C        BUG 
C         CALL D2SUI(VDIA,VDIA,VDIA,
C     >                  COORD((INO-1)*IDIMC+1),VDIA,IDIMC,
C     >                  ITAB((I-1)*NIADEC+1),RTAB((I-1)*IRADEC+2),
C     >                  RTAB((I-1)*IRADEC+1),
C     >                  ITAB((I-1)*NIADEC+2),
C     >                  RTAB((I-1)*IRADEC+3),COEF,TS,IERR)
      CALL DIPOOB(IDIMC,COORD((INO-1)*IDIMC+1),
     >            ITAB((I-1)*NIADEC+2),RTAB((I-1)*IRADEC+3),
     >            DISTAN,IERR)
C     >            ITYPO,ROBJET,DBARYC,IERR)
      CALL SCSUPO(ITAB((I-1)*NIADEC+1),RTAB((I-1)*IRADEC+2),
     >            RTAB((I-1)*IRADEC+1),DISTAN,TS)
C      CALL SCSUPO(ITYPS,TSP,RSG,DBARYC,TSBARY)
C         PRINT *,' POUR DENSITE ',I,' LA DENSITE = ',TS
         IF( IERR.NE. 0 )THEN
C           CALL DSERRE(1,IERR,'DNCCTB','APPEL D2SUI')
           CALL DSERRE(1,IERR,'DNCCTB','APPEL DIPOOB')
           CALL DSERRE(1,IERR,'DNCCTB','APPEL D2SUI')
           CALL DSERRE(1,IERR,'DNCCTB','CALCUL DE LA DENSITE !')
C           CALL ESEINT(1,' DENSITE = ',I,1)
C           CALL ESEINT(1,' AU NOEUD = ',INO,1)
         ENDIF
         RTBDEN(INO) = MIN(TS,RTBDEN(INO))
  210   CONTINUE  
  220 CONTINUE  
      GOTO 500
C     ---- CONCENTRATION NODALES ----
  300 CONTINUE
      DO 310 INO=1,NBN
         RTBDEN(INO) = RTAB(INO)
         IF( RTAB(INO).LT.ZERO )THEN
           IERR = -1
           CALL DSERRE(1,IERR,'DNCCTB','DENSITE NEGATIVE OU NULLE !')
C           CALL ESEINT(1,' DENSITE DU NOEUD = ',INO,1)
           GOTO 9999
         ENDIF
  310 CONTINUE
      GOTO 500
C     ---- CONCENTRATION ALEATOIRE ----
  400 CONTINUE
      IERR = -3
      CALL DSERRE(1,IERR,'DNCCTB','DENSITE ALEATOIRE')
      GOTO 9999      
      GOTO 500
C     ---- ----
  500 CONTINUE
      DO 510 INO=1,NBN
         IF( RTBDEN(INO).LT.ZERO )THEN
           IERR = -1
           CALL DSERRE(1,IERR,'DNCCTB','DENSITE NEGATIVE OU NULLE !')
C           CALL ESEINT(1,' DENSITE AU NOEUD = ',INO,1)
           GOTO 9999
         ENDIF
  510 CONTINUE
C
      IERR = 0   
 9999 END       
C

C     **********************************************************************
C     MODULE   : 
C     FICHIER  : rf_raf3d.f
C     OBJET    : RAFFINEMENT D'UNE TRIANGULATION DE DELAUNAY 2D et 3D
C     FONCT.   :
C       RFRAFF : RAFFINE UN MAILLAGE TRIANGULAIRE 2D et 3D
C
C     FONCT. LOCALES   :
C     OBJET SUGMOY : CALCULE LA VALEUR QUI MINIMISE (pas teste)
C     OBJET SUTSNO : CALCULE LA VALEUR EN UN NOEUD POUR MINIMISER (LOCAL)
C     OBJET SXNOVO : RENVOI LES NOEUDS VOISINS D'UN NOEUD(SIMPLEXE) (LOCAL)
C     OBJET RFNOTS : RENVOI LA TS AU NOEUD A PARTIR DES TS DES KPPV (LOCAL)
C     OBJET RFRECH : RECHERCHE DE L'ELEMENT A RAFINER (LOCAL)
C     OBJET RFITER : RAFFINE ITERATIVEMENT UN MAILLAGE TRIANGULAIRE (LOCAL)
C
C     AUTEUR   : O. STAB
C     DATE     : 
C     TESTS    : 
C     MODIFICATIONS :
C        AUTEUR, DATE, OBJET : 31.01.05 fusion avec tampo.f (RFNOTS... )
C
C
C     **********************************************************************

C

      SUBROUTINE SUGMOY(DISTV,VALV,NBV,VALNO)
C     *****************************************************************
C     OBJET SUGMOY : CALCULE LA VALEUR QUI MINIMISE (pas teste)
C     LA PROGRESSION GEOMETRIQUES DES VALEURS DES KPPV (CONNECTE)
C     pas testee !!
C     *****************************************************************
      REAL    DISTV(*),VALV(*)
      INTEGER NBV
      REAL    VALNO
C
      REAL SOMNUM,SOMDEN
      INTEGER I
C
      SOMNUM = 0
      SOMDEN = 0    
      DO 50 I=1,NBV
        SOMNUM = SOMNUM + (VALV(I)/DISTV(I))
        SOMDEN = SOMDEN + (1.0/DISTV(I))
 50   CONTINUE
      VALNO = SOMNUM / SOMDEN
      END
C
C
      SUBROUTINE SUTSNO(INODE,ITVOIS,NBVOIS,COORD,IDIMC,TVALVO,NBVAL,
     >                  VALNO,IERR)
C     *****************************************************************
C     OBJET SUTSNO : CALCULE LA VALEUR EN UN NOEUD POUR MINIMISER (LOCAL)
C           LA PROGRESSION GEOMETRIQUES DES VALEURS DES KPPV (CONNECTE)
C
C     EN ENTREE :
C        INODE : LE NOEUD DONT ON CHERCHE LA VALEUR (VALNO)
C        ITVOIS,NBVOIS : TABLEAU DES NOEUDS VOISINS
C        COORD,IDIMC : TABLEAU DES COORDONNEES
C        TVALVO,NBVAL: TABLEAU DES GRANDEURS
C
C     EN SORTIE : 
C        VALNO : LA VALEUR AU NOEUD (INODE)
C
C     REMARQUE : DANS LE CAS D'UN POINT CONFONDU AVEC INODE, CE DERNIER
C                PREND LA VALEUR (INFLUENCE INFINIE)
C     *****************************************************************
      INTEGER INODE,ITVOIS(*),NBVOIS,IDIMC,NBVAL
      REAL    COORD(*),TVALVO(*)
      REAL    VALNO
      INTEGER IERR
C
      REAL    DISTV,SOMNUM,SOMDEN
      INTEGER IVOIS,I
      EXTERNAL DISPP
      REAL     DISPP
C
      COMMON /CGEPSI/XYZHUG,XYZMIN,XYZEPS
      REAL   XYZHUG,XYZMIN,XYZEPS
C
      IF(NBVOIS.LE.0)THEN
        IERR = -1
        GOTO 9999
      ENDIF
      IERR = 0
      SOMNUM = 0
      SOMDEN = 0    
       DO 50 I=1,NBVOIS
        IVOIS = ITVOIS(I)
        DISTV = DISPP(IDIMC,COORD((INODE-1)*IDIMC+1),
     >                      COORD((IVOIS-1)*IDIMC+1))
        IF(DISTV.LE.XYZEPS)THEN
          VALNO = TVALVO(IVOIS)
          GOTO 9999
        ELSE 
          DISTV = 1.0 / DISTV
        ENDIF
        SOMNUM = SOMNUM + (TVALVO(IVOIS) * DISTV)
        SOMDEN = SOMDEN + DISTV
 50   CONTINUE
      VALNO = SOMNUM / SOMDEN
 9999 CONTINUE
      END
C 
C
      SUBROUTINE SXNOVO(INOEUD,NBTEL,ITRNOE,NBNMAX,ITRTRI,NBCMAX,
     >                  ITVL,NITMAX,
     >                  ITVOIS,NBVMAX,NBVOIS,IERR)
C     *****************************************************************
C     OBJET SXNOVO : RENVOI LES NOEUDS VOISINS D'UN NOEUD(SIMPLEXE) (LOCAL)
C
C     EN ENTREE :
C        INOEUD : LE NOEUD DONT ON RECHERCHE LES VOISINS
C        NBTEL  : LES ELEMENTS INCIDENTS A INOEUD
C        ITRNOE,NBNMAX,ITRTRI,NBCMAX : LE MAILLAGE
C        ITVL,NITMAX: TABLEAUX DE TRAVAIL
C
C        NBVMAX : TAILLE DU TABLEAU ITVOIS
C         NBVMAX DOIT ETRE >= 2* NBVOIS
C         SI NBVMAX < 0 : DANS NBVOIS ON RENVOI LA TAILLE NECESSAIRE A NBVMAX
C         SI NBVMAX = 0 : DANS NBVOIS ON RENVOI LE NOMBRE DE VOISINS
C         SI NBVMAX > 0 ET NBVOIS <= NBVMAX : LE TABLEAU ITVOIS EST REMPLI
C                       ET NBVOIS >  NBVMAX : ERREUR DE MEMEOIRE (IERR = -2)
C
C     EN SORTIE :
C         ITVOIS : LE TABLEAU DES NOEUD VOISINS (SI NBVMAX > NBVOIS)
C         NBVOIS : LE NOMBRE DE NOEUDS VOISINS (SI NBVMAX >= 0)
C                  LA TAILLE NECESSAIRE A ITVOIS (C.A.D NBVMAX) SI NBVMAX <0
C
C     LIMITATIONS :
C         1.FONCTIONNE SUR LES SIMPLEXES
C         2.LES ELEMENTS INCIDENTS SONT LES NBTNEW PREMIERS (DU MAILLAGE)
C     A FAIRE : LEVER LA LIMITATION 2
C     *****************************************************************
      INTEGER INOEUD,NBTEL
      INTEGER ITRNOE(*),NBNMAX,ITRTRI(*),NBCMAX
      INTEGER ITVL(*),NITMAX
      INTEGER ITVOIS(*),NBVMAX,NBVOIS,IERR
C
      INTEGER IVOIS,NBV,ITRAV,I,J      
C         ------------------------------------
C     ---- LES ELEMENTS CONTENANT LE NOEUD     -----
C         ------------------------------------
*     pour generaliser la procedure il faudra lever la limitation : elements consecutifs !
C         ------------------------------------
C     ---- EXTRACTION DES NOEUDS VOISINS       -----
C         ------------------------------------
*     pour tester la memoire :
      ITVL(NITMAX-1) = 0
*
      IERR = 0
      IVOIS = 1
      NBV = 0
      DO 30 I=1,NBTEL
        DO 10 J=1,NBNMAX 
*        on prend tous les noeuds sauf INOEUD (simplexes)
         IF(ITRNOE((I-1)*NBNMAX+J).NE.INOEUD)THEN
           NBV = NBV + 1
           IF( NBV.GT.NITMAX )THEN
             IERR = -2
             GOTO 9999
           ELSE     
             ITVL(IVOIS + NBV - 1)= ITRNOE((I-1)*NBNMAX+J)
           ENDIF
         ENDIF
 10     CONTINUE
 30   CONTINUE
      IF(NBVMAX.LT.0)GOTO 9999
C         ------------------------------------
C     ---- ON TRIE ET ON SUPPRIME LES DOUBLONS ----
C         ------------------------------------
      ITRAV = IVOIS + NBV
      IF( (NITMAX - ITRAV).LT.NBV )THEN
        IERR = -2
        GOTO 9999
      ENDIF
C
      IF( NBVMAX.EQ.0)THEN
C       --- ON NE FAIT QUE COMPTER ---
        CALL  TBVTAB(ITVL(IVOIS),NBV,ITVL(ITRAV),
     >               ITVL(IVOIS),NBVOIS,NBVMAX,IERR)
      ELSE
C       --- ON REMPLI LE TABLEAU : ITVOIS ---
        CALL  TBVTAB(ITVL(IVOIS),NBV,ITVL(ITRAV),
     >               ITVOIS,NBVOIS,NBVMAX,IERR)
      ENDIF
*     on a maintenant les noeuds distincts dans ITVOIS
 9999 CONTINUE
      END
C
C
C
C
C
      SUBROUTINE RFNOTS(INOEUD,NBTEL,ITRNOE,NBNMAX,ITRTRI,NBCMAX,
     >            COORD,IDIMC,TVALNO,NBVAL,
     >            ITVL,NITMAX,
     >            VALNO,IERR)
C     *****************************************************************
C     OBJET RFNOTS : RENVOI LA TS AU NOEUD A PARTIR DES TS DES KPPV (LOCAL)
C     appele dans rf_raf3d.f
C     *****************************************************************
      INTEGER INOEUD,NBTEL
      INTEGER ITRNOE(*),NBNMAX,ITRTRI(*),NBCMAX,ITVL(*),NITMAX
      REAL    COORD(*),TVALNO(*)
      INTEGER IDIMC,NBVAL
      REAL    VALNO
      INTEGER IERR
C
      INTEGER ITVOIS,NBVOIS,NBVMAX,NTVMAX
C
*     pour tester la memoire :
      ITVL(NITMAX-1) = 0
*
      ITVOIS = NITMAX / 2
      NBVOIS = 0
      NBVMAX = NITMAX / 2
      NTVMAX = NITMAX - NBVMAX
      CALL SXNOVO(INOEUD,NBTEL,ITRNOE,NBNMAX,ITRTRI,NBCMAX,
     >                  ITVL,NTVMAX,
     >                  ITVL(ITVOIS),NBVMAX,NBVOIS,IERR)
      IF(IERR.NE.0)THEN
        CALL DSERRE(1,IERR,' ','APPEL SXNOVO : CALCUL DES VOISINS')
        GOTO 9999
      ENDIF
      IF(NBVOIS.EQ.0)THEN
        IERR = -1
        CALL DSERRE(1,IERR,' ','PAS DE NOEUD VOISIN!')
        GOTO 9999
      ENDIF
      CALL SUTSNO(INOEUD,ITVL(ITVOIS),NBVOIS,COORD,IDIMC,TVALNO,NBVAL,
     >                  VALNO,IERR)
      IF(IERR.NE.0)THEN
        CALL DSERRE(1,IERR,' ','APPEL SUTSNO : CALCUL DE LA TS')
        GOTO 9999
      ENDIF
 9999 CONTINUE
      END
C
C
C
      SUBROUTINE RFRECH(IDIMC,ITRNOE,NBNMAX,NBE,COORD,SPH,
     >                      NBSMAX,IT,XPT,COEF,IERR)
C     **********************************************************************
C     OBJET RFRECH : RECHERCHE DE L'ELEMENT A RAFINER (LOCAL)
C     EN ENTREE  :
C       COORD          : COORDONNEES DES POINTS 
C       IDIMC          : DIMENSION DE L'ESPACE
C       ITRNOE,NBNMAX  : SOMMETS DES ELEMENTS
C       NBE            : NOMBRE D'ELEMENTS
C       SPH,NBSMAX     : CERCLES CIRCONSCRITS AUX ELEMENTS
C
C     EN SORTIE  : 
C       IT             : L'ELEMENT A REFFINER
C       XPT            : LE POINT A AJOUTER
C       COEF           : LA VALEUR DU RAFFINEMENT [0-1]
C                        PLUS COEF EST PETIT PLUS ON RAFFINE
C       IERR           : CODE D'ERREUR (INUTILISE)
C     **********************************************************************
      REAL       COORD(*),SPH(*)
      INTEGER    IDIMC,ITRNOE(*),NBNMAX,NBE,NBSMAX,IT,IERR
      REAL       COEF,XPT(*)
C
      INTEGER  I,NUMP3,INDICE
      REAL     CLRC,LRCMIN,XDEMI
C
      INDICE = IDIMC + 1
      LRCMIN = 1.0
      XDEMI = 0.5
      IT = 0
C     --- RECHERCHE DU PLUS PETIT DIAMETRE ---
      DO 10 I=1,NBE 
        CLRC = SPH((I-1)*NBSMAX+INDICE)
        IF( CLRC .LT. LRCMIN )THEN
          IT = I
          LRCMIN = CLRC 
        ENDIF
   10 CONTINUE
C
      IF( IT.EQ. 0 )THEN
        COEF = 1.
        GOTO 9999
      ENDIF
C     --- CENTRE = PT3 + SPH / 2 ------------------
      CALL MUSCVE(SPH((IT-1)*NBSMAX+1),XDEMI,IDIMC,XPT)
      NUMP3 = ITRNOE((IT-1)*NBNMAX+INDICE) 
      CALL SOMMVE(COORD((NUMP3-1)*IDIMC+1),XPT,IDIMC,XPT)
C
      COEF = LRCMIN
 9999 END
C
      SUBROUTINE RFITER(FADEC,ITAB,RTAB,IMODE,
     >          ITRNOE,NBNMAX,ITRTRI,NBCMAX,NOETRI,NOEMAX,
     >          COORD,IDIMC,NBN,NBE,NBPMAX,NBEMAX,
     >          ITVL,IMAX,RTVL,IRMAX,NBENEW,IERR)
C     *****************************************************************
C     OBJET RFITER : RAFFINE ITERATIVEMENT UN MAILLAGE TRIANGULAIRE (LOCAL)
C     EN ENTREE 
C       --------- LE DECOUPAGE -------------------
C       FADEC     : FONCTION D'EVALUATION DU DECOUPAGE ET DE
C                   CALCUL D'UN NOEUD, ELLE A LE FORMAT SUIVANT :
C   
C           FADEC(IT,ITRNOE,NBNMAX,ITRTRI,NBCMAX,
C                 COORD,IDIMC,SPH,NBSMAX,ITAB,RTAB,COEF,TS,IERR)
C           CF. D2IDEF
C 
C       ITAB     : PARAMETRES ENTIERS DE LA FONCTION FADEC
C       RTAB     : PARAMETRES REELS DE LA FONCTION FADEC
C       IMODE    : IL Y A 3 MODES DE FONCTIONNEMENT
C        (1) LE MODE DEFAUT SIMPLE
C        (2) LE MODE CONCENTRATIONS(X,Y)
C        (3) LE MODE VALEURS NODALES
C
C       --------- TABLEAUX DE TRAVAIL -------------------
C       ITVL     : TABLEAU DE TRAVAIL (6*NBADET+10)
C       IMAX     : TAILLE DU TABLEAU DE TRAVAIL
C       RTVL     : TABLEAU DE TRAVAIL COORDONNEES + SPHERES
C       IRMAX    : TAILLE DE RTVL >= 3*(3*NBNPTMAX-2*NBN+NBE) 
C       --------- LE MAILLAGE ---------------------
C       ITRNOE,NBNMAX,ITRTRI,NBCMAX,NOETRI,NOEMAX,NBN,NBE : LE MAILLAGE
C       COORD,IDIMC: LES COORDONNEES DES NOEUDS
C       NBPMAX     : NOMBRE MAXIMUM DE POINTS
C       NBEMAX     : NOMBRE MAXIMUM D'ELEMENTS
C
C     EN SORTIE     : LE MAILLAGE MODIFIE
C       NBN       : LE NOMBRE DE NOEUDS = NBP + NBPNEW
C       NBE       : LE NOMBRE D'ELEMENTS = 2 * NBPNEW + NBE
C       NBENEW    : LE NOMBRE D'ELEMENTS GENEREES = 2 * NBPNEW
C       IERR      : CODE D'ERREUR
C                       2 LE NOMBRE D'ELEMENTS MAXIMUM EST ATTEINT (MEMOIRE)
C                       1 LE NOMBRE DE NOEUDS MAXIMUM (DONNE) EST ATTEINT 
C                       0 LA TAILLE SOUHAITEE EST ATTEINTE
C                      -1 TOUS LES POINTS N'ONT PAS PU ETRE AJOUTES
C                      -2 ITVL OU RTVL TROP PETIT
C     REMARQUES :
C       NBPNEW    : LE NOMBRE DE NOEUDS GENERES = NBENEW / 2
C     **********************************************************************
      INTEGER ITAB(*),IMODE
      REAL    RTAB(*)
      INTEGER NBE,NBEMAX,ITRNOE(*),NBNMAX,ITRTRI(*),NBCMAX
      INTEGER ITVL(*),IMAX
      INTEGER IDIMC,NOETRI(*),NOEMAX,NBN,NBPMAX,IRMAX,NBENEW,IERR
      REAL    COORD(*),RTVL(*)
      EXTERNAL FADEC
C
C     --- POUR LES STATS ---
C
      COMMON /STATS/ ICARD(100)
      INTEGER       ICARD 
C     --- CONSTANTES ---
      INTEGER   NADMAX
      PARAMETER ( NADMAX = 50 )
      REAL      ZEROTR 
      PARAMETER ( ZEROTR = 1.E-30 )
C     --- VARIABLES INTERNES ---
      REAL    XPT(3)
      INTEGER IDE,NCOORD,MODAJT,I,J,IPT,NBTGEN
      INTEGER ISPH
      INTEGER NCFMAX,ICOORD
      INTEGER IT,IPTNEW
      REAL    COEF,SZERO,TS,COEF2,COEFX,COEFMX
      INTEGER NBSMAX,NBTNEW,ITRACE,NBVAL
      REAL      COEF3,DFRMIN,VALNO
C     --- COEF3 = SQRT(3) ------------
      DATA COEF3 /1.73205080756887729352/
C     --- RAPPORT MINI COEFMX = TS/TR = 1/1.5 ---
      DATA COEFMX/0.66666666666666666666/
C
C     ---- MODIF DU 09.02.1999 : O.STAB 
      REAL SZERO2,SZERO3
      PARAMETER (SZERO2 = 1.E-16,SZERO3 = 1.E-16)
C
*     pour tester la memoire :
      ITVL(IMAX-1) = 0
*
C          
C          ====================================
C
C     =====          INITIALISATION            =====
C
C          ====================================
C
C     TEST DES ENTREES
C     NORMALISATION DES POINTS (PTINIT)
C     CALCUL DES SPHERES CIRCONSCRITES
C     TRI DES ELEMENTS A RAFFINER
C
      NBVAL  = 1
      NBENEW = 0      
      ITRACE = 1
      NBSMAX = IDIMC+1
      IERR   = 0
      IPTNEW  = 0
      IDE = IDIMC
      NCOORD = NBN
C     --- MODE D'AJOUT DU POINT : ON NE FORCE PAS ---
      MODAJT = 0
      NBSMAX = IDIMC+1
      IF(IDIMC.EQ.2)THEN
C        SZERO  = 1.E-8
        SZERO  = SZERO2
C       THEORIQUE 60 DEG :
C        COEFX = 9.0 / 8.0
C       THEORIQUE 30 DEG : DT > 2 RC SINT(TETA)**2
C                          RC > 3/4 TS
C                          COEFX = 3/2 SIN(TETA)**2
        COEFX = 0.375
      ELSE
C     --- IDIMC = 3 ---
C        SZERO  = 1.E-8
        SZERO  = SZERO3
C       THEORIQUE 60 DEG :
C        COEFX = 1.0
C       EMPIRIQUE 30 DEG:
        COEFX = 0.5
      ENDIF
C     LE NOMBRE MAXIMUM DE NOEUDS DONNE PAR L'UTILISATEUR EST ATTEINT
C     
      IF( NBN.EQ.NBPMAX )THEN
        IERR = 1
        GOTO 9999
      ENDIF
C
      IF((NBN.EQ.0).OR.(IDIMC.LT. 2).OR.(IDIMC.GT. 3))THEN
        IERR = -1
        CALL DSERRE(1,IERR,'RFITER',' DONNEES INCORRECTES ')
C        PRINT *,'NBN,IDIMC = ',NBN,IDIMC
        GOTO 9999
      ENDIF
      IF((NBNMAX.LT.IDE).OR.(NBCMAX.LT.IDE))THEN
        IERR = -1
        CALL DSERRE(1,IERR,'RFITER',' DONNEES INCOMPATIBLES ')
C        PRINT *,'NBNMAX,NBCMAX,IDE = ',NBNMAX,NBCMAX,IDE
        GOTO 9999
      ENDIF
C
      ISPH   = (IDIMC * NBPMAX)  + 1
      ICOORD = 1
      IF( (IRMAX-ISPH).LT.(NBE*NBSMAX))THEN
        IERR = -2
        CALL DSERRE(1,IERR,'RFITER',' TABLEAU DES REELS ')
        GOTO 9999
      ENDIF
C      CALL PTINIT(COORD,IDIMC,NBN,ZEROTR,RTVL(ICOORD),IERR)
C     --- ON NE NORMALISE PAS POUR POUVOIR DEBUGGER ---
      CALL COPIVE(COORD,(NBN*IDIMC),RTVL(ICOORD))
C        ----------------------------------------------------
C     --- CALCUL DES SPHERES ET DES COEFICIENTS DES ELEMENTS ------
C        ----------------------------------------------------
      DO 20 I=1,NBE
C        CALL SPCRSX(IDIMC,I,ITRNOE((I-1)*NBNMAX+1),RTVL(ICOORD),
C
C       REMPLACE : O.STAB, 10.97, V.2.0.0
C
        CALL SPCREE(IDIMC,I,ITRNOE((I-1)*NBNMAX+1),RTVL(ICOORD),
     >             RTVL(ISPH),ZEROTR,IERR)
C         
        IF( IERR .NE. 0  )THEN
          CALL DSERRE(1,IERR,'RFITER',' APPEL SPCREE') 
C          PRINT *,'ELEMENT = ',I         
          GOTO 9999
        ENDIF
        CALL FADEC(I,ITRNOE,NBNMAX,ITRTRI,NBCMAX,
     >            RTVL(ICOORD),IDIMC,RTVL(ISPH),NBSMAX,
     >            ITAB,RTAB,COEF,TS,IERR)
*        RTVL((I-1)*NBSMAX+ISPH+2) = COEF
        RTVL((I-1)*NBSMAX+ISPH+IDIMC) = COEF
C         
        IF( IERR .NE. 0  )THEN
          CALL DSERRE(1,IERR,'RFITER',
     >        'APPEL FADEC (CALCUL DE LA TAILLE SOUHAITE)')          
          GOTO 9999
        ENDIF
   20 CONTINUE
C     -------- POUR LE DEBUG ---------------
      NCFMAX = IDE
      IF( ITRACE.NE.0 )THEN
C        PRINT *,'VERIF TRIANGULATION INITIALE'
      IF( IERR .NE. 0 )THEN
        GO TO 9999
      ENDIF
      ENDIF
C
C      NBSMAX = 3
      IPT = NBN 
C          
C          ====================================
C
C     ===== BOUCLE SUR LES ELEMENTS A RAFFINER  =====
C
C          ====================================
C
   30 CONTINUE
      IERR = 0
C          ------------------
C     ---- CHOIX DE L'ELEMENT  ----------------------
C          ------------------
      CALL RFRECH(IDIMC,ITRNOE,NBNMAX,
     >           NBE,RTVL(ICOORD),RTVL(ISPH),
     >           NBSMAX,IT,XPT,COEF,IERR)
C
C      IF( ITRACE.NE.0 )
C     >  PRINT *,' IT =',IT,' 2*L/RC =',COEF,' XPT = ',(XPT(J),J=1,IDIMC)
C        ------------------------------------------------          
C     ---- SORTIE DE BOUCLE : PLUS D'ELEMENTS A RAFFINER ---
C        ------------------------------------------------          
      IF((IT.EQ.0).OR.(COEF.GT.COEFMX))THEN
C     --- ON NE NORMALISE PAS POUR POUVOIR DEBUGGER ---
        IERR = 0
        CALL COPIVE(RTVL,(NBN*IDIMC),COORD)
C        PRINT *,'NOMBRE DE NOEUD GENERES = ',NBN - NCOORD
C        PRINT *,'NOMBRE DE NOEUD TESTES = ',IPT - NCOORD
        GOTO 9999
      ENDIF
C        ----------------------------------------------------
C     --- TAILLE MINI. DES NOUVEAUX ELEMENTS                ------
C        ----------------------------------------------------
        CALL FADEC(IT,ITRNOE,NBNMAX,ITRTRI,NBCMAX,
     >            RTVL(ICOORD),IDIMC,RTVL(ISPH),NBSMAX,
     >            ITAB,RTAB,COEF2,TS,IERR)
C     --- POUR LE DEBUG ---
      IF((1.-COEF2).LT.0.0001)THEN
        IERR = -1
        CALL DSERRE(1,IERR,'RFITER',
     >                     'TAILLE DES NOUVEAUX ELEMENTS')          
C        PRINT *,'ERREUR ET FIN ',COEF, COEF2
        CALL RFRECH(IDIMC,ITRNOE,NBNMAX,
     >           NBE,RTVL(ICOORD),RTVL(ISPH),
     >           NBSMAX,IT,XPT,COEF,IERR)
        GOTO 9999
      ENDIF
C     -------------------------------------------------------------
C     POUR EVITER LA GENERATION D'ELEMENTS APPLATIS A LA FRONTIERE
C     ON INTERDIT LES SURFACES TROP PETITES   
C     SZERO = SURFACE D'UN TRIANGLE EQUILATERAL DE RAYON 0.75 * TS
C     TS    = RAYON SOUHAITE POUR LE CERCLE CIRCONSCRIT
C     -------------------------------------------------------------
C      SZERO = COEFX * TS**(IDIMC) 
      DFRMIN = COEFX * TS
C      SZERO = 1.E-08
      SZERO = SZERO2
C        ----------------------------------------------------
C     ---- INSERTION DANS LE MAILLAGE 2D                     ------
C        ----------------------------------------------------
      IF(NBN+1.GT.NBPMAX)THEN
        IERR = 1
        GOTO 9999
      ENDIF
      IPT = IPT + 1
      CALL S0AJNO(XPT,RTVL(ICOORD),IDIMC,NBN,NBPMAX,
     >                NOETRI,NOEMAX,IPTNEW,IERR)  
      IF( IERR.NE.0 )THEN
        CALL DSERRE(1,IERR,'RFITER','APPEL S0AJNO')
      ENDIF    
      IF( ITRACE .NE. 0 )THEN
C        PRINT *,'*********************'
C        PRINT *,'AJOUT DU POINT :',IPTNEW
      ENDIF
C
C      IF( IPTNEW.GE.5403 )THEN
C         ---- POUR LE DEBUG ---
C          PRINT *,'VERIF TRIANGULATION '
C          CALL SDBTRI(IDE,ITRNOE,NBNMAX,ITRTRI,NBCMAX,NOETRI,
C     >              NBE,NBN,ITRACE,IERR)
C          CALL SDBORI(IDE,IDIMC,ITRNOE,NBNMAX,ITRTRI,NBCMAX,
C     >              NOETRI,NBE,RTVL(ICOORD),ITRACE,IERR) 
C      ENDIF
C
      IF(IDIMC.EQ.2)THEN
        CALL TRAJPO(IPTNEW,IT,ITRNOE,NBNMAX,ITRTRI,
     >    NBCMAX,NOETRI,NBE,RTVL(ICOORD),RTVL(ISPH),
     >    NBSMAX,ITVL,IMAX,SZERO,DFRMIN,NBTNEW,IERR)
      ELSE
        CALL TTAJPO(IPTNEW,IT,ITRNOE,NBNMAX,NBEMAX,ITRTRI,
     >    NBCMAX,NOETRI,NBE,RTVL(ICOORD),RTVL(ISPH),
     >    NBSMAX,ITVL,IMAX,SZERO,DFRMIN,MODAJT,NBTNEW,IERR)
      ENDIF
C
      IF( IERR.NE.0 )THEN
        IF( IERR.EQ.-2 )THEN
          CALL DSERRE(1,IERR,'RFITER','APPEL TTAJPO ')
          GOTO 9999
        ENDIF
        IF( IERR.EQ.-1 )THEN
          CALL DSERRE(1,IERR,'RFITER','APPEL TTAJPO ')
C         ---- POUR LE DEBUG ---
C          PRINT *,'VERIF TRIANGULATION '
C          CALL SDBTRI(IDE,ITRNOE,NBNMAX,ITRTRI,NBCMAX,NOETRI,
C     >              NBE,NBN,ITRACE,IERR)
C          CALL SDBORI(IDE,IDIMC,ITRNOE,NBNMAX,ITRTRI,NBCMAX,
C     >              NOETRI,NBE,RTVL(ICOORD),ITRACE,IERR) 
          GOTO 9999
        ENDIF
C
        IF( IERR.EQ.1 )THEN
C       --- L'ELEMENT NE PEUT PAS ETRE RAFFINE ---
C          PRINT *,'RFITER : REJET DU POINT ',IPTNEW
          RTVL((IT-1)*NBSMAX+ISPH+IDIMC) = 1.
C          PRINT *,'NBN = ',NBN
C          PRINT *,' CONNECTE A : ',NOETRI(IPTNEW)
          CALL S0DTNO(IPTNEW,RTVL(ICOORD),IDIMC,NBN,NBPMAX,
     >                NOETRI,NOEMAX,IERR)      
          IERR = 0
        ENDIF
C
        IF( IERR.EQ.2 )THEN
C       --- L'ELEMENT NE PEUT PAS ETRE RAFFINE ---
          CALL DSERRE(1,-IERR,'RFITER','APPEL TTAJPO ')
C          PRINT *,'RFRAFF : PLUS DE PLACE POUR LES ELEMENTS '
C          PRINT *,'NBE =',NBE,' EST PROCHE DE NBEMAX =',NBEMAX
C          PRINT *,'NBN = ',NBN
          CALL COPIVE(RTVL,(NBN*IDIMC),COORD)
          GOTO 9999
        ENDIF
      ELSE
C        ----------------------------------------------------
C     --- MISE A JOUR DES COEFICIENTS DES NOUVEAUX ELEMENTS ------
C        ----------------------------------------------------
C     AJOUT D'UNE LIGNE POUR LA MISE A JOUR DES CHAMPS POINTS
C
C      IF(IMODE.EQ.3)RTAB(IPTNEW) = TS
C     remplace le 02.03.2001 par O.STAB par :
      IF(IMODE.EQ.3)THEN
        CALL RFNOTS(IPTNEW,NBTNEW,ITRNOE,NBNMAX,ITRTRI,NBCMAX,
     >            RTVL(ICOORD),IDIMC,RTAB,NBVAL,
     >            ITVL,IMAX,
     >            VALNO,IERR)
        IF( IERR.NE.0 )THEN
          CALL DSERRE(1,-IERR,'RFITER','APPEL RFNOTS ')
          GOTO 9999
        ENDIF
C        PRINT *,'IPTNEW = ',IPTNEW,' VALNO = ',VALNO
        RTAB(IPTNEW) = VALNO
      ENDIF
C
      NBENEW = NBENEW + NBTNEW
      DO 40 I=1,NBTNEW
        CALL FADEC(I,ITRNOE,NBNMAX,ITRTRI,NBCMAX,
     >            RTVL(ICOORD),IDIMC,RTVL(ISPH),NBSMAX,
     >            ITAB,RTAB,COEF,TS,IERR)
        RTVL((I-1)*NBSMAX+ISPH+IDIMC) = COEF
   40 CONTINUE 
      ENDIF
C     -------- POUR LE DEBUG ---------------
      NCFMAX = IDE
      IF( ITRACE .NE. 0 )THEN
      IF( IERR .NE. 0 )THEN
        GO TO 9999
      ENDIF
      ENDIF
C     -------- FIN POUR DEBUG ---------------
      IF( IPTNEW .LT. NBPMAX )GO TO 30
C          
C          ====================================
C
C     =====           FIN                      =====
C
C          ====================================
C
C      PRINT *,' NOMBRE MAXIMUM DE NOEUDS GENERES',IPTNEW
C     --- ON NE NORMALISE PAS POUR POUVOIR DEBUGGER ---
      IERR = 1
      CALL COPIVE(RTVL,(NBN*IDIMC),COORD)
C
 9999 END
C
C
C
      SUBROUTINE RFRAFF(IMODE,ITRNOE,NBNMAX,ITRTRI,NBCMAX,NOETRI,NOEMAX,
     >                 COORD,IDIMC,NBN,NBE,NBPMAX,NBEMAX,
     >                 FADEC,ITAB,NIADEC,RTAB,IRADEC,NFADEC,
     >                 ITVL,NITMAX,RTVL,NRTMAX,IERR)
C     **********************************************************************
C     OBJET RFRAFF : RAFFINE UNE TRIANGULATION PLANE. 
C
C     EN ENTREE   :
C       --------- LE MAILLAGE ---------------------
C       ITRNOE,NBNMAX,ITRTRI,NBCMAX,NOETRI,NOEMAX,NBN,NBE : LE MAILLAGE
C       COORD,IDIMC: LES COORDONNEES DES NOEUDS
C       NBPMAX     : NOMBRE MAXIMUM DE POINTS
C       NBEMAX     : NOMBRE MAXIMUM D'ELEMENTS
C
C       ---- DEFINITION DU RAFFINEMENT --------------
C       FADEC    :
C       ITAB((I-1)*NIADEC+1) : PARAMETRES ENTIERS DU IEME RAFFINEMENT
C       NIADEC  : NOMBRE MAX. DE PARAMETRES ENTIERS
C       RTAB((I-1)*NIADEC+1) : PARAMETRES REELS DU IEME RAFFINEMENT
C       IRADEC  : NOMBRE MAX. DE PARAMETRES REELS
C       NFADEC  : NOMBRE DE RAFFINEMENTS
C
C       ---- TABLEAUX DE TRAVAIL --------------------
C       ITVL : SERT POUR TAJPOT                  
C       NITMAX  : TAILLE DE (6*NBADET+10) (CF. TAJPOT)
C       RTVL : TABLEAU DE REELS POUR LES CALCULS
C       NRTMAX  : TAILLE DE RTVL (8*NBNPMAX+244)
C
C     EN SORTIE     : LE MAILLAGE MODIFIE
C       NBE,NBN     : LE NOMBRE DE TRIANGLES ET DE NOEUDS APRES GENERATION
C       IERR        : 
C                        MAILLAGE CORRECT
C                      2 LE NOMBRE D'ELEMENTS MAXIMUM EST ATTEINT (MEMOIRE)
C                      1 LE NOMBRE DE NOEUDS MAXIMUM (DONNE) EST ATTEINT 
C                      0 OK
C                        MAILLAGE INCORRECT
C                     -1 SI DONNEES INCORRECTES
C                     -2 SI TABLEAUX INSUFFISANTS
C
C     REMARQUES :
C           - LES NOEUDS CALCULES SONT AJOUTES A LA TRIANGULATION
C             PAR LA METHODE DE DELAUNAY (APPEL TAJPOT)
C           - on applique dans l'ordre les fonctions de densite.
C           - APPEL RFITER.
C     **********************************************************************
      INTEGER    IMODE,NBE,NBEMAX,ITRNOE(*),NBNMAX,ITRTRI(*),NBCMAX
      INTEGER    NOETRI(*),NOEMAX,NBN,NBPMAX
      REAL       COORD(*)
      INTEGER    IDIMC,ITAB(*),NFADEC,NIADEC,IRADEC
      INTEGER    ITVL(*)
      REAL       RTAB(*),RTVL(*)
      INTEGER    NITMAX,NRTMAX,IERR
      EXTERNAL   FADEC
C
      INTEGER  NBENEW,I,ITZERO(1)
C      INTEGER  DNIDEF,D2IDEF
      EXTERNAL DNIDEF
      REAL VZERO(1)
C
      IERR = 0
      NBENEW = 0
      IF(IMODE.EQ.1)THEN
        VZERO(1) = 0.0
        ITZERO(1) = 0
C        CALL RFITER(DNIDEF,0,ZERO,IMODE,
        CALL RFITER(DNIDEF,ITZERO,VZERO,IMODE,
     >          ITRNOE,NBNMAX,ITRTRI,NBCMAX,NOETRI,NOEMAX,
     >          COORD,IDIMC,NBN,NBE,NBPMAX,NBEMAX,
     >          ITVL,NITMAX,RTVL,NRTMAX,NBENEW,IERR)
       GOTO 9999
      ENDIF
C
      IF( IMODE.GE.2)THEN
C     --- A REVOIR ---
      DO 10 I=1,NFADEC
         CALL RFITER(FADEC,
     >            ITAB((I-1)*NIADEC+1),RTAB((I-1)*IRADEC+1),
     >            IMODE,
     >            ITRNOE,NBNMAX,ITRTRI,NBCMAX,NOETRI,NOEMAX,
     >            COORD,IDIMC,NBN,NBE,NBPMAX,NBEMAX,
     >           ITVL,NITMAX,RTVL,NRTMAX,NBENEW,IERR)
        IF( IERR.NE.0 )GOTO 9999
   10 CONTINUE
      GOTO 9999
      ENDIF
C
      IERR = -1
      CALL DSERRE(1,IERR,'RFRAFF',' MODE DE RAFFINEMENT')
C
 9999 END
C
      
      

