separm
C SEPARM SOURCE PV090527 23/09/13 21:15:03 11739 IMPLICIT INTEGER(I-N) IMPLICIT REAL*8 (A-H,O-Z) integer oooval -INC SMRIGID -INC SMCOORD -INC SMELEME -INC PPARAM -INC CCOPTIO -INC CCREEL * extrait de mrigid dans ri1 la partie des relations pouvant etre * traitees comme des dependances (elimination des inconnues) * il faut que la premiere inconnue d'une dependance n'apparaisse pas * dans les autres dependances * juillet 2003 passage aux simples multiplicateurs de Lagrange, mais * separm dualise ceux qu'il garde *-INC CCHAMP segment trav1 character*(lochpo) compp(lcomp1) C* character*4 compp(nbincp) endsegment segment trav2 integer ielim(nbnoc,nbincp),iautr(nbnoc,nbincp) integer icomb(nbnoc,nbincp),ideja(nbnoc,nbincp) endsegment segment trav3 integer posinc(nligrp) endsegment segment trav4 integer itrv1(nbprl) integer itrv2(nbprl) real*8 dtrv1(nbprl) real*8 dtrv2(nbprl) endsegment segment icpr(nbpts) character*(lochpo) co1 integer ri1s,ri2s,ri1f ** write(6,*) ' entree de separm ' ** call ooodmp(0) ** nbav=oooval(2,1) * write (6,*) ' dans separm nouinl ',nounil nbdep=0 nbpiv=0 nbpvt=0 nbno=nbpts segini icpr nbnoc=0 segact mrigid do 760 irig=1,irigel(/2) meleme=irigel(1,irig) segact meleme ** write(6,*) '1 itypel dans separm',itypel do il=1,num(/2) do ip=1,num(/1) ipt=num(ip,il) if (icpr(ipt).eq.0) then nbnoc=nbnoc+1 icpr(ipt)=nbnoc endif enddo enddo 760 continue * remplissage du segment trav1 (liste des noms de composantes) lcomp1 = 50 segini trav1 nbincp=0 do 10 irig=1,irigel(/2) *** if (irigel(6,irig).ne.0.and.irigel(6,irig).ne.2 *** & .and.nounil.eq.0) goto 10 if (irigel(6,irig).ne.0.and.nounil.eq.0) goto 10 meleme=irigel(1,irig) segact meleme if (itypel.ne.22.and.itypel.ne.28) goto 20 if (irigel(7,irig).ne.0) goto 20 descr=irigel(3,irig) segact descr do 40 nligrp=2,lisinc(/2) C print *,'lisinc(',nligrp,'/',lisinc(/2),')=',lisinc(nligrp) do 50 inc=1,nbincp if (compp(inc).eq.lisinc(nligrp)) goto 40 50 continue nbincp=nbincp+1 if (nbincp.GT.lcomp1) then lcomp1 = lcomp1 + 50 segadj trav1 endif compp(nbincp)=lisinc(nligrp) 40 continue segdes,descr 20 continue 10 continue c* lcomp1 = nbincp c* segadj trav1 * on construit ri1 et ri2 en notant dans le segment trav2 ce qu'on fait * write(6,*) 'separm nbno nbnoc ',nbno,nbnoc segini trav2 * on interdit d'eliminer les inconnues apparaissant dans des conditions unilaterales * ainsi qur toutes si on est el elim 0 do 60 irig=1,irigel(/2) meleme=irigel(1,irig) if (nelim.ne.0) then if(itypel.ne.28) then if (irigel(6,irig).eq.0.or.nounil.eq.1) goto 60 endif endif ** write(6,*) 'itypel dans separm',itypel segact meleme ** if(itypel.eq.28) write(6,*) 'taille super el ',num(/1) if (itypel.ne.22.and. > (itypel.ne.28.or.num(/1).lt.255.or.if.lt.3)) goto 60 if (irigel(7,irig).ne.0) goto 60 descr=irigel(3,irig) segact descr nld=2 if(itypel.eq.28) then nld=1 ** write(6,*) 'taille super el ',num(/1) endif do 70 nligrp=nld,lisinc(/2) do 80 inc=1,nbincp C print *,'lisinc(',nligrp,'/',lisinc(/2),')=',lisinc(nligrp) C & ,' compp(',inc,')=',compp(inc) if (compp(inc).eq.lisinc(nligrp)) goto 90 80 continue *** write(ioimp,*) '- ',lisinc(nligrp),' non trouve dans trav1' goto 70 90 continue ip=noelep(nligrp) do 100 j=1,num(/2) C IF(num(ip,j).GT.ielim(/1).OR.inc.GT.ielim(/2).OR. C * num(ip,j).GT.iautr(/1).OR.inc.GT.iautr(/2))THEN C print *,'BUG DANS SEPARM : ', C & num(ip,j),'>',ielim(/1),iautr(/1), C & inc,'>',ielim(/2),iautr(/2) C ENDIF ielim(icpr(num(ip,j)),inc)=1 iautr(icpr(num(ip,j)),inc)=1 100 continue 70 continue segdes descr 60 continue 61 continue * do 700 irig=1,irigel(/2) if (irigel(6,irig).ne.0.and.nounil.eq.0) goto 690 meleme=irigel(1,irig) descr=irigel(3,irig) xmatri=irigel(4,irig) segact meleme if (itypel.ne.22) goto 690 if (irigel(7,irig).ne.0) goto 690 segact descr * remplir posinc pour accelerer les tests sur les composantes nligrp=lisinc(/2) segini trav3 do 730 inc=2,nligrp do 720 incp=1,nbincp if (lisinc(inc).eq.compp(incp)) then posinc(inc)=incp goto 730 endif 720 continue 730 continue do 750 ince=2,lisinc(/2) incp=posinc(ince) do 740 j=1,num(/2) ip=num(noelep(ince),j) icomb(icpr(ip),incp)=icomb(icpr(ip),incp)+1 740 continue 750 continue segsup trav3 690 continue 700 continue ipass=1 2000 continue segini,ri1=mrigid segini,ri2=mrigid * quelques preparatifs * on remplit le segment qui sert a trier les relations * trier pour attaquer en premier les relations portant sur le moins de noeud nbprl=irigel(/2) segini trav4 do 765 irig=1,nbprl descr=irigel(3,irig) segact descr dtrv1(irig)= lisinc(/2)+0.1 if(irigel(6,irig).ne.0) dtrv1(irig)=dtrv1(irig)+1000000 if(irigel(6,irig).eq.2) dtrv1(irig)=dtrv1(irig)+1000000 ** if(irigel(6,irig).eq.0) dtrv1(irig)=dtrv1(irig)+1000000 ** itrv1(irig)=nbprl-irig+1 itrv1(irig)= irig 765 continue do 200 iri=1,irigel(/2) irig=itrv1(iri) ** irig=iri ** if (ipass.eq.1) irig=itrv1(iri) * write(6,*) ' boucle 200 irig iri nbprl ',irig,iri,nbprl if (irigel(6,irig).ne.0.and.nounil.eq.0) goto 190 meleme=irigel(1,irig) descr=irigel(3,irig) Xmatri=irigel(4,irig) segact meleme if (itypel.ne.22) goto 190 if (irigel(7,irig).ne.0) goto 190 segact descr,Xmatri if (abs(re(1,1,1)).gt.1d-30) goto 190 * remplir posinc pour accelerer les tests sur les composantes nligrp=lisinc(/2) segini trav3 do 230 inc=2,nligrp do 220 incp=1,nbincp if (lisinc(inc).eq.compp(incp)) then posinc(inc)=incp goto 230 endif 220 continue 230 continue nbdepe=0 * pour arriver à eliminer, il est interessant de faire pivoter les matrices * on va le faire en se basant sur le milieu du paquet iel=num(/2)/2+1 incf=0 do 1000 ince=2,lisinc(/2) ipp=num(noelep(ince),iel) incpp=posinc(ince) * cette inconnue apparait elle dejà dans une autre relation if (iautr(icpr(ipp),incpp).eq.1) goto 1000 * cette matrice touche t elle une autre relation do 1240 inc=2,lisinc(/2) if (inc.eq.ince) goto 1240 incp=posinc(inc) ip=num(noelep(inc), iel) if (ielim(icpr(ip),incp).eq.1) goto 1000 1240 continue * le pivot est il correct remax=abs(re(1,1,iel)) do 1270 ilig=2,re(/2) remax=max(remax,abs(re(1,ilig,iel))) 1270 continue remax=remax*0.9 if (abs(re(1,ince,iel)).lt.remax) goto 1000 * ok on pivote si il y a lieu * write (6,*) ' ipp incpp icomb ',ipp,incpp,icomb(icpr(ipp),incpp) if (icomb(icpr(ipp),incpp).eq.1) goto 1010 if (incf.eq.0) incf=ince incf=ince goto 1000 1000 continue ince=2 if (incf.ne.0) ince=incf 1010 continue inm=0 if (ince.ne.2) then * on pivote 2 et ince * write (6,*) ' on pivote avec la ligne ',ince nbpvt=nbpvt+1 incp=posinc(ince) posinc(ince)=posinc(2) posinc(2)=incp segini,des1=descr segdes descr descr=des1 ri1.irigel(3,irig)=descr ri2.irigel(3,irig)=descr * write (6,*) noelep(2),noelep(ince),lisinc(2),lisinc(ince) co1=lisinc(2) lisinc(2)=lisinc(ince) lisinc(ince)=co1 co1=lisdua(2) lisdua(2)=lisdua(ince) lisdua(ince)=co1 noe=noelep(2) noelep(2)=noelep(ince) noelep(ince)=noe noe=noeled(2) noeled(2)=noeled(ince) noeled(ince)=noe inm=1 segini,Xmatr1=Xmatri segdes Xmatri Xmatri=Xmatr1 ri1.irigel(4,irig)=Xmatri ri2.irigel(4,irig)=Xmatri do 1100 im=1,re(/3) do 1130 il=1,re(/1) ret=re(il,2,im) re(il,2,im)=re(il,ince,im) re(il,ince,im)=ret 1130 continue do 1160 il=1,re(/2) ret=re(2,il,im) re(2,il,im)=re(ince,il,im) re(ince,il,im)=ret 1160 continue * segdes xmatri 1100 continue endif * peut etre une dependance segini,ipt1=meleme if(inm.eq.0) then segini,xmatr1=xmatri else xmatr1=xmatri endif * write(6,*) 'separm xmatr1 ipt1 ipt1.itypel ', * > xmatr1,ipt1,ipt1.itypel do 210 j=1,num(/2) ip=ipt1.num(noelep(2),j) * cette matrice contient t elle des inconnues if (noelep(/1).le.1) then ipt1.num(1,j)=0 goto 210 endif incp=posinc(2) if (ipass.eq.1.and.icomb(icpr(ip),incp).ne.1) then ipt1.num(1,j)=0 goto 210 endif if (iautr(icpr(ip),incp).eq.1) then ipt1.num(1,j)=0 goto 210 endif * cette matrice touche t elle une autre relation do 240 inc=2,lisinc(/2) incp=posinc(inc) ip=ipt1.num(noelep(inc),j) if (ielim(icpr(ip),incp).eq.1) then ipt1.num(1,j)=0 goto 210 endif 240 continue * le pivot est il correct remax=xpetit*1d4 do 270 ilig=2,re(/2) remax=max(remax,abs(re(1,ilig,j))) 270 continue remax=remax*1d-2 if (abs(re(1,2,j)).le.remax) then ipt1.num(1,j)=0 nbpiv=nbpiv+1 goto 210 endif * Y a t'il deux fois la meme inconnue? ideux=0 do inc=2,lisinc(/2) if (ideja(icpr(ipt1.num(noelep(inc),j)),posinc(inc)).eq.1) then ideux=inc else ideja(icpr(ipt1.num(noelep(inc),j)),posinc(inc))=1 endif enddo do inc=2,lisinc(/2) ideja(icpr(ipt1.num(noelep(inc),j)),posinc(inc))=0 enddo if (ideux.ne.0) then moterr(1:4)=lisinc(ideux) interr(1)=ipt1.num(noelep(ideux),j) ipt1.num(1,j)=0 goto 210 endif * la matrice est elle augmentee if (abs(re(1,1,j)).gt.1d-5) then ipt1.num(1,j)=0 goto 210 endif * segdes xmatri * ok on la prend en dependance nbdepe=nbdepe+1 nbdep=nbdep+1 * write (6,*) ' inconnu eliminee ',ipt1.num(noelep(2),j), * > lisinc(2) ielim(icpr(ipt1.num(noelep(2),j)),posinc(2))=1 do 280 inc=2,lisinc(/2) iautr(icpr(ipt1.num(noelep(inc),j)),posinc(inc))=1 280 continue 210 continue segsup trav3 * il faut maintenant tasser ipt1 et creer ipt2 nbnn=num(/1) nbelem=num(/2)-nbdepe ** if(nbelem.eq.0) write(6,*) ' separm nbelem ',nbelem ** write(6,*) ' nombre d elements crees pour ipt2 ',nbelem nbsous=0 nbref=0 segini ipt2 ipt2.itypel=itypel nelrig=nbelem nligrd=re(/1) nligrp=re(/2) segini xmatr2 xmatr2.symre=symre idec=0 do 300 j=1,num(/2) if (ipt1.num(1,j).eq.0) then idec=idec+1 do 310 i=1,num(/1) ipt2.num(i,idec)=num(i,j) 310 continue do io=1,nligrp do iu=1,nligrd xmatr2.re(iu,io,idec)=re(iu,io,j) enddo enddo * imatr2.imattt(idec)=imattt(j) else do 320 i=1,num(/1) ipt1.num(i,j-idec)=num(i,j) 320 continue do io=1,nligrp do iu=1,nligrd xmatr1.re(iu,io,j-idec)=re(iu,io,j) enddo enddo * imatr1.imattt(j-idec)=imattt(j) endif 300 continue nbelem=nbdepe segadj ipt1 nelrig=nbelem segadj xmatr1 ri1.irigel(1,irig)=ipt1 ri2.irigel(1,irig)=ipt2 ri1.irigel(4,irig)=xmatr1 ri2.irigel(4,irig)=xmatr2 segdes xmatr1,xmatr2 goto 200 190 continue * pas une dependance ri1.irigel(1,irig)=0 200 continue segsup trav4 * compression de ri1 idec=0 do 500 irig=1,irigel(/2) meleme=ri1.irigel(1,irig) if (meleme.eq.0) then idec=idec+1 else segact meleme if (num(/2).eq.0) then idec=idec+1 segsup meleme xmatri=ri1.irigel(4,irig) segsup xmatri else do 510 ir=1,irigel(/1) ri1.irigel(ir,irig-idec)=ri1.irigel(ir,irig) 510 continue ri1.coerig(irig-idec)=ri1.coerig(irig) endif endif 500 continue nrige=max(irigel(/1),8) nrigel=irigel(/2)-idec * write (6,*) ' dimension de ri1 ',nrige,nrigel segadj ri1 do irig=1,nrigel ri1.irigel(8,irig)=1 enddo * compression de ri2 idec=0 do 600 irig=1,irigel(/2) meleme=ri2.irigel(1,irig) if (meleme.eq.0) then idec=idec+1 else segact meleme if (num(/2).eq.0) then idec=idec+1 segsup meleme xmatri=ri2.irigel(4,irig) segsup xmatri else do 610 ir=1,irigel(/1) ri2.irigel(ir,irig-idec)=ri2.irigel(ir,irig) 610 continue ri2.coerig(irig-idec)=ri2.coerig(irig) endif endif 600 continue nrige=max(irigel(/1),8) nrigel=irigel(/2)-idec * write (6,*) ' dimension de ri2 ',nrige,nrigel segadj ri2 do irig=1,nrigel ri2.irigel(8,irig)=0 enddo * On va voir si on ne peut pas faire pivoter ri2 if (ipass.eq.2) goto 2001 ri1s=ri1 ri2s=ri2 mrigis=mrigid mrigid=ri2 nbpiv=0 ipass=ipass+1 goto 2000 2001 continue mrigid=mrigis ri1=ri1f segsup trav1,trav2,icpr if (iimpi.ne.0) then write (6,*) ' nombre de relations éliminées ',nbdep write (6,*) ' nombre de relations gardées à cause du pivot ', > nbpiv write (6,*) ' nombre de relations gardées car non indépendantes ', > nbinc write (6,*) ' nombre de paquets pivotés ', > nbpvt endif * dualisation des multiplicateurs de Lagrange dans ri2 * si on a des conditions unilatérales, on ne dualise pas, ce sera fait * dans le resou de unilater iunil=0 segact ri2 do ir=1,ri2.irigel(/2) if (ri2.irigel(6,ir).ne.0) iunil=1 enddo if ((iunil.eq.0.or.nounil.eq.1).and.lagdua.ge.0) * write(6,*) ' dans separm lagdua ',lagdua * write (6,*) ' matrice ri1 ' * call prrigi(ri1) * write (6,*) ' matrice ri2 ' * call prrigi(ri2) ** write(6,*) ' sortie de separm ' ** call ooodmp(0) ** nbap=oooval(2,1) ** write(6,*) 'nb segmts dans separm avant apres ',nbav,nbap end
© Cast3M 2003 - Tous droits réservés.
Mentions légales