numop3
C NUMOP3 SOURCE GOUNAND 25/05/15 21:15:09 12268 SUBROUTINE NUMOP3(MELEME,ICPR,NODES) IMPLICIT REAL*8 (A-H,O-Z) IMPLICIT INTEGER (I-N) C*********************************************************************** C NOM : NUMOP3 C DESCRIPTION : Numerotation des noeuds d'un maillage C par la methode de SLOAN C Reprise de NUMOP2 pour le graphe d'adjacence C et le placement des multiplicateurs C C C LANGAGE : ESOPE C AUTEUR : Stephane GOUNAND (CEA/DES/ISAS/DM2S/SEMT/LTA) C mel : gounand@semt2.smts.cea.fr C*********************************************************************** C APPELES : C APPELES (E/S) : C APPELES (BLAS) : C APPELES (CALCUL) : C APPELE PAR : C*********************************************************************** C SYNTAXE GIBIANE : C ENTREES : C ENTREES/SORTIES : C SORTIES : C*********************************************************************** C VERSION : v1, 06/05/2025, version initiale C HISTORIQUE : v1, 06/05/2025, creation C HISTORIQUE : C HISTORIQUE : C*********************************************************************** -INC PPARAM -INC CCOPTIO -INC CCREEL -INC SMELEME -INC SMCOORD LOGICAL CONNEC SEGMENT JMEM(NODES+1),JMEMN(NODES+1) C JMEM et JMEMN contiennent le nombre d'element auquel appartient un noeud SEGMENT JNT(NODES) C JNT contient la nouvelle numerotation SEGMENT IJNT(NODES) C IJNT contient l'inverse de la nouvelle numerotation SEGMENT JORDRE(NODES) C Ordre des noeuds SEGMENT IWORK(3*NODES+1) C Tableau de travail pour prsloa SEGMENT IJNT2(NODES) SEGMENT JOR2(NODES) C Tableau de travail pour trifus SEGMENT ICPR(nbpts) C ICPR au debut contient l'ancienne numerotation , C a la fin la nouvelle. SEGMENT IADJ(NODES+1) SEGMENT JADJC(0) C IADJ(i) pointe sur JADJC qui contient les voisins de i entre C IADJ(i) et IADJ(i+1)-1 SEGMENT LAGRAN(NB) C contient les noeud de lagrange et les noeuds les suivant directement C cf element de type 49 SEGMENT BOOLEEN LOGICAL BOOL(NODES) ENDSEGMENT C BOOL(i) = true si le noeud i a ete deja mentionne dans la liste C des voisins JADJC. SEGMENT IMEMOIR(NBV),LMEMOIR(NBV) C contient les elements appartenant a chaque noeud,sous forme de liste. INTEGER ELEM C nom d'un element LOGICAL LDBNUM,LVERIF * * Executable statements * LDBNUM=.FALSE. LVERIF=.FALSE. SEGACT ICPR*MOD NODES=ICPR(/1) SEGACT MELEME C icpr: numero des noeuds. C meleme: objet de maillage (cf assem2.eso) DO 10 I=1,ICPR(/1) ICPR(I)=0 10 CONTINUE IPT1=MELEME IKOU=0 NBV=0 NB1=0 NB2=0 DO 100 IO=1,MAX(1,LISOUS(/1)) IF (LISOUS(/1).GT.0) THEN IPT1=LISOUS(IO) SEGACT IPT1 ENDIF C on cree la numerotation des noeuds. C 'nb noeuds/element'=IPT1.NUM(/1) C 'nb element'=IPT1.NUM(/2) IF(abs(IPT1.ITYPEL).EQ.49) THEN NB1=NB1+IPT1.NUM(/2) NB2=MAX(NB2,IPT1.NUM(/1)) C NB1= nbre d'éléments de type 49. C NB2=nbre de noeuds/élément maximum parmi C les éléments de type 22. ENDIF DO J=1,IPT1.NUM(/2) DO I=1,IPT1.NUM(/1) IJ=IPT1.NUM(I,J) C IJ est le Ième noeud du Jème élément. IF (ICPR(IJ).EQ.0) THEN C s'il est déjà numéroté, on ne fait rien. IKOU=IKOU+1 ICPR(IJ)=IKOU ENDIF enddo enddo 100 CONTINUE NODES=IKOU NB=NB2*NB1 C***** initalisation des segments********* SEGINI,LAGRAN SEGINI IADJ,JADJC SEGINI,JMEM,JMEMN SEGINI BOOLEEN C****************************************** IPT1=MELEME IADJ(1)=1 INC=0 DO 200 IO=1,MAX(1,LISOUS(/1)) IF (LISOUS(/1).GT.0) IPT1=LISOUS(IO) DO 210 J=1,IPT1.NUM(/2) IF(abs(IPT1.ITYPEL).EQ.49) THEN is=sign(1,ipt1.itypel) DO 220 I=1,IPT1.NUM(/1) C chaque element de type 49 a au plus NB2 noeuds. LAGRAN(INC*NB2+I)=ICPR(IPT1.NUM(I,J))*is C les noeuds de l'elements de type 49 C sont ranges dans le vecteur LAGRAN. 220 CONTINUE DO 225 I=IPT1.NUM(/1)+1,NB2 LAGRAN(INC*NB2+I)=0 C comme on a alloue la place memoire maximale, C on remplit les cases restantes avec des 0. 225 CONTINUE INC=INC+1 C INC=le nbre d'elements de type 49. ENDIF DO 230 I=1,IPT1.NUM(/1) IJ=ICPR(IPT1.NUM(I,J))+1 JMEM(IJ)=JMEM(IJ)+1 C JMEM(I+1): nb elements auquel le noeud I appartient 230 CONTINUE 210 CONTINUE 200 CONTINUE JMEM(1)=1 DO 30 I=1,NODES JMEM(I+1)=JMEM(I)+JMEM(I+1) C JMEM(I+1)=indice de depart des elements C auxquels le noeud I appartient. 30 CONTINUE NBV=JMEM(NODES+1) C NBV= dimension de IMEMOIR. SEGINI IMEMOIR,LMEMOIR IPT1=MELEME DO 300 IO=1,MAX(1,LISOUS(/1)) IF (LISOUS(/1).GT.0) THEN IPT1=LISOUS(IO) ENDIF DO J=1,IPT1.NUM(/2) DO I=1,IPT1.NUM(/1) IJ=ICPR(IPT1.NUM(I,J)) JMEMN(IJ+1)=JMEMN(IJ+1)+1 IMEMOIR(JMEM(IJ)+JMEMN(IJ+1)-1)=J LMEMOIR(JMEM(IJ)+JMEMN(IJ+1)-1)=IO C on range dans IMEMOIR tous les elements des sous-objets C IO auxquels appartient le noeud ICPR(IPT1.NUM(I,J)). C On connait pour chaque element, le sous-objet auquel C il appartient grace a LMEMOIR enddo enddo 300 CONTINUE DO 410 J=1,NODES BOOL(J)=.FALSE. 410 CONTINUE DO 400 I=1,NODES IADJ(I+1)=IADJ(I) DO 420 J=JMEM(I),JMEM(I+1)-1 ELEM=IMEMOIR(J) C ELEM=element auquel appartient le noeud I. IPT1=MELEME IF (LISOUS(/1).GT.0) IPT1=LISOUS(LMEMOIR(J)) itype = abs(ipt1.itypel) * si element de type 49 ou 22, on ne connecte pas 2 noeuds non LX if (itype.eq.49) then do k=3,ipt1.num(/1) enddo endif DO 430 K=1,IPT1.NUM(/1) C k representatif du nb de noeuds par elements. IK=ICPR(IPT1.NUM(K,ELEM)) IF ((I.NE.IK).AND. & (.NOT.(BOOL(IK)))) THEN C si i n'est pas egal a un des nouveaux numeros des noeuds C de l'element ELEM et si il n'appartient pas deja a l'ens des C voisins du noeud i(jadjc(i)),alors on le rajoute. C JADJC(IADJ(I+1))=IK JADJC(**)=IK IADJ(I+1)=IADJ(I+1)+1 BOOL(IK)=.TRUE. ENDIF 430 CONTINUE 420 CONTINUE ** pour ne pas avoir un tableau de longueur nulle, ce que esope n'aime pas * if(jadjc(/1).eq.0) jadjc(**)=0 * remise a faux de bool DO 412 J=IADJ(I),IADJ(I+1)-1 IK=JADJC(J) BOOL(IK)=.FALSE. 412 CONTINUE 400 CONTINUE SEGSUP JMEM,JMEMN SEGSUP IMEMOIR,LMEMOIR SEGSUP BOOLEEN * * A ce stade, le graphe d'adjacence est près * if (ldbnum) Write(ioimp,*) 'Graphe adjacence nodes=',nodes if (ldbnum) segprt,IADJ if (ldbnum) segprt,JADJC SEGINI JNT SEGINI IWORK E2=JADJC(/1) $ JNT(1), $ IWORK(1), $ IMPR,IRET) IF (IRET.NE.0) GOTO 9999 SEGSUP IWORK SEGSUP IADJ,JADJC if (ldbnum) SEGPRT,JNT * * Maintenant, il faut mettre les Lagrange a la bonne place !!!! * On fait comme dans KRES24 * IF (NB1.EQ.0) GOTO 2000 SEGINI IJNT DO I=1,NODES IJNT(JNT(I))=I ENDDO * Il y a trois types différents de -1 à 1 : il faut pouvoir placer * les multiplicateurs de lagrange entre les autres noeuds NTYP=3 SEGINI JORDRE DO I=1,NODES JORDRE(I)=I*NTYP ENDDO JORMAX= (NODES+1)*NTYP if (ldbnum) write(ioimp,*) 'Avant mise a la bonne place' if (ldbnum) segprt,jordre do 700 J=0,NB1-1 ipaur=-igrand ipaus=igrand do 800 il=3,nb2 ip = abs(LAGRAN(J*NB2+il)) * if (ip.eq.0) write (6,*) ' prob numop3 ' if (ip.eq.0) goto 710 jddln=JNT(IP) jordre(jddln)=-abs(jordre(jddln)) ipaur=max(ipaur,jordre(jddln)) ipaus=min(ipaus,jordre(jddln)) 800 continue 710 continue * * On va laisser comme ça * Ce cas peut arriver après élimination * Cela devrait revenir à placer les multiplicateurs en fin ou début * de matrice if (ipaur.eq.-igrand.or.ipaus.eq.igrand) then * Write(ioimp,*) 'mulag sans relations pas ok' * goto 9999 ipaur=0 ipaus=-jormax endif if (ldbnum) write(ioimp,*) 'j,ipaur,ipaus=',j,ipaur $ ,ipaus * * le premier mult avant le premier noeud ip=abs(LAGRAN(J*NB2+1)) iddln=JNT(IP) jordre(iddln)=ipaur+1 * * le deuxieme mult apres le dernier noeud ip=abs(LAGRAN(J*NB2+2)) iddln=JNT(IP) jordre(iddln)=ipaus-1 * 700 continue * WRITE(IOIMP,*) 'Avant chgt signe' * segprt,jordre DO I=1,nodes JORDRE(I)=-JORDRE(I) ENDDO * Avant tri if (ldbnum) WRITE(IOIMP,*) 'Avant TRIFUS' if (ldbnum) SEGPRT,IJNT if (ldbnum) SEGPRT,JORDRE SEGINI JOR2 SEGINI IJNT2 * ok maintenant on trie CALL TRIFUS(nodes,JORDRE(1),IJNT(1),JOR2(1),IJNT2(1)) SEGSUP IJNT2 SEGSUP JOR2 * Apres tri if (ldbnum) WRITE(IOIMP,*) 'Apres TRIFUS' if (ldbnum) SEGPRT,IJNT if (ldbnum) SEGPRT,JORDRE * permutation inverse DO I=1,nodes JNT(IJNT(I))=I ENDDO * Verification que dans la nouvelle numerotation les multiplicateurs * sont correctement places... IF (LVERIF) THEN write(ioimp,*) 'VERIF NUMOP3' do 1700 J=0,NB1-1 ipaur=-igrand ipaus=igrand do 1800 il=3,nb2 ip = abs(LAGRAN(J*NB2+il)) * if (ip.eq.0) write (6,*) ' prob numop3 ' if (ip.eq.0) goto 1710 jddln=JNT(IP) ipaur=max(ipaur,jddln) ipaus=min(ipaus,jddln) 1800 continue 1710 continue if (ipaur.eq.-igrand.or.ipaus.eq.igrand) then goto 1700 * Write(ioimp,*) 'mulag sans relations pas ok' * goto 9999 endif ip=abs(LAGRAN(J*NB2+1)) iddln=JNT(IP) if (ipaus.le.iddln) then write(ioimp,*) 'Erreur numerotation' write(ioimp,*) 'ip,iddln,ipaus=',ip,iddln,ipaus goto 9999 endif ip=abs(LAGRAN(J*NB2+2)) iddln=JNT(IP) if (ipaur.ge.iddln) then write(ioimp,*) 'Erreur numerotation' write(ioimp,*) 'ip,iddln,ipaur=',ip,iddln,ipaur goto 9999 endif 1700 continue ENDIF C*************************************************************************** SEGSUP JORDRE SEGSUP IJNT 2000 CONTINUE DO 860 I=1,ICPR(/1) IF(ICPR(I).NE.0) ICPR(I)=JNT(ICPR(I)) C numerotation finale. 860 CONTINUE SEGSUP JNT SEGSUP LAGRAN * * Normal termination * RETURN * * Format handling * * * Error handling * 9999 CONTINUE WRITE(IOIMP,*) 'An error was detected in subroutine numop3' RETURN * * End of subroutine NUMOP3 * END
© Cast3M 2003 - Tous droits réservés.
Mentions légales