calnu5
C CALNU5 SOURCE PV 20/09/26 21:15:25 10724 $ IRENU, $ NEWNUM, $ IMPR,IRET) IMPLICIT REAL*8 (A-H,O-Z) IMPLICIT INTEGER (I-N) C*********************************************************************** C NOM : CALNU5 C PROJET : Noyau linéaire NLIN C DESCRIPTION : Calcul d'une renumérotation avec minimisation d'un C profil PUIS placement des inconnues suivant l'ordre C donné par LIORD C Dans calnum, on effectuait les choses suivantes : C - minimisation du profil sur les ddl sans les ML. C - insertion des ML dans la nouvelle numérotation C Maintenant, on essaie la chose suivante : C - minimisation du profil sur les ddl AVEC les ML.; C - retrait des ML de la numérotation ; C - réinsertion des ML pour les placer après les ddl non C ML auxquels ils sont liés. C C IRENU=1 'RIEN' : pas de renumérotation C 2 'SLOA' : algorithme de chez Sloan C 3 'GIPR' : Gibbs-King (profile reduction) C 4 'GIBA' : Gibbs-Poole-Stockmeyer (bandwidth reduction) C C LANGAGE : ESOPE C AUTEUR : Stéphane GOUNAND (CEA/DRN/DMT/SEMT/LTMF) C mél : gounand@semt2.smts.cea.fr C*********************************************************************** C APPELES : RENUME C APPELES (UTIL.) : ISETI, ISHELI, RSETXI C APPELE PAR : PRASEM C*********************************************************************** C ENTREES : KMINCT, PMTOT, IRENU C SORTIES : NEWNUM C CODE RETOUR (IRET) : = 0 si tout s'est bien passé C*********************************************************************** C VERSION : v1, 01/04/04, version initiale C HISTORIQUE : v1, 01/04/04, création C HISTORIQUE : C HISTORIQUE : C*********************************************************************** C Prière de PRENDRE LE TEMPS de compléter les commentaires C en cas de modification de ce sous-programme afin de faciliter C la maintenance ! C*********************************************************************** -INC PPARAM -INC CCOPTIO -INC SMMATRIK POINTEUR KMINCT.MINC POINTEUR PMTOT.PMORS -INC SMLENTI INTEGER JG POINTEUR LITYP.MLENTI POINTEUR LINIV.MLENTI POINTEUR DDLINC.MLENTI *inu POINTEUR DDLPT.MLENTI POINTEUR NEWNUM.MLENTI POINTEUR KRDDL.MLENTI POINTEUR NNUTOT.MLENTI POINTEUR PRMDDL.MLENTI SEGMENT LML POINTEUR ML(NINC).MLENTI ENDSEGMENT POINTEUR DDLDIM.MLENTI POINTEUR ITTDDL.MLENTI POINTEUR INUDDL.MLENTI POINTEUR LDD.LML POINTEUR LDDI.MLENTI POINTEUR NNU.LML POINTEUR NNUI.MLENTI POINTEUR NNUJ.MLENTI POINTEUR NNUK.MLENTI POINTEUR PRM.LML POINTEUR PRMI.MLENTI *-INC SMLLOGI SEGMENT MLLOGI LOGICAL LOGI(JG) ENDSEGMENT POINTEUR DDLOK.MLLOGI POINTEUR PTLAG.MLLOGI * *STAT-INC SMSTAT * INTEGER IMPR,IRET INTEGER IRENU * INTEGER ITOTPO,JTTDDL INTEGER NTOTPO,NTTDDL LOGICAL LLAG,LRELA * * Executable statements * IF (IMPR.GT.1) WRITE(IOIMP,*) 'Entrée dans calnu5' * * Construction de DDLINC : c'est un tableau d'entiers tel que : * DDLINC(jttddl) = ordre du ddl * C SEGPRT,KMINCT C SEGPRT,LITYP C SEGPRT,LINIV SEGACT KMINCT SEGACT LITYP SEGACT LINIV NINC=KMINCT.LISINC(/2) MAXNIV=0 DO IINC=1,NINC MAXNIV=MAX(MAXNIV,LINIV.LECT(IINC)) ENDDO * * Construction de DDLINC et DDLPT : sorte de segment réciproque * de KMINCT * En fait, DDLPT est inutile pour la suite. * Construction de PTLAG : liste des points sur lesquels * il n'y a que des inconnues de niveau > 1 *!* Non ! il n'y a que des multiplicateurs de Lagrange * NTOTPO=KMINCT.NPOS(/1)-1 NTTDDL=KMINCT.NPOS(NTOTPO+1)-1 JG=NTTDDL SEGINI DDLINC *inu JG=NTTDDL *inu SEGINI DDLPT JG=NTOTPO SEGINI PTLAG LRELA=.FALSE. DO ITOTPO=1,NTOTPO LLAG=.TRUE. DO IINC=1,NINC IPOS=KMINCT.MPOS(ITOTPO,IINC) IF (IPOS.NE.0) THEN JPOS=KMINCT.NPOS(ITOTPO)+IPOS-1 DDLINC.LECT(JPOS)=IINC *inu DDLPT.LECT(JPOS)=ITOTPO * Non ! IF (LITYP.LECT(IINC).LE.2) THEN IF (LINIV.LECT(IINC).LT.2) THEN LLAG=.FALSE. ENDIF ENDIF ENDDO PTLAG.LOGI(ITOTPO)=LLAG LRELA=LRELA.OR.LLAG ENDDO C SEGPRT,DDLINC C SEGPRT,DDLPT C SEGPRT,PTLAG *inu SEGSUP DDLPT * * Construction des tableaux d'entiers suivants : * LDD.IINC(1..NTTINC) liste des ddl de l'inconnue iinc * DDLINC(JTTDDL)=IINC : numéro de l'inconnue du ddl de numéro jttddl * KRDDL(JTTDDL)=ITTINC avec LDD.IINC(ITTINC) * SEGINI LDD JG=NINC SEGINI DDLDIM DO IINC=1,NINC JG=0 SEGINI LDDI LDD.ML(IINC)=LDDI ENDDO JG=NTTDDL SEGINI KRDDL DO JTTDDL=1,NTTDDL IINC=DDLINC.LECT(JTTDDL) LDDI=LDD.ML(IINC) ITTINC=DDLDIM.LECT(IINC)+1 LDDI.LECT(**)=JTTDDL KRDDL.LECT(JTTDDL)=ITTINC DDLDIM.LECT(IINC)=ITTINC ENDDO C SEGPRT,DDLDIM C SEGPRT,LDD C DO IINC=1,NINC C LDDI=LDD.ML(IINC) C SEGPRT,LDDI C ENDDO C SEGPRT,KRDDL *STAT CALL PRMSTA(' Préparation renume divers',MSTAT,IMPR) * * Obtention de la nouvelle numérotation des ddl * In RENUME : SEGINI NNUTOT * In RENUME : SEGDES NNUTOT IF (IRET.NE.0) GOTO 9999 C SEGPRT,NNUTOT *STAT CALL PRMSTA(' Après renume',MSTAT,IMPR) * * Construction des NNUs pour les points où il n'y a pas de * multiplicateurs de Lagrange * SEGACT,NNUTOT * NINC=NINC SEGINI NNU DO IINC=1,NINC JG=DDLDIM.LECT(IINC) SEGINI NNUI NNU.ML(IINC)=NNUI ENDDO DO ITOTPO=1,NTOTPO IF (.NOT.PTLAG.LOGI(ITOTPO)) THEN INNU=0 DO IINC=1,NINC IPOS=KMINCT.MPOS(ITOTPO,IINC) IF (IPOS.NE.0) THEN JPOS=KMINCT.NPOS(ITOTPO)+IPOS-1 IF (INNU.EQ.0) THEN INNU=NNUTOT.LECT(JPOS) ENDIF NNUI=NNU.ML(IINC) KRNNUI=KRDDL.LECT(JPOS) NNUI.LECT(KRNNUI)=INNU ENDIF ENDDO ENDIF ENDDO SEGSUP NNUTOT C SEGPRT,NNU C DO IINC=1,NINC C NNUI=NNU.ML(IINC) C SEGPRT,NNUI C ENDDO IF (LRELA) THEN C C Obtention des numéros des ddl portant sur des points C où il n'y a que des multiplicateurs de Lagrange C le max ou le min des ddl de niveau INIV-1 qui lui sont C reliés C SEGACT PMTOT DO INIV=2,MAXNIV DO IINC=1,NINC JNIV=LINIV.LECT(IINC) IF (JNIV.EQ.INIV) THEN JTYP=LITYP.LECT(IINC) DO ITOTPO=1,NTOTPO IF (PTLAG.LOGI(ITOTPO)) THEN IPOS=KMINCT.MPOS(ITOTPO,IINC) IF (IPOS.NE.0) THEN JTTDDL=KMINCT.NPOS(ITOTPO)+IPOS-1 JNNU=0 KSTRT=PMTOT.IA(JTTDDL) KSTOP=PMTOT.IA(JTTDDL+1)-1 DO KIND=KSTRT,KSTOP KTTDDL=PMTOT.JA(KIND) KINC=DDLINC.LECT(KTTDDL) KNIV=LINIV.LECT(KINC) IF (KNIV.EQ.INIV-1) THEN NNUK=NNU.ML(KINC) KRNNUK=KRDDL.LECT(KTTDDL) KNNU=NNUK.LECT(KRNNUK) IF (KNNU.EQ.0) THEN WRITE(IOIMP,*) 'Erreur trop grave' GOTO 9999 ENDIF IF (JNNU.EQ.0) THEN JNNU=KNNU ELSE IF (JTYP.EQ.4) THEN JNNU=MIN(JNNU,KNNU) *! ELSEIF (JTYP.EQ.3) THEN ELSEIF (JTYP.EQ.3.OR.JTYP.EQ.2) THEN JNNU=MAX(JNNU,KNNU) ELSE WRITE(IOIMP,*) 'Erreur grave 1.2' GOTO 9999 ENDIF ENDIF ENDIF ENDDO ENDIF ENDIF ENDDO IF (JNNU.EQ.0) THEN WRITE(IOIMP,*) 'Erreur grave 1.5' GOTO 9999 ENDIF NNUJ=NNU.ML(IINC) KRNNUJ=KRDDL.LECT(JTTDDL) NNUJ.LECT(KRNNUJ)=JNNU ENDIF ENDDO ENDDO SEGDES PMTOT ENDIF SEGSUP KRDDL SEGSUP PTLAG SEGSUP DDLINC SEGDES LINIV SEGDES LITYP SEGDES KMINCT C SEGPRT,NNU C DO IINC=1,NINC C NNUI=NNU.ML(IINC) C SEGPRT,NNUI C ENDDO * * 1 On calcule les permutations qui permettent de trier NNU * par ordre croissant de nouveau numéro. * SEGINI PRM DO IINC=1,NINC NTTINC=DDLDIM.LECT(IINC) JG=NTTINC SEGINI PRMI PRM.ML(IINC)=PRMI NNUI=NNU.ML(IINC) $ IMPR,IRET) IF (IRET.NE.0) GOTO 9999 ENDDO C SEGPRT,PRM C DO IORD=1,NORD C PRMI=PRM.ML(IORD) C SEGPRT,PRMI C ENDDO * * 3 En "merge"ant les listes précédentes, on obtient * la permutation réciproque de la nouvelle numérotation * totale que l'on cherche (si, si !) * JG=NTTDDL SEGINI PRMDDL JG=NINC SEGINI ITTDDL DO IINC=1,NINC ITTDDL.LECT(IINC)=1 ENDDO JG=NINC SEGINI DDLOK DO IINC=1,NINC DDLOK.LOGI(IINC)=(ITTDDL.LECT(IINC).LE.DDLDIM.LECT(IINC)) ENDDO JG=NINC SEGINI INUDDL DO IINC=1,NINC IF (DDLOK.LOGI(IINC)) THEN NNUI=NNU.ML(IINC) PRMI=PRM.ML(IINC) * IITT=ITTDDL.LECT(IORD) * IPRM=PRM1.LECT(IITT) * INNU=NNU1.LECT(IPRM) INUDDL.LECT(IINC)=NNUI.LECT(PRMI.LECT(ITTDDL.LECT(IINC))) ENDIF ENDDO DO JTTDDL=1,NTTDDL JNUMIN=0 JINC=0 DO IINC=1,NINC IF (DDLOK.LOGI(IINC)) THEN IF (JNUMIN.EQ.0) THEN JNUMIN=INUDDL.LECT(IINC) JINC=IINC ELSE KNUMIN=INUDDL.LECT(IINC) IF (KNUMIN.LT.JNUMIN) THEN JNUMIN=KNUMIN JINC=IINC ENDIF ENDIF ENDIF ENDDO IF ((JNUMIN.EQ.0).OR.(JINC.EQ.0)) THEN WRITE(IOIMP,*) 'Erreur trop grave 2' GOTO 9999 ENDIF LDDI=LDD.ML(JINC) NNUI=NNU.ML(JINC) PRMI=PRM.ML(JINC) KTTDDL=ITTDDL.LECT(JINC) PRMDDL.LECT(JTTDDL)=LDDI.LECT(PRMI.LECT(KTTDDL)) ITTDDL.LECT(JINC)=KTTDDL+1 DDLOK.LOGI(JINC)=(ITTDDL.LECT(JINC).LE.DDLDIM.LECT(JINC)) IF (DDLOK.LOGI(JINC)) THEN NNUI=NNU.ML(JINC) PRMI=PRM.ML(JINC) INUDDL.LECT(JINC)=NNUI.LECT(PRMI.LECT(ITTDDL.LECT(JINC))) ENDIF ENDDO SEGSUP INUDDL SEGSUP DDLOK SEGSUP ITTDDL DO IINC=1,NINC PRMI=PRM.ML(IINC) SEGSUP PRMI ENDDO SEGSUP PRM DO IINC=1,NINC NNUI=NNU.ML(IINC) SEGSUP NNUI ENDDO SEGSUP NNU SEGSUP DDLDIM DO IINC=1,NINC LDDI=LDD.ML(IINC) SEGSUP LDDI ENDDO SEGSUP LDD * SEGPRT,PRMDDL * * D'où la nouvelle numérotation : * JG=NTTDDL SEGINI NEWNUM SEGDES NEWNUM SEGSUP PRMDDL *STAT CALL PRMSTA(' Merge et obtention NEWNUM',MSTAT,IMPR) * SEGPRT,NEWNUM * STOP 16 * * Normal termination * IRET=0 RETURN * * Format handling * * * Error handling * 9999 CONTINUE IRET=1 WRITE(IOIMP,*) 'An error was detected in subroutine calnu5' RETURN * * End of subroutine CALNU5 * END
© Cast3M 2003 - Tous droits réservés.
Mentions légales