Télécharger bcgg.eso

Retour à la liste

Numérotation des lignes :

bcgg
  1. C BCGG SOURCE GOUNAND 23/07/31 21:15:03 11713
  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*10.D0
  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. ENDDO
  244. ZMAX=MAX(ZMAX,ABS(Z.IJ(I,I)))
  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. * Faute de mieux
  265. ZTERM=1.D0/(MAX(ZMAX*PETIT,(XPETIT**0.5D0)))
  266. DO I=1,LBCG
  267. DO J=1,LBCG
  268. IF (I.EQ.J) THEN
  269. ZM1.IJ(I,J)=ZTERM
  270. ELSE
  271. ZM1.IJ(I,J)=XZERO
  272. ENDIF
  273. ENDDO
  274. ENDDO
  275. * SEGPRT,Z
  276. * GOTO 25
  277. ENDIF
  278. *
  279. DO I=1,LBCG
  280. YP.A(I)=ZERO
  281. DO J=1,LBCG
  282. YP.A(I)=YP.A(I)+(ZM1.IJ(I,J)*Y.A(J))
  283. ENDDO
  284. ENDDO
  285. OMEGA=YP.A(LBCG)
  286. DO I=1,LBCG
  287. UI =U.WRK(1)
  288. UIP=U.WRK(I+1)
  289. CALL GAXPY (-YP.A(I),UIP,UI)
  290. RI=R.WRK(I)
  291. CALL GAXPY ( YP.A(I),RI,XTLD)
  292. RI =R.WRK(1)
  293. RIP=R.WRK(I+1)
  294. CALL GAXPY (-YP.A(I),RIP,RI)
  295. ENDDO
  296. *
  297. * Compute residual
  298. *
  299. RI=R.WRK(1)
  300. RNRM2I=GNRM2(RI)
  301. RESID=RNRM2I / BNRM2
  302. IF (RESID.GT.RESMAX) THEN
  303. IGRAN=IGRAN+1
  304. ELSE
  305. IGRAN=0
  306. ENDIF
  307. LRES.PROG(ITER+1)=RESID
  308. LNMV.LECT(ITER+1)=INMV
  309. * WRITE(IOIMP,*) 'ITER=',ITER,' RESID=',RESID
  310. *
  311. * Reliable update
  312. *
  313. ZMXRNX=MAX(RNRM2I,ZMXRNX)
  314. ZMXRNR=MAX(RNRM2I,ZMXRNR)
  315. LUPDAX=(RNRM2I.LT.XDELTA*RNRM2.AND.RNRM2.LT.ZMXRNX)
  316. LCPRES=((RNRM2I.LT.XDELTA*ZMXRNR.AND.RNRM2.LT.ZMXRNR)
  317. $ .OR.LUPDAX)
  318. IF (LCPRES) THEN
  319. RI=R.WRK(1)
  320. CALL GCOPY(BP,RI)
  321. CALL PSOLVE('N',KPREC,KMORS,KISA,INVDIA,ILUM,ILUI
  322. $ ,UHAT,XTLD)
  323. CALL GMOMV(IMVEC,'N',-ONE,KMORS,KISA,UHAT,ONE,RI)
  324. INMV=INMV+1
  325. ZMXRNR=RNRM2I
  326. *! WRITE(IOIMP,*) 'Compute residual'
  327. IF (LUPDAX) THEN
  328. CALL GAXPY(ONE,UHAT,X)
  329. CALL GSCAL(ZERO,XTLD)
  330. CALL GCOPY(RI,BP)
  331. ZMXRNX=RNRM2I
  332. *! WRITE(IOIMP,*) 'Update approx'
  333. ENDIF
  334. ENDIF
  335. *
  336. * Check for tolerance.
  337. *
  338. IF (RESID.LE.TOL) THEN
  339. CALL PSOLVE('N',KPREC,KMORS,KISA,INVDIA,ILUM,ILUI
  340. $ ,UHAT,XTLD)
  341. CALL GAXPY(ONE,UHAT,X)
  342. GOTO 30
  343. ENDIF
  344. *
  345. * Iteration fails.
  346. *
  347. * IF (ITER.EQ.MAXIT) THEN
  348. IF (INMV.GE.MAXIT.OR.IGRAN.GT.MGRAN) THEN
  349. CALL PSOLVE('N',KPREC,KMORS,KISA,INVDIA,ILUM,ILUI
  350. $ ,UHAT,XTLD)
  351. CALL GAXPY(ONE,UHAT,X)
  352. IRET = 1
  353. IF (IMPR.GT.0) THEN
  354. C WRITE(IOIMP,*)
  355. C $ 'bcgg.eso : Convergence to tolerance not achieved'
  356. C WRITE(IOIMP,*) 'INMV=',INMV,
  357. C $ ' TOL=',TOL,
  358. C $ ' RESID=',RESID
  359. IF (IWARN.GT.0) THEN
  360. WRITE(IOIMP,*) 'BiCGStab(l)G nearly failed ',IWARN
  361. $ ,' times.'
  362. ENDIF
  363. ENDIF
  364. RETURN
  365. ENDIF
  366. *
  367. * Do some more
  368. *
  369. GOTO 10
  370. *
  371. * A breakdown in the method has occured.
  372. *
  373. 25 CONTINUE
  374. IF (IWARN.GT.0.AND.IMPR.GT.0) THEN
  375. WRITE(IOIMP,*) 'BiCGStab(l)G nearly failed ',IWARN
  376. $ ,' times.'
  377. ENDIF
  378. IRET=-1
  379. RETURN
  380. *
  381. * Iteration successful
  382. *
  383. 30 CONTINUE
  384. IF (IWARN.GT.0.AND.IMPR.GT.0) THEN
  385. WRITE(IOIMP,*) 'BiCGStab(l)G nearly failed ',IWARN
  386. $ ,' times.'
  387. ENDIF
  388. IRET = 0
  389. RETURN
  390. *
  391. * End of BCGG.
  392. *
  393. END
  394.  
  395.  

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