Télécharger bcgg.eso

Retour à la liste

Numérotation des lignes :

bcgg
  1. C BCGG SOURCE GOUNAND 25/04/30 21:15:01 12258
  2. SUBROUTINE BCGG(KMORS,KISA,B,X,
  3. $ KPREC,INVDIA,ILUM,ILUI,
  4. $ LRES,LNMV,
  5. $ RTLD,XTLD,UHAT,R,U,Z,ZM1,Y,YP,BP,TRAV,
  6. $ ITER,INMV,BRTOL,LBCG,RESID,ICALRS,IDDOT,IMVEC,IMPR,IRET)
  7. IMPLICIT REAL*8 (A-H,O-Z)
  8. IMPLICIT INTEGER(I-N)
  9. C***********************************************************************
  10. C NOM : BCGG
  11. C DESCRIPTION :
  12. C Résolution d'un système linéaire Ax=b
  13. C par une méthode BiCGSTAB(l) préconditionnée ou non avec reliable
  14. C updates et convex combination.
  15. C
  16. C LANGAGE : FORTRAN 77 + chouhia ESOPE (pour les E/S)
  17. C AUTEUR : Stéphane GOUNAND (CEA/DRN/DMT/SEMT/TTMF)
  18. C mél : gounand@semt2.smts.cea.fr
  19. C REFERENCE (bibtex-like) :
  20. C @BOOK{templates,
  21. C AUTHOR={R.Barrett, M.Berry, T.F.Chan, J.Demmel, J.Donato,
  22. C J.Dongarra, V.Eijkhout, R.Pozo, C.Romine,
  23. C H. Van der Vorst},
  24. C TITLE={Templates for the Solution of Linear Systems :
  25. C Building Blocks for Iterative Methods},
  26. C PUBLISHER={SIAM}, YEAR={1994}, ADDRESS={Philadelphia,PA} }
  27. C -> URL : http://www.netlib.org/templates/Templates.html
  28. C@TechReport{fokkema,
  29. C author = {DR Fokkema},
  30. C title = {Enhanced implementation of BiCGSTAB(l) for solving
  31. C linear systems of equations},
  32. C institution = {?},
  33. C year = {1996}}
  34. C***********************************************************************
  35. C ENTREES :
  36. C ENTREES/SORTIES :
  37. C SORTIES :
  38. C CODE RETOUR (IRET) : 0 si ok
  39. C <0 si problème (non utilisé !)
  40. C >0 si l'algorithme n'a pas convergé
  41. C***********************************************************************
  42. C VERSION : v1, 28/02/06, version initiale
  43. C HISTORIQUE : v1, 28/02/06, création
  44. C HISTORIQUE :
  45. C HISTORIQUE :
  46. C***********************************************************************
  47. C Prière de PRENDRE LE TEMPS de compléter les commentaires
  48. C en cas de modification de ce sous-programme afin de faciliter
  49. C la maintenance !
  50. C***********************************************************************
  51. *
  52. * .. Includes .. a commenter si mise au point ok
  53. -INC CCREEL
  54.  
  55. -INC PPARAM
  56. -INC CCOPTIO
  57. -INC SMLREEL
  58. POINTEUR LRES.MLREEL
  59. -INC SMLENTI
  60. POINTEUR LNMV.MLENTI
  61. POINTEUR TRAV.MLENTI
  62. POINTEUR KMORS.PMORS
  63. POINTEUR KISA.IZA
  64. POINTEUR INVDIA.IZA
  65. POINTEUR ILUM.PMORS
  66. POINTEUR ILUI.IZA
  67. POINTEUR B.IZA
  68. POINTEUR X.IZA
  69. * .. Work Vectors for BiCGSTAB(l)
  70. SEGMENT SPACE
  71. REAL*8 IJ(NI,NJ)
  72. ENDSEGMENT
  73. POINTEUR Z.SPACE,ZM1.SPACE
  74. SEGMENT SPACE2
  75. POINTEUR WRK(NIZA).IZA
  76. ENDSEGMENT
  77. POINTEUR R.SPACE2,U.SPACE2
  78. * .. Work Vectors for BiCGStab
  79. POINTEUR RTLD.IZA,XTLD.IZA,BP.IZA
  80. POINTEUR RI.IZA,UI.IZA,UIP.IZA,RIP.IZA
  81. POINTEUR UHAT.IZA,RHAT.IZA,Y.IZA,YP.IZA
  82. *
  83. INTEGER IMPR
  84. * .. Scalar Arguments ..
  85. INTEGER N,NNZ
  86. INTEGER ITER,IRET
  87. REAL*8 BRTOL,RESID
  88. * ..
  89. *
  90. *
  91. * .. Variables locales
  92. * .. Parameters
  93. REAL*8 ZERO,ONE
  94. PARAMETER (ZERO=0.0D0, ONE=1.0D0)
  95. * ..
  96. INTEGER MAXIT,III
  97. REAL*8 TOL,ALPHA,BETA,RHO,RHO1,BNRM2,OMEGA
  98. REAL*8 RHOTOL,OMETOL
  99. REAL*8 GDOT,GNRM2,PETIT,ZMXRNR,ZMXRNX
  100. LOGICAL LCPRES,LUPDAX
  101. * ..
  102. * .. External subroutines and functions..
  103. * ..
  104. * .. Executable Statements ..
  105. *
  106. *
  107. IRET = 0
  108. INMV = 0
  109. IWARN = 0
  110. IGRAN = 0
  111. MGRAN = 3
  112. MAXIT = ITER
  113. TOL = RESID
  114. *
  115. * Same memory space
  116. RHAT=UHAT
  117. *
  118. IF(IMPR.GT.5) WRITE(IOIMP,*) 'Entrée dans bcgg.eso'
  119. *
  120. * Set parameter tolerances.
  121. *
  122. RHOTOL = BRTOL
  123. SIGTOL = BRTOL
  124. RRMAX = 1.D0/(XZPREC**0.25D0)
  125. * XZPREC* 1.D0 plante si tous les termes de la matrice Z sont égaux
  126. * sur IBM
  127. PETIT = XZPREC**0.5D0
  128. *
  129. * Set initial residual.
  130. *
  131. C r(1)=b
  132. RI=R.WRK(1)
  133. CALL GCOPY(B,RI)
  134. C r(1)=b-Ax
  135. * IF (GNRM2(X).NE.ZERO) THEN
  136. C r(1)=b-Ax
  137. * CALL GMOMV ('N',-ONE,KMORS,KISA,X,ONE,R)
  138. * ENDIF
  139. CALL GMOMV(IMVEC,'N',-ONE,KMORS,KISA,X,ONE,RI)
  140. INMV=INMV+1
  141. CALL GCOPY(RI,BP)
  142. *
  143. ITER = 0
  144. BNRM2 = GNRM2(B)
  145. IF(IMPR.GT.6) THEN
  146. WRITE(IOIMP,*) '||B||=',BNRM2
  147. ENDIF
  148. RNRM2 = GNRM2(RI)
  149. IF (ICALRS.EQ.1) BNRM2=RNRM2
  150. *
  151. IF (BNRM2.LT.XPETIT) BNRM2 = ONE
  152. RESID = RNRM2 / BNRM2
  153. IF(IMPR.GT.6) THEN
  154. WRITE(IOIMP,*) 'Résidu initial=',RESID
  155. ENDIF
  156. RESMAX = RESID * RRMAX
  157. LRES.PROG(ITER+1)=RESID
  158. LNMV.LECT(ITER+1)=INMV
  159. IF (RESID.LE.TOL) GOTO 30
  160. C
  161. C Variables for reliable updating
  162. C
  163. ZMXRNR=RNRM2
  164. ZMXRNX=RNRM2
  165. LCPRES=.FALSE.
  166. LUPDAX=.FALSE.
  167. XDELTA=1.D-2
  168. C r[tilde]=r(1)
  169. CALL GCOPY(RI,RTLD)
  170. C alpha = rho0 = omega = 1
  171. ALPHA = ONE
  172. RHO0 = ONE
  173. OMEGA = ONE
  174. *
  175. 10 CONTINUE
  176. * Gestion du CTRL-C
  177. if (ierr.NE.0) return
  178. *
  179. * Perform BiConjugate Gradient part.
  180. *
  181. ITER = ITER + 1
  182. IF(IMPR.GT.7) THEN
  183. WRITE(IOIMP,*) 'ITER=',ITER
  184. ENDIF
  185. *
  186. C rho0 = -omega rho0
  187. RHO0 = -OMEGA * RHO0
  188. DO J = 1 , LBCG
  189. RI = R.WRK(J)
  190. RHO1 = GDOT(RI,RTLD,IDDOT)
  191. IF (ABS(RHO0).LT.RHOTOL) THEN
  192. RHO0=SIGN(XZPREC,RHO0)
  193. IWARN=IWARN+1
  194. ENDIF
  195. BETA = ALPHA * (RHO1 / RHO0)
  196. RHO0 = RHO1
  197. DO I = 1 , J
  198. UI = U.WRK(I)
  199. RI = R.WRK(I)
  200. CALL GSCAL(-BETA,UI)
  201. CALL GAXPY(ONE,RI,UI)
  202. ENDDO
  203. UI = U.WRK(J)
  204. UIP = U.WRK(J+1)
  205. CALL PSOLVE('N',KPREC,KMORS,KISA,INVDIA,ILUM,ILUI
  206. $ ,UHAT,UI)
  207. CALL GMOMV(IMVEC,'N',ONE,KMORS,KISA,UHAT,ZERO,UIP)
  208. INMV=INMV+1
  209. C
  210. SIGMA = GDOT(UIP,RTLD,IDDOT)
  211. IF (ABS(SIGMA).LT.SIGTOL) THEN
  212. SIGMA=SIGN(XZPREC,SIGMA)
  213. IWARN=IWARN+1
  214. ENDIF
  215. ALPHA = RHO1 / SIGMA
  216. UI = U.WRK(1)
  217. CALL GAXPY( ALPHA, UI , XTLD)
  218. DO I = 1 , J
  219. UIP = U.WRK(I+1)
  220. RI = R.WRK(I)
  221. CALL GAXPY(-ALPHA,UIP,RI)
  222. ENDDO
  223. RI = R.WRK(J)
  224. RIP = R.WRK(J+1)
  225. CALL PSOLVE('N',KPREC,KMORS,KISA,INVDIA,ILUM,ILUI
  226. $ ,RHAT,RI)
  227. CALL GMOMV(IMVEC,'N',ONE,KMORS,KISA,RHAT,ZERO,RIP)
  228. INMV=INMV+1
  229. ENDDO
  230. *
  231. * Perform polynomial part.
  232. *
  233. ZMAX=0.D0
  234. DO I=1,LBCG
  235. DO J=1,I
  236. RI = R.WRK(I+1)
  237. RIP = R.WRK(J+1)
  238. TAU = GDOT (RIP, RI,IDDOT)
  239. Z.IJ(I,J) = TAU
  240. IF (I .NE. J) THEN
  241. Z.IJ(J,I) = TAU
  242. ENDIF
  243. ZMAX=MAX(ZMAX,ABS(Z.IJ(J,I)))
  244. ENDDO
  245. RI = R.WRK(1)
  246. RIP = R.WRK(I+1)
  247. Y.A(I)=GDOT(RI,RIP,IDDOT)
  248. ENDDO
  249. * Ca arrive dans invdiag et invide.dgibi !
  250. *delme IF (ZMAX.LT.(XPETIT**0.5D0)) THEN
  251. *delme WRITE(IOIMP,*) '!!!!!!!!!!!!!!!!! GLOUBI BOULGA'
  252. *delme ZMAX=XZPREC
  253. *delme ENDIF
  254. * Cette pénalisation faisait planter enc2dQ.dgibi avec la valeur de
  255. * PETIT qui change, quel que soit la diminution du résidu.
  256. *delme* Petite pénalisation des familles pour l'inversibilité
  257. *delme* DO I=1,LBCG
  258. *delme* Z.IJ(I,I)=Z.IJ(I,I)+PETIT*ZMAX
  259. *delme* ENDDO
  260. IIMPR=0
  261. CALL IVMAT(LBCG,Z.IJ,TRAV.LECT,ZM1.IJ,XDETZ,IIMPR,IRET)
  262. * IF (IRET.NE.0) GOTO 25
  263. IF (IRET.NE.0) THEN
  264. * Mettre plus que SQRT(XPETIT) car c'est le critere utilise dans
  265. * ivmat pour la nullite
  266. ZMAX2=MAX(ZMAX*PETIT,(XPETIT**0.33D0))
  267. * write(ioimp,*) 'ZMAX,PETIT,XPETIT,ZMAX2=',ZMAX,PETIT,XPETIT
  268. * $ ,ZMAX2
  269. * Petite pénalisation des familles pour l'inversibilité
  270. DO I=1,LBCG
  271. Z.IJ(I,I)=Z.IJ(I,I)+ZMAX2
  272. ENDDO
  273. CALL IVMAT(LBCG,Z.IJ,TRAV.LECT,ZM1.IJ,XDETZ,IIMPR,IRET)
  274. IF (IRET.NE.0) THEN
  275. write(ioimp,*) 'Matrice penalized with ZMAX2=',ZMAX2
  276. MOTERR(1:8)='bcgg.eso'
  277. CALL ERREUR(700)
  278. RETURN
  279. ENDIF
  280. ENDIF
  281. *
  282. DO I=1,LBCG
  283. YP.A(I)=ZERO
  284. DO J=1,LBCG
  285. YP.A(I)=YP.A(I)+(ZM1.IJ(I,J)*Y.A(J))
  286. ENDDO
  287. ENDDO
  288. OMEGA=YP.A(LBCG)
  289. DO I=1,LBCG
  290. UI =U.WRK(1)
  291. UIP=U.WRK(I+1)
  292. CALL GAXPY (-YP.A(I),UIP,UI)
  293. RI=R.WRK(I)
  294. CALL GAXPY ( YP.A(I),RI,XTLD)
  295. RI =R.WRK(1)
  296. RIP=R.WRK(I+1)
  297. CALL GAXPY (-YP.A(I),RIP,RI)
  298. ENDDO
  299. *
  300. * Compute residual
  301. *
  302. RI=R.WRK(1)
  303. RNRM2I=GNRM2(RI)
  304. RESID=RNRM2I / BNRM2
  305. IF (RESID.GT.RESMAX) THEN
  306. IGRAN=IGRAN+1
  307. ELSE
  308. IGRAN=0
  309. ENDIF
  310. LRES.PROG(ITER+1)=RESID
  311. LNMV.LECT(ITER+1)=INMV
  312. * WRITE(IOIMP,*) 'ITER=',ITER,' RESID=',RESID
  313. *
  314. * Reliable update
  315. *
  316. ZMXRNX=MAX(RNRM2I,ZMXRNX)
  317. ZMXRNR=MAX(RNRM2I,ZMXRNR)
  318. LUPDAX=(RNRM2I.LT.XDELTA*RNRM2.AND.RNRM2.LT.ZMXRNX)
  319. LCPRES=((RNRM2I.LT.XDELTA*ZMXRNR.AND.RNRM2.LT.ZMXRNR)
  320. $ .OR.LUPDAX)
  321. IF (LCPRES) THEN
  322. RI=R.WRK(1)
  323. CALL GCOPY(BP,RI)
  324. CALL PSOLVE('N',KPREC,KMORS,KISA,INVDIA,ILUM,ILUI
  325. $ ,UHAT,XTLD)
  326. CALL GMOMV(IMVEC,'N',-ONE,KMORS,KISA,UHAT,ONE,RI)
  327. INMV=INMV+1
  328. ZMXRNR=RNRM2I
  329. *! WRITE(IOIMP,*) 'Compute residual'
  330. IF (LUPDAX) THEN
  331. CALL GAXPY(ONE,UHAT,X)
  332. CALL GSCAL(ZERO,XTLD)
  333. CALL GCOPY(RI,BP)
  334. ZMXRNX=RNRM2I
  335. *! WRITE(IOIMP,*) 'Update approx'
  336. ENDIF
  337. ENDIF
  338. *
  339. * Check for tolerance.
  340. *
  341. IF (RESID.LE.TOL) THEN
  342. CALL PSOLVE('N',KPREC,KMORS,KISA,INVDIA,ILUM,ILUI
  343. $ ,UHAT,XTLD)
  344. CALL GAXPY(ONE,UHAT,X)
  345. GOTO 30
  346. ENDIF
  347. *
  348. * Iteration fails.
  349. *
  350. * IF (ITER.EQ.MAXIT) THEN
  351. IF (INMV.GE.MAXIT.OR.IGRAN.GT.MGRAN) THEN
  352. CALL PSOLVE('N',KPREC,KMORS,KISA,INVDIA,ILUM,ILUI
  353. $ ,UHAT,XTLD)
  354. CALL GAXPY(ONE,UHAT,X)
  355. IRET = 1
  356. IF (IMPR.GT.0) THEN
  357. C WRITE(IOIMP,*)
  358. C $ 'bcgg.eso : Convergence to tolerance not achieved'
  359. C WRITE(IOIMP,*) 'INMV=',INMV,
  360. C $ ' TOL=',TOL,
  361. C $ ' RESID=',RESID
  362. IF (IWARN.GT.0) THEN
  363. WRITE(IOIMP,*) 'BiCGStab(l)G nearly failed ',IWARN
  364. $ ,' times.'
  365. ENDIF
  366. ENDIF
  367. RETURN
  368. ENDIF
  369. *
  370. * Do some more
  371. *
  372. GOTO 10
  373. *
  374. * A breakdown in the method has occured.
  375. *
  376. 25 CONTINUE
  377. IF (IWARN.GT.0.AND.IMPR.GT.0) THEN
  378. WRITE(IOIMP,*) 'BiCGStab(l)G nearly failed ',IWARN
  379. $ ,' times.'
  380. ENDIF
  381. IRET=-1
  382. RETURN
  383. *
  384. * Iteration successful
  385. *
  386. 30 CONTINUE
  387. IF (IWARN.GT.0.AND.IMPR.GT.0) THEN
  388. WRITE(IOIMP,*) 'BiCGStab(l)G nearly failed ',IWARN
  389. $ ,' times.'
  390. ENDIF
  391. IRET = 0
  392. RETURN
  393. *
  394. * End of BCGG.
  395. *
  396. END
  397.  
  398.  

© Cast3M 2003 - Tous droits réservés.
Mentions légales