C MODNUM SOURCE MAGN 09/07/30 21:19:36 6458 SUBROUTINE MODNUM(LILAG,KMINCT,PMTOT, $ NEWNUM, $ IMPR,IRET) IMPLICIT INTEGER(I-N) IMPLICIT REAL*8 (A-H,O-Z) C*********************************************************************** C NOM : MODNUM C PROJET : Noyau linéaire NLIN C DESCRIPTION : Modification de la nouvelle numérotation C pour placer les multiplicateurs de Lagrange C après les inconnues auxquelles ils se rapportent. C En gros, dans la nouvelle numérotation, on permute le numéro du C multiplicateur avec le numéro le plus grand des inconnues associés C s'il est supérieur au numéro du multiplicateur. C C C LANGAGE : ESOPE C AUTEUR : Stéphane GOUNAND (CEA/DRN/DMT/SEMT/LTMF) C mél : gounand@semt2.smts.cea.fr C*********************************************************************** C APPELE PAR : PRASEM C*********************************************************************** C ENTREES : LILAG, KMINCT, PMTOT C ENTREES/SORTIES : NEWNUM C CODE RETOUR (IRET) : = 0 si tout s'est bien passé C*********************************************************************** C VERSION : v1, 02/12/99, version initiale C HISTORIQUE : v1, 02/12/99, création C HISTORIQUE : 17/01/2000 : Correction d'un bug sévère de programmation C qui entrainait un fonctionnement de la subroutine non conforme à C sa description. C 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 CCOPTIO *-INC SMLLOGI SEGMENT MLLOGI LOGICAL LOGI(JG) ENDSEGMENT POINTEUR LILAG.MLLOGI POINTEUR KRDLAG.MLLOGI -INC SMMATRIK POINTEUR KMINCT.MINC POINTEUR PMTOT.PMORS -INC SMLENTI INTEGER JG POINTEUR NEWNUM.MLENTI POINTEUR NUINLA.MLENTI POINTEUR LDDLAG.MLENTI INTEGER IMPR,IRET * INTEGER IDDLAG,ITOTIN,ITOTLA,ITOTPO INTEGER NDDLAG,NTOTIN,NTOTLA,NTOTPO,NTTDDL INTEGER NTOTI2,NTTDD2 INTEGER NUMDDL,NUMLAG,NNUDDL,NNULAG INTEGER MANNDL,MANUDL INTEGER POSI INTEGER J,JSTOP,JSTRT * * Executable statements * IF (IMPR.GT.1) WRITE(IOIMP,*) 'Entrée dans modnum' * * Construction de NUINLA : la liste d'entiers telle que : * KMINCT.LISINC(NUINLA.LECT(imulag)), imulag=1..nbulag * sont des noms d'inconnues "mult. lag." * JG=0 SEGINI NUINLA SEGACT LILAG NTOTIN=LILAG.LOGI(/1) DO 1 ITOTIN=1,NTOTIN IF (LILAG.LOGI(ITOTIN)) THEN NUINLA.LECT(**)=ITOTIN ENDIF 1 CONTINUE SEGDES LILAG NTOTLA=NUINLA.LECT(/1) IF (NTOTLA.GT.0) THEN * * Construction de LDDLAG : liste d'entiers telle que : \forall i * LDDLAG.LECT(i) est un numéro de ddl "multiplicateur de lagrange" (ML) * SEGACT KMINCT NTOTI2=KMINCT.LISINC(/2) IF (NTOTI2.NE.NTOTIN) GOTO 9998 NTOTPO=KMINCT.NPOS(/1)-1 NTTDDL=KMINCT.NPOS(NTOTPO+1)-1 JG=NTTDDL SEGINI LDDLAG NDDLAG=0 *! *! La boucle est dans le mauvais ordre mais comme ca LDDLAG est dans *! l'ordre croissant. *! (En fait, c'est plutôt) MPOS qui a ses indices *! dans l'ordre inverse par rapport au naturel *! *! DO 3 ITOTLA=1,NTOTLA ITOTIN=NUINLA.LECT(ITOTLA) DO 32 ITOTPO=1,NTOTPO POSI=KMINCT.MPOS(ITOTPO,ITOTIN) IF (POSI.NE.0) THEN NDDLAG=NDDLAG+1 LDDLAG.LECT(NDDLAG)=KMINCT.NPOS(ITOTPO)+POSI-1 ENDIF 32 CONTINUE 3 CONTINUE SEGDES KMINCT JG=NDDLAG SEGADJ,LDDLAG JG=NTTDDL SEGINI KRDLAG DO 4 IDDLAG=1,NDDLAG KRDLAG.LOGI(LDDLAG.LECT(IDDLAG))=.TRUE. 4 CONTINUE * * Maintenant, pour chaque ML de LDDLAG : on regarde si les ddl * associés dans PMTOT ont des numéros plus grand dans la nouvelle * numérotation... Si oui, on permute le numéro le plus grand et celui * du ML * SEGACT PMTOT NTTDD2=PMTOT.IA(/1)-1 IF (NTTDD2.NE.NTTDDL) GOTO 9998 * SEGPRT,LDDLAG * SEGPRT,NEWNUM SEGACT NEWNUM*MOD NTTDD2=NEWNUM.LECT(/1) IF (NTTDD2.NE.NTTDDL) GOTO 9998 DO 5 IDDLAG=1,NDDLAG NUMLAG=LDDLAG.LECT(IDDLAG) NNULAG=NEWNUM.LECT(NUMLAG) MANUDL=NUMLAG MANNDL=NNULAG JSTRT=PMTOT.IA(NUMLAG) JSTOP=PMTOT.IA(NUMLAG+1)-1 DO 52 J=JSTRT,JSTOP NUMDDL=PMTOT.JA(J) IF (.NOT.KRDLAG.LOGI(NUMDDL)) THEN NNUDDL=NEWNUM.LECT(NUMDDL) IF (NNUDDL.GT.MANNDL) THEN MANNDL=NNUDDL MANUDL=NUMDDL ENDIF ENDIF 52 CONTINUE * On a trouvé un numéro plus grand, on permute IF (NUMLAG.NE.MANNDL) THEN NEWNUM.LECT(NUMLAG)=MANNDL NEWNUM.LECT(MANUDL)=NNULAG ENDIF 5 CONTINUE * SEGPRT,NEWNUM SEGDES NEWNUM SEGDES PMTOT SEGSUP KRDLAG SEGSUP LDDLAG ENDIF SEGSUP NUINLA * * Normal termination * IRET=0 RETURN * * Format handling * * * Error handling * 9998 CONTINUE WRITE(IOIMP,*) 'Pb. compatibilité d''objets (dimensions)' 9999 CONTINUE IRET=1 WRITE(IOIMP,*) 'An error was detected in subroutine modnum' RETURN * * End of subroutine MODNUM * END