resou
C RESOU SOURCE MB234859 25/01/03 21:15:26 12105 SUBROUTINE RESOU C---------------------------------------------------------------------- C **** CET OPERATEUR SERT A RESOUDRE UN SYSTEME D EQUATIONS LINEAIRES C **** CHPOINT = RESOU RIGIDITE CHPOINT C---------------------------------------------------------------------- IMPLICIT INTEGER(I-N) IMPLICIT REAL*8 (A-H,O-Z) C -INC PPARAM -INC CCOPTIO -INC SMRIGID -INC SMTEXTE -INC SMTABLE -INC SMCHPOI -INC SMELEME -INC SMLCHPO -INC CCREEL C SEGMENT IDEMEM(0) segment ideme0(idemem(/1),30) segment ideme1(idemem(/1),30) segment idnote(0) C CHARACTER*4 LISM(9) CHARACTER*72 CHARRE REAL*8 XVA LOGICAL ILOG,ILUG,casfimp,notok,bdblx DATA LISM/'NOID','NOUN','ENSE','GRAD','CHOL','STAB','ELIM', >'NOST','SOUC'/ DATA ILOG/.FALSE./ C XVA=REAL(0.D0) IOB=0 C * sauvegarde norinc * write(6,*) 'norinc norind ',norinc,norind norins=norinc iverif=1 ipt8=0 iunil=0 * le defaut est de faire une passe d'elimination nelim=30 * experimentalement 2 passes est mieux nelim=2 IMTVID=0 NOUNIL=0 NOID=0 NOEN=1 IGRADJ = 0 ICHSKI = 0 INSYM = 0 KIKI=0 KSYMET = 0 IPSHPO = 0 ISTAB=0 ISOUCI = 0 ifochs = -99 NDEMEM=0 C---------------------------------------------------------------------- C LECTURE DES ARGUMENTS DE L'OPERATEUR RESOU C---------------------------------------------------------------------- C LECTURE DES OPTIONS/MOTS-CLES 5 CONTINUE IF (KIKI.EQ.1) NOID=1 IF (KIKI.EQ.2) NOUNIL=1 IF (KIKI.EQ.3) NOEN=0 * IF (KIKI.EQ.4) IGRADJ = 1 * IF (KIKI.EQ.5) ICHSKI = 1 * IF (KIKI.EQ.4.OR.KIKI.EQ.5) KSYMET = 1 IF (KIKI.EQ.6) ISTAB=1 IF (KIKI.EQ.7) then nelim=min(30,max(0,nelim)) endif IF (KIKI.EQ.8) ISTAB=0 IF (KIKI.EQ.9) ISOUCI=1 IF (KIKI.NE.0) GOTO 5 C if (noid.eq.1) iverif=0 IF(NUCROU.EQ.0) THEN ICHSKI=1 ELSEIF(NUCROU.EQ.1) THEN IGRADJ=1 KSYMET=1 ENDIF * WRITE(6,*) ' nucrou', nucrou * IF ( IGRADJ + ICHSKI .EQ. 0 ) ICHSKI = 1 C C LECTURE DE LA RIGIDITE IF(IERR.NE.0) GO TO 5000 IPRIGO=IPOIRI C C LECTURE DE LA PRECISION PREC=REAL(xspeti) IF(IERR.NE.0) GO TO 5000 C C REMPLISSAGE DU 2ND MEMBRE IDEMEM(**) A PARTIR DE C ... CHPOINT SEGINI IDEMEM 1 CONTINUE IF(IRETOU.NE.0) THEN IDEMEM(**)=ISECO NDEMEM=NDEMEM+1 mchpoi=iseco segact mchpoi if (mchpoi.jattri(/1).ge.1) then notok=(mchpoi.jattri(1).ne.2) else notok=.true. endif if (notok) then INTERR=mchpoi endif GOTO 1 ENDIF C C ... LISTCHPO IF(IRETOU.NE.0) THEN mlchpo=ISECO segact mlchpo NDEMEM = ichpoi(/1) do iu = 1,NDEMEM idemem(**) = ichpoi(iu) * write(6,*) ' extension idemem 2 ',idemem(/1) enddo segdes mlchpo n1 = ndemem segini mlchpo ipshpo = mlchpo ENDIF IF (IERR.NE.0) RETURN C C ... TABLE DE SOUS-TYPE LIAISONS_STATIQUES IF (ITBAS.EQ.0) GOTO 90 C IF (IIMPI.EQ.333) THEN WRITE(IOIMP,*) 'on a lu la table des conditions aux limites' ENDIF mtab1 = itbas segact mtab1 ima = mtab1.mlotab - 1 segini idnote im = 0 segdes mtab1 80 CONTINUE im = im + 1 itmod = 0 ichp0 = 0 if (im.gt.ima) then IF (NDEMEM.GT.0) GOTO 90 * pas de champs de force return endif & 'TABLE',I1,X1,CHARRE,.true.,ITMOD) if (ierr.ne.0) return c table itmod trouvee --> on recupere la force if (itmod.gt.0) then & 'CHPOINT',I1,X1,CHARRE,.true.,ICHP0) if (ierr.ne.0) return if (ichp0.gt.0) then idemem(**) = ichp0 NDEMEM=NDEMEM+1 * write(6,*) ' extension idemem 3 ',idemem(/1) idnote(**) = im else return endif c on cree le point repere ici & 'POINT',0,0.0D0,' ',.TRUE.,IPOIN) endif GOTO 80 IF (IERR.NE.0) RETURN C---------------------------------------------------------------------- C DEBUT DU TRAVAIL 90 CONTINUE SEGINI IDEME0,IDEME1 C C Verifier qu'il n'y a pas de blocage en double *** call verlag(ipoiri) if (ierr.ne.0) return * y a t il des matrices de relations non unilaterales mrigid=ipoiri C call prrigi(ipoiri,1) segact mrigid ifochs=iforig idepe=0 * write(ioimp,*) 'dans resou mrigid iforig ',mrigid,iforig C nbr = irigel(/2) if (jrcond.ne.0) nelim=30 do 1000 irig = 1,nbr meleme=irigel(1,irig) segact meleme if ((irigel(6,irig).eq.0.or.nounil.eq.1).and.itypel.eq.22) > idepe=idepe+num(/2) if (irigel(6,irig).ne.0) iunil=1 if (irigel(6,irig).eq.2) nelim=30 if (irigel(7,irig).ne.0) then insym=1 ichski=0 endif 1000 continue C C Elimination recursive des conditions aux limites * on la fait en gradient conjugue ou en appel de unilater if (igradj.eq.1.or.(iunil.eq.1.and.nounil.eq.0)) nelim=30 nfois=nelim-1 bdblx=.false. imult=1 icond=idepe icondi=(icond*10)/9+1 if=0 do ifois=1,nfois if(imult.ne.0.and.icond.ne.0.and.(icond*10)/9.lt.icondi.and. > (icondi-icond.gt.0.or.igradj.eq.1)) then icondi=icond if=if+1 if(ierr.ne.0) return call resouc(mrigid,mrigic,idemem,ideme0,ideme1, > nounil,bdblx,icond,imult,if,imtvid,nelim) C write(ioimp,*) ' passe ',if,' condition ',icond,ifois if(ierr.ne.0) return mrigid=mrigic endif enddo C C S'il reste des conditions : dedoubler les mult de Lagrange restants C -> nouvel appel pour creer lagdua et adapter les seconds membres if (iunil.eq.0.or.nounil.eq.1) then if (icond.ne.0) then if=if+1 bdblx=.true. if(ierr.ne.0) return call resouc(mrigid,mrigic,idemem,ideme0,ideme1, > nounil,bdblx,icond,imult,if,imtvid,nelim) * write(ioimp,*) ' passe ','finale',' condition ',icond if(ierr.ne.0) return mrigid=mrigic endif endif * write (ioimp,*) 'nombre de passes',if,mrigid.imlag if (idepe.ne.0) noid=1 C C Rigidite reduite aux inconnues independantes ipoiri=mrigid * call prrigi(ipoiri,1) C------------------------------------------------------- * * Si au moins une des matrices n'est pas symétrique, on passera * par le solveur non-symétrique LDMT. * SEGACT MRIGID*MOD NRG = IRIGEL(/1) NBR = IRIGEL(/2) C ... Ceci peut arriver si par exemple on extrait la partie C symétrique d'une matrice purement antisymétrique ... * IF(NBR.EQ.0) THEN * SEGDES MRIGID * CALL ERREUR(727) * RETURN * ENDIF C ... Mais avant on va tester si la normalisation des variables C primales et duales a été demandée - ceci entraîne la perte C de la symétrie ... IF(NORINC.GT.0 .AND. NORIND.GT.0) THEN IF(KSYMET.EQ.1) THEN SEGDES,MRIGID RETURN ENDIF INSYM = 1 IGRADJ = 0 ICHSKI = 0 GOTO 15 ENDIF C ... On teste si la matrice contient des matrices non symétriques ... C ... Si OUI, ce n'est pas la peine de faire les autres tests ... DO 9 IN = 1,NBR IF(IRIGEL(7,IN).GT.0) THEN C ... On vérifie si l'utilisateur n'a pas demandé explicitement C la résolution par Choleski ou gradient conjugué, C si OUI on râle puis on s'en va !!! ... IF(KSYMET.EQ.1) THEN SEGDES,MRIGID RETURN ENDIF IF(NORINC.NE.0.AND.NORIND.EQ.0) THEN * on supprime la normalisation au lieu de faire une erreur norinc=0 ** CALL ERREUR(760) ** SEGDES,MRIGID ** RETURN ENDIF INSYM = 1 IGRADJ = 0 ICHSKI = 0 GOTO 15 ENDIF 9 CONTINUE 15 CONTINUE C C **** ON S'ASSURE QU'IL N'Y A PAS D'APPUIS UNILATERAUX C IF (IUNIL.EQ.0.OR.NOUNIL.EQ.1) GOTO 30 C C **** EXISTENCE DES APPUIS UNILATERAUX C **** SI ON EST DEJA PASSE DANS LES APPUIS UNILATERAUX C ISUPEQ POINTE SUR UNE TABLE CONTENANT LES DONNEES A PASSER C A LA PROCEDURE UNILATER C ISUPLO=ISUPEQ IF (ISUPLO.NE.0) GOTO 27 C C Distinguer ce qui est unilateral (RI2) du reste (RI1) DO 22 I=1,IRIGEL(/2) 22 CONTINUE GOTO 5000 ENDIF C NRIGE=IRIGEL(/1) NRIGEL=NNOR SEGINI RI1 RI1.IFORIG = IFORIG c* RI1.MTYMAT = MTYMAT <- type TEMPORAI(RE) plantage severe RI1.MTYMAT = ' ' SEGINI RI2 RI2.IFORIG = IFORIG c* RI2.MTYMAT = MTYMAT <- type TEMPORAI(RE) plantage severe RI2.MTYMAT = ' ' II1=0 II2=0 DO 23 I=1,IRIGEL(/2) IF(IRIGEL(6,I).NE.0) THEN RI3=RI2 II2=II2+1 II=II2 ELSE RI3=RI1 II1=II1+1 II=II1 ENDIF DO 24 J=1,NRIGE RI3.IRIGEL(J,II) = IRIGEL(J,I) 24 CONTINUE RI3.COERIG(II)=COERIG(I) 23 CONTINUE C C Creation de la table a transmettre a UNILATER (stockee dans la C raideur initiale) ISUPEQ=MTABLE MRIGID=IPRIGO SEGACT MRIGID*MOD ISUPEQ=MTABLE $ 'RIGIDITE',IOB,XVA,' ',ILOG,RI1) $ 'RIGIDITE',IOB,XVA,' ',ILOG,RI2) $ 'LOGIQUE ',IOB,XVA,' ',ILOG,IOB) ISUPLO=MTABLE SEGDES RI1,RI2,MTABLE C C Recuperer la table a transmettre a UNILATER 27 CONTINUE MTABLE=ISUPLO SEGACT MTABLE ILUG=(INSYM.EQ.1) C $ 'LOGIQUE ',IOB,XVA,' ' ,ILUG,IOB) if(idepe.ne.0) then * on passe les ideme* a mrem sous forme de listchpo n1=if segini mlchpo,mlchp1 do i=1,if mlchpo.ichpoi(i)=ideme0(1,i) mlchp1.ichpoi(i)=ideme1(1,i) enddo $ 'LISTCHPO',IOB,XVA,' ',ILOG,mlchpo) $ 'LISTCHPO',IOB,XVA,' ',ILOG,mlchp1) * pour mrem on met la derniere raideur condensee. Elle contient les pointeurs pour remonter $ 'RIGIDITE',IOB,XVA,' ',ILOG,ipoiri) endif SEGDES MRIGID DO 26 I=NDEMEM,1,-1 ISECO=IDEMEM(I) 26 CONTINUE SEGSUP IDEMEM SEGINI MTEXTE LTT=8 MTEXT(1:LTT) ='UNILATER' NCART=8 SEGDES MTEXTE mrigid=iprigo segdes mrigid GOTO 5000 C C ... On arrive ici dans le cas où il n'y a pas d'appuis unilatéraux ... 30 CONTINUE * il se peut que le dernier chp soit du frottement * on l'enleve car il ne sert a rien si on n'appele pas unilater if (NDEMEM.gt.1.and.idepe.ne.0) then mchpoi=ideme0(NDEMEM,if) segact MCHPOI if (mtypoi.eq.'LX ') NDEMEM=NDEMEM-1 endif C * write(6,*) ' ichski, igradj,insym ',ichski, igradj,insym * write (6,*) ' imtvid ',imtvid C C Cas matrice vide if (imtvid.eq.1) then *** write(6,*) ' attention matrice vide. Système surcontraint ' * nsoupo=0 nat=0 segact idemem*mod do i=1,idemem(/1) segini mchpoi mchpoi.ifopoi = ifochs idemem(i)=mchpoi enddo if (noen.eq.0) then nat=2 nsoupo=0 segini mchpo4 endif else * write(6,*) ' appel resou1 -- idemem(1)' * segact idemem * idesec= idemem(1) * call ecchpo(idesec,0) * write(6,*) ' appel resou1 -- ipoiri' * call prrigi ( ipoiri,1) * write(6,*) ' ichski insym ', ichski, insym IF(ICHSKI.EQ.1) CALL RESOU1(IPOIRI,IDEMEM,NOID,NOEN,PREC, > ISTAB,ISOUCI) IF(IERR.NE.0) GO TO 5000 ENDIF C C ----------------------------------------------------------------- C Reintroduire les inconnues eliminees do 2010 ifois=1,30 segact mrigid mrigid=jrsup if (mrigid.eq.0) goto 2011 if(ierr.ne.0) GOTO 5000 call resour(idemem,ideme0,ideme1,mrigid,if,ipt8,isouci,iverif) if(ierr.ne.0) GOTO 5000 if=if-1 2010 continue 2011 continue C C ----------------------------------------------------------------- C ECRITURE DES OBJETS RESULTATS SEGACT IDEMEM do 3 i=1,NDEMEM il = NDEMEM + 1 - i iret=idemem(il) C mchpoi=iret segact mchpoi*mod mchpoi.jattri(1)=1 C if (itbas.ne.0) then ilo = idnote(il) & 'TABLE',I1,X1,CHARRE,.true.,ITMOD) if (ierr.ne.0) GOTO 5000 & .TRUE.,0,'CHPOINT',0,0.D0,' ',.TRUE.,IRET) if (i.EQ.NDEMEM) then segdes mtab1 segsup idnote endif else if (ipshpo.gt.0) then mlchpo = ipshpo ichpoi(il) = iret if (i.EQ.NDEMEM) then mlchpo = ipshpo endif else endif 3 CONTINUE SEGSUP IDEMEM C 5000 CONTINUE norinc=norins END
© Cast3M 2003 - Tous droits réservés.
Mentions légales