kres23
C KRES23 SOURCE GOUNAND 25/04/30 21:15:13 12258 $ IPERM,IPBLOC) IMPLICIT REAL*8 (A-H,O-Z) IMPLICIT INTEGER (I-N) C*********************************************************************** C NOM : KRES23 C DESCRIPTION : - Reordonnancer par bloc pour le multigrille C C Ce source est une adaptation de KRES13 C C LANGAGE : ESOPE C AUTEUR : Stéphane GOUNAND (CEA/DEN/DM2S/SFME/LTMF) C mél : gounand@semt2.smts.cea.fr C*********************************************************************** C VERSION : v1, 22/04/2025, version initiale C HISTORIQUE : v1, 22/04/2025, création C HISTORIQUE : C HISTORIQUE : C*********************************************************************** -INC PPARAM -INC CCOPTIO -INC CCREEL -INC SMMATRIK POINTEUR KMINCT.MINC POINTEUR KMORS.PMORS POINTEUR KIZA.IZA -INC SMLENTI POINTEUR KTYINC.MLENTI POINTEUR KTYDDL.MLENTI POINTEUR KNODDL.MLENTI POINTEUR KRINC.MLENTI POINTEUR IWORK.MLENTI POINTEUR LAGRAN.MLENTI POINTEUR JORDRE.MLENTI,JORTMP.MLENTI POINTEUR IPERM.MLENTI,JPETMP.MLENTI POINTEUR JPERM.MLENTI,NNUTOT.MLENTI POINTEUR IBLOCK.MLENTI,IPBLOC.MLENTI POINTEUR ICPR.MLENTI -INC SMLOBJE POINTEUR IORINC.MLOBJE -INC SMLMOTS POINTEUR JORINC.MLMOTS,JORINU.MLMOTS -INC SMTABLE POINTEUR KTIME.MTABLE DIMENSION ITTIME(4) CHARACTER*(LOCHPO) CHCOMP CHARACTER*16 CHARI CHARACTER*1 CCOMP LOGICAL LTIME,LOGII,LNOD,LBLOCK,LOK,LNUL,LVERIF C C Executable statements C LVERIF=.FALSE. LNOD=(KTYPI.EQ.11) SEGACT KMINCT NCOMP=KMINCT.LISINC(/2) NNOE=KMINCT.MPOS(/1) INC=KMINCT.NPOS(NNOE+1)-1 JG=INC SEGINI KTYDDL KNODDL=0 IF (LNOD) SEGINI KNODDL * WRITE(IOIMP,*) 'NCOMP,IORINC= ',NCOMP,IORINC * IF (IORINC.NE.0) THEN SEGACT IORINC NTYINC=IORINC.LISOBJ(/1) JGN=0 JGM=0 DO ITYINC=1,NTYINC MLMOTS=IORINC.LISOBJ(ITYINC) SEGACT MLMOTS ENDDO SEGINI,JORINC SEGINI,JORINU JG=JGM IG=0 SEGINI KTYINC DO ITYINC=1,NTYINC MLMOTS=IORINC.LISOBJ(ITYINC) IG=IG+1 KTYINC.LECT(IG)=ITYINC ENDDO ENDDO * write(ioimp,*) 'JGN,JGM=',JGN,JGM IF (IRET.NE.0) GOTO 9999 IF (JGM.NE.JGMU) THEN WRITE(IOIMP,*) 'IORINC ne doit pas avoir de doublons' GOTO 9999 ENDIF SEGSUP JORINU IF (JGM.NE.NCOMP) THEN WRITE(IOIMP,*) 'IORINC doit referencer toutes' $ ,'les inconnues de la matrice' GOTO 9999 ENDIF JG=NCOMP SEGINI KRINC $ ,IMPR,IRET) IF (IRET.NE.0) GOTO 9999 ELSE NTYINC=NCOMP ENDIF IF (IIMPI.NE.0) THEN WRITE(IOIMP,*) 'NCOMP= ',NCOMP WRITE(IOIMP,*) 'KMINCT.LISINC(1..',NCOMP,')= ' WRITE(IOIMP,*)(KMINCT.LISINC(II),II=1,NCOMP) IF (IORINC.NE.0) THEN WRITE(IOIMP,*) 'JORINC.MOTS(1..',NCOMP,')= ' WRITE(IOIMP,*) 'KRINC.LECT(1..',NCOMP,')= ' WRITE(IOIMP,*)(KRINC.LECT(II),II=1,NCOMP) ENDIF ENDIF * segprt,mincpo DO ICOMP=1,NCOMP DO INOE=1,NNOE IPOS=KMINCT.MPOS(INOE,ICOMP) IF (IPOS.NE.0) THEN JPOS=KMINCT.NPOS(INOE)+IPOS-1 IF (IORINC.ne.0) then KTYDDL.LECT(JPOS)=KTYINC.LECT(KRINC.LECT(ICOMP)) ELSE KTYDDL.LECT(JPOS)=ICOMP ENDIF IF (LNOD) KNODDL.LECT(JPOS)=INOE ENDIF ENDDO ENDDO * segprt,ktyddl * if (lnod) segprt,knoddl segact kmors segact kiza * segact nnutot * write(ioimp,*) 'Permutation nnutot' * write(ioimp,187) (nnutot.lect(I),I=1,nnutot.lect(/1)) * 1) Trouver le nombre de blocs NBLOCK=NTYINC ntt=inc if (iimpi.ne.0) then write(ioimp,*) 'Nb d''inconnues=',ntt write(ioimp,*) 'Nb de blocs detectes nblock=',nblock endif JG=NBLOCK+1 SEGINI IBLOCK lblock=nblock.gt.1 187 FORMAT (5X,10I8) if (lblock) then jg=ntt * segini jperm2 segini iperm segini jperm do i=1,ntt jperm.lect(nnutot.lect(i))=i enddo * segprt,jperm * * 2) Trouver le nombre d'inconnus par blocs DO i=1,ntt jblock=ktyddl.lect(i) iblock.lect(jblock)=iblock.lect(jblock)+1 enddo if (iimpi.ne.0) then write(ioimp,*) 'Nb inconnues par blocs' write(ioimp,187) (iblock.lect(I),I=1,iblock.lect(/1)) endif * 3) D'où le segment de repérage do i=nblock,1,-1 iblock.lect(i+1)=iblock.lect(i) enddo if (iimpi.ne.0) then write(ioimp,*) 'Segment de repérage tmp' write(ioimp,187) (iblock.lect(I),I=1,iblock.lect(/1)) endif iblock.lect(1)=1 do i=1,nblock iblock.lect(i+1)=iblock.lect(i+1)+iblock.lect(i) enddo if (iimpi.ne.0) then write(ioimp,*) 'Segment de repérage' write(ioimp,187) (iblock.lect(I),I=1,iblock.lect(/1)) endif * 4) Construction des permutations if (iimpi.ne.0) then write(ioimp,*) 'Nb d''inconnues 2 ntt=',ntt endif if (ktypi.eq.11) then * Petite verif sur la taille des blocs nddl1=iblock.lect(2)-iblock.lect(1) do i=2,nblock nddl=iblock.lect(i+1)-iblock.lect(i) if (nddl.ne.nddl1) then write(ioimp,*) 'Le bloc ',i,' de taille =',nddl write(ioimp,*) 'na pas la meme taille que le bloc 1 =' $ ,nddl1 goto 9999 endif enddo * Le premier bloc donne le tableau de correspondance pour les noeuds JG=NNOE SEGINI ICPR ktt=0 kblock=1 do jtt=1,ntt itt=jperm.lect(jtt) jblock=ktyddl.lect(itt) if (jblock.eq.kblock) then ktt=ktt+1 iperm.lect(itt)=ktt inod=knoddl.lect(itt) * jperm2.lect(ktt)=itt ICPR.LECT(INOD)=ktt endif enddo * segprt,iperm * segprt,iCPR do kblock=2,nblock ideb=iblock.lect(kblock) do jtt=1,ntt itt=jperm.lect(jtt) jblock=ktyddl.lect(itt) if (jblock.eq.kblock) then inod=knoddl.lect(itt) ktt1=ICPR.LECT(inod) if (ktt1.eq.0) then write(ioimp,*) 'Le noeud ',inod $ ,' present dans le bloc 1 nexiste pas' $ ,' dans le bloc ',kblock goto 9999 else ktti=ideb+ktt1-1 iperm.lect(itt)=ktti endif endif enddo enddo * segprt,iperm else ktt=0 do kblock=1,nblock do jtt=1,ntt itt=jperm.lect(jtt) jblock=ktyddl.lect(itt) if (kblock.eq.jblock) then ktt=ktt+1 iperm.lect(itt)=ktt * jperm2.lect(ktt)=itt endif enddo enddo endif * Attention, on reutilise jperm pour etre la reciproque de iperm et * non plus de nnutot do i=1,ntt jperm.lect(iperm.lect(i))=i enddo * write(ioimp,*) 'Permutation i' * write(ioimp,187) (iperm.lect(I),I=1,iperm.lect(/1)) * write(ioimp,*) 'Permutation j' * write(ioimp,187) (jperm.lect(I),I=1,jperm.lect(/1)) else if (ktypi.eq.10.or.ktypi.eq.11) then write(ioimp,*) $ 'The AGMG Stokes and NS solvers need blocks' goto 9999 endif iperm=nnutot jperm=0 iblock.lect(1)=1 iblock.lect(2)=ntt+1 if (iimpi.ne.0) then write(ioimp,*) 'Segment de repérage' write(ioimp,187) (iblock.lect(I),I=1,iblock.lect(/1)) endif endif * * Verif pas de terme diagonal nul dans la matrice (sauf AGMG-Stokes KTYPI=10) * * segprt,kmors * segprt,kiza DO I=1,NTT LNUL=.FALSE. * WRITE(IOIMP,*) 'I,J=',I,J * WRITE(IOIMP,*) 'JA(J)=',KMORS.JA(J) * WRITE(IOIMP,*) 'KIZA.A(J)=',KIZA.A(J) LNUL=(KIZA.A(J).EQ.XZERO) IF (LNUL) GOTO 10 ENDIF ENDDO 10 CONTINUE * WRITE(IOIMP,*) 'IFOUND=',IFOUND IF (LNUL) THEN LOK=.FALSE. * Le pivot a le droit d'etre nul s'il s'agit du dernier bloc pour la * methode AGMGStokes IF (KTYPI.EQ.10) THEN IF (KTYDDL.LECT(I).EQ.NBLOCK) THEN LOK=.TRUE. ENDIF ENDIF IF (.NOT.LOK) THEN WRITE(IOIMP,*) 'The ',I $ ,'th diagonal term of the matrix is nil' IF (LNOD) THEN write(ioimp,*) 'Node =',KNODDL.LECT(I) ENDIF write(ioimp,*) 'Bloc =',KTYDDL.LECT(I) IRET=-3 GOTO 9999 ENDIF ENDIF ENDDO * * Verifier que les blocs sont de meme taille pour NS * if (ktypi.eq.10.or.ktypi.eq.11.and.LVERIF) then IF (.NOT.lblock) THEN write(ioimp,*) 'The AGMG Stokes and NS solvers need blocks' goto 9999 ENDIF if (ktypi.eq.11) then nddl1=iblock.lect(2)-iblock.lect(1) do i=2,nblock nddl=iblock.lect(i+1)-iblock.lect(i) if (nddl.ne.nddl1) then write(ioimp,*) 'Le bloc ',i,' de taille =',nddl write(ioimp,*) 'na pas la meme taille que le bloc 1 =' $ ,nddl1 goto 9999 endif enddo * * Verif que les inconnues sont dans le même ordre à l'intérieur de * chaque bloc * do i=2,nblock nddl=iblock.lect(i+1)-iblock.lect(i) ideb=iblock.lect(i) do iddl=1,nddl inod1=knoddl.lect(jperm.lect(iddl)) inodi=knoddl.lect(jperm.lect(ideb+iddl-1)) if (inodi.ne.inod1) then write(ioimp,*) 'Dans le bloc ',i,' le ddl ',iddl $ ,' porte sur le noeud inodi=',inodi write(ioimp,*) 'Dans le bloc ',1,' le ddl ',iddl $ ,' porte sur le noeud inod1=',inod1 write(ioimp,*) 'inod1 != inodi est une erreur !' goto 9999 endif enddo enddo endif endif * IF (IORINC.NE.0) THEN SEGSUP KRINC SEGSUP KTYINC SEGSUP JORINC ENDIF IF (LNOD) SEGSUP KNODDL SEGSUP KTYDDL IF (jperm.ne.0) segsup jperm C IPBLOC=IBLOCK C C Normal termination C RETURN C C Error Handling C 9999 CONTINUE MOTERR(1:8)='KRES23 ' RETURN C C Format handling C 2022 FORMAT(10(1X,1PG12.5)) C C End of subroutine KRES23 C END
© Cast3M 2003 - Tous droits réservés.
Mentions légales