1 SUBROUTINE gmresr(oktest,n,j,mgmres,b,x,work,eps,stc,
2 & maxits,resid,matvec,iflag)
65 integer i,iflag,its,nits,itsinn,j,k,maxits,mgmres,n
67 real*8 b(n),x(n),work(n,0:(2*j+mgmres+2-1)),
68 & alpha,alphai,cknorm,ckres,ddot,dnrm2,eps,epsinn,
76 integer c, u, workres, workgmre
79 if((stc.NE.
'rel').and.(stc.NE.
'abs'))
then
80 print *,
'Error in VACGMRESR:'
81 print *,
'PARAMETER STC=',stc,
' SHOULD BE rel OR abs.'
118 call matvec(x,work(1,workres),n)
120 call daxpy(n,alpha,b,1,work(1,workres),1)
121 call dscal(n,alpha,work(1,workres),1)
124 res0 = dnrm2(n,work(1,workres),1)
128 if ( res0 .eq. 0.0d0 )
then
134 if (stc.eq.
'abs')
then
140 if ( resid .le. eps )
then
150 if(oktest)
write(*,199)its,resid
151 199
format(
' its =', i4,
' resid =', d20.6)
173 if (mgmres.eq.0)
then
175 call dcopy(n,work(1,workres),1,work(1,u+mod(k,j)),1)
176 call matvec(work(1,u+mod(k,j)),work(1,c+mod(k,j)),n)
199 call gmres0(oktest,n,mgmres,
200 & work(1,workres),work(1,u+mod(k,j)),
201 & work(1,c+mod(k,j)),work(1,workgmre),
202 & epsinn,itsinn,matvec)
213 do i = max0(0,k-j),k-1
214 alphai = ddot(n,work(1,c+mod(i,j)),1,work(1,c+mod(k,j)),1)
215 call daxpy(n,-alphai,work(1,c+mod(i,j)),1,
216 & work(1,c+mod(k,j)),1)
217 call daxpy(n,-alphai,work(1,u+mod(i,j)),1,
218 & work(1,u+mod(k,j)),1)
222 cknorm = dnrm2(n,work(1,c+mod(k,j)),1)
224 call dscal(n,cknorm,work(1,c+mod(k,j)),1)
225 call dscal(n,cknorm,work(1,u+mod(k,j)),1)
228 ckres = ddot(n,work(1,c+mod(k,j)),1,work(1,workres),1)
229 call daxpy(n, ckres,work(1,u+mod(k,j)),1,x, 1)
230 call daxpy(n,-ckres,work(1,c+mod(k,j)),1,work(1,workres),1)
235 resnor = dnrm2(n,work(1,workres),1)
237 if (stc.eq.
'abs')
then
243 if ( resid .le. eps )
then
248 if (its .ge. maxits*j)
then
264 subroutine gmres0(oktest,n,im,rhs,uu,cc,work0,eps,maxits,matvec)
315 integer maxdim,maxd1,md1max
316 parameter(maxdim=10, maxd1=maxdim+1, md1max=maxdim*maxd1)
321 integer i,i1,im,its,j,k,k1,maxits,n
322 real*8 cc,coeff,coef1,dabs,ddot,dnrm2,dsqrt,eps,epsmac,
323 & gam,rhs(n),ro,uu(n),work0(n,im+1),t
325 real*8 hh(maxd1,maxdim),hh1(maxd1,maxdim),c(maxdim),
326 & s(maxdim),rs(maxd1),rs1(maxd1)
328 data (( hh(jj1,jjj), jj1=1,maxd1), jjj=1,maxdim) / md1max*0.0 / ,
332 if (im .gt. maxdim)
then
334 write (*,
'(A,i2)')
'GMRES0: dimension has been reduced to ',im
335 write (*,
'(A)')
' => reset MAXDIM if you want it to be more'
336 write (*,
'(A)')
' BUT read comments near MAXDIM before'
351 call dscal(n,coeff,uu,1)
353 call dcopy(n,rhs,1,work0,1)
355 ro = dnrm2(n, work0, 1)
356 if ((ro .eq. 0.0d0).or.(ro .le. eps))
then
357 call matvec(uu, cc, n)
364 call dscal(n,coeff,work0,1)
366 if (oktest)
write(*, 199) its, ro
376 call matvec(work0(1,i), work0(1,i1), n)
381 t = ddot(n, work0(1,j),1,work0(1,i1),1)
383 call daxpy(n, -t, work0(1,j), 1, work0(1,i1), 1)
385 t = dnrm2(n, work0(1,i1), 1)
387 if (t .ne. 0.0d0)
then
389 call dscal(n, t, work0(1,i1), 1)
391 call dcopy(maxd1,hh(1,i),1,hh1(1,i),1)
401 hh(k1,i) = c(k1)*t + s(k1)*hh(k,i)
402 hh(k,i) = -s(k1)*t + c(k1)*hh(k,i)
405 gam = dsqrt(hh(i,i)**2 + hh(i1,i)**2)
406 if (gam .eq. 0.0d0) gam = epsmac
415 hh(i,i) = c(i)*hh(i,i) + s(i)*hh(i1,i)
417 if (oktest)
write(*, 199) its, ro
418 if ((i .lt. im) .and. (ro .gt. eps))
goto 4
424 call dtrsv(
'U',
'N',
'N',i,hh,maxd1,rs,1)
430 call daxpy(n, t, work0(1,j), 1, uu,1)
440 call dgemv(
'N',i1,i,coeff,hh1,maxd1,rs,1,coef1,rs1,1)
444 call dscal(n,coef1,cc,1)
447 call daxpy(n, t, work0(1,j), 1, cc,1)
450 199
format(
'itsinn =', i4,
' res. norm =', d20.6)