scnd3
C SCND3 SOURCE MB234859 25/02/17 21:15:14 12155 C subroutine scnd3(mrigid,ri1,ri4) C---------------------------------------------------------------------- C Eliminer les inconnues dependantes des matrices elementaires C C Entrees : C --------- C MRIGID : pointeur MRIGID sur les rigidites elementaires a conserver. C ri1 : pointeur MRIGID sur les rigidites elementaires reecrites C sous forme de dependance : indique les noeuds a eliminer. C C Sortie : C --------- C ri4 : pointeur MRIGID sur les rigidites elementaires a conserver C ou ont ete eliminees les inconnues dependantes. C C Remarque : Le(s) ddl(s) dont dependantes les ddls a eliminer ne sont C pas eliminables dans la meme passe. C---------------------------------------------------------------------- IMPLICIT INTEGER(I-N) IMPLICIT REAL*8 (A-H,O-Z) C -INC PPARAM -INC CCOPTIO -INC CCHAMP -INC CCREEL -INC SMCOORD -INC SMRIGID -INC SMELEME C segment trav1 character*4 compd(nbincl),compdd(nbincl) endsegment segment trav2 integer irigd(nbnoc,nbincd),nelrigd(nbnoc,nbincd) endsegment segment trav3 integer cor1p(nligrp5),cor1d(nligrd5) endsegment C segment ldesc(6,ndes) segment lrigi(nbrig) segment lelem(3,nelem) segment ltrav integer iporig(ncomp),ipnouv(ncomp),iligne(nlr,ncomp) integer ipinco(ncomp),ipnode(ncomp),innode(ncomp),nbrel(ncomp) real*8 xcoeff(nlr,ncomp) endsegment pointeur ltravp.ltrav,ltravd.ltrav segment linco(nnoeud) segment xrela(nligrm5) segment lincp(nligrp5) segment lincd(nligrd5) character*(LOCHPO) coelim,coelid logical bvu,bnew,bnsym,bok C ================================================================= C Segments trav1 (noms de composantes) et icpr (numero de noeuds) C ================================================================= xzref=5.d-12 nde0=8 nbdeg=0 nbincd=0 nbincl=8 segini trav1 nbno=nbpts segini icpr nbnoc=0 nrigto=0 C C Rigidite contenant les inconnues a eliminer segact ri1 nri1=ri1.irigel(/2) do 10 irig=1,nri1 descr=ri1.irigel(3,irig) segact descr C C Composante a eliminer (lisdua(/2)=1) coelim=lisdua(1) do 50 inc=1,nbincd if (compd(inc).eq.coelim) goto 40 50 continue C C Ajout de la composante nbincd=nbincd+1 if(nbincd.gt.nbincl) then nbincl=nbincd+8 segadj trav1 endif compd(nbincd)=coelim C 40 continue C C Identifier les noeuds presents meleme=ri1.irigel(1,irig) segact meleme do j=1,num(/2) do k=1,num(/1) ip=num(k,j) if(icpr(ip).eq.0) then nbnoc=nbnoc+1 icpr(ip)=nbnoc endif enddo enddo C C Boucle sur les composantes dont peut dependre l'inc eliminee do 45 iligrd=1,lisinc(/2) do 55 inc=1,nbincd if (compd(inc).eq.lisinc(iligrd)) goto 45 55 continue C C Ajout de la composante nbincd=nbincd+1 inc=nbincd if(nbincd.gt.nbincl) then nbincl=nbincd+8 segadj trav1 endif compd(nbincd)=lisinc(iligrd) C 45 continue 10 continue * write (6,*) ' scnd3 - 1 ',(compd(i),i=1,nbincd) C C Rigidite contenant les matrices elementaires a conserver segact mrigid nbrig=mrigid.irigel(/2) nnoeud=0 nligrp5=0 nligrd5=0 do 110 irig=1,nbrig descr=irigel(3,irig) segact descr lpri=lisinc(/2) ldua=lisdua(/2) nligrp5=max(nligrp5,lpri) nligrd5=max(nligrd5,ldua) do 140 iprim=1,lpri do 150 ico=1,nbincd if (compd(ico).eq.lisinc(iprim)) goto 140 150 continue C C Ajout de la composante nbincd=nbincd+1 ico=nbincd if(nbincd.gt.nbincl) then nbincl=nbincd+8 segadj trav1 endif compd(nbincd)=lisinc(iprim) C 140 continue C C Identifier les noeuds presents meleme=irigel(1,irig) segact meleme nnoeud=max(nnoeud,num(/1)) do j=1,num(/2) do i=1,num(/1) ip=num(i,j) if(icpr(ip).eq.0) then nbnoc=nbnoc+1 icpr(ip)=nbnoc endif enddo enddo 110 continue nligrm5=max(nligrp5,nligrd5) segini,linco,xrela,lincp,lincd,trav3 * write (6,*) ' scnd3 - 2 ',(compd(i),i=1,nbincd) C C Noms des composantes duales : recuperer dans nomdu C eventuellement surcharger/completer par l'utilisateur (opti inco) do 300 i=1,nbincd do 310 j=1,lnomdd if (compd(i).eq.nomdd(j)) goto 320 310 continue C C write (6,*) 'Inco. non definie ',compd(i),' ',compdd(i) moterr(1:LOCHPO)=compd(i) return C 320 continue compdd(i)=nomdu(j) ** write (6,*) ' correspondance ', compd(i), compdd(i) 300 continue * write (6,*) ' scnd3 - 3 ',compd(/2),(compd(i),i=1,compd(/2)) * write (6,*) ' scnd3 - 3 ',compdd(/2),(compdd(i),i=1,compdd(/2)) C ================================================================= C Segment trav2 : identifier les numeros des noeuds a eliminer C ================================================================= segini trav2 do 200 irig=1,nri1 meleme=ri1.irigel(1,irig) descr =ri1.irigel(3,irig) do 250 ico=1,nbincd if (compd(ico).eq.lisdua(1)) goto 260 250 continue 260 continue do 240 i=1,num(/2) ip=num(noeled(1),i) irigd(icpr(ip),ico)=irig nelrigd(icpr(ip),ico)=i 240 continue 200 continue C C Nombre max de relations dans lesquelles intervient un ddl donne nlr=0 do 201 irig=1,nri1 meleme=ri1.irigel(1,irig) descr =ri1.irigel(3,irig) lpri=noelep(/1) do 241 i=1,num(/2) do 242 j=1,lpri ip=num(noelep(j),i) do 252 ico=1,nbincd if (compd(ico).eq.lisinc(j)) goto 262 252 continue 262 continue if (nelrigd(icpr(ip),ico).gt.0) goto 242 nelrigd(icpr(ip),ico)=nelrigd(icpr(ip),ico)-1 nlr=max(nlr,abs(nelrigd(icpr(ip),ico))) 242 continue 241 continue 201 continue C ================================================================= C Eliminer des matrices elementaires les inc qui doivent l'etre C ================================================================= ndes=nde0 segini,lrigi,ldesc krigel=0 C ---------------------------- C Boucle sur les sous-matrices do 1000 irig=1,nbrig ipt4 =mrigid.irigel(1,irig) des4 =mrigid.irigel(3,irig) xmatr4=mrigid.irigel(4,irig) segact,ipt4,des4,xmatr4 C C La matrice est-elle symetrique bnsym=(xmatr4.symre.ne.0) C nelrig=xmatr4.re(/3) nligrp4=des4.lisinc(/2) nligrd4=des4.lisdua(/2) C C Correspondance lisinc, lisdua, numero ico dans trav1 do 410 iprim=1,nligrp4 cor1p(iprim)=0 do 420 ico=1,nbincd if (compd(ico).eq.des4.lisinc(iprim)) then cor1p(iprim)=ico goto 410 endif 420 continue ** write(6,*) 'cor1p pas de correspondance' ** call erreur(5) 410 continue C do 510 idua=1,nligrd4 cor1d(idua)=0 do 520 ico=1,nbincd if (compdd(ico).eq.des4.lisdua(idua)) then cor1d(idua)=ico goto 510 endif 520 continue ** call erreur(5) 510 continue C nnoeu=ipt4.num(/1) nelem=ipt4.num(/2) segini,lelem lrigi(irig)=lelem bvu=.false. C C =============================================================== C Boucle sur les elements C =============================================================== do 1040 iel=1,nelem C C Reinitialiser linco, lincp et lincd do inn=1,nnoeu linco(inn)=0 enddo do inn=1,nligrp4 lincp(inn)=0 enddo if (bnsym) then do inn=1,nligrd4 lincd(inn)=0 enddo endif ipass=1 C icpt=0 kelimp=0 ncor=0 do 1009 iligri=1,nligrp4 incp=cor1p(iligri) ip=ipt4.num(des4.noelep(iligri),iel) inn=des4.noelep(iligri) linco(inn)=linco(inn)+1 C C Ce ddl est-il a eliminer if (nelrigd(icpr(ip),incp).le.0) then icpt=icpt+1 lincp(iligri)=icpt goto 1009 endif C linco(inn)=linco(inn)-1 irig1=irigd(icpr(ip),incp) i1 =nelrigd(icpr(ip),incp) des1 =ri1.irigel(3,irig1) ncor=ncor+des1.lisinc(/2) kelimp=kelimp+1 1009 continue C C Matrice non symetrique : verifier si la duale de l'inconnue C eliminee n'est pas presente kelimd=kelimp if (bnsym) then icpt=0 kelimd=0 do 1010 iligrd=1,nligrd4 incd=cor1d(iligrd) ip=ipt4.num(des4.noeled(iligrd),iel) inn=des4.noeled(iligrd) linco(inn)=linco(inn)+1 C C L'inconnue primale associee est-il eliminee if (nelrigd(icpr(ip),incd).le.0) then icpt=icpt+1 lincd(iligrd)=icpt goto 1010 endif C linco(inn)=linco(inn)-1 irig1=irigd(icpr(ip),incd) i1 =nelrigd(icpr(ip),incd) des1 =ri1.irigel(3,irig1) ncor=ncor+des1.lisinc(/2) kelimd=kelimd+1 1010 continue endif C C ------------------------------------------------------------- C Pas de modification a apporter, passer a l'element suivant if ((kelimp+kelimd).eq.0) then if (.not.bvu) then krigel=krigel+1 jdori=krigel isizz=ldesc(/2) if (isizz.lt.jdori) then ndes=jdori+nde0 segadj,ldesc endif ldesc(1,jdori)=des4 ldesc(2,jdori)=0 ldesc(3,jdori)=mrigid.irigel(2,irig) ldesc(4,jdori)=mrigid.irigel(5,irig) ldesc(5,jdori)=mrigid.irigel(6,irig) ldesc(6,jdori)=mrigid.irigel(7,irig) bvu=.true. endif lelem(1,iel)=ipt4 lelem(2,iel)=jdori lelem(3,iel)=-1*xmatr4 ldesc(2,jdori)=ldesc(2,jdori)+1 goto 1040 endif C C ------------------------------------------------------------- C Modifications de la matrice elementraire C C Les noeuds sont-ils toujours presents nbn1=0 do ind=1,nnoeu if (linco(ind).gt.0) then nbn1=nbn1+1 linco(ind)=nbn1 endif enddo C ncomp=nligrp4+ncor segini,ltravp ltrav=ltravp nbcomp=nligrp4 ncompp=ncomp kelim=kelimp kno=0 C 1111 continue C if (ipass.eq.2) then ncomp=nligrd4+ncor segini,ltravd ltrav=ltravd nbcomp=nligrd4 ncompd=ncomp kelim=kelimd endif C ltrav.iporig(icc)=icc if (ipass.eq.1) then ipn=des4.noelep(icc) incp=cor1p(icc) else ipn=des4.noeled(icc) incp=cor1d(icc) endif if (linco(ipn).ne.0) then ip=ipt4.num(ipn,iel) ltrav.innode(icc)=ip ltrav.ipnode(icc)=linco(ipn) ltrav.ipinco(icc)=incp C Ce ddl est-il a eliminer if (nelrigd(icpr(ip),incp).le.0) then if (ipass.eq.1) ltrav.ipnouv(icc)=lincp(icc) if (ipass.eq.2) ltrav.ipnouv(icc)=lincd(icc) endif endif enddo C kligrp4=0 kcomp=nbcomp C if (ipass.eq.1) then ipn=des4.noelep(iligri) incp=cor1p(iligri) else ipn=des4.noeled(iligri) incp=cor1d(iligri) endif ip=ipt4.num(ipn,iel) C C Ce ddl est-il a eliminer if (nelrigd(icpr(ip),incp).le.0) goto 1011 C C Le(s) ddl(s) lie(s) au ddl elimine exite(nt)-il(s) irig1=irigd(icpr(ip),incp) i1 =nelrigd(icpr(ip),incp) ipt1 =ri1.irigel(1,irig1) des1 =ri1.irigel(3,irig1) xmatr1=ri1.irigel(4,irig1) segact,xmatr1 C xvalm=0.d0 do icoel=1,des1.lisinc(/2) xvalm=max(xvalm,abs(xmatr1.re(1,icoel,i1))) enddo xvalm=xvalm*xzref C C ----------------------------------------------------------- do 1012 icoel=1,des1.lisinc(/2) C C Coefficient de la relation non significatif : iterer if (abs(xmatr1.re(1,icoel,i1)).le.xvalm) goto 1012 C ipl=ipt1.num(des1.noelep(icoel),i1) C do 1420 ico=1,nbincd if (compd(ico).eq.des1.lisinc(icoel)) then iprim=ico goto 1410 endif 1420 continue 1410 continue C C Noeuds deja presents dans l'element ino=0 ipo=0 do 1013 idq=1,ncomp if (ltrav.innode(idq).ne.ipl) goto 1013 ino=ltrav.ipnode(idq) if (ltrav.ipinco(idq).ne.iprim) goto 1013 ipo=idq goto 1014 1013 continue C C Il faut ajouter un noeud au segment descripteur if (ino.eq.0) then kno=kno+1 ino=nbn1+kno endif C C Il faut completer le segment descripteur kligrp4=kligrp4+1 C 1014 continue C if (ipo.eq.0) then C Conserver les informations du nouveau ddl kcomp=kcomp+1 ltrav.innode(kcomp)=ipl ltrav.ipnode(kcomp)=ino ltrav.ipinco(kcomp)=iprim ltrav.ipnouv(kcomp)=nbcomp-kelim+kligrp4 ipo=kcomp endif C ltrav.nbrel(ipo)=ltrav.nbrel(ipo)+1 ltrav.xcoeff(ltrav.nbrel(ipo),ipo)=xmatr1.re(1,icoel,i1) ltrav.iligne(ltrav.nbrel(ipo),ipo)=ltrav.iporig(iligri) C 1012 continue C ----------------------------------------------------------- C 1011 continue C C Cas d'une matrice vide if (ipass.eq.1) then nligrp=nligrp4-kelimp+kligrp4 if (nligrp.eq.0) goto 1040 C C Matrice non-symetrique : refaire le travail sur les duales if (bnsym) then ipass=2 goto 1111 endif C C Matrice symetrique : infos duals identiques ltravd=ltravp ncompd=ncompp nligrd=nligrp else nligrd=nligrd4-kelimd+kligrp4 if (nligrd.eq.0) goto 1040 endif C C Matrice de relation vide car tout a ete elimine ityp4=28 if ((ipt4.itypel.eq.49).or.(ipt4.itypel.eq.22)) then iid=1 if (ipt4.itypel.eq.49) iid=2 if (nligrp.le.iid) then nbdeg=nbdeg+1 goto 1040 endif ityp4=ipt4.itypel endif C C Creation du nouveau maillage, descripteur, matrice C nbnn=nbn1+kno nbelem=1 nbref=0 nbsous=0 segini,ipt2 ipt2.itypel=ityp4 C segini,des2 C nelrig=1 segini,xmatr2 xmatr2.symre=xmatr4.symre C C Renseigner le maillage et le descripteur do 1021 ic=1,ncompp inew=ltravp.ipnouv(ic) if (inew.ne.0) then des2.noelep(inew)=ltravp.ipnode(ic) des2.lisinc(inew)=compd(ltravp.ipinco(ic)) ipt2.num(ltravp.ipnode(ic),1)=ltravp.innode(ic) endif 1021 continue do 1022 ic=1,ncompd inew=ltravd.ipnouv(ic) if (inew.ne.0) then des2.noeled(inew)=ltravd.ipnode(ic) des2.lisdua(inew)=compdd(ltravd.ipinco(ic)) ipt2.num(ltravd.ipnode(ic),1)=ltravd.innode(ic) endif 1022 continue C C Renseigner la matrice do 1024 ic=1,ncompp iori=ltravp.iporig(ic) inew=ltravp.ipnouv(ic) if (inew.ne.0) then C C Reinitialiser xrela if (iori.ne.0) then do il=1,nligrd4 xrela(il)=xmatr4.re(il,iori,iel) enddo else do il=1,nligrd4 xrela(il)=0.D0 enddo endif C do inr=1,ltravp.nbrel(ic) xtmp=ltravp.xcoeff(inr,ic) ilig=ltravp.iligne(inr,ic) do il=1,nligrd4 xval=xmatr4.re(il,ilig,iel)*xtmp xrela(il)=xrela(il)+xval enddo enddo C do ie=1,ncompd knew=ltravd.ipnouv(ie) if (knew.ne.0) then xval=0.D0 if (ie.le.nligrd4) xval=xrela(ie) do inr=1,ltravd.nbrel(ie) xtmp=ltravd.xcoeff(inr,ie) ilig=ltravd.iligne(inr,ie) xval=xval+xtmp*xrela(ilig) enddo xmatr2.re(knew,inew,1)=xmatr2.re(knew,inew,1)+xval endif enddo C endif 1024 continue C C Supprimer les segments de travail segsup,ltravp if (bnsym) segsup,ltravd C C Recyclage eventuel du descripteur jdes=0 if (krigel.ge.1) then do 1031 ides=1,krigel des3=ldesc(1,ides) C C A-t-on les memes caracteristiques? if (ldesc(3,ides).ne.mrigid.irigel(2,irig)) goto 1030 if (ldesc(4,ides).ne.mrigid.irigel(5,irig)) goto 1030 if (ldesc(5,ides).ne.mrigid.irigel(6,irig)) goto 1030 if (ldesc(6,ides).ne.mrigid.irigel(7,irig)) goto 1030 C if (nligrd.ne.des3.noeled(/1)) goto 1030 if (nligrp.ne.des3.noelep(/1)) goto 1030 do id1=1,nligrd if (des2.noeled(id1).ne.des3.noeled(id1)) goto 1030 if (des2.lisdua(id1).ne.des3.lisdua(id1)) goto 1030 enddo do id1=1,nligrp if (des2.noelep(id1).ne.des3.noelep(id1)) goto 1030 if (des2.lisinc(id1).ne.des3.lisinc(id1)) goto 1030 enddo C jdes=ides ldesc(2,jdes)=ldesc(2,jdes)+1 segsup,des2 goto 1032 1030 continue 1031 continue 1032 continue endif C if (jdes.eq.0) then krigel=krigel+1 jdes=krigel isizz=ldesc(/2) if (isizz.lt.jdes) then ndes=jdes+nde0 segadj,ldesc endif ldesc(1,jdes)=des2 ldesc(2,jdes)=1 ldesc(3,jdes)=mrigid.irigel(2,irig) ldesc(4,jdes)=mrigid.irigel(5,irig) ldesc(5,jdes)=mrigid.irigel(6,irig) ldesc(6,jdes)=mrigid.irigel(7,irig) endif C lelem(1,iel)=ipt2 lelem(2,iel)=jdes lelem(3,iel)=xmatr2 C 1040 continue C =============================================================== C 1000 continue C Fin de boucle sur les sous-matrices C ----------------------------------- segsup,linco,xrela,lincp,lincd,trav3 C ================================================================= C Construire la rigidite ou les inconnues ont ete eliminees C ================================================================= nrigel=krigel segini,ri4 ri4.mtymat='TEMPORAI' ri4.iforig=mrigid.iforig do ibr=1,nbrig lelem=lrigi(ibr) ipt4 =mrigid.irigel(1,ibr) C C Renseigner les matrices elementaires do 1042 iel=1,ipt4.num(/2) ipt6=lelem(1,iel) if (ipt6.eq.0) goto 1042 kdes=lelem(2,iel) xmatr6=lelem(3,iel) C itmp=1 bnew=.true. if (xmatr6.lt.0) then bnew=.false. xmatr6=abs(xmatr6) itmp=iel endif C des3=ldesc(1,kdes) nelt=ldesc(2,kdes) ipt5=ri4.irigel(1,kdes) C C Creation de la sous-matrice if (ipt5.eq.0) then ldesc(2,kdes)=1 C nligrp=des3.noelep(/1) nligrd=des3.noeled(/1) nelrig=nelt C bok=(nelrig.eq.xmatr6.re(/3).and.bnew) if (bok) then xmatr5=xmatr6 ipt5=ipt6 goto 1041 endif C segini,xmatr5 xmatr5.symre=xmatr6.symre C nbnn=ipt6.num(/1) nbelem=nelt nbref=0 nbsous=0 segini,ipt5 if (bnew) then ipt5.itypel=28 if ((ipt6.itypel.eq.49).or.(ipt6.itypel.eq.22)) then ipt5.itypel=ipt6.itypel endif else ipt5.itypel=ipt6.itypel endif C 1041 continue C ri4.coerig(kdes)=mrigid.coerig(ibr) ri4.irigel(1,kdes)=ipt5 ri4.irigel(2,kdes)=mrigid.irigel(2,ibr) ri4.irigel(3,kdes)=des3 ri4.irigel(4,kdes)=xmatr5 ri4.irigel(5,kdes)=mrigid.irigel(5,ibr) ri4.irigel(6,kdes)=mrigid.irigel(6,ibr) ri4.irigel(7,kdes)=mrigid.irigel(7,ibr) ri4.irigel(8,kdes)=mrigid.irigel(8,ibr) C if (bok) goto 1042 endif C ielmt=ldesc(2,kdes) do inn=1,ipt6.num(/1) ipt5.num(inn,ielmt)=ipt6.num(inn,itmp) enddo C xcoer=mrigid.coerig(ibr)/ri4.coerig(kdes) xmatr5=ri4.irigel(4,kdes) do ilc=1,xmatr5.re(/2) do ili=1,xmatr5.re(/1) xmatr5.re(ili,ilc,ielmt)=xcoer*xmatr6.re(ili,ilc,itmp) enddo enddo C ldesc(2,kdes)=ldesc(2,kdes)+1 if (bnew) segsup,ipt6,xmatr6 1042 continue segsup,lelem enddo segsup,icpr,trav1,trav2,lrigi,ldesc C CCC WRITE(*,*) 'MRIGID' CCC call prrigi(MRIGID,0) CCC WRITE(*,*) 'RI1' CCC call prrigi(ri1,0) CCC WRITE(*,*) 'RI4' CCC call prrigi(ri4,0) C ================================================================= C Desactivation generale C ================================================================= segact mrigid do irig=1,nbrig xmatri=irigel(4,irig) meleme=irigel(1,irig) descr=irigel(3,irig) segdes xmatri,descr enddo segact ri4 do irig=1,ri4.irigel(/2) xmatri=ri4.irigel(4,irig) meleme=ri4.irigel(1,irig) descr=ri4.irigel(3,irig) segdes xmatri,descr enddo segact ri1 do irig=1,nri1 xmatri=ri1.irigel(4,irig) meleme=ri1.irigel(1,irig) descr=ri1.irigel(3,irig) segdes xmatri,descr enddo if(iimpi.ne.0.and.nbdeg.ne.0) > write (6,*) ' nombre de relations degenerees'// > ' apres elimination ',nbdeg * write(6,*) 'nbincl nligrp5 nnoeud ndes nlr', * > nbincl,nligrp5,nnoeud,ndes,nlr end
© Cast3M 2003 - Tous droits réservés.
Mentions légales