cmct5
C CMCT5 SOURCE GOUNAND 25/03/17 21:15:03 12207 SUBROUTINE CMCT5(IRI1,INFMEL,IRI3) *_______________________________________________________________________ c c opérateur cmct option ELEM c c Réduction de la rigidité IRI1 sur le maillage IMEL c ICPR,INODE,JELNUM,IZONE sont des objets de c preconditionnement C associes a IMEL C C C En entree/sortie : IRI3 est definie sur IMEL et son nombre d'elements C est le meme que IMEL C Si IRI3=0 en entrée, on cree son descripteur DES3 C par assemblage des descripteurs DES1 de IRI1 C si necessaire C SI IRI3 different de 0 en entree, on utilise les descripteurs C DES3 deja presents C C Gérer le cas où la matrice est deja réduite comme il faut ??? C c *_______________________________________________________________________ IMPLICIT INTEGER(I-N) IMPLICIT REAL*8(A-H,O-Z) * -INC PPARAM -INC CCOPTIO -INC CCREEL -INC SMRIGID -INC SMELEME -INC CCHAMP -INC SMCOORD -INC SMCHPOI segment icpr(nbpts) segment inode(ino) segment jelnum(imaxel,ino) segment izone(imaxel,ino) segment INFMEL integer jmel,jcpr,jnode,kelnum,jzone endsegment * segment ilmasq(nele1) segment iddlp(nligrp) segment iddld(nligrd) segment INFRIG INTEGER jzon(NRIGEL) INTEGER jlmasq(NRIGEL) INTEGER jddlp(NRIGEL) INTEGER jddld(NRIGEL) endsegment logical ldescr * * Recuperation IMEL et objets de preconditionnements eventuels * MELEME=jmel nbsou=lisous(/1) if (jcpr.eq.0) then * * creation d'une numerotation locale * segini icpr ino=0 do 1 i =1, nbsou ipt1=lisous(i) do 2 j=1,ipt1.num(/2) do 22 k=1,ipt1.num(/1) ia= ipt1.num(k,j) if(icpr(ia).eq.0) then ino=ino+1 icpr(ia)=ino endif 22 continue 2 continue 1 continue * write(ioimp,*) 'ino=',ino * segprt,icpr * * on compte combien d'elements touche un noeud * segini inode do 3 i=1,nbsou ipt1=lisous(i) do 4 j=1,ipt1.num(/2) do 42 k=1,ipt1.num(/1) ia=ipt1.num(k,j) ib= icpr(ia) * write(ioimp,*) 'ia,ib=',ia,ib inode(ib)=inode(ib)+1 42 continue 4 continue 3 continue imaxel=0 do i=1,ino imaxel=max(imaxel,inode(i)) inode(i)=0 enddo segini jelnum,izone * * jelnum(i,k) dira le Ieme element qui touche le noeud k * izone (i,k) dira dans quel lisous le ieme element se trouve * attention le noeud K est le plus petit de l'élément * do 5 i=1,nbsou ipt1=lisous(i) do 6 j=1,ipt1.num(/2) ipeti=igrand do k=1,ipt1.num(/1) ipeti=min(ipt1.num(k,j),ipeti) enddo * write(ioimp,*) 'ipeti=',ipeti ib= icpr(ipeti) inode(ib)=inode(ib)+1 ic=inode(ib) jelnum(ic,ib)=j izone(ic,ib)=i 6 continue 5 continue * segprt,izone * segprt,jelnum * Sauvegarde des objets créés dans INFMEL jcpr=icpr jnode=inode kelnum=jelnum jzone=izone endif icpr=jcpr inode=jnode jelnum=kelnum izone=jzone * * Matrice réduite (sortie) * RI1=IRI1 SEGACT MELEME IF (IRI3.EQ.0) THEN ldescr=.true. NRIG3=LISOUS(/1) NRIGEL=NRIG3 SEGINI RI3 IRI3=RI3 RI3.MTYMAT='CMCT5' RI3.IFORIG=IFOUR RI3.MCRCNF=MCOORD NLIGRP=0 NLIGRD=0 DO irig3=1,nrig3 SEGINI,DES3 RI3.IRIGEL(3,irig3)=DES3 ENDDO ELSE ldescr=.false. RI3=IRI3 SEGACT RI3*MOD NRIG3=RI3.COERIG(/1) IF (NRIG3.NE.LISOUS(/1)) THEN write(ioimp,*) 'Erreur grave 1 dans cmct5' return endif DO irig3=1,nrig3 DES3=RI3.IRIGEL(3,irig3) SEGACT,DES3 ENDDO ENDIF RI3.MTYMAT='CMCT5' RI3.IFORIG=IFOUR RI3.MCRCNF=MCOORD DO irig3=1,nrig3 RI3.COERIG(irig3)=1.D0 ipt3=LISOUS(irig3) RI3.IRIGEL(1,irig3)=ipt3 ENDDO * * Traitement de la matrice d'entree * SEGACT RI1 NRIG1=RI1.COERIG(/1) NRIGEL=NRIG1 SEGINI INFRIG * DO IRIG1=1,nrig1 IPT1=RI1.IRIGEL(1,IRIG1) * Y a-t-il des elements a considerer SEGACT IPT1 nele1=ipt1.num(/2) segini ilmasq nnod1=ipt1.num(/1) izon =0 ielzo=0 DO 11 iele1=1,nele1 ipeti=IGRAND DO inod1=1,nnod1 ipeti=min(ipeti,ipt1.num(inod1,iele1)) enddo * on regarde s'il existe un element de ipt1 ayant ce noeud en plus * petit position si non on passe a l'élément suivant ib=icpr(ipeti) if(ib.eq.0) go to 11 if(inode(ib).eq.0) go to 11 do 13 mm=1,inode(ib) kzon=izone(mm,ib) ipt3 = lisous(kzon) if (ipt3.eq.ipt1) then segsup ilmasq ilmasq=-1 izon=kzon ielzo=ipt3.num(/2) goto 14 endif if (ipt3.num(/1).ne.ipt1.num(/1)) go to 13 iel=jelnum(mm,ib) do in=1,ipt1.num(/1) if( ipt1.num(in,iele1).ne.ipt3.num(in,iel))go to 13 enddo * on a trouve un element a conserver ielzo=ielzo+1 ilmasq(iele1)=iel if (izon.eq.0) then izon=kzon else if (izon.ne.kzon) then write(ioimp,*) 'Erreur grave 2 dans cmct5' return endif endif 13 continue 11 continue 14 continue jzon(irig1)=izon if (izon.eq.0.or.ielzo.eq.0) then segsup ilmasq ilmasq=0 endif jlmasq(irig1)=ilmasq if (ilmasq.ne.0) then * if (ilmasq.gt.0) then * segprt,ilmasq * else * write(ioimp,*) 'ilmasq=',ilmasq * endif * tableau de correspondance des DESCR DES3=RI3.IRIGEL(3,IZON) DES1=RI1.IRIGEL(3,IRIG1) SEGACT DES1 * pour la primale NLIGP1=DES1.NOELEP(/1) NLIGRP=NLIGP1 SEGINI IDDLP DO ILIGP1=1,NLIGP1 nno1=des1.noelep(iligp1) ilig3=0 nligp3=des3.noelep(/1) do 113 iligp3=1,nligp3 if (des3.noelep(iligp3).ne.nno1) goto 113 if (des3.lisinc(iligp3).ne.des1.lisinc(iligp1)) $ goto 113 ilig3=iligp3 goto 114 113 continue 114 continue IF (ilig3.EQ.0) THEN if (ldescr) then NLIGP3=NLIGP3+1 NLIGRP=NLIGP3 NLIGRD=des3.noeled(/1) SEGADJ DES3 des3.noelep(nligp3)=des1.noelep(iligp1) des3.lisinc(nligp3)=des1.lisinc(iligp1) IDDLP(ILIGP1)=nligp3 else write(ioimp,*) 'Inconnue de nom : ' $ ,des1.lisinc(iligp1),' noeud : ' $ ,des1.noelep(iligp1) write(ioimp,*) ' presente dans la rigidite : ',ri1 write(ioimp,*) ' non presente dans la rigidite : ' $ ,ri3 return endif ELSE IDDLP(ILIGP1)=ilig3 ENDIF ENDDO JDDLP(irig1)=IDDLP * segprt,iddlp * pour la duale NLIGD1=DES1.NOELED(/1) NLIGRD=NLIGD1 SEGINI IDDLD DO ILIGD1=1,NLIGD1 nno1=des1.noeled(iligd1) ilig3=0 nligd3=des3.noeled(/1) do 213 iligd3=1,nligd3 if (des3.noeled(iligd3).ne.nno1) goto 213 if (des3.lisdua(iligd3).ne.des1.lisdua(iligd1)) $ goto 213 ilig3=iligd3 goto 214 213 continue 214 continue IF (ilig3.EQ.0) THEN if (ldescr) then NLIGD3=NLIGD3+1 NLIGRD=NLIGD3 NLIGRP=des3.noelep(/1) SEGADJ DES3 des3.noeled(nligd3)=des1.noeled(iligd1) des3.lisdua(nligd3)=des1.lisdua(iligd1) IDDLD(iligd1)=NLIGD3 else write(ioimp,*) 'Inconnue de nom : ' $ ,des1.lisdua(iligd1),' noeud : ' $ ,des1.noeled(iligd1) write(ioimp,*) ' presente dans la rigidite : ',ri1 write(ioimp,*) ' non presente dans la rigidite : ' $ ,ri3 return endif ELSE IDDLD(iligd1)=ILIG3 ENDIF ENDDO JDDLD(irig1)=IDDLD * segprt,iddld endif ENDDO * do irig3=1,nrig3 * des3=ri3.irigel(3,irig3) * write(ioimp,*) 'irig3=',irig3 * segprt,des3 * enddo * * Transfert des xmatr selon le descripteur final des3 * DO IRIG1=1,nrig1 ilmasq=jlmasq(irig1) if (ilmasq.ne.0) then izon=jzon(irig1) iddlp=jddlp(irig1) iddld=jddld(irig1) xmatr3=ri3.irigel(4,izon) xc1=RI1.COERIG(IRIG1) XMATR1=RI1.IRIGEL(4,IRIG1) SEGACT XMATR1 if (xmatr3.eq.0) then ipt3=ri3.irigel(1,izon) des3=ri3.irigel(3,izon) NLIGRD=des3.NOELED(/1) NLIGRP=des3.NOELEP(/1) NELRIG=ipt3.num(/2) SEGINI XMATR3 ri3.irigel(4,izon)=xmatr3 ri3.irigel(7,izon)=max(ri3.irigel(7,izon),ri1.irigel(7 $ ,irig1)) xmatr3.symre=max(xmatr3.symre,xmatr1.symre) endif NLIGD1=XMATR1.RE(/1) NLIGP1=XMATR1.RE(/2) NELE1 =XMATR1.RE(/3) if (ilmasq.gt.0) then DO iele1=1,nele1 iele3=ilmasq(iele1) IF (iele3.ne.0) THEN DO ILIGP1=1,NLIGP1 ILIGP3=IDDLP(ILIGP1) DO ILIGD1=1,NLIGD1 ILIGD3=IDDLD(ILIGD1) XMATR3.RE(ILIGD3,ILIGP3,IELE3)= $ XMATR3.RE(ILIGD3,ILIGP3,IELE3) $ +XMATR1.RE(ILIGD1,ILIGP1,IELE1)*xc1 ENDDO ENDDO ENDIF ENDDO else DO iele1=1,nele1 DO ILIGP1=1,NLIGP1 ILIGP3=IDDLP(ILIGP1) DO ILIGD1=1,NLIGD1 ILIGD3=IDDLD(ILIGD1) XMATR3.RE(ILIGD3,ILIGP3,IELE1)= $ XMATR3.RE(ILIGD3,ILIGP3,IELE1) $ +XMATR1.RE(ILIGD1,ILIGP1,IELE1)*xc1 ENDDO ENDDO ENDDO endif endif ENDDO * do irig3=1,nrig3 * xmatr3=ri3.irigel(4,irig3) * write(ioimp,*) 'irig3=',irig3 * if (xmatr3.gt.0) then * segprt,xmatr3 * else * write(ioimp,*) 'xmatr3=',xmatr3 * endif * enddo * Menage DO IRIG1=1,nrig1 ilmasq=jlmasq(irig1) if (ilmasq.gt.0) segsup ilmasq iddlp=jddlp(irig1) if (iddlp.gt.0) segsup iddlp iddld=jddld(irig1) if (iddld.gt.0) segsup iddld ENDDO SEGSUP INFRIG RETURN END
© Cast3M 2003 - Tous droits réservés.
Mentions légales