00001 module krylov
00002
00003
00004 use mF
00005
00006 use myFunctions
00007
00008 use demonaParameters
00009
00010 implicit none
00011
00012
00013 contains
00014
00015 subroutine gmres(b,myX,m,restart,tolerance,residualVector,val,colInd,rowPtr,diag,valsize,totalit,preconditioner)
00016
00017 implicit none
00018 integer i,j,ii,jj,dir(9)
00019 integer m,restart,RestartCounter
00020 integer q,rIndex
00021
00022 integer totalit
00023 real(8) beta,residual,aux,BetaZero,oldresidual
00024
00025 real(8) tolerance
00026
00027
00028 real(8) POINTER, myX(:)
00029 real(8) w(size(myX)), b(size(myX))
00030 real(8) f(size(myX))
00031
00032 real(8) p(size(myX))
00033
00034 real(8) residualVector(size(myX))
00035
00036
00037
00038
00039 real(8), POINTER, DIMENSION(:) :: y
00040 real(8), POINTER, DIMENSION(:) :: H
00041 real(8), POINTER, DIMENSION(:) :: sint
00042 real(8), POINTER, DIMENSION(:) :: cost
00043 real(8), POINTER, DIMENSION(:) :: gamma
00044 real(8), POINTER, DIMENSION(:,:) :: V
00045 real(8), POINTER, DIMENSION(:,:) :: R
00046 logical NP,LP,RP
00047 real(8) res_test(size(myX)),progressCounter,temp1,temp2
00048 integer happy
00049
00050
00051
00052
00053 integer valSize
00054 real(8) val(valSize)
00055 integer colInd(valSize)
00056 integer rowPtr(size(myX)+1)
00057 integer diag(size(myX))
00058
00059 integer preconditioner
00060
00061
00062 if (gsSolver.eqv.no) then
00063
00064 print*,' '
00065 print*,'###################'
00066 print*,'GMRES'
00067 print*,'###################'
00068
00069 end if
00070
00071
00072
00073 RestartCounter=0
00074 Open (1,File='GmresResidual.dat',Status='unknown')
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091 totalit=0
00092
00093 10 w=0.d0
00094
00095
00096 allocate(V(size(myX),1),H(2),R(2,1),sint(1),cost(1),gamma(1))
00097
00098 V=0.d0
00099 H=0.d0
00100 R=0.d0
00101 sint=0.d0
00102 cost=1.d0
00103
00104 p=residualVector
00105
00106
00107 20 continue
00108
00109
00110
00111
00112 v(:,1)=b-matVec(myX)
00113
00114
00115
00116 if (preconditioner.eq.1) then
00117
00118 V(:,1)=LUyX(val,colInd,rowPtr,size(myX),diag,valSize,V(:,1))
00119
00120 end if
00121
00122
00123
00124 V(:,1)=invscaler(V(:,1),p)
00125
00126
00127 beta=dsqrt(dot_product(v(:,1),v(:,1)))
00128
00129
00130
00131 v(:,1)=v(:,1)/beta
00132
00133
00134
00135 gamma(1)=beta
00136
00137
00138 if (RestartCounter.eq.0) then
00139 residual=beta
00140 BetaZero=beta
00141
00142 write(1,'(E20.12,1X)')residual/1.d0
00143 end if
00144
00145
00146
00147
00148 do j=1,m
00149
00150 totalit=totalit+1
00151
00152
00153 if (preconditioner.eq.0) then
00154
00155 w=matVec(V(:,j))
00156
00157 elseif (preconditioner.eq.1) then
00158
00159 w=LUyX(val,colInd,rowPtr,size(myX),diag,valSize,matVec(V(:,j)))
00160
00161 elseif (preconditioner.eq.2) then
00162
00163 w=matVec(LUyX(val,colInd,rowPtr,size(myX),diag,valSize,V(:,j)))
00164
00165 end if
00166
00167
00168
00169 w=invscaler(w,p)
00170
00171 do i=1,j
00172 H(i)=dot_product(w,v(:,i))
00173 w=w-H(i)*v(:,i)
00174 end do
00175
00176
00177
00178 H(j+1)=dsqrt(dot_product(w,w))
00179
00180
00181
00182 R=>reallocate_matrix(R,j+1,j)
00183
00184
00185 R(:,j)=previous(H,sint,cost)
00186
00187 if (j.gt.1) R(j+1,j-1)=0.d0
00188
00189
00190 sint(j)=R(j+1,j)/dsqrt(R(j+1,j)**2+R(j,j)**2)
00191 cost(j)=R(j,j)/dsqrt(R(j+1,j)**2+R(j,j)**2)
00192
00193
00194 if (dabs(H(j+1)).le.epsilon(0.d0)) then
00195 if (gsSolver.eqv.no) print*,' |Happy Breakdown!'
00196 happy=1
00197 exit
00198 end if
00199
00200
00201
00202
00203 aux=R(j,j)
00204 R(j,j)=cost(j)*R(j,j)+sint(j)*R(j+1,j)
00205
00206 R(j+1,j)=-sint(j)*aux+cost(j)*R(j+1,j)
00207
00208 gamma=>reallocate_vector(gamma,j+1)
00209 gamma(j+1)=0.d0
00210 aux=gamma(j)
00211 gamma(j)=cost(j)*gamma(j)+sint(j)*gamma(j+1)
00212 gamma(j+1)=-sint(j)*aux+cost(j)*gamma(j+1)
00213
00214 residual=-sint(j)*residual
00215
00216
00217
00218
00219 write(1,'(E20.12,1X)')dabs(residual/1.d0)
00220
00221
00222 if (((dabs(residual/1.d0)).LE.tolerance).OR.(j.EQ.m)) exit
00223
00224 H=>reallocate_vector(H,j+2)
00225 sint=>reallocate_vector(sint,j+1)
00226 cost=>reallocate_vector(cost,j+1)
00227 V=>reallocate_matrix(V,size(myX),j+1)
00228
00229 v(:,j+1)=w/H(j+1)
00230
00231 end do
00232
00233 if (gsSolver.eqv.no) print*,' |gmres exit @ j=',j,' |'
00234
00235 if (gsSolver.eqv.no) print*,' |residual is=',dabs(residual/1.d0),' |'
00236
00237
00238 allocate(y(size(R,DIM=2)))
00239
00240 y=0.d0
00241 y=backwardsub(R(1:size(R,DIM=2),:),gamma(1:size(R,DIM=2)))
00242
00243
00244 if (preconditioner.ne.2) then
00245
00246 myX=myX+matmul(V(:,1:size(R,DIM=2)),y)
00247
00248 else
00249
00250 myX=myX+LUyX(val,colInd,rowPtr,size(myX),diag,valSize,matmul(V(:,1:size(R,DIM=2)),y))
00251
00252 end if
00253
00254
00255
00256 deallocate(y,H,cost,gamma,V,R)
00257
00258
00259
00260
00261 deallocate(sint)
00262
00263
00264 if (happy.eq.1) goto 101
00265
00266
00267 if ((dabs(residual/1.d0)).GT.tolerance) then
00268 RestartCounter=RestartCounter+1
00269 if (RestartCounter.le.restart) then
00270 if (gsSolver.eqv.no) print*,' |restart ',RestartCounter
00271 goto 10
00272 end if
00273 end if
00274
00275 101 continue
00276
00277
00278 close(1)
00279
00280
00281
00282
00283
00284
00285
00286
00287 end subroutine gmres
00288
00289
00290
00291 subroutine bicgstabRP(b,myx,tol,maxIter,residualVector,val,colInd,rowPtr,diag,valsize,totalit)
00292
00293
00294
00295
00296
00297 implicit none
00298
00299 integer i,j
00300
00301 integer n
00302
00303 integer maxIter
00304
00305 real(8) myx(:),b(:)
00306
00307
00308 real(8) tol
00309
00310
00311
00312
00313 real(8) r(size(b)),p(size(b)),rHat(size(b)),s(size(b)),v(size(b)),t(size(b)),shat(size(b)),phat(size(b))
00314
00315 real(8) residualVector(size(b))
00316
00317
00318 real(8) alphaB,omegaB,betaB,rhoNewB,rhoOldB,rRhat
00319
00320
00321 real(8) normR,normS,normIni
00322
00323 real(8) rho,rhonew
00324
00325 real(8) res_one,norm_value,bNorm
00326
00327 integer totalit
00328
00329
00330
00331 integer valSize
00332 real(8) val(valSize)
00333 integer colInd(valSize)
00334 integer rowPtr(size(myX)+1)
00335 integer diag(size(myX))
00336
00337
00338 print*,' '
00339 print*,'###################'
00340 print*,'BICGSTAB'
00341 print*,'###################'
00342
00343
00344
00345
00346
00347
00348
00349 n=size(b)
00350
00351 totalit=0
00352
00353
00354
00355 912 FORMAT(1(F30.20,1X))
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365 r=b-matvec(myX)
00366
00367
00368
00369
00370
00371
00372
00373 normIni=dsqrt(dot_product(r,r))
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395 bNorm=dsqrt(dot_product(b,b))
00396
00397
00398 if (bNorm.eq.0.d0) bNorm=1.d0
00399
00400
00401
00402
00403
00404
00405 rHat=r
00406
00407
00408 p=0.d0
00409 v=0.d0
00410 s=0.d0
00411 t=0.d0
00412
00413 rhoOldB=1.d0
00414 alphaB=1.d0
00415 omegaB=1.d0
00416
00417 rho=1.d0
00418
00419
00420
00421
00422
00423 Open (111,File='bicgstab.dat',Status='unknown')
00424
00425 write(111,'(F20.12,1X)')normIni
00426
00427
00428 if (normIni.le.tol) then
00429
00430 print*,'no iter convergence'
00431
00432 goto 100
00433
00434 end if
00435
00436
00437 alphaB=0.d0
00438 betaB=0.d0
00439 omegaB=1.d0
00440 rhoNewB=0.d0
00441 rhoOldB=0.d0
00442
00443
00444 do i=1,maxIter
00445
00446
00447 totalit=totalit+1
00448
00449
00450
00451
00452 rhoNewB = dot_product(rHat,r)
00453
00454
00455
00456
00457 if (rhoNewB.eq.0.d0) then
00458 print*,rhoNewB
00459 print*,'Method fails: rho=0'
00460 exit
00461 end if
00462
00463
00464 if (i.eq.1) then
00465
00466 p=r
00467
00468
00469 else
00470
00471 betaB = (rhoNewB / rhoOldB) * (alphaB / omegaB)
00472
00473
00474 p = r + betaB * (p - omegaB * v)
00475
00476 end if
00477
00478
00479 phat=p
00480
00481 v=matvec(phat)
00482
00483
00484 alphaB = rhoNewB / dot_product(rHat,v)
00485
00486
00487
00488
00489
00490 s = r-alphaB * v
00491
00492 if (i.eq.20) then
00493
00494
00495
00496
00497 end if
00498
00499
00500 normS=dsqrt(dot_product(s,s))
00501
00502 if (normS.le.tol) then
00503 myX = myX + alphaB * phat
00504 write(111,'(F20.12,1X)')normS
00505 print*,'s exit'
00506 exit
00507 end if
00508
00509
00510
00511 shat=s
00512
00513 t=matvec(shat)
00514
00515
00516 omegaB = dot_product(t,s) / dot_product(t,t)
00517
00518
00519
00520
00521
00522
00523 myX = myX + alphaB * phat +omegaB * shat
00524
00525
00526
00527 r = s - omegaB * t
00528
00529
00530
00531
00532
00533
00534
00535 normR=dsqrt(dot_product(r,r))
00536
00537
00538
00539 write(111,'(F20.12,1X)')normR
00540
00541 if (mod(i,100).eq.0) print*,normR
00542
00543
00544 if ((normR).le.tol) then
00545
00546 print*,'bicgstab converged in iter=',i
00547 print*,'abs norm=',normR
00548
00549
00550 exit
00551
00552 end if
00553
00554
00555 if (omegaB.eq.0.d0) then
00556 print*,'Method cannot continue:w=0'
00557 print*,i
00558 exit
00559 end if
00560
00561
00562
00563 rhoOldB = rhoNewB
00564
00565
00566
00567
00568 end do
00569
00570
00571 100 continue
00572
00573 close(111)
00574
00575
00576
00577
00578
00579
00580 residualVector=0.d0
00581 residualVector=b-matVec(myX)
00582
00583
00584
00585
00586
00587
00588
00589 end subroutine bicgstabRP
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615 end module krylov