hbmcon
C HBMCON SOURCE OF166741 26/05/11 21:15:08 12538 *======================================================================= * Continuation par pseudo longueur d'arc *======================================================================= & KTPHI,KCPR,KOCLFA,KOCLB1,NHBM,NFFT,KPARNUM, & KSORT,NSPAS,ITER) IMPLICIT INTEGER (I-N) IMPLICIT REAL*8 (A-H,O-Z) -INC PPARAM -INC CCOPTIO -INC TMDYNC SEGMENT mwork REAL*8 dw0 REAL*8 FTEST(4), FTEST0(4) REAL*8 Rco(NT,NT),fvec(NT),XAUX(NFFT) ENDSEGMENT INTEGER NSPAS INTEGER IREDU, METSTB, CPOSRE, IREMAX,INFO PARAMETER(IREMAX=6) LOGICAL CHECK,CHECKBIF, ZINIT,ZSTAB CHARACTER*8 FLAG * .. External Functions .. * Variables generalisees MTQ = KTQ * Partie lineaire MTKAM = KTKAM * Parametres numeriques PARNUM = KPARNUM * Reste des segments MTPHI = KTPHI MTFEX = KTFEX MTPAS = KTPAS MTLIAA = KTLIAA MTLIAB = KTLIAB LOCLFA = KOCLFA LOCLB1 = KOCLB1 MTEMP = KTEMP * Tableau des resultats PSORT = KSORT * NT = Q1(/1) NDDL = NT/(2*NHBM+1) PDT = 1./NFFT PSORT.CBIF = 0 SEGINI,MWORK *======================================================================= *=== INITIALISATION *======================================================================= II=1 IF (BAL.EQ.1) THEN DO I=1,NT Rw(I) = Rw(I) - TWO*OMEG*FEXA(I) ENDDO END IF DO I=1,NT dX(I) = -Rw(I) ENDDO c WRITE(*,*) '>>> dX=',(dX(IOU),IOU=1,NT) dw = ONE/sqrt(a*a+ONE) dw = -dw ENDIF t0(NT+1)=dw DO J=1,NT dX(J) = dX(J)*dw t0(J) = dX(J) ENDDO * Sauvegarde des donnees de sortie DO I=1,NT QSAVE(I,II)=Q1(I) ENDDO WSAVE(II)=OMEG * Stabilite de la solution initiale ZINIT = .TRUE. * CALL STBHILL(NT,NHBM,NDDL,OMEG,Q1,RX,XM,XASM,t0,ZINIT, * & LSAVE(1,1,II),ZSAVE(II),FTEST,FLAG,ZSTAB) & LSAVE(1,1,II),ZSAVE(II),CPOSRE,FLAG,ZSTAB) ZINIT = .FALSE. * Message relatif au pas #0 (solution initiale) IF(IIMPI.GE.1) THEN WRITE(IOIMP,667) WRITE(IOIMP,660) WRITE(IOIMP,667) c WRITE(IOIMP,666) (II-1),ITER,OMEG,r_z,ZSTAB WRITE(IOIMP,666) (II-1),ITER,OMEG,r_z,CPOSRE IF (IIMPI.GE.2) WRITE(IOIMP,667) ENDIF *======================================================================= * 1ere prediction *======================================================================= OMEG = OMEG + DS*dw DO J=1,NT Q1(J) = Q1(J)+DS*dX(J) ENDDO c WRITE(*,*) '>>> DS=',DS c WRITE(*,*) '>>> Q1^pred=',(Q1(IOU),IOU=1,NT) IREDU = 0 II = 2 METSTB = 0 *======================================================================= *======================= Boucle sur la frequence ======================= *======================================================================= DO WHILE (II .LE. NBPAS) * === Correction ================================================= & MTLIAA,MTLIAB,MTFEX,MTPAS,LOCLFA,LOCLB1,CHECK,'CF',ITER) * ----------------------------- * ----------------------------- * ---- si NEWT a converge, ---- * ----------------------------- * ----------------------------- IF (.NOT.CHECK) THEN * Sauvegarde des donnees de sortie * Frequence, coeffs de Fourier, Norme des coeffs de Fourier DO I=1,NT QSAVE(I,II)=Q1(I) ENDDO WSAVE(II)=OMEG * * === Prediction ============================================== * Pas tangent a la courbe IF (BAL.EQ.1) THEN DO I=1,NT Rw(I) = Rw(I) - TWO*OMEG*FEXA(I) ENDDO END IF DO KK= 1,NT Rw2(KK) = Rw(KK) ENDDO DO J=1,NT dX(J) = -Rw(J) tp(J) = dX(J) ENDDO tp(NT+1) = ONE dw0 = dw dw = ONE/sqrt(ONE+a**2) c WRITE(*,*) 'dw=',dw c signe de dw = | fourni par l'utilisateur si 1er pas c | tel que l'on continu colineairement au pas precedent IF (II.EQ.2) THEN dw = -dw ENDIF ELSE dw = (SIGN(dw,aux)) ENDIF DO K = 1,NT dX(K) = dX(K)*dw tp(K) = dX(K) ENDDO tp(NT+1) = dw * === Stabilite pour la solution convergee ==================== * via Methode de Hill IF (METSTB.EQ.0) THEN * FTEST0 = FTEST * CALL STBHILL(NT,NHBM,NDDL,OMEG,Q1,Rco,XM,XASM,t0,ZINIT, * & LSAVE(1,1,II),ZSAVE(II),FTEST,FLAG,ZSTAB) DO J=1,NT DO I=1,NT RX(I,J) = ZZ(I,J)-JAC(I,J) ENDDO ENDDO & LSAVE(1,1,II),ZSAVE(II),CPOSRE,FLAG,ZSTAB) * via Matrice de Monodromie ELSE * CALL STBMONO(NT,NDDL,NFFT,NHBM,MTQ,MTKAM,MTPHI,MTLIAA, * & MTLIAB,MTFEX,MTPAS,LOCLFA,LOCLB1,FLAG) ENDIF * Sauvegarde des donnees de sortie: LSAVE et ZSTAB rempli par STBHILL * WRITE(*,*) 'Pas ',II,', w=',OMEG,'STAB =',ZSTAB * === Message relatif au pas #II ============================== IF(IIMPI.GE.1) THEN c WRITE(IOIMP,666) (II-1),ITER,OMEG,r_z,ZSTAB WRITE(IOIMP,666) (II-1),ITER,OMEG,r_z,CPOSRE IF (IIMPI.GE.2) WRITE(IOIMP,667) ENDIF * * === Bifurcation? ============================================ IF ((FLAG.NE.'S')) THEN WRITE(IOIMP,*) 'Bifurcation detectee! Type :',FLAG cbp IF (FLAG.NE.'N') THEN & MTLIAA,MTLIAB,MTFEX,MTPAS,LOCLFA,LOCLB1,CHECKBIF,FLAG, & PARNUM,PSORT) IF (.NOT.CHECKBIF) THEN WRITE(IOIMP,*) 'Bifurcation localisee :)' ELSE WRITE(IOIMP,*) 'Bifurcation non localisee :(' ENDIF cbp ENDIF ENDIF * === Tests d'arret =========================================== * On verifie la condition d'arret par rapport a OMEG * IF ((OMEG.GE.PARFIN).OR.(OMEG.LE.PARINI)) THEN IF ((OMEG-PARFIN)*(PARFIN-PARINI).GE.0) THEN WRITE(IOIMP,*) 'Fin de la continuation apres',II,' pas.' IF (II.LT.NBPAS) THEN * WRITE(*,*) 'NPAS sera egal a:',II NT1 = QSAVE(/1) NA1 = LSAVE(/2)/2 * NPAS = QSAVE(/2) NBIFU = QBIFU(/2) * write(*,*) NT1,NA1,NPAS,NBIFU NPAS = II SEGADJ, PSORT ENDIF KSORT = PSORT RETURN ENDIF * === prediction + donnees pour le prochain pas =============== * ajustement automatique de la longueur du pas c if(II.ge.62) write(*,*) '>>>t0=',(t0(iou),iou=1,NT+1) c if(II.ge.62) write(*,*) '>>>tp=',(tp(iou),iou=1,NT+1) & NT+1,t0,tp) c WRITE(*,*) '>>> DS=',DS * stockage des donnees de fin de pas utiles (dans *OLD) * pas predictif : Q1, OMEG DO I=1,NT+1 t0(I) = tp(I) ENDDO c DSREDU=MAX(0.25*DS,DSMIN) DO KK = 1,NT c c ici, on anticipe la reduction du pas predicteur c c en maintenant la direction dX fixe c QOLD(KK) = Q1(KK)+DSREDU*dX(KK) c et ici, on laisse la possibilite a DX d'evoluer QOLD(KK) = Q1(KK) Q1(KK) = Q1(KK)+DS*dX(KK) ENDDO c idem pour OMEGOLD que QOLD c OMEGOLD = OMEG + DSREDU*dw OMEGOLD = OMEG OMEG = OMEG + DS*dw IREDU = 0 ISTRA2=0 cdebug c if(II.ge.62.and.II.le.68) then c write(*,*) 'prediction Q=',(Q1(iou),iou=1,NT) c write(*,*) 'DS, OMEG=',DS,OMEG c endif * ----------------------------------- * ----------------------------------- * ---- si NEWT n'a pas converge, ---- * ----------------------------------- * ----------------------------------- ELSE * === Message relatif au pas non converge #II ================= IF(IIMPI.GE.1) THEN WRITE(IOIMP,665) (II-1),ITER,OMEG,r_z IF (IIMPI.GE.2) WRITE(IOIMP,667) ENDIF * === strategie 2 (non-convergence alors qu'on a deja ========= * === atteint DSMIN) : on quitte ! ========= IF (DS.LE.DSMIN) THEN DS=DSMIN DO I=1,NT Q1(I) = QOLD(I) ENDDO OMEG = OMEGOLD c et on arrete IREDU=IREMAX II = II-1 * === strategie 1 : Recommencer le pas en diminuant DS ======== c test sur II>1 car pour l'instant on n'a pas branche la recup d'une solution initiale ELSEIF (II.GT.1) THEN c c en maintenant la direction dX fixe c c (attention : DS doit etre = DSREDU !!!) c DS = MAX(0.25*DS,DSMIN) c DO I=1,NT c Q1(I) = QOLD(I) c ENDDO c OMEG = OMEGOLD * mise a jour de la prediction avec nouveau DS (dX et dw n'ont pas change) DS = MAX(0.25D0*DS,DSMIN) DO I=1,NT Q1(I) = QOLD(I)+DS*dX(I) ENDDO OMEG = OMEGOLD + DS*dw II = II-1 IREDU = IREDU + 1 * message IF (IIMPI.GE.2) WRITE(IOIMP,668) IREDU,DS ENDIF 888 continue c apres reduction de 0.25**10 = 1.E-6 , echec ! c 0.25**5 = 1.E-3 IF (IREDU.GE.IREMAX) THEN * message interne IF (IIMPI.GE.1) WRITE(IOIMP,669) DS c Pas de convergence apres %i1 iterations. L'execution continue INTERR(1)=ITERMAX * ajustement des tableaux de sorties IF (II.LT.NBPAS) THEN NT1 = QSAVE(/1) NA1 = LSAVE(/2)/2 * NPAS = QSAVE(/2) NBIFU = QBIFU(/2) NPAS = II SEGADJ, PSORT ENDIF KSORT = PSORT RETURN ENDIF ENDIF * ---------------------------------------------- * ---------------------------------------------- * ---- fin distinction NEWT converge ou pas ---- * ---------------------------------------------- * ---------------------------------------------- * incrementation du compteur II = II+1 ENDDO *======================================================================= * fin de la boucle sur la frequence *======================================================================= * message c IF(IIMPI.GE.1) WRITE(IOIMP,667) c WRITE(IOIMP,*) NBPAS, 'pas de continuation realises!' KSORT = PSORT SEGSUP,MWORK *======================================================================= * Mise en forme des messages *======================================================================= * Dernier message pour fermer le tableau dans le cas iimpi=1 IF (IIMPI.EQ.1) WRITE(IOIMP,667) c 660 FORMAT(' | Pas | Iter | w | Q | Stab |') 660 FORMAT(' | Pas | Iter | w | Q | Unst |') 665 FORMAT(' | ',I5,' | ',I4,' | ',F9.5,' | ',F9.5,' | - |') c 666 FORMAT(' | ',I5,' | ',I4,' | ',F9.5,' | ',F9.5,' | ',L3,' |') 666 FORMAT(' | ',I5,' | ',I4,' | ',F9.5,' | ',F9.5,' | ',I3,' |') 667 FORMAT(' +-------+------+-----------+-----------+------+') 669 FORMAT(' + cont : pas de convergence avec ds=dsmin=',F13.9) RETURN END
© Cast3M 2003 - Tous droits réservés.
Mentions légales