85 INTEGER,
PARAMETER :: maxlev=40, real_len=8
86 INTEGER,
PARAMETER :: nsmooth=1, smoothtype=1, nstep=-1, nlvcyc=0
87 INTEGER,
PARAMETER :: npass=2,maxcoarsesize=400,maxcoarsesizeslow=4000
118 REAL(kind(0.0d0)),
PARAMETER :: resi=0.2, trspos=0.45
119 REAL(kind(0.0d0)),
PARAMETER :: kaptg_blocdia=8, kaptg_dampjac=10
120 REAL(kind(0.0d0)),
PARAMETER :: checkdd=0.5
121 REAL(kind(0.0d0)),
PARAMETER :: targetcoarsefac=2.0**npass
122 REAL(kind(0.0d0)),
PARAMETER :: fracnegrcsum=0.25
127 REAL(kind(0.0d0)),
DIMENSION(:),
POINTER :: a
128 INTEGER,
DIMENSION(:),
POINTER :: ja
129 INTEGER,
DIMENSION(:),
POINTER :: ia
130 INTEGER,
DIMENSION(:),
POINTER :: il
131 INTEGER,
DIMENSION(:),
POINTER :: iu
132 REAL(kind(0.0d0)),
DIMENSION(:),
POINTER :: p
133 INTEGER,
DIMENSION(:),
POINTER :: idiag
134 INTEGER,
DIMENSION(:),
POINTER :: ind
135 INTEGER,
DIMENSION(:),
POINTER :: iext
136 INTEGER,
DIMENSION(:),
POINTER :: ilstout
137 INTEGER,
DIMENSION(:),
POINTER :: lstout
138 INTEGER,
DIMENSION(:),
POINTER :: ilstin
139 INTEGER,
DIMENSION(:),
POINTER :: lstin
143 REAL(kind(0.0d0)),
ALLOCATABLE :: scald(:)
144 INTEGER :: nn(maxlev),kstat(2,maxlev)=0,innermax(maxlev)
145 INTEGER :: nlev,nwrkcum,iout,nrst
146 INTEGER :: maxcoarset=maxcoarsesize,maxcoarseslowt=maxcoarsesizeslow
147 REAL(kind(0.0d0)) :: memi=0.0,memax=0.0,memr=0.0,mritr,rlenilen
148 REAL(kind(0.0d0)) :: wcplex(4),fracnz(maxlev)
149 LOGICAL :: spd,wfo,wff,allzero,trans,transint,zerors,gcrin
150 REAL(kind(0.0d0)),
PARAMETER :: cplxmax=3.0, xsi=0.6d0
151 REAL(kind(0.0d0)),
PARAMETER :: repsmach=1.49d-8
152 INTEGER :: nlc(2),nlcp(2),nlc1(2),icum,imult
153 REAL(kind(0.0d0)) :: ngl(2),nglp(2),nlctot(2),ngl1(2),ngltot(2)
154 INTEGER,
DIMENSION(:),
POINTER :: iextl1
155 INTEGER,
PARAMETER :: irank=-9999
156 REAL(kind(0.0d0)),
PARAMETER :: &
158 REAL(kind(0.0d0)),
PARAMETER :: &
159 checkddb=1.28571428571429d0
166 SUBROUTINE dagmg_mestime(id,cputm,eltm)
168 INTEGER,
SAVE :: cpt_init(10)=-1,cpt_fin,cpt_max,freq,cpt
169 REAL,
SAVE :: t1(10), t2
170 REAL(kind(0.0d0)) :: cputm,eltm
176 CALL system_clock(cpt_fin,freq,cpt_max)
178 cpt = cpt_fin - cpt_init(id)
179 IF (cpt_fin < cpt_init(id)) cpt = cpt + cpt_max
180 eltm = dble(cpt) / freq
181 cputm = dble(t2 - t1(id))
185 CALL system_clock(cpt_init(-id),freq,cpt_max)
192 END SUBROUTINE dagmg_mestime
196 MODULE dagmg_allroutines
201 SUBROUTINE dagmg_relmem
207 IF(nn(l) > 0)
DEALLOCATE(
dt(l)%a,
dt(l)%ja,
dt(l)%il,
dt(l)%iu)
208 IF (nn(l+1) > 0)
DEALLOCATE(
dt(l)%ind)
214 END SUBROUTINE dagmg_relmem
220 SUBROUTINE dagmg_applyprec( N,f,X,a,ja,ia,flop)
224 REAL(kind(0.0d0)) :: flop
225 REAL(kind(0.0d0)) :: f(n), x(n)
226 INTEGER :: ja(*), ia(n+1)
227 REAL(kind(0.0d0)) :: a(*)
228 REAL(kind(0.0d0)),
ALLOCATABLE :: s(:)
231 ALLOCATE (s(nwrkcum+n))
232 CALL dagmg_prec_matv(1,f,x,s,flop,s(n+1),.false.)
233 kstat(2,1)=kstat(2,1)+1
237 END SUBROUTINE dagmg_applyprec
243 SUBROUTINE dagmg_partroword(n, a, ja, ia, idiag, w, iw, iext)
253 INTEGER :: n, ja(*), ia(n+1), idiag(n)
254 INTEGER,
OPTIONAL :: iext(*)
255 INTEGER,
TARGET :: iw(*)
256 REAL(kind(0.0d0)) :: a(*), p
257 REAL(kind(0.0d0)),
TARGET :: w(*)
258 INTEGER :: i, j, k, ipos, nzu, nze
264 DO k = ia(i), ia(i+1) - 1
293 END SUBROUTINE dagmg_partroword
299 SUBROUTINE dagmg_csrdlu(n,a,ja,ia,idiag,ao,jao,il,iu,trans,iext,iexto)
317 INTEGER :: n, ja(*), ia(n+1), idiag(n), jao(n+1:*), il(n+1), iu(n+1)
318 INTEGER,
OPTIONAL :: iext(n),iexto(n+1)
319 REAL(kind(0.0d0)) :: a(*),ao(*)
320 INTEGER :: i,j,ili,iui,iei,ipos,ili0,iui0,iei0,nl,nu,k,next
332 iui=ia(i+1)-idiag(i)-1
343 ili=ia(i+1)-idiag(i)-1
346 DO k=ia(i),idiag(i)-1
347 iu(ja(k)+1)=iu(ja(k)+1)+1
349 DO k=idiag(i)+1,ia(i+1)-1
350 il(ja(k)+1)=il(ja(k)+1)+1
389 il(i+1) = il(i) + il(i+1)
390 iu(i+1) = iu(i) + iu(i+1)
394 DO k=ia(i),idiag(i)-1
402 DO k=idiag(i)+1,ia(i+1)-1
419 END SUBROUTINE dagmg_csrdlu
425 SUBROUTINE dagmg_csrmv(n, a, ja, ifja, ia, x, ifx, y, iad, flop, lstin)
450 INTEGER :: n, ifja, ja(ifja:*), ia(n+1), iad, ifx, i, k, j
451 INTEGER,
OPTIONAL :: lstin(0:*)
452 REAL(kind(0.0d0)) :: a(*), x(ifx:*), y(n), t
453 REAL(kind(0.0d0)) :: flop
455 IF (iad .LT. -1)
THEN 459 t = t - a(k)*x(ja(k))
463 ELSE IF (iad .GT. 1)
THEN 467 t = t + a(k)*x(ja(k))
471 ELSE IF (iad .EQ. -1)
THEN 475 t = t - a(k)*x(ja(k))
483 t = t + a(k)*x(ja(k))
489 flop=flop+dble(2*(ia(n+1)-ia(1)))
491 END SUBROUTINE dagmg_csrmv
497 SUBROUTINE dagmg_csrlsolve(n, a, ja, ifja, ia, p, x, y, iunit, flop)
515 INTEGER :: n, ifja, ja(ifja:*), ia(n+1), iunit, i, k
516 REAL(kind(0.0d0)) :: a(*), p(n), x(n), y(n), t
517 REAL(kind(0.0d0)) :: flop
519 IF (iunit .LT. 0)
THEN 524 t = t - a(k)*x(ja(k))
528 flop=flop+dble(n+2*(ia(n+1)-ia(1)))
529 ELSE IF (iunit .GT. 0)
THEN 534 t = t - a(k)*x(ja(k))
538 flop=flop+dble(n+2*(ia(n+1)-ia(1)))
544 t = t - a(k)*x(ja(k))
548 flop=flop+dble(2*(ia(n+1)-ia(1)))
551 END SUBROUTINE dagmg_csrlsolve
553 SUBROUTINE dagmg_csrusolve(n, a, ja, ifja, ia, p, x, y, iunit,flop)
571 INTEGER :: n, ifja, ja(ifja:*), ia(n+1), iunit, i, k
572 REAL(kind(0.0d0)) :: a(*), p(n), x(n), y(n), t
573 REAL(kind(0.0d0)) :: flop
575 IF (iunit .LT. 0)
THEN 580 t = t - a(k)*x(ja(k))
584 flop=flop+dble(n+2*(ia(n+1)-ia(1)))
585 ELSE IF (iunit .GT. 0)
THEN 590 t = t - a(k)*x(ja(k))
594 flop=flop+dble(n+2*(ia(n+1)-ia(1)))
600 t = t - a(k)*x(ja(k))
604 flop=flop+dble(2*(ia(n+1)-ia(1)))
607 END SUBROUTINE dagmg_csrusolve
613 SUBROUTINE dagmg_flexcg(N,f,X,ITER,RESID,a,ja,ia,init,flop)
620 INTEGER :: n, iter, init
621 REAL(kind(0.0d0)) :: flop
622 REAL(kind(0.0d0)) :: f(n), x(n)
623 INTEGER :: ja(*), ia(n+1)
624 REAL(kind(0.0d0)) :: a(*)
625 INTEGER :: maxit, ierr, kk
626 REAL(kind(0.0d0)) :: tol, bnorm, resid, dum0
627 REAL(kind(0.0d0)) :: alpha, bet0, rho, dum(6), td
628 REAL(kind(0.0d0)) :: bet1
629 REAL(kind(0.0d0)),
ALLOCATABLE :: sd(:)
630 REAL(kind(0.0d0)),
ALLOCATABLE :: s(:),fsc(:)
631 REAL(kind(0.0d0)),
external :: ddot
632 REAL(kind(0.0d0)),
external :: dnrm2
633 INTEGER ,
parameter :: ione=1
636 ALLOCATE (s(2*n+1:nwrkcum+5*n),sd(n))
641 WRITE(iout,940) irank
647 IF (smoothtype == 1)
THEN 648 WRITE(iout,945) nsmooth
650 WRITE(iout,946) nsmooth
659 dum(3) = dnrm2(n, f, ione)**2
665 CALL dagmg_matv(n,x,sd,a,ja,ia,flop,trans )
666 f(1:n)=f(1:n)-sd(1:n)
667 dum(2) = dnrm2(n, f, ione)**2
670 IF (bnorm.EQ.0.0d0)
THEN 682 IF(wff.AND. (maxit <= 0 .OR. resid <= tol))
THEN 683 WRITE(iout,900) 0, resid*bnorm, resid
688 DO WHILE ( iter < maxit .AND. resid > tol )
693 CALL dagmg_prec_matv(1,f,s(1+3*n),s(1+4*n),flop,s(1+5*n),.false.)
698 dum(1) = - ddot(n, sd, ione, s(1+3*n), ione)
701 CALL daxpy(n, bet1, s(1+2*n), ione, s(1+3*n), ione)
704 CALL dcopy(n, s(1+3*n), ione, s(1+2*n), ione)
705 CALL dagmg_matv(n,s(1+2*n),sd,a,ja,ia,flop,trans )
707 dum(1) = ddot(n, s(1+2*n), ione, sd, ione)
708 dum(2) = ddot(n,s(1+2*n),ione,f,ione)
714 IF (bnorm.EQ.0.0d0)
THEN 727 WRITE(iout,900) 0, resid*bnorm, resid
735 IF (iter == 1 .AND. init == 0)
THEN 736 CALL dcopy(n,s(1+2*n),ione,x,ione)
737 CALL dscal(n,alpha,x,ione)
740 CALL daxpy(n, alpha, s(1+2*n), ione, x, ione)
743 CALL daxpy(n, -alpha, sd, ione, f, ione)
745 dum0 = dnrm2(n,f,ione)**2
750 WRITE(iout,900) iter, resid*bnorm, resid
755 IF( resid > tol )
THEN 773 IF(
ALLOCATED(fsc))
DEALLOCATE(fsc)
775 900
FORMAT(
'**** Iter=',i5,
' Resid=',e9.2, &
776 ' Relat. res.=',e9.2)
778 '*SOLUTION: flexible conjugate gradient iterations (FCG(1))')
779 941
FORMAT(
'**** Rmk: solve system with the transpose of the input matrix')
780 945
FORMAT(
'**** AMG preconditioner with',i2, &
781 ' Gauss-Seidel pre-and post-smoothing step(s)')
782 946
FORMAT(
'**** AMG preconditioner with',i2, &
783 ' ILU(0) pre-and post-smoothing step(s)')
784 947
FORMAT(
'**** at each level')
785 950
FORMAT(
'**** !!! WARNING!!!',i5,
' ITERATIONS WERE')
786 951
FORMAT(
'**** INSUFFICIENT TO ACHIEVE THE DESIRED ACCURACY')
787 952
FORMAT(
'**** - Convergence reached in',i5,
' iterations -')
788 998
FORMAT(
'**** The norm of the right hand side is zero:')
789 999
FORMAT(
'**** set x equal to the zero vector and exit')
791 END SUBROUTINE dagmg_flexcg
793 SUBROUTINE dagmg_gcr(N,f,X,ITER,RESID,a,ja,ia,init,flop)
796 INTEGER :: n, iter, init
797 REAL(kind(0.0d0)) :: flop
798 REAL(kind(0.0d0)) :: f(n), x(n)
799 INTEGER :: ja(*), ia(n+1)
800 REAL(kind(0.0d0)) :: a(*)
801 INTEGER :: maxit,i,itm,irst,ierr,j,k
802 REAL(kind(0.0d0)) :: alpha, bet0
803 REAL(kind(0.0d0)) :: resid, resid2, bnorm2, rho, trs
804 REAL(kind(0.0d0)) :: tol, tol2bnorm2, tolt, dum0
805 REAL(kind(0.0d0)) :: dum(6),xd,t
806 REAL(kind(0.0d0)),
ALLOCATABLE :: sc(:),siv(:),sir(:)
807 REAL(kind(0.0d0)),
ALLOCATABLE :: su(:),r(:),fsc(:),sw(:)
808 REAL(kind(0.0d0)),
external :: ddot
809 REAL(kind(0.0d0)),
external :: dnrm2
810 INTEGER ,
parameter :: ione=1
811 INTEGER :: itm1, m, info
813 mritr=nwrkcum+n*2*nrst+((nrst+1)*nrst)/2+nrst
814 ALLOCATE (su(n*nrst),sc(n*nrst) &
815 ,sir(((nrst+1)*nrst)/2),siv(nrst) &
821 WRITE(iout,938) irank,nrst
827 IF (smoothtype == 1)
THEN 828 WRITE(iout,945) nsmooth
830 WRITE(iout,946) nsmooth
843 dum(3) = dnrm2(n, f, ione)**2
849 CALL dagmg_matv(n,x,sc,a,ja,ia,flop,trans )
850 f(1:n)=f(1:n)-sc(1:n)
851 dum(2) = dnrm2(n, f, ione)**2
854 IF (bnorm2.EQ.0.0d0)
THEN 865 tol2bnorm2 = tol*tol*bnorm2
866 IF (wff.AND. (maxit <= 0 .OR. resid2 <= tol2bnorm2))
THEN 867 WRITE(iout,900) 0, 0,sqrt(resid2),sqrt(resid2/bnorm2)
873 DO WHILE ( iter < maxit .AND. resid2 > tol2bnorm2 )
879 CALL dtptrs(
'U',
'N',
'U',m,ione,sir,siv,m,info)
880 IF (irst == 0 .AND. init == 0)
THEN 881 CALL dgemv(
'N',n,m,1.0d0,su, &
882 n,siv,ione,0.0d0,x,ione)
883 flop=flop+dble(2*m*n+m*(m+1))
885 CALL dgemv(
'N',n,m,1.0d0,su, &
886 n,siv,ione,1.0d0,x,ione)
887 flop=flop+dble((2*m+1)*n+m*(m+1))
895 CALL dagmg_prec_matv(1,f,su(1+itm*n),sc(1+itm*n),flop,r,.false.)
896 CALL dagmg_matv(n, su(1+itm*n), sc(1+itm*n) &
897 , a, ja, ia, flop,trans )
903 dum(1)=ddot(n,sc(1+i*n),ione,sc(1+itm*n),ione)
905 bet0=bet0/sir(1+i+(i*(i+1))/2)
906 sir(1+i+(itm*(itm+1))/2)=bet0
907 CALL daxpy(n,-bet0,sc(1+i*n),ione,sc(1+itm*n),ione)
914 dum(1)=dnrm2(n,sc(1+itm*n),ione)**2
915 dum(2)=ddot(n, sc(1+itm*n), ione, f, ione)
920 IF (bnorm2.EQ.0.0d0)
THEN 931 tol2bnorm2=tol*tol*bnorm2
934 WRITE(iout,900) 0, 0,sqrt(resid2),sqrt(resid2/bnorm2)
936 tolt = max(tol2bnorm2,trs*resid2)
941 sir(1+itm+(itm*(itm+1))/2)=rho
945 CALL daxpy(n, -bet0, sc(1+itm*n), ione, f, ione)
948 resid2 = resid2 - alpha*alpha/rho
949 IF (resid2 <= tolt)
THEN 950 resid2 = dnrm2(n,f,ione)**2
952 tolt = max(tol2bnorm2,trs*resid2)
955 WRITE(iout,900) iter,irst,sqrt(abs(resid2)),sqrt(abs(resid2/bnorm2))
962 CALL dtptrs(
'U',
'N',
'U',itm1, ione,sir,siv,m,info)
963 IF (irst == 0 .AND. init == 0)
THEN 964 CALL dgemv(
'N',n,itm1,1.0d0,su, &
965 n,siv,ione,0.0d0,x,ione)
966 flop=flop+dble(2*(itm+1)*n+(itm+1)*(itm+2))
968 CALL dgemv(
'N',n,itm1,1.0d0,su, &
969 n,siv,ione,1.0d0,x,ione)
970 flop=flop+dble((2*(itm+1)+1)*n+(itm+1)*(itm+2))
974 resid=sqrt(resid2/bnorm2)
975 IF( resid > tol )
THEN 990 DEALLOCATE (su,sc,r,siv,sir)
991 IF(
ALLOCATED(fsc))
DEALLOCATE(fsc)
992 IF(
ALLOCATED(sw))
DEALLOCATE(sw)
997 900
FORMAT(
'**** Iter=',i5,
' (',i2,
' rest.) Resid=',e9.2, &
998 ' Relat. res.=',e9.2)
999 938
FORMAT(i3,
'*SOLUTION: GCR iterations (GCR(',i2,
'))')
1000 941
FORMAT(
'**** Rmk: solve system with the transpose of the input matrix')
1001 945
FORMAT(
'**** AMG preconditioner with',i2, &
1002 ' Gauss-Seidel pre-and post-smoothing step(s)')
1003 946
FORMAT(
'**** AMG preconditioner with',i2, &
1004 ' ILU(0) pre-and post-smoothing step(s)')
1005 947
FORMAT(
'**** at each level')
1006 950
FORMAT(
'**** !!! WARNING!!!',i5,
' ITERATIONS WERE')
1007 951
FORMAT(
'**** INSUFFICIENT TO ACHIEVE THE DESIRED ACCURACY')
1008 952
FORMAT(
'**** - Convergence reached in',i5,
' iterations -')
1009 998
FORMAT(
'**** The norm of the right hand side is zero:')
1010 999
FORMAT(
'**** set x equal to the zero vector and exit')
1012 END SUBROUTINE dagmg_gcr
1014 SUBROUTINE dagmg_matv(n, x, y, a, ja, ia, flop, transpose, &
1015 iext, lstout, ilstout, lstin, ilstin)
1021 INTEGER :: n, ja(*), ia(n+1), i, kk, k1, k2, ier, idum(1)
1022 INTEGER,
OPTIONAL :: iext(n), lstout(*), ilstout(*), lstin(0:*), ilstin(*)
1023 REAL(kind(0.0d0)) :: y(n), a(*), t, xx
1024 REAL(kind(0.0d0)) :: x(n)
1025 REAL(kind(0.0d0)) :: flop
1026 LOGICAL :: transpose
1029 IF (.NOT.transpose)
THEN 1045 DO kk = ia(i), ia(i+1)-1
1046 y(ja(kk)) = y(ja(kk)) + a(kk)*xx
1051 flop = flop + dble(2 *(ia(n+1)-1)-n)
1054 END SUBROUTINE dagmg_matv
1056 RECURSIVE SUBROUTINE dagmg_prec_matv(l,B,X,AX,flop,R,matv)
1081 REAL(kind(0.0d0)),
OPTIONAL :: flop
1082 REAL(kind(0.0d0)),
OPTIONAL :: b(*), x(*), ax(*), r(*)
1083 REAL(kind(0.0d0)) :: dum(1)
1084 LOGICAL,
OPTIONAL :: matv
1086 INTEGER :: is,n,nnext,xn,bn,axn,rn,idum(1)
1092 INTEGER,
PARAMETER :: nsmotot=nsmooth*smoothtype
1102 CALL dagmg_mumpsseq(n,
dt(l)%a,
dt(l)%ja,
dt(l)%ia,x,2,flop)
1111 IF (nsmotot == 1)
THEN 1115 CALL dagmg_fwgs(l,b,x,ax,flop,.false.,r)
1127 CALL dagmg_fwbwsolve1(l,
dt(l)%a,b,x,ax,flop,update,r)
1130 IF (mod(nsmotot,2) .EQ. 1)
THEN 1136 CALL dagmg_fwgs(l,b,x,ax,flop,.true.,r)
1152 IF (l+1 == nlev) bn=xn
1154 CALL dagmg_restag(n,nnext,ax,r(bn),
dt(l)%ind,flop)
1156 IF (l+1 == nlev)
THEN 1159 CALL dagmg_mumpsseq(nnext,
dt(l+1)%a,
dt(l+1)%ja,
dt(l+1)%ia,r,2,flop)
1161 ELSE IF ( innermax(l+1) <= 1 )
THEN 1167 CALL dagmg_prec_matv(l+1,r(bn),r(xn),r(axn),flop,r(rn),.false.)
1169 kstat(1,l+1)=max(kstat(1,l+1),1)
1170 kstat(2,l+1)=kstat(2,l+1)+1
1177 CALL dagmg_inner_iter(nnext,r(xn),r(bn),l+1,flop)
1182 CALL dagmg_prolag(n,nnext,x,r(xn),
dt(l)%ind,flop)
1188 IF (nsmotot == 1)
THEN 1192 CALL dagmg_bwgs(l,b,x,ax,flop,matv)
1195 IF (mod(nsmotot,2) .EQ. 1)
THEN 1200 CALL dagmg_bwgs(l,b,x,ax,flop,.false.)
1211 IF (is .GE. nsmotot-1) update=matv
1212 CALL dagmg_fwbwsolve2(l,
dt(l)%a,b,x,ax,flop,update,r)
1216 END SUBROUTINE dagmg_prec_matv
1218 SUBROUTINE dagmg_fwgs(l,B,X,AX,flop,update,R)
1239 INTEGER :: l, n, idum(1), ier
1240 REAL(kind(0.0d0)) :: flop
1241 REAL(kind(0.0d0)) :: b(*), x(*), ax(*), r(*)
1249 CALL dagmg_csrlsolve(n,
dt(l)%a,
dt(l)%ja,n+1,
dt(l)%il,
dt(l)%a &
1251 x(1:n)=x(1:n)+r(1:n)
1258 CALL dagmg_csrmv(n,
dt(l)%a,
dt(l)%ja,n+1,
dt(l)%iu,r,1,ax,-1,flop)
1264 CALL dagmg_csrlsolve(n,
dt(l)%a,
dt(l)%ja,n+1,
dt(l)%il,
dt(l)%a,x,b,1,flop)
1269 CALL dagmg_csrmv(n,
dt(l)%a,
dt(l)%ja,n+1,
dt(l)%iu,x,1,ax,-1,flop)
1273 END SUBROUTINE dagmg_fwgs
1275 SUBROUTINE dagmg_bwgs(l,B,X,AX,flop,matv)
1296 INTEGER :: l, n, idum(1), ier
1297 REAL(kind(0.0d0)) :: flop
1298 REAL(kind(0.0d0)) :: b(*), x(*), ax(*)
1305 CALL dagmg_csrmv(n,
dt(l)%a,
dt(l)%ja,n+1,
dt(l)%il,x,1,ax,-2,flop)
1310 CALL dagmg_csrusolve(n,
dt(l)%a,
dt(l)%ja,n+1,
dt(l)%iu,
dt(l)%a,x,ax,1,flop)
1312 IF (.NOT.matv)
RETURN 1317 CALL dagmg_csrmv(n,
dt(l)%a,
dt(l)%ja,n+1,
dt(l)%il,x,1,ax,2,flop)
1319 END SUBROUTINE dagmg_bwgs
1321 SUBROUTINE dagmg_fwbwsolve1(l,p,B,X,AX,flop,update,R)
1347 INTEGER :: l, n, idum(1), ier
1348 REAL(kind(0.0d0)) :: p(*), b(*), x(*), ax(*), r(*)
1349 REAL(kind(0.0d0)) :: flop
1353 IF (.NOT.update)
THEN 1357 CALL dagmg_csrlsolve(n,
dt(l)%a,
dt(l)%ja,n+1,
dt(l)%il,p &
1362 CALL dagmg_csrusolve(n,
dt(l)%a,
dt(l)%ja,n+1,
dt(l)%iu,p &
1371 ax(1:n)=b(1:n)-r(1:n)
1376 CALL dagmg_csrmv(n,
dt(l)%a,
dt(l)%ja,n+1,
dt(l)%il,x,1,ax,-2,flop)
1379 IF (smoothtype == 2) ax(1:n)=ax(1:n)-
dt(l)%a(1:n)*x(1:n)
1385 CALL dagmg_csrlsolve(n,
dt(l)%a,
dt(l)%ja,n+1,
dt(l)%il,p &
1390 CALL dagmg_csrusolve(n,
dt(l)%a,
dt(l)%ja,n+1,
dt(l)%iu,p &
1395 x(1:n)=x(1:n)+r(n+1:2*n)
1403 ax(1:n)=ax(1:n)-r(1:n)
1408 CALL dagmg_csrmv(n,
dt(l)%a,
dt(l)%ja,n+1,
dt(l)%il,r(n+1),1,ax &
1412 IF (smoothtype == 2) ax(1:n)=ax(1:n)-
dt(l)%a(1:n)*r(n+1:2*n)
1413 IF (smoothtype == 2) flop=flop+dble(2*n)
1418 END SUBROUTINE dagmg_fwbwsolve1
1420 SUBROUTINE dagmg_fwbwsolve2(l,p,B,X,AX,flop,matv,R)
1444 INTEGER :: l, n, idum(1), ier
1445 REAL(kind(0.0d0)) :: p(*), b(*), x(*), ax(*), r(*)
1446 REAL(kind(0.0d0)) :: flop
1456 CALL dagmg_csrmv(n,
dt(l)%a,
dt(l)%ja,n+1,
dt(l)%iu,x,1,ax,0,flop)
1459 r(1:n)=b(1:n)-ax(1:n)
1461 IF (smoothtype == 2) r(1:n)=r(1:n)-
dt(l)%a(1:n)*x(1:n)
1462 IF (smoothtype == 2) flop=flop+dble(2*n)
1467 CALL dagmg_csrlsolve(n,
dt(l)%a,
dt(l)%ja,n+1,
dt(l)%il,p &
1472 r(1:n) = r(n+1:2*n) - x(1:n)
1473 CALL dagmg_csrusolve(n,
dt(l)%a,
dt(l)%ja,n+1,
dt(l)%iu,p &
1478 x(1:n)=x(1:n) + r(1:n)
1481 IF (.NOT.matv)
RETURN 1490 ax(1:n)=ax(1:n)+r(n+1:2*n)/p(1:n)
1495 CALL dagmg_csrmv(n,
dt(l)%a,
dt(l)%ja,n+1,
dt(l)%il,x,1,ax,2,flop)
1497 IF (smoothtype == 2) ax(1:n)=ax(1:n)+
dt(l)%a(1:n)*r(n+1:2*n)
1498 IF (smoothtype == 2) flop=flop+dble(2*n)
1500 END SUBROUTINE dagmg_fwbwsolve2
1502 RECURSIVE SUBROUTINE dagmg_inner_iter(n,X,R,l,flop)
1527 INTEGER :: n, iter, l, ierr, k
1528 REAL(kind(0.0d0)) :: resid, flop, bnorm, det
1529 REAL(kind(0.0d0)) :: x(n), r(n,*)
1530 REAL(kind(0.0d0)) :: alpha1,alpha2,bet0,bet1,bet2,rho1,rho2,gamm0,gamm1,zeta
1531 REAL(kind(0.0d0)) :: dum(10),y1,y2
1532 REAL(kind(0.0d0)),
external :: ddot
1533 REAL(kind(0.0d0)),
external :: dnrm2
1534 INTEGER ,
parameter :: ione=1
1538 dum(3)=dnrm2(n, r, ione)**2
1542 IF (dum(3) .EQ. 0.0d0)
THEN 1553 CALL dagmg_prec_matv(l,r,x,r(1,2),flop,r(1,3),.true.)
1557 dum(1) = ddot(n,x,ione,r(1,2),ione)
1558 dum(2) = ddot(n,x,ione,r,ione)
1559 IF (abs(dum(1)) .LE. repsmach*abs(dum(2)))
THEN 1573 CALL daxpy(n, -bet0, r(1,2), ione, r, ione)
1575 resid = dnrm2(n,r,ione)**2
1576 IF (resid <= resi*resi*bnorm)
THEN 1583 CALL dscal( n, bet0, x, ione )
1584 flop=flop+dble(11*n)
1585 kstat(1,l)=max(kstat(1,l),iter)
1586 kstat(2,l)=kstat(2,l)+iter
1597 CALL dagmg_prec_matv(l,r,r(1,3),r(1,4),flop,r(1,5),.true.)
1603 dum(1) = ddot(n,r(1,3),ione,r(1,2),ione)
1604 dum(2) = ddot(n,r(1,3),ione,r,ione)
1605 dum(3) = ddot(n,r(1,3),ione,r(1,4),ione)
1606 IF (.NOT.spd) dum(4) = ddot(n,x,ione,r(1,4),ione)
1618 bet1=rho2-gamm0*gamm1/rho1
1619 bet2=(alpha1-alpha2*gamm1/bet1)/rho1
1622 IF (abs(bet1).LE.repsmach*abs(alpha2) .OR. &
1623 abs(bet2)*repsmach.GE.1.0d0)
THEN 1627 IF (.NOT.spd) flop=flop+dble(2*n)
1630 CALL dscal(n, bet2, x, ione)
1631 CALL daxpy(n, zeta, r(1,3), ione, x, ione)
1652 kstat(1,l)=max(kstat(1,l),iter)
1653 kstat(2,l)=kstat(2,l)+iter
1655 flop=flop+dble(19*n)
1656 IF (.NOT.spd) flop=flop+dble(2*n)
1661 dum(1)=dnrm2(n,r(1,2),ione)**2
1662 dum(2)=ddot(n, r(1,2), ione, r, ione )
1671 resid=bnorm-alpha1*bet0
1672 IF (resid <= resi*resi*bnorm)
THEN 1679 CALL dscal( n, bet0, x, ione )
1681 kstat(1,l)=max(kstat(1,l),iter)
1682 kstat(2,l)=kstat(2,l)+iter
1687 CALL daxpy(n, -bet0, r(1,2), ione, r, ione)
1696 CALL dagmg_prec_matv(l,r,r(1,3),r(1,4),flop,r(1,5),.true.)
1699 dum(1) = ddot(n,r(1,4),ione,r(1,2),ione)
1700 dum(2) = ddot(n,r(1,4),ione,r,ione)
1701 dum(3) = dnrm2(n,r(1,4),ione)**2
1709 bet1=rho2-gamm0*gamm1/rho1
1710 bet2=(alpha1-alpha2*gamm1/bet1)/rho1
1713 CALL dscal(n, bet2, x, ione)
1714 CALL daxpy(n, zeta, r(1,3), ione, x, ione)
1735 kstat(1,l)=max(kstat(1,l),iter)
1736 kstat(2,l)=kstat(2,l)+iter
1738 flop=flop+dble(19*n)
1762 dum(1) = dnrm2(n,r(1,2),ione)**2
1763 dum(2) = ddot(n,r(1,4),ione,r(1,2),ione)
1764 dum(3) = dnrm2(n,r(1,4),ione)**2
1765 dum(4) = ddot(n,r(1,2),ione,r,ione)
1766 dum(5) = ddot(n,r(1,4),ione,r,ione)
1768 dum(4) = dum(4)+bet0*dum(1)
1769 dum(5) = dum(5)+bet0*dum(2)
1770 det = dum(1)*dum(3)-dum(2)*dum(2)
1771 y1 = (dum(3)*dum(4)-dum(2)*dum(5))/det
1772 y2 = (-dum(2)*dum(4)+dum(1)*dum(5))/det
1773 CALL dscal( n, y1, x, ione )
1774 CALL daxpy( n, y2, r(1,3), ione, x, ione )
1775 kstat(1,l)=max(kstat(1,l),iter)
1776 kstat(2,l)=kstat(2,l)+iter
1778 flop=flop+dble(23*n)
1782 END SUBROUTINE dagmg_inner_iter
1784 RECURSIVE SUBROUTINE dagmg_galerkin_inner(n,X,R,l,flop)
1803 INTEGER :: n, iter, l, ierr, k
1804 REAL(kind(0.0d0)) :: resid, flop, bnorm
1805 REAL(kind(0.0d0)) :: x(n), r(n,*)
1806 REAL(kind(0.0d0)) :: alpha1,alpha2,bet0,bet1,bet2,rho1,rho2,gamm0,gamm1,zeta
1807 REAL(kind(0.0d0)) :: dum(10)
1808 REAL(kind(0.0d0)),
external :: ddot
1809 REAL(kind(0.0d0)),
external :: dnrm2
1810 INTEGER ,
parameter :: ione=1
1814 dum(3)=dnrm2(n, r, ione)**2
1818 IF (dum(3) .EQ. 0.0d0)
THEN 1829 CALL dagmg_prec_matv(l,r,x,r(1,2),flop,r(1,3),.true.)
1831 dum(1) = ddot(n,x,ione,r(1,2),ione)
1832 dum(2) = ddot(n,x,ione,r,ione)
1841 CALL daxpy(n, -bet0, r(1,2), ione, r, ione)
1843 resid = dnrm2(n,r,ione)**2
1844 IF (resid <= resi*resi*bnorm)
THEN 1851 CALL dscal( n, bet0, x, ione )
1852 flop=flop+dble(11*n)
1853 kstat(1,l)=max(kstat(1,l),iter)
1854 kstat(2,l)=kstat(2,l)+iter
1865 CALL dagmg_prec_matv(l,r,r(1,3),r(1,4),flop,r(1,5),.true.)
1868 dum(1) = ddot(n,r(1,3),ione,r(1,2),ione)
1869 dum(2) = ddot(n,r(1,3),ione,r,ione)
1870 dum(3) = ddot(n,r(1,3),ione,r(1,4),ione)
1871 IF (.NOT.spd) dum(4) = ddot(n,x,ione,r(1,4),ione)
1883 bet1=rho2-gamm0*gamm1/rho1
1884 bet2=(alpha1-alpha2*gamm1/bet1)/rho1
1887 CALL dscal(n, bet2, x, ione)
1888 CALL daxpy(n, zeta, r(1,3), ione, x, ione)
1909 kstat(1,l)=max(kstat(1,l),iter)
1910 kstat(2,l)=kstat(2,l)+iter
1912 flop=flop+dble(19*n)
1913 IF (.NOT.spd) flop=flop+dble(2*n)
1917 END SUBROUTINE dagmg_galerkin_inner
1919 SUBROUTINE dagmg_prolag(n, nc, V, B, ind, flop)
1928 INTEGER :: n, nc, ind(n), k, i
1929 REAL(kind(0.0d0)) :: v(n), b(nc)
1930 REAL(kind(0.0d0)) :: flop
1938 flop = flop + dble(n)
1940 END SUBROUTINE dagmg_prolag
1942 SUBROUTINE dagmg_restag(n, nc, V, B, ind, flop)
1951 INTEGER :: n, nc, ind(n), k, i
1952 REAL(kind(0.0d0)) :: v(n), b(nc)
1953 REAL(kind(0.0d0)) :: flop
1959 IF (k.GT.0) b(k) = b(k) + v(i)
1961 flop = flop + dble(n)
1963 END SUBROUTINE dagmg_restag
1969 RECURSIVE SUBROUTINE dagmg_setupl1(n,a,ja,ia,listrank,ifl)
1987 INTEGER :: ja(*),ia(n+1)
1988 REAL(kind(0.0d0)) :: a(*)
1989 INTEGER :: ifl,listrank(ifl:*)
1990 INTEGER :: nc,ierr,i,j,k,nz
1992 INTEGER,
POINTER,
DIMENSION(:) :: jap
1993 REAL(kind(0.0d0)),
POINTER,
DIMENSION(:) :: ap
1994 REAL(kind(0.0d0)) :: ops,eta,dum(2)
1995 CHARACTER(len=13) :: prtint
1996 REAL (kind(0.0d0)) :: fff(1)
2000 nlc(2)=ia(n+1)-ia(1)
2013 maxcoarset=maxcoarsesize
2014 maxcoarseslowt=maxcoarsesizeslow
2015 maxcoarset=floor(maxcoarset*(ngl(1)**(1.0d0/3)))
2016 maxcoarseslowt=floor(maxcoarseslowt*(ngl(1)**(1.0d0/3)))
2019 IF (n > 9.9e10)
THEN 2020 WRITE(prtint(1:12),
'(1pe12.5)') dble(n)
2022 WRITE(prtint(1:12),
'(i12)') n
2025 WRITE(iout,918) prtint(1:12)
2026 IF (nlc(2) > 9.9e10)
THEN 2027 WRITE(prtint(1:12),
'(1pe12.5)') dble(nlc(2))
2029 WRITE(prtint(1:12),
'(i12)') nlc(2)
2031 WRITE(iout,919) prtint(1:12),dble(nlc(2))/dble(n)
2034 IF ( 0 == nstep .OR. 1 == maxlev .OR. ngl(1) <= maxcoarset ) nlev=1
2042 CALL dagmg_aggregation(1,n,a,ja,ia,nc)
2046 CALL dagmg_setup(2,nc)
2052 DEALLOCATE(
dt(1)%idiag)
2054 CALL dagmg_mumpsseq(n,a,ja,ia,fff,1,ops)
2056 WRITE(iout,911) irank,ops/dble(11*nn(1)+2*nlc1(2))
2059 IF (ngl(1) > maxcoarset) wcplex(4)=-1.0d0
2060 IF (ngl(1) > maxcoarseslowt) wcplex(4)=ngl(1)/(1000*ngl1(1)**(1.0d0/3))
2075 ALLOCATE(ap(nz),jap(nz-n),
dt(1)%il(n+1),
dt(1)%iu(n+1))
2079 ALLOCATE(ap(nz),jap(nz-n),
dt(1)%iu(n+1))
2080 dt(1)%il =>
dt(1)%idiag
2084 memax=max(memax,memr+memi*rlenilen)
2086 CALL dagmg_csrdlu(n,a,ja,ia,
dt(1)%idiag &
2087 ,ap,jap,
dt(1)%il,
dt(1)%iu,transint )
2089 DEALLOCATE(
dt(1)%idiag)
2092 NULLIFY(
dt(1)%idiag)
2103 eta=xsi/((1-xsi)*(cplxmax-1))
2106 innermax(i)=min(2,floor(xsi**(i-1)/(eta*fracnz(i)*icum)))
2107 IF (nlev-i.LE.nlvcyc .AND. i.GT.2) innermax(i)=1
2108 icum=icum*innermax(i)
2109 wcplex(2)=wcplex(2)+icum*fracnz(i)
2110 wcplex(3)=wcplex(3)+(2**(i-1))*fracnz(i)
2112 wcplex(2)=wcplex(2)+(2**(nlev-1))*fracnz(nlev)
2113 wcplex(3)=wcplex(3)+(2**(nlev-1))*fracnz(nlev)
2114 IF (nsmooth*smoothtype > 1)
THEN 2115 nwrkcum=2*nn(nlev-1)
2119 nwrkcum=max(nwrkcum,1)
2121 nwrkcum=nwrkcum+3*nn(i+1)
2122 IF (innermax(i+1) > 1) nwrkcum=nwrkcum+2*nn(i+1)
2123 IF (nsmooth*smoothtype > 1) nwrkcum=max(2*nn(i),nwrkcum)
2127 WRITE(iout,954) nlctot(1)/dble(nlc1(1))
2128 WRITE(iout,955) nlctot(2)/dble(nlc1(2))
2131 WRITE(iout,956) wcplex(3)
2132 WRITE(iout,957) wcplex(2)
2136 911
FORMAT(i3,
'*',
' Exact factorization:',f12.3, &
2137 ' equiv. CG iterations')
2138 918
FORMAT(
'****',
' Number of unknowns:', a12)
2139 919
FORMAT(
'****',
' Nonzeros :', a12, &
2140 ' (per row:',f7.2,
')')
2141 920
FORMAT(
'****',
' Number of variables:',a12, &
2142 ' (reduction ratio:',f5.2,
')')
2143 921
FORMAT(
'****',
' Nonzeros:',a12, &
2144 ' (per row:',f4.1, &
2145 '; red. ratio:',f5.2,
')')
2146 954
FORMAT(
'****',
' Grid complexity:',f9.2)
2147 955
FORMAT(
'****',
' Operator complexity:',f9.2)
2148 956
FORMAT(
'****',
' Theoretical Weighted complexity:',f9.2, &
2149 ' (K-cycle at each level)' )
2150 957
FORMAT(
'****',
' Effective Weighted complexity:',f9.2, &
2151 ' (V-cycle enforced where needed)' )
2152 END SUBROUTINE dagmg_setupl1
2154 RECURSIVE SUBROUTINE dagmg_setup(l,n,listrank)
2172 INTEGER,
OPTIONAL :: listrank(n+1:*)
2173 INTEGER :: nc,ierr,i,j,k,nz
2175 INTEGER,
POINTER,
DIMENSION(:) :: jap
2176 REAL(kind(0.0d0)),
POINTER,
DIMENSION(:) :: ap
2177 LOGICAL,
SAVE :: slowcoarse
2178 REAL(kind(0.0d0)) :: ops,fw,eta,dum(2)
2179 CHARACTER(len=13) :: prtint
2180 REAL (kind(0.0d0)) :: fff(1)
2185 nlc(2)=
dt(l)%ia(n+1)-
dt(l)%ia(1)
2196 WRITE(iout,914) irank,l
2197 IF (n > 9.9e10)
THEN 2198 WRITE(prtint(1:12),
'(1pe12.5)') dble(n)
2200 WRITE(prtint(1:12),
'(i12)') n
2202 WRITE(iout,920) prtint(1:12),dble(nlcp(1))/dble(n)
2203 IF (nlc(2) > 9.9e10)
THEN 2204 WRITE(prtint(1:12),
'(1pe12.5)') dble(nlc(2))
2206 WRITE(prtint(1:12),
'(i12)') nlc(2)
2208 WRITE(iout,921) prtint(1:12),dble(nlc(2))/dble(n), &
2209 dble(nlcp(2))/dble(nlc(2))
2211 fracnz(l)=ngl(2)/ngl1(2)
2213 wcplex(1)=ngl1(2)/ngl(2)
2217 slcoarse = nglp(1) < 2*ngl(1) .AND. nglp(2) < 2*ngl(2)
2218 IF( l == nstep+1 .OR. l == maxlev &
2219 .OR. ( ngl(1) <= maxcoarset) &
2220 .OR. ( slcoarse .AND. ngl(1) <= maxcoarseslowt ) &
2222 .OR. ( slowcoarse .AND. slcoarse ) &
2223 .OR. nglp(1) ==ngl(1) )
THEN 2241 CALL dagmg_aggregation(l,n,
dt(l)%a,
dt(l)%ja,
dt(l)%ia,nc)
2245 CALL dagmg_setup(l+1,nc)
2251 DEALLOCATE(
dt(l)%idiag)
2253 CALL dagmg_mumpsseq(n,
dt(l)%a,
dt(l)%ja,
dt(l)%ia,fff,1,ops)
2257 memi=memi-
size(
dt(l)%ja)-n-1
2258 memr=memr-
size(
dt(l)%a)
2259 DEALLOCATE(
dt(l)%a,
dt(l)%ja,
dt(l)%ia)
2262 WRITE(iout,911) irank,ops/dble(11*nn(1)+2*nlc1(2))
2265 IF (ngl(1) > maxcoarset) wcplex(4)=-1.0d0
2266 IF (ngl(1) > maxcoarseslowt) wcplex(4)=ngl(1)/(1000*ngl1(1)**(1.0d0/3))
2279 nz=
dt(l)%ia(n+1)-
dt(l)%ia(1)
2281 ALLOCATE(ap(nz),jap(nz-n),
dt(l)%il(n+1),
dt(l)%iu(n+1))
2285 ALLOCATE(ap(nz),jap(nz-n))
2286 dt(l)%iu =>
dt(l)%ia
2287 dt(l)%il =>
dt(l)%idiag
2291 memax=max(memax,memr+memi*rlenilen)
2293 CALL dagmg_csrdlu(n,
dt(l)%a,
dt(l)%ja,
dt(l)%ia,
dt(l)%idiag &
2294 ,ap,jap,
dt(l)%il,
dt(l)%iu,transint )
2295 memi=memi-
size(
dt(l)%ja)
2296 memr=memr-
size(
dt(l)%a)
2297 DEALLOCATE(
dt(l)%a,
dt(l)%ja)
2299 DEALLOCATE(
dt(l)%idiag,
dt(l)%ia)
2302 NULLIFY(
dt(l)%idiag,
dt(l)%ia)
2309 911
FORMAT(i3,
'*',
' Exact factorization:',f12.3, &
2310 ' equiv. CG iterations')
2311 914
FORMAT(i3,
'*',
' Level:',i12)
2312 918
FORMAT(
'****',
' Number of unknowns:', a12)
2313 919
FORMAT(
'****',
' Nonzeros :', a12, &
2314 ' (per row:',f7.2,
')')
2315 920
FORMAT(
'****',
' Number of variables:',a12, &
2316 ' (reduction ratio:',f5.2,
')')
2317 921
FORMAT(
'****',
' Nonzeros:',a12, &
2318 ' (per row:',f4.1, &
2319 '; red. ratio:',f5.2,
')')
2320 954
FORMAT(
'****',
' relative complexity (grid):',f9.2)
2321 955
FORMAT(
'****',
' relative complexity (nnzs):',f9.2)
2322 END SUBROUTINE dagmg_setup
2324 SUBROUTINE dagmg_smoothsetup
2331 IF (smoothtype == 1)
THEN 2337 dt(l)%a(i)=1.0d0/
dt(l)%a(i)
2342 END SUBROUTINE dagmg_smoothsetup
2344 SUBROUTINE dagmg_aggregation(l,n,a,ja,ia,nc,listrank)
2367 INTEGER :: ja(*),ia(n+1)
2368 INTEGER,
OPTIONAL :: listrank(*)
2369 REAL (kind(0.0d0)) :: a(*), dum
2370 INTEGER :: ier,i,j,k,maxdg,np,kpass,nzc,m1,ndd,nzp,isize,nddp,npass1,nz
2373 INTEGER,
POINTER,
DIMENSION(:) :: jan,ian,idiagn,iextn,ind2,lcg,lcgn
2374 REAL(kind(0.0d0)),
POINTER,
DIMENSION(:) :: an
2375 REAL(kind(0.0d0)),
POINTER,
DIMENSION(:) :: sinn
2377 INTEGER,
POINTER,
DIMENSION(:) :: jap,iap,idiagp,iextp,lcg1
2378 REAL(kind(0.0d0)),
POINTER,
DIMENSION(:) :: ap
2379 REAL(kind(0.0d0)),
POINTER,
DIMENSION(:) :: sip
2381 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: ldd,iw,iperm,riperm
2382 REAL(kind(0.0d0)),
ALLOCATABLE,
DIMENSION(:) :: si1,w
2383 REAL(kind(0.0d0)),
ALLOCATABLE,
DIMENSION(:) :: wc
2388 WRITE (iout,901) irank
2393 ELSE IF ( transint)
THEN 2397 WRITE (iout,902)
'Jacobi',kaptg_dampjac,checkddj
2399 WRITE (iout,902)
'BlockD',kaptg_blocdia,checkddb
2401 IF (checkdd < 0)
THEN 2404 WRITE(iout,903) npass,targetcoarsefac
2405 WRITE (iout,905) trspos
2410 ALLOCATE(si1(n),ind2(n),iperm(n),riperm(n))
2413 CALL dagmg_setcmk(n,ja,ia,
dt(l)%idiag,riperm,iperm)
2415 ALLOCATE(si1(n),ind2(n),iperm(n))
2420 memax=max(memax,memr+memi*rlenilen)
2422 call dagmg_prepareagg(n,a,ja,ia,
dt(l)%idiag,ind2,iperm,si1,ndd,l )
2424 IF (ndd .EQ. n)
THEN 2427 DEALLOCATE(si1,iperm,ind2)
2437 ALLOCATE(ldd(ndd),lcg(2*(n-ndd)))
2439 memax=max(memax,memr+memi*rlenilen)
2441 IF (dble(n) .GT. targetcoarsefac*(n-ndd))
THEN 2456 CALL dagmg_findpairs_si(n,a,ja,ia,
dt(l)%idiag,si1 &
2457 ,ind2,lcg,nc,ndd,ldd,skipass,iperm )
2459 CALL dagmg_findpairs_gi(n,a,ja,ia,
dt(l)%idiag,si1 &
2460 ,ind2,lcg,nc,ndd,ldd,skipass,iperm )
2466 CALL dagmg_findpairs_si1(n,a,ja,ia,
dt(l)%idiag,si1 &
2467 ,ind2,lcg,nc,ndd,ldd,skipass,riperm,iperm )
2469 CALL dagmg_findpairs_gi1(n,a,ja,ia,
dt(l)%idiag,si1 &
2470 ,ind2,lcg,nc,ndd,ldd,skipass,riperm,iperm )
2472 DEALLOCATE(iperm,riperm)
2485 IF (npass1.GT.1)
THEN 2490 ALLOCATE(an(nz-2*(n-nc)+ndd),jan(nz-2*(n-nc)+ndd) &
2491 ,ian(nc+1),idiagn(nc+1),sinn(isize),wc(nc),iw(2*nc))
2492 memi=memi+nz-2*(n-nc)+ndd+2*(nc+1)+2*nc+isize
2493 memr=memr+nz-2*(n-nc)+ndd+nc
2494 memax=max(memax,memr+memi*rlenilen)
2495 CALL dagmg_setcg(n,a,ja,ia,
dt(l)%idiag,si1,ind2,lcg,nc,an,jan,ian &
2496 ,idiagn,sinn,npass1.GT.1,maxdg,iw,wc )
2501 IF (dble(nz).GT.targetcoarsefac*nzc .OR. npass1.LE.1)
THEN 2502 DEALLOCATE(si1,sinn,lcg)
2509 dt(l+1)%idiag=> idiagn
2510 NULLIFY(ind2,an,jan,ian,idiagn)
2535 NULLIFY(an,jan,ian,idiagn,sinn)
2537 ALLOCATE(lcg(2*np),ind2(np),w(maxdg),iw(maxdg))
2538 memi=memi+maxdg+3*np
2540 memax=max(memax,memr+memi*rlenilen)
2546 CALL dagmg_findpairs_sf(np,ap,jap,iap,idiagp,sip &
2548 ,m1,lcg1,a,ja,ia,
dt(l)%idiag,si1,w,iw )
2550 CALL dagmg_findpairs_gf(np,ap,jap,iap,idiagp,sip &
2552 ,m1,lcg1,a,ja,ia,
dt(l)%idiag,si1,w,iw )
2557 IF (kpass.NE.npass1)
THEN 2574 ALLOCATE(an(nzp-2*(np-nc)),jan(nzp-2*(np-nc)) &
2575 ,ian(nc+1),idiagn(nc+1),sinn(isize),wc(nc),iw(2*nc))
2576 memi=memi+nzp-2*(np-nc)+2*(nc+1)+2*nc+isize
2577 memr=memr+nzp-2*(np-nc)+nc
2578 memax=max(memax,memr+memi*rlenilen)
2585 CALL dagmg_setcg(np,ap,jap,iap,idiagp,sip,ind2,lcg,nc,an &
2586 ,jan,ian,idiagn,sinn,kpass.NE.npass1,maxdg,iw,wc )
2587 memi=memi-
SIZE(jap)-2*(np+1)-np-2*nc
2588 memr=memr-
SIZE(ap)-
SIZE(sip)-nc
2589 DEALLOCATE(ap,jap,iap,idiagp,sip,ind2,wc,iw)
2597 ALLOCATE(lcgn(2*m1*nc))
2599 memax=max(memax,memr+memi*rlenilen)
2600 CALL dagmg_lcgmix(nc,m1,lcg1,lcg,lcgn)
2601 memi=memi-
SIZE(lcg)-
SIZE(lcg1)
2602 DEALLOCATE(lcg,lcg1)
2610 IF ( kpass.NE.npass1 .AND. dble(nz).GT.targetcoarsefac*nzc )
THEN 2617 memr=memr-
SIZE(sinn)
2620 ALLOCATE(
dt(l)%ind(n))
2622 memax=max(memax,memr+memi*rlenilen)
2623 CALL dagmg_setind(nc,ndd,ldd,lcg1,2*m1,
dt(l)%ind)
2624 memi=memi-ndd-
SIZE(lcg1)
2625 DEALLOCATE(lcg1,ldd)
2633 dt(l+1)%idiag=> idiagn
2634 NULLIFY(an,jan,ian,idiagn)
2639 901
FORMAT(i3,
'*SETUP: Coarsening by multiple pairwise aggregation')
2640 902
FORMAT(
'**** Quality threshold (',a6,
'):',f6.2, &
2641 ' ; Strong diag. dom. trs:',f5.2)
2642 903
FORMAT(
'**** Maximal number of passes:',i3, &
2643 ' ; Target coarsening factor:',f5.2)
2644 904
FORMAT(
'**** Diag. dom. checked w.r.t. sum of offdiag', &
2645 ' (no absolute vaues)')
2646 905
FORMAT(
'****',22x,
'Threshold for rows with large pos. offdiag.:',f5.2)
2647 906
FORMAT(
'**** Rmk: Setup performed assuming the matrix symmetric')
2648 908
FORMAT(
'**** Rmk: Setup performed for the transpose of the input matrix')
2649 END SUBROUTINE dagmg_aggregation
2651 SUBROUTINE dagmg_setcmk(n,ja,ia,idiag,riperm,iperm,iext)
2657 INTEGER :: n,ja(*),ia(n+1),idiag(n),riperm(*),iperm(n)
2658 INTEGER,
OPTIONAL :: iext(*)
2660 INTEGER :: i,j,jj,jk,jd,k,kk,j1,j2,i1,i2,ijs,ijs1,ijs2,dg,mindg,kdim
2674 IF (dg.LT.mindg)
THEN 2696 DO WHILE (i1.LE.i2 .AND. i2.LT.n)
2708 IF (iperm(j) .LT. 0)
THEN 2716 IF (iperm(j) .LT. 0)
THEN 2727 exc=.true. .AND. ijs2.GT.ijs1
2731 IF( iperm(riperm(kk)) .GT. iperm(riperm(kk-1)) )
THEN 2733 riperm(kk)=riperm(kk-1)
2740 iperm(riperm(kk))=kk
2752 DO WHILE (jj .EQ. 0)
2754 IF (ijs .GT. n)
THEN 2759 IF (iperm(ijs1).LT.0 .AND. ia(ijs1+1)-ia(ijs1).EQ.mindg) &
2768 END SUBROUTINE dagmg_setcmk
2770 SUBROUTINE dagmg_prepareagg(n,a,ja,ia,idiag,ind2,iperm,si,ndd,l,iext)
2780 INTEGER :: n,ja(*),ia(n+1),idiag(n),ind2(n),iperm(n)
2781 INTEGER,
OPTIONAL :: iext(*)
2783 REAL(kind(0.0d0)) :: a(*)
2784 REAL(kind(0.0d0)) ,
TARGET :: si(n)
2785 REAL(kind(0.0d0)) :: checkddl,oda,odm,ods,vald
2786 INTEGER :: i,j,jj,jk,jd,k,kk,j1,j2,i1,i2,ijs,ijs1,ijs2,dg,kdim,nnegrcs
2787 REAL(kind(0.0d0)),
POINTER,
DIMENSION(:) :: odmax,odabs,osi
2801 IF (checkdd > 0)
THEN 2802 ALLOCATE(odmax(n),odabs(n))
2812 memax=max(memax,memr+memi*rlenilen)
2819 osi(jk)=osi(jk)+a(k)
2820 odmax(jk)=max(odmax(jk),a(k))
2821 IF (checkdd > 0) odabs(jk)=odabs(jk)+abs(a(k))
2825 osi(jk)=osi(jk)+a(k)
2826 odmax(jk)=max(odmax(jk),a(k))
2827 IF (checkdd > 0) odabs(jk)=odabs(jk)+abs(a(k))
2849 IF (checkdd > 0) oda=oda+abs(a(kk))
2854 IF (checkdd > 0) oda=oda+abs(a(kk))
2860 odm=max(odm,odmax(i))
2861 IF (checkdd > 0) oda=(oda+odabs(i))/2
2865 IF ((vald+ods) .LT. -repsmach*abs(vald)) nnegrcs=nnegrcs+1
2870 IF ( (checkdd.GT.0 .AND. vald.GT.checkddl*oda) &
2871 .OR. (checkdd.LT.0 .AND. vald.GT.checkddl*abs(ods)) )
THEN 2883 IF (odm .GT. trspos*vald) iperm(i)=0
2890 IF (nnegrcs .GT. fracnegrcsum*n)
THEN 2898 IF (checkdd > 0)
THEN 2899 DEALLOCATE(odmax,odabs)
2907 END SUBROUTINE dagmg_prepareagg
2909 SUBROUTINE dagmg_findpairs_gf(n,a,ja,ia,idiag,si,ind,lcg,nc &
2910 ,m1,lcg1,a1,ja1,ia1,idiag1,si1,rtent,jtent )
2918 INTEGER :: n,ja(*),ia(n+1),idiag(n),ind(n),lcg(2,*),nc
2919 REAL(kind(0.0d0)) :: a(*)
2920 REAL(kind(0.0d0)) :: si(n)
2921 INTEGER :: m1,ja1(*),ia1(*),idiag1(*),jtent(*),lcg1(m1,n)
2922 REAL(kind(0.0d0)) :: a1(*)
2923 REAL(kind(0.0d0)) :: si1(*),rtent(*)
2966 REAL(kind(0.0d0)) :: val,vals,valp,tent,rsi,rsj,epsr
2967 REAL(kind(0.0d0)) :: del1,del2,eta1,eta2,del12,sig1,sig2,rnd,vald
2968 INTEGER :: mindg,i,j,jj,k,kk,jk,isel,dg,ipair,nmark,idd
2969 INTEGER :: i1,i2,i3,ijs,ntentleft,npc,itrs,ijtent,j2
2970 LOGICAL :: acc,ifirst
2971 REAL(kind(0.0d0)) :: kaptg,bndmum1m1,dbndmum1,umdbndmum1
2976 kaptg=imult*kaptg_dampjac
2977 bndmum1m1=1.0d0/(kaptg-1.0d0)
2978 dbndmum1=2*1.0d0/kaptg
2979 umdbndmum1=1.0d0-dbndmum1
2985 DO WHILE (nmark.LT.n)
2992 IF (ind(isel) .GE. 0) cycle
3002 IF (lcg1(2,isel) .EQ. 0)
THEN 3014 IF (i .EQ. idiag(isel)) cycle
3017 IF(lcg1(2,j).EQ.0 .OR. ind(j).GE.0) cycle
3020 IF (i .LT. idiag(isel))
THEN 3023 IF (ja(jk) .EQ. isel)
THEN 3029 DO jk=ia(j),idiag(j)-1
3030 IF (ja(jk) .EQ. isel)
THEN 3037 IF(kk .NE. 0) vals=vals-a(kk)/2
3044 rsi=-si(isel)+a(idiag(isel))
3045 rsj=-si(j)+a(idiag(j))
3046 eta1=2*a(idiag(isel))
3056 IF (sig1 > 0.0d0)
THEN 3061 IF (sig2 > 0.0d0)
THEN 3066 IF (vals > 0.0d0)
THEN 3068 IF (abs(del1) < epsr .AND. abs(del2) < epsr)
THEN 3069 valp=(eta1*eta2)/(vals*(eta1+eta2))
3070 ELSE IF (abs(del1) < epsr)
THEN 3071 IF (del2 < -epsr) cycle
3072 valp=(eta1*eta2)/(vals*(eta1+eta2))
3073 ELSE IF (abs(del2) < epsr)
THEN 3074 IF (del1 < -epsr) cycle
3075 valp=(eta1*eta2)/(vals*(eta1+eta2))
3078 IF (del12 < -epsr) cycle
3079 valp=vals+del1*del2/del12
3080 IF (valp < 0.0d0) cycle
3081 valp=((eta1*eta2)/(eta1+eta2))/valp
3084 IF (del1 .LE. 0.0d0 .OR. del2 .LE. 0.0d0) cycle
3085 valp=vals+del1*del2/(del1+del2)
3086 IF (valp < 0.0d0) cycle
3087 vals=(eta1*eta2)/(eta1+eta2)
3091 IF (valp > kaptg) cycle
3099 IF (ipair.EQ.0)
GOTO 10
3100 ntentleft=ntentleft+1
3101 IF (16*(tent-val).LT.-1)
GOTO 9
3102 IF (16*(tent-val).LT.1 .AND. j.LT.ipair)
GOTO 9
3103 rtent(ntentleft)=tent
3107 rtent(ntentleft)=val
3108 jtent(ntentleft)=ipair
3113 IF (ipair .EQ. 0)
GOTO 25
3117 CALL dagmg_checktentagg_gf
3121 IF (ntentleft .GT.0)
THEN 3124 DO WHILE (i .LE. ntentleft)
3125 IF (jtent(j).GT.0)
THEN 3127 IF (ipair.EQ.0)
GOTO 22
3128 IF (16*(tent-val).LT.-1)
GOTO 22
3129 IF (16*(tent-val).LT.1 .AND. j.LT.ipair)
GOTO 22
3140 ntentleft=ntentleft-1
3148 IF (ipair .EQ. 0)
THEN 3161 SUBROUTINE dagmg_checktentagg_gf
3172 INTEGER,
PARAMETER :: mm=max(2**(npass+1),8)
3173 REAL(kind(0.0d0)) :: w(mm,mm),
sig(mm), age(mm), v(mm)
3174 REAL(kind(0.0d0)) :: alpha, alp, tmp, beta, f1, f2
3175 INTEGER :: j,jj,k,l,m,info, setdim1, setdim, l2, k2
3176 INTEGER :: set(mm), l1, wdtht
3177 REAL(kind(0.0d0)) :: t
3182 IF (lcg1(2,isel) .LT. 0)
THEN 3183 IF (lcg1(2,ipair) .LT. 0)
THEN 3185 set(2)=lcg1(1,ipair)
3189 set(2)=lcg1(1,ipair)
3190 set(3)=lcg1(2,ipair)
3195 IF (lcg1(2,ipair) .LT. 0)
THEN 3198 set(3)=lcg1(1,ipair)
3203 set(3)=lcg1(1,ipair)
3204 set(4)=lcg1(2,ipair)
3211 IF (lcg1(m1,isel).LT.0) l1=-lcg1(m1,isel)
3212 set(1:l1)=lcg1(1:l1,isel)
3214 IF (lcg1(m1,ipair).LT.0) l2=-lcg1(m1,ipair)
3215 set(l1+1:l1+l2)=lcg1(1:l2,ipair)
3225 IF( set(l)<set(l-1) )
THEN 3244 w(j,j)=a1(idiag1(jj))
3245 age(j)=w(j,j)-
sig(j)
3253 DO k=idiag1(jj)+1,k2
3264 DO k=ia1(jj),idiag1(jj)-1
3288 IF (
sig(j) < 0.0d0) age(j)=age(j)+2*
sig(j)
3304 w(j,j)=umdbndmum1*w(j,j)-abs(
sig(j))
3313 alp=max(alp,abs(age(j)))
3325 w(j,k)=w(j,k)+beta*v(j)*v(k)
3337 IF (alp.LT.repsmach*beta)
THEN 3349 SELECT CASE (setdim1)
3367 CALL dpotrf(
'U',setdim1,w,mm,info)
3368 IF (info .NE. 0)
RETURN 3372 IF (w(8,8) .LE. 0.0d0)
RETURN 3373 w(7,7) = w(7,7) - (w(7,8)/w(8,8)) * w(7,8)
3375 w(6,7) = w(6,7) - t * w(7,8)
3376 w(6,6) = w(6,6) - t * w(6,8)
3378 w(5,7) = w(5,7) - t * w(7,8)
3379 w(5,6) = w(5,6) - t * w(6,8)
3380 w(5,5) = w(5,5) - t * w(5,8)
3382 w(4,7) = w(4,7) - t * w(7,8)
3383 w(4,6) = w(4,6) - t * w(6,8)
3384 w(4,5) = w(4,5) - t * w(5,8)
3385 w(4,4) = w(4,4) - t * w(4,8)
3387 w(3,7) = w(3,7) - t * w(7,8)
3388 w(3,6) = w(3,6) - t * w(6,8)
3389 w(3,5) = w(3,5) - t * w(5,8)
3390 w(3,4) = w(3,4) - t * w(4,8)
3391 w(3,3) = w(3,3) - t * w(3,8)
3393 w(2,7) = w(2,7) - t * w(7,8)
3394 w(2,6) = w(2,6) - t * w(6,8)
3395 w(2,5) = w(2,5) - t * w(5,8)
3396 w(2,4) = w(2,4) - t * w(4,8)
3397 w(2,3) = w(2,3) - t * w(3,8)
3398 w(2,2) = w(2,2) - t * w(2,8)
3400 w(1,7) = w(1,7) - t * w(7,8)
3401 w(1,6) = w(1,6) - t * w(6,8)
3402 w(1,5) = w(1,5) - t * w(5,8)
3403 w(1,4) = w(1,4) - t * w(4,8)
3404 w(1,3) = w(1,3) - t * w(3,8)
3405 w(1,2) = w(1,2) - t * w(2,8)
3406 w(1,1) = w(1,1) - t * w(1,8)
3408 IF (w(7,7) .LE. 0.0d0)
RETURN 3409 w(6,6) = w(6,6) - (w(6,7)/w(7,7)) * w(6,7)
3411 w(5,6) = w(5,6) - t * w(6,7)
3412 w(5,5) = w(5,5) - t * w(5,7)
3414 w(4,6) = w(4,6) - t * w(6,7)
3415 w(4,5) = w(4,5) - t * w(5,7)
3416 w(4,4) = w(4,4) - t * w(4,7)
3418 w(3,6) = w(3,6) - t * w(6,7)
3419 w(3,5) = w(3,5) - t * w(5,7)
3420 w(3,4) = w(3,4) - t * w(4,7)
3421 w(3,3) = w(3,3) - t * w(3,7)
3423 w(2,6) = w(2,6) - t * w(6,7)
3424 w(2,5) = w(2,5) - t * w(5,7)
3425 w(2,4) = w(2,4) - t * w(4,7)
3426 w(2,3) = w(2,3) - t * w(3,7)
3427 w(2,2) = w(2,2) - t * w(2,7)
3429 w(1,6) = w(1,6) - t * w(6,7)
3430 w(1,5) = w(1,5) - t * w(5,7)
3431 w(1,4) = w(1,4) - t * w(4,7)
3432 w(1,3) = w(1,3) - t * w(3,7)
3433 w(1,2) = w(1,2) - t * w(2,7)
3434 w(1,1) = w(1,1) - t * w(1,7)
3436 IF (w(6,6) .LE. 0.0d0)
RETURN 3437 w(5,5) = w(5,5) - (w(5,6)/w(6,6)) * w(5,6)
3439 w(4,5) = w(4,5) - t * w(5,6)
3440 w(4,4) = w(4,4) - t * w(4,6)
3442 w(3,5) = w(3,5) - t * w(5,6)
3443 w(3,4) = w(3,4) - t * w(4,6)
3444 w(3,3) = w(3,3) - t * w(3,6)
3446 w(2,5) = w(2,5) - t * w(5,6)
3447 w(2,4) = w(2,4) - t * w(4,6)
3448 w(2,3) = w(2,3) - t * w(3,6)
3449 w(2,2) = w(2,2) - t * w(2,6)
3451 w(1,5) = w(1,5) - t * w(5,6)
3452 w(1,4) = w(1,4) - t * w(4,6)
3453 w(1,3) = w(1,3) - t * w(3,6)
3454 w(1,2) = w(1,2) - t * w(2,6)
3455 w(1,1) = w(1,1) - t * w(1,6)
3457 IF (w(5,5) .LE. 0.0d0)
RETURN 3458 w(4,4) = w(4,4) - (w(4,5)/w(5,5)) * w(4,5)
3460 w(3,4) = w(3,4) - t * w(4,5)
3461 w(3,3) = w(3,3) - t * w(3,5)
3463 w(2,4) = w(2,4) - t * w(4,5)
3464 w(2,3) = w(2,3) - t * w(3,5)
3465 w(2,2) = w(2,2) - t * w(2,5)
3467 w(1,4) = w(1,4) - t * w(4,5)
3468 w(1,3) = w(1,3) - t * w(3,5)
3469 w(1,2) = w(1,2) - t * w(2,5)
3470 w(1,1) = w(1,1) - t * w(1,5)
3472 IF (w(4,4) .LE. 0.0d0)
RETURN 3473 w(3,3) = w(3,3) - (w(3,4)/w(4,4)) * w(3,4)
3475 w(2,3) = w(2,3) - t * w(3,4)
3476 w(2,2) = w(2,2) - t * w(2,4)
3478 w(1,3) = w(1,3) - t * w(3,4)
3479 w(1,2) = w(1,2) - t * w(2,4)
3480 w(1,1) = w(1,1) - t * w(1,4)
3482 IF (w(3,3) .LE. 0.0d0)
RETURN 3483 w(2,2) = w(2,2) - (w(2,3)/w(3,3)) * w(2,3)
3485 w(1,2) = w(1,2) - t * w(2,3)
3486 w(1,1) = w(1,1) - t * w(1,3)
3488 IF (w(2,2) .LE. 0.0d0)
RETURN 3489 w(1,1) = w(1,1) - (w(1,2)/w(2,2)) * w(1,2)
3491 IF (w(1,1) .LE. 0.0d0)
RETURN 3498 END SUBROUTINE dagmg_checktentagg_gf
3499 END SUBROUTINE dagmg_findpairs_gf
3501 SUBROUTINE dagmg_findpairs_sf(n,a,ja,ia,idiag,si,ind,lcg,nc &
3502 ,m1,lcg1,a1,ja1,ia1,idiag1,si1,rtent,jtent )
3510 INTEGER :: n,ja(*),ia(n+1),idiag(n),ind(n),lcg(2,*),nc
3511 REAL(kind(0.0d0)) :: a(*)
3512 REAL(kind(0.0d0)) :: si(n)
3513 INTEGER :: m1,ja1(*),ia1(*),idiag1(*),jtent(*),lcg1(m1,n)
3514 REAL(kind(0.0d0)) :: a1(*)
3515 REAL(kind(0.0d0)) :: si1(*),rtent(*)
3558 REAL(kind(0.0d0)) :: val,vals,valp,tent,rsi,rsj,epsr
3559 REAL(kind(0.0d0)) :: del1,del2,eta1,eta2,del12,sig1,sig2,rnd,vald
3560 INTEGER :: mindg,i,j,jj,k,kk,jk,isel,dg,ipair,nmark,idd
3561 INTEGER :: i1,i2,i3,ijs,ntentleft,npc,itrs,ijtent,j2
3562 LOGICAL :: acc,ifirst
3563 REAL(kind(0.0d0)) :: kaptg,bndmum1m1,dbndmum1,umdbndmum1
3568 kaptg=imult*kaptg_blocdia
3569 bndmum1m1=1.0d0/(kaptg-1.0d0)
3570 dbndmum1=2*1.0d0/kaptg
3571 umdbndmum1=1.0d0-dbndmum1
3577 DO WHILE (nmark.LT.n)
3584 IF (ind(isel) .GE. 0) cycle
3594 IF (lcg1(2,isel) .EQ. 0)
THEN 3606 IF (i .EQ. idiag(isel)) cycle
3609 IF(lcg1(2,j).EQ.0 .OR. ind(j).GE.0) cycle
3615 rsi=-si(isel)+a(idiag(isel))
3616 rsj=-si(j)+a(idiag(j))
3625 IF (sig1 > 0.0d0)
THEN 3632 IF (eta1 < 0.0d0) cycle
3633 IF (sig2 > 0.0d0)
THEN 3640 IF (eta2 < 0.0d0) cycle
3641 IF (vals > 0.0d0)
THEN 3643 IF (abs(del1) < epsr .AND. abs(del2) < epsr)
THEN 3644 valp=1.0d0+(eta1*eta2)/(vals*(eta1+eta2))
3645 ELSE IF (abs(del1) < epsr)
THEN 3646 IF (del2 < -epsr) cycle
3647 valp=1.0d0+(eta1*eta2)/(vals*(eta1+eta2))
3648 ELSE IF (abs(del2) < epsr)
THEN 3649 IF (del1 < -epsr) cycle
3650 valp=1.0d0+(eta1*eta2)/(vals*(eta1+eta2))
3653 IF (del12 < -epsr) cycle
3654 valp=vals+del1*del2/del12
3655 IF (valp < 0.0d0) cycle
3656 valp=(vals+(eta1*eta2)/(eta1+eta2))/valp
3659 IF (del1 .LE. 0.0d0 .OR. del2 .LE. 0.0d0) cycle
3660 valp=vals+del1*del2/(del1+del2)
3661 IF (valp < 0.0d0) cycle
3662 vals=vals+(eta1*eta2)/(eta1+eta2)
3663 IF (vals < 0.0d0) cycle
3667 IF (valp > kaptg) cycle
3675 IF (ipair.EQ.0)
GOTO 10
3676 ntentleft=ntentleft+1
3677 IF (16*(tent-val).LT.-1)
GOTO 9
3678 IF (16*(tent-val).LT.1 .AND. j.LT.ipair)
GOTO 9
3679 rtent(ntentleft)=tent
3683 rtent(ntentleft)=val
3684 jtent(ntentleft)=ipair
3689 IF (ipair .EQ. 0)
GOTO 25
3693 CALL dagmg_checktentagg_sf
3697 IF (ntentleft .GT.0)
THEN 3700 DO WHILE (i .LE. ntentleft)
3701 IF (jtent(j).GT.0)
THEN 3703 IF (ipair.EQ.0)
GOTO 22
3704 IF (16*(tent-val).LT.-1)
GOTO 22
3705 IF (16*(tent-val).LT.1 .AND. j.LT.ipair)
GOTO 22
3716 ntentleft=ntentleft-1
3724 IF (ipair .EQ. 0)
THEN 3737 SUBROUTINE dagmg_checktentagg_sf
3748 INTEGER,
PARAMETER :: mm=max(2**(npass+1),8)
3749 REAL(kind(0.0d0)) :: w(mm,mm),
sig(mm), age(mm), v(mm)
3750 REAL(kind(0.0d0)) :: alpha, alp, tmp, beta, f1, f2
3751 INTEGER :: j,jj,k,l,m,info, setdim1, setdim, l2, k2
3752 INTEGER :: set(mm), l1, wdtht
3753 REAL(kind(0.0d0)) :: t
3758 IF (lcg1(2,isel) .LT. 0)
THEN 3759 IF (lcg1(2,ipair) .LT. 0)
THEN 3761 set(2)=lcg1(1,ipair)
3765 set(2)=lcg1(1,ipair)
3766 set(3)=lcg1(2,ipair)
3771 IF (lcg1(2,ipair) .LT. 0)
THEN 3774 set(3)=lcg1(1,ipair)
3779 set(3)=lcg1(1,ipair)
3780 set(4)=lcg1(2,ipair)
3787 IF (lcg1(m1,isel).LT.0) l1=-lcg1(m1,isel)
3788 set(1:l1)=lcg1(1:l1,isel)
3790 IF (lcg1(m1,ipair).LT.0) l2=-lcg1(m1,ipair)
3791 set(l1+1:l1+l2)=lcg1(1:l2,ipair)
3801 IF( set(l)<set(l-1) )
THEN 3820 w(j,j)=a1(idiag1(jj))
3821 age(j)=w(j,j)-
sig(j)
3829 DO k=idiag1(jj)+1,k2
3853 IF (
sig(j) < 0.0d0) age(j)=age(j)+2*
sig(j)
3858 w(j,j)=w(j,j)-abs(
sig(j))
3873 w(j,j)=w(j,j)-bndmum1m1*tmp
3885 alp=max(alp,abs(age(j)))
3897 w(j,k)=w(j,k)+beta*v(j)*v(k)
3909 IF (alp.LT.repsmach*beta)
THEN 3921 SELECT CASE (setdim1)
3939 CALL dpotrf(
'U',setdim1,w,mm,info)
3940 IF (info .NE. 0)
RETURN 3944 IF (w(8,8) .LE. 0.0d0)
RETURN 3945 w(7,7) = w(7,7) - (w(7,8)/w(8,8)) * w(7,8)
3947 w(6,7) = w(6,7) - t * w(7,8)
3948 w(6,6) = w(6,6) - t * w(6,8)
3950 w(5,7) = w(5,7) - t * w(7,8)
3951 w(5,6) = w(5,6) - t * w(6,8)
3952 w(5,5) = w(5,5) - t * w(5,8)
3954 w(4,7) = w(4,7) - t * w(7,8)
3955 w(4,6) = w(4,6) - t * w(6,8)
3956 w(4,5) = w(4,5) - t * w(5,8)
3957 w(4,4) = w(4,4) - t * w(4,8)
3959 w(3,7) = w(3,7) - t * w(7,8)
3960 w(3,6) = w(3,6) - t * w(6,8)
3961 w(3,5) = w(3,5) - t * w(5,8)
3962 w(3,4) = w(3,4) - t * w(4,8)
3963 w(3,3) = w(3,3) - t * w(3,8)
3965 w(2,7) = w(2,7) - t * w(7,8)
3966 w(2,6) = w(2,6) - t * w(6,8)
3967 w(2,5) = w(2,5) - t * w(5,8)
3968 w(2,4) = w(2,4) - t * w(4,8)
3969 w(2,3) = w(2,3) - t * w(3,8)
3970 w(2,2) = w(2,2) - t * w(2,8)
3972 w(1,7) = w(1,7) - t * w(7,8)
3973 w(1,6) = w(1,6) - t * w(6,8)
3974 w(1,5) = w(1,5) - t * w(5,8)
3975 w(1,4) = w(1,4) - t * w(4,8)
3976 w(1,3) = w(1,3) - t * w(3,8)
3977 w(1,2) = w(1,2) - t * w(2,8)
3978 w(1,1) = w(1,1) - t * w(1,8)
3980 IF (w(7,7) .LE. 0.0d0)
RETURN 3981 w(6,6) = w(6,6) - (w(6,7)/w(7,7)) * w(6,7)
3983 w(5,6) = w(5,6) - t * w(6,7)
3984 w(5,5) = w(5,5) - t * w(5,7)
3986 w(4,6) = w(4,6) - t * w(6,7)
3987 w(4,5) = w(4,5) - t * w(5,7)
3988 w(4,4) = w(4,4) - t * w(4,7)
3990 w(3,6) = w(3,6) - t * w(6,7)
3991 w(3,5) = w(3,5) - t * w(5,7)
3992 w(3,4) = w(3,4) - t * w(4,7)
3993 w(3,3) = w(3,3) - t * w(3,7)
3995 w(2,6) = w(2,6) - t * w(6,7)
3996 w(2,5) = w(2,5) - t * w(5,7)
3997 w(2,4) = w(2,4) - t * w(4,7)
3998 w(2,3) = w(2,3) - t * w(3,7)
3999 w(2,2) = w(2,2) - t * w(2,7)
4001 w(1,6) = w(1,6) - t * w(6,7)
4002 w(1,5) = w(1,5) - t * w(5,7)
4003 w(1,4) = w(1,4) - t * w(4,7)
4004 w(1,3) = w(1,3) - t * w(3,7)
4005 w(1,2) = w(1,2) - t * w(2,7)
4006 w(1,1) = w(1,1) - t * w(1,7)
4008 IF (w(6,6) .LE. 0.0d0)
RETURN 4009 w(5,5) = w(5,5) - (w(5,6)/w(6,6)) * w(5,6)
4011 w(4,5) = w(4,5) - t * w(5,6)
4012 w(4,4) = w(4,4) - t * w(4,6)
4014 w(3,5) = w(3,5) - t * w(5,6)
4015 w(3,4) = w(3,4) - t * w(4,6)
4016 w(3,3) = w(3,3) - t * w(3,6)
4018 w(2,5) = w(2,5) - t * w(5,6)
4019 w(2,4) = w(2,4) - t * w(4,6)
4020 w(2,3) = w(2,3) - t * w(3,6)
4021 w(2,2) = w(2,2) - t * w(2,6)
4023 w(1,5) = w(1,5) - t * w(5,6)
4024 w(1,4) = w(1,4) - t * w(4,6)
4025 w(1,3) = w(1,3) - t * w(3,6)
4026 w(1,2) = w(1,2) - t * w(2,6)
4027 w(1,1) = w(1,1) - t * w(1,6)
4029 IF (w(5,5) .LE. 0.0d0)
RETURN 4030 w(4,4) = w(4,4) - (w(4,5)/w(5,5)) * w(4,5)
4032 w(3,4) = w(3,4) - t * w(4,5)
4033 w(3,3) = w(3,3) - t * w(3,5)
4035 w(2,4) = w(2,4) - t * w(4,5)
4036 w(2,3) = w(2,3) - t * w(3,5)
4037 w(2,2) = w(2,2) - t * w(2,5)
4039 w(1,4) = w(1,4) - t * w(4,5)
4040 w(1,3) = w(1,3) - t * w(3,5)
4041 w(1,2) = w(1,2) - t * w(2,5)
4042 w(1,1) = w(1,1) - t * w(1,5)
4044 IF (w(4,4) .LE. 0.0d0)
RETURN 4045 w(3,3) = w(3,3) - (w(3,4)/w(4,4)) * w(3,4)
4047 w(2,3) = w(2,3) - t * w(3,4)
4048 w(2,2) = w(2,2) - t * w(2,4)
4050 w(1,3) = w(1,3) - t * w(3,4)
4051 w(1,2) = w(1,2) - t * w(2,4)
4052 w(1,1) = w(1,1) - t * w(1,4)
4054 IF (w(3,3) .LE. 0.0d0)
RETURN 4055 w(2,2) = w(2,2) - (w(2,3)/w(3,3)) * w(2,3)
4057 w(1,2) = w(1,2) - t * w(2,3)
4058 w(1,1) = w(1,1) - t * w(1,3)
4060 IF (w(2,2) .LE. 0.0d0)
RETURN 4061 w(1,1) = w(1,1) - (w(1,2)/w(2,2)) * w(1,2)
4063 IF (w(1,1) .LE. 0.0d0)
RETURN 4070 END SUBROUTINE dagmg_checktentagg_sf
4071 END SUBROUTINE dagmg_findpairs_sf
4073 SUBROUTINE dagmg_findpairs_gi(n,a,ja,ia,idiag,si,ind,lcg,nc &
4083 INTEGER :: n,ja(*),ia(n+1),idiag(n),ind(n),lcg(2,*),nc
4084 REAL(kind(0.0d0)) :: a(*)
4085 REAL(kind(0.0d0)) :: si(n)
4086 INTEGER :: ldd(nddl),nddl
4131 REAL(kind(0.0d0)) :: val,vals,valp,tent,rsi,rsj,epsr
4132 REAL(kind(0.0d0)) :: del1,del2,eta1,eta2,del12,sig1,sig2,rnd,vald
4133 INTEGER :: mindg,i,j,jj,k,kk,jk,isel,dg,ipair,nmark,idd
4134 INTEGER :: i1,i2,i3,ijs,ntentleft,npc,itrs,ijtent,j2
4135 LOGICAL :: acc,ifirst
4136 REAL(kind(0.0d0)) :: kaptg,bndmum1m1,dbndmum1,umdbndmum1
4141 kaptg=imult*kaptg_dampjac
4142 bndmum1m1=1.0d0/(kaptg-1.0d0)
4143 dbndmum1=2*1.0d0/kaptg
4144 umdbndmum1=1.0d0-dbndmum1
4150 DO WHILE (nmark.LT.n)
4157 IF (ind(isel) .EQ. 0)
THEN 4165 IF (ind(isel) .GE. 0) cycle
4175 IF (ipc(isel) .EQ. 0)
THEN 4191 IF (i .EQ. idiag(isel)) cycle
4194 IF(ipc(j).EQ.0 .OR. ind(j).GE.0) cycle
4197 IF (i .LT. idiag(isel))
THEN 4200 IF (ja(jk) .EQ. isel)
THEN 4206 DO jk=ia(j),idiag(j)-1
4207 IF (ja(jk) .EQ. isel)
THEN 4214 IF(kk .NE. 0) vals=vals-a(kk)/2
4221 rsi=-si(isel)+a(idiag(isel))
4222 rsj=-si(j)+a(idiag(j))
4223 eta1=2*a(idiag(isel))
4233 IF (sig1 > 0.0d0)
THEN 4238 IF (sig2 > 0.0d0)
THEN 4243 IF (vals > 0.0d0)
THEN 4245 IF (abs(del1) < epsr .AND. abs(del2) < epsr)
THEN 4246 valp=(eta1*eta2)/(vals*(eta1+eta2))
4247 ELSE IF (abs(del1) < epsr)
THEN 4248 IF (del2 < -epsr) cycle
4249 valp=(eta1*eta2)/(vals*(eta1+eta2))
4250 ELSE IF (abs(del2) < epsr)
THEN 4251 IF (del1 < -epsr) cycle
4252 valp=(eta1*eta2)/(vals*(eta1+eta2))
4255 IF (del12 < -epsr) cycle
4256 valp=vals+del1*del2/del12
4257 IF (valp < 0.0d0) cycle
4258 valp=((eta1*eta2)/(eta1+eta2))/valp
4261 IF (del1 .LE. 0.0d0 .OR. del2 .LE. 0.0d0) cycle
4262 valp=vals+del1*del2/(del1+del2)
4263 IF (valp < 0.0d0) cycle
4264 vals=(eta1*eta2)/(eta1+eta2)
4268 IF (valp > kaptg) cycle
4275 IF (ipair.EQ.0)
GOTO 10
4276 IF (16*(tent-val).LT.-1)
GOTO 9
4277 IF (16*(tent-val).LT.1 .AND. j.LT.ipair)
GOTO 9
4285 IF (ipair .EQ. 0)
THEN 4300 IF (ifirst .AND. 3*nc.GE.2*n .AND. ngl(1).GT.maxcoarseslowt)
THEN 4303 WRITE (iout,901) irank,imult*kaptg_dampjac
4306 '* Coarsening too slow: quality threshold increased to',f6.2)
4315 END SUBROUTINE dagmg_findpairs_gi
4317 SUBROUTINE dagmg_findpairs_si(n,a,ja,ia,idiag,si,ind,lcg,nc &
4327 INTEGER :: n,ja(*),ia(n+1),idiag(n),ind(n),lcg(2,*),nc
4328 REAL(kind(0.0d0)) :: a(*)
4329 REAL(kind(0.0d0)) :: si(n)
4330 INTEGER :: ldd(nddl),nddl
4375 REAL(kind(0.0d0)) :: val,vals,valp,tent,rsi,rsj,epsr
4376 REAL(kind(0.0d0)) :: del1,del2,eta1,eta2,del12,sig1,sig2,rnd,vald
4377 INTEGER :: mindg,i,j,jj,k,kk,jk,isel,dg,ipair,nmark,idd
4378 INTEGER :: i1,i2,i3,ijs,ntentleft,npc,itrs,ijtent,j2
4379 LOGICAL :: acc,ifirst
4380 REAL(kind(0.0d0)) :: kaptg,bndmum1m1,dbndmum1,umdbndmum1
4385 kaptg=imult*kaptg_blocdia
4386 bndmum1m1=1.0d0/(kaptg-1.0d0)
4387 dbndmum1=2*1.0d0/kaptg
4388 umdbndmum1=1.0d0-dbndmum1
4394 DO WHILE (nmark.LT.n)
4401 IF (ind(isel) .EQ. 0)
THEN 4409 IF (ind(isel) .GE. 0) cycle
4419 IF (ipc(isel) .EQ. 0)
THEN 4435 IF (i .EQ. idiag(isel)) cycle
4438 IF(ipc(j).EQ.0 .OR. ind(j).GE.0) cycle
4444 rsi=-si(isel)+a(idiag(isel))
4445 rsj=-si(j)+a(idiag(j))
4454 IF (sig1 > 0.0d0)
THEN 4461 IF (eta1 < 0.0d0) cycle
4462 IF (sig2 > 0.0d0)
THEN 4469 IF (eta2 < 0.0d0) cycle
4470 IF (vals > 0.0d0)
THEN 4472 IF (abs(del1) < epsr .AND. abs(del2) < epsr)
THEN 4473 valp=1.0d0+(eta1*eta2)/(vals*(eta1+eta2))
4474 ELSE IF (abs(del1) < epsr)
THEN 4475 IF (del2 < -epsr) cycle
4476 valp=1.0d0+(eta1*eta2)/(vals*(eta1+eta2))
4477 ELSE IF (abs(del2) < epsr)
THEN 4478 IF (del1 < -epsr) cycle
4479 valp=1.0d0+(eta1*eta2)/(vals*(eta1+eta2))
4482 IF (del12 < -epsr) cycle
4483 valp=vals+del1*del2/del12
4484 IF (valp < 0.0d0) cycle
4485 valp=(vals+(eta1*eta2)/(eta1+eta2))/valp
4488 IF (del1 .LE. 0.0d0 .OR. del2 .LE. 0.0d0) cycle
4489 valp=vals+del1*del2/(del1+del2)
4490 IF (valp < 0.0d0) cycle
4491 vals=vals+(eta1*eta2)/(eta1+eta2)
4492 IF (vals < 0.0d0) cycle
4496 IF (valp > kaptg) cycle
4503 IF (ipair.EQ.0)
GOTO 10
4504 IF (16*(tent-val).LT.-1)
GOTO 9
4505 IF (16*(tent-val).LT.1 .AND. j.LT.ipair)
GOTO 9
4513 IF (ipair .EQ. 0)
THEN 4528 IF (ifirst .AND. 3*nc.GE.2*n .AND. ngl(1).GT.maxcoarseslowt)
THEN 4531 WRITE (iout,901) irank,imult*kaptg_blocdia
4534 '* Coarsening too slow: quality threshold increased to',f6.2)
4543 END SUBROUTINE dagmg_findpairs_si
4545 SUBROUTINE dagmg_findpairs_gi1(n,a,ja,ia,idiag,si,ind,lcg,nc &
4555 INTEGER :: n,ja(*),ia(n+1),idiag(n),ind(n),lcg(2,*),nc
4556 REAL(kind(0.0d0)) :: a(*)
4557 REAL(kind(0.0d0)) :: si(n)
4558 INTEGER :: ldd(nddl),nddl
4560 INTEGER :: iperm(n),riperm(n)
4604 REAL(kind(0.0d0)) :: val,vals,valp,tent,rsi,rsj,epsr
4605 REAL(kind(0.0d0)) :: del1,del2,eta1,eta2,del12,sig1,sig2,rnd,vald
4606 INTEGER :: mindg,i,j,jj,k,kk,jk,isel,dg,ipair,nmark,idd
4607 INTEGER :: i1,i2,i3,ijs,ntentleft,npc,itrs,ijtent,j2
4608 LOGICAL :: acc,ifirst
4609 REAL(kind(0.0d0)) :: kaptg,bndmum1m1,dbndmum1,umdbndmum1
4614 kaptg=imult*kaptg_dampjac
4615 bndmum1m1=1.0d0/(kaptg-1.0d0)
4616 dbndmum1=2*1.0d0/kaptg
4617 umdbndmum1=1.0d0-dbndmum1
4623 DO WHILE (nmark.LT.n)
4631 IF (ind(isel) .EQ. 0)
THEN 4639 IF (ind(isel) .GE. 0) cycle
4649 IF (iperm(isel) .EQ. 0)
THEN 4665 IF (i .EQ. idiag(isel)) cycle
4668 IF(iperm(j).EQ.0 .OR. ind(j).GE.0) cycle
4671 IF (i .LT. idiag(isel))
THEN 4674 IF (ja(jk) .EQ. isel)
THEN 4680 DO jk=ia(j),idiag(j)-1
4681 IF (ja(jk) .EQ. isel)
THEN 4688 IF(kk .NE. 0) vals=vals-a(kk)/2
4695 rsi=-si(isel)+a(idiag(isel))
4696 rsj=-si(j)+a(idiag(j))
4697 eta1=2*a(idiag(isel))
4707 IF (sig1 > 0.0d0)
THEN 4712 IF (sig2 > 0.0d0)
THEN 4717 IF (vals > 0.0d0)
THEN 4719 IF (abs(del1) < epsr .AND. abs(del2) < epsr)
THEN 4720 valp=(eta1*eta2)/(vals*(eta1+eta2))
4721 ELSE IF (abs(del1) < epsr)
THEN 4722 IF (del2 < -epsr) cycle
4723 valp=(eta1*eta2)/(vals*(eta1+eta2))
4724 ELSE IF (abs(del2) < epsr)
THEN 4725 IF (del1 < -epsr) cycle
4726 valp=(eta1*eta2)/(vals*(eta1+eta2))
4729 IF (del12 < -epsr) cycle
4730 valp=vals+del1*del2/del12
4731 IF (valp < 0.0d0) cycle
4732 valp=((eta1*eta2)/(eta1+eta2))/valp
4735 IF (del1 .LE. 0.0d0 .OR. del2 .LE. 0.0d0) cycle
4736 valp=vals+del1*del2/(del1+del2)
4737 IF (valp < 0.0d0) cycle
4738 vals=(eta1*eta2)/(eta1+eta2)
4742 IF (valp > kaptg) cycle
4749 IF (ipair.EQ.0)
GOTO 10
4750 IF (16*(tent-val).LT.-1)
GOTO 9
4751 IF (16*(tent-val).LT.1 .AND. iperm(j).LT.iperm(ipair))
GOTO 9
4759 IF (ipair .EQ. 0)
THEN 4774 IF (ifirst .AND. 3*nc.GE.2*n .AND. ngl(1).GT.maxcoarseslowt)
THEN 4777 WRITE (iout,901) irank,imult*kaptg_dampjac
4780 '* Coarsening too slow: quality threshold increased to',f6.2)
4789 END SUBROUTINE dagmg_findpairs_gi1
4791 SUBROUTINE dagmg_findpairs_si1(n,a,ja,ia,idiag,si,ind,lcg,nc &
4801 INTEGER :: n,ja(*),ia(n+1),idiag(n),ind(n),lcg(2,*),nc
4802 REAL(kind(0.0d0)) :: a(*)
4803 REAL(kind(0.0d0)) :: si(n)
4804 INTEGER :: ldd(nddl),nddl
4806 INTEGER :: iperm(n),riperm(n)
4850 REAL(kind(0.0d0)) :: val,vals,valp,tent,rsi,rsj,epsr
4851 REAL(kind(0.0d0)) :: del1,del2,eta1,eta2,del12,sig1,sig2,rnd,vald
4852 INTEGER :: mindg,i,j,jj,k,kk,jk,isel,dg,ipair,nmark,idd
4853 INTEGER :: i1,i2,i3,ijs,ntentleft,npc,itrs,ijtent,j2
4854 LOGICAL :: acc,ifirst
4855 REAL(kind(0.0d0)) :: kaptg,bndmum1m1,dbndmum1,umdbndmum1
4860 kaptg=imult*kaptg_blocdia
4861 bndmum1m1=1.0d0/(kaptg-1.0d0)
4862 dbndmum1=2*1.0d0/kaptg
4863 umdbndmum1=1.0d0-dbndmum1
4869 DO WHILE (nmark.LT.n)
4877 IF (ind(isel) .EQ. 0)
THEN 4885 IF (ind(isel) .GE. 0) cycle
4895 IF (iperm(isel) .EQ. 0)
THEN 4911 IF (i .EQ. idiag(isel)) cycle
4914 IF(iperm(j).EQ.0 .OR. ind(j).GE.0) cycle
4920 rsi=-si(isel)+a(idiag(isel))
4921 rsj=-si(j)+a(idiag(j))
4930 IF (sig1 > 0.0d0)
THEN 4937 IF (eta1 < 0.0d0) cycle
4938 IF (sig2 > 0.0d0)
THEN 4945 IF (eta2 < 0.0d0) cycle
4946 IF (vals > 0.0d0)
THEN 4948 IF (abs(del1) < epsr .AND. abs(del2) < epsr)
THEN 4949 valp=1.0d0+(eta1*eta2)/(vals*(eta1+eta2))
4950 ELSE IF (abs(del1) < epsr)
THEN 4951 IF (del2 < -epsr) cycle
4952 valp=1.0d0+(eta1*eta2)/(vals*(eta1+eta2))
4953 ELSE IF (abs(del2) < epsr)
THEN 4954 IF (del1 < -epsr) cycle
4955 valp=1.0d0+(eta1*eta2)/(vals*(eta1+eta2))
4958 IF (del12 < -epsr) cycle
4959 valp=vals+del1*del2/del12
4960 IF (valp < 0.0d0) cycle
4961 valp=(vals+(eta1*eta2)/(eta1+eta2))/valp
4964 IF (del1 .LE. 0.0d0 .OR. del2 .LE. 0.0d0) cycle
4965 valp=vals+del1*del2/(del1+del2)
4966 IF (valp < 0.0d0) cycle
4967 vals=vals+(eta1*eta2)/(eta1+eta2)
4968 IF (vals < 0.0d0) cycle
4972 IF (valp > kaptg) cycle
4979 IF (ipair.EQ.0)
GOTO 10
4980 IF (16*(tent-val).LT.-1)
GOTO 9
4981 IF (16*(tent-val).LT.1 .AND. iperm(j).LT.iperm(ipair))
GOTO 9
4989 IF (ipair .EQ. 0)
THEN 5004 IF (ifirst .AND. 3*nc.GE.2*n .AND. ngl(1).GT.maxcoarseslowt)
THEN 5007 WRITE (iout,901) irank,imult*kaptg_blocdia
5010 '* Coarsening too slow: quality threshold increased to',f6.2)
5019 END SUBROUTINE dagmg_findpairs_si1
5021 SUBROUTINE dagmg_lcgmix(nc,m,lcg1,lcg,lcgn)
5022 INTEGER :: nc,m,lcg1(m,*),lcg(2,*),lcgn(2*m,*),i,l,l1,l2
5025 IF(lcg(2,i) .EQ. 0)
THEN 5026 lcgn(1,i)=lcg1(1,lcg(1,i))
5029 ELSE IF(lcg(2,i) .LT. 0)
THEN 5030 IF (lcg1(2,lcg(1,i)) .LT. 0)
THEN 5031 lcgn(1,i)=lcg1(1,lcg(1,i))
5035 lcgn(1,i)=lcg1(1,lcg(1,i))
5036 lcgn(2,i)=lcg1(2,lcg(1,i))
5040 IF (lcg1(2,lcg(1,i)) .LT. 0)
THEN 5041 IF (lcg1(2,lcg(2,i)) .LT. 0)
THEN 5042 lcgn(1,i)=lcg1(1,lcg(1,i))
5043 lcgn(2,i)=lcg1(1,lcg(2,i))
5046 lcgn(1,i)=lcg1(1,lcg(1,i))
5047 lcgn(2,i)=lcg1(1,lcg(2,i))
5048 lcgn(3,i)=lcg1(2,lcg(2,i))
5052 IF (lcg1(2,lcg(2,i)) .LT. 0)
THEN 5053 lcgn(1,i)=lcg1(1,lcg(1,i))
5054 lcgn(2,i)=lcg1(2,lcg(1,i))
5055 lcgn(3,i)=lcg1(1,lcg(2,i))
5058 lcgn(1,i)=lcg1(1,lcg(1,i))
5059 lcgn(2,i)=lcg1(2,lcg(1,i))
5060 lcgn(3,i)=lcg1(1,lcg(2,i))
5061 lcgn(4,i)=lcg1(2,lcg(2,i))
5068 IF(lcg(2,i) .EQ. 0)
THEN 5069 lcgn(1,i)=lcg1(1,lcg(1,i))
5075 IF (lcg1(m,lcg(1,i)).LT.0) l1=-lcg1(m,lcg(1,i))
5076 lcgn(1:l1,i)=lcg1(1:l1,lcg(1,i))
5077 IF(lcg(2,i) .LT. 0)
THEN 5081 IF (lcg1(m,lcg(2,i)).LT.0) l2=-lcg1(m,lcg(2,i))
5082 lcgn(l1+1:l1+l2,i)=lcg1(1:l2,lcg(2,i))
5085 IF(l .LT. 2*m) lcgn(2*m,i)=-l
5090 END SUBROUTINE dagmg_lcgmix
5092 SUBROUTINE dagmg_setind(nc,ndd,ldd,lcg,m,ind)
5093 INTEGER :: nc,m,lcg(m,*),nll,ldd(ndd),ind(*),i,k,l
5099 IF (lcg(m,i) .LT. 0) l=-lcg(m,i)
5105 END SUBROUTINE dagmg_setind
5107 SUBROUTINE dagmg_setcg(n,a,ja,ia,idiag,si,ind,lcg &
5108 ,nc,a2,ja2,ia2,idiag2,si2,ysi,maxdg,iw,w,iext,iext2)
5111 INTEGER :: n,ja(*),ia(n+1),idiag(n),ind(n),nc,lcg(2,nc)
5112 INTEGER :: ja2(*),ia2(n+1),idiag2(n),maxdg
5113 INTEGER,
TARGET :: iw(2*nc)
5114 INTEGER,
OPTIONAL :: iext(*),iext2(*)
5115 REAL(kind(0.0d0)) :: a(*),a2(*),w(nc),vald
5116 REAL(kind(0.0d0)) :: si(n),si2(*),sii
5118 INTEGER :: nz,nzu,i,jj,jc,jcol,ki,kb,kf,jpos
5119 INTEGER,
POINTER,
DIMENSION(:) :: iw1, iw2
5122 iw2 => iw(nc+1:2*nc)
5134 IF (ki.EQ.1 .OR. jj.GT.0)
THEN 5135 IF (ysi) sii=sii+si(jj)
5140 IF (jcol .GT. 0)
THEN 5141 IF (jcol .LT. i)
THEN 5149 a2(jpos) = a2(jpos) + a(kb)
5151 ELSE IF (jcol .GT. i)
THEN 5159 w(jpos) = w(jpos) + a(kb)
5163 IF (ysi .AND. jc.NE.jj) sii=sii+a(kb)
5173 a2(nz+1:nz+nzu)=w(1:nzu)
5174 ja2(nz+1:nz+nzu)=iw2(1:nzu)
5176 maxdg=max(maxdg,nz-ia2(i))
5184 END SUBROUTINE dagmg_setcg
5190 SUBROUTINE dagmg_lapack(N,a,ja,ia,f,ijb,flop)
5193 INTEGER :: n,ia(n+1),ja(*),ijb
5194 REAL(kind(0.0d0)) :: a(*),f(n)
5195 REAL(kind(0.0d0)) :: flop
5197 REAL(kind(0.0d0)),
ALLOCATABLE,
SAVE :: ac(:,:)
5198 INTEGER ,
ALLOCATABLE,
SAVE :: ipiv(:)
5199 INTEGER,
SAVE :: iflop
5200 INTEGER :: i,kk,iext
5202 INTEGER ,
parameter :: ione=1
5207 DEALLOCATE (ac,ipiv)
5209 ELSE IF (ijb == 1)
THEN 5211 ALLOCATE (ac(n,n),ipiv(n))
5214 memax=max(memax,memr+memi*rlenilen)
5217 DO kk=ia(i),ia(i+1)-1
5221 CALL dgetrf(n,n,ac,n,ipiv,ierr)
5223 WRITE(iout, *)
' FATAL ERROR in GETRF: ierror=',ierr
5227 flop=(2*1.0d0)/(3*1.0d0)*(dble(n)**3)
5229 ELSE IF (ijb == 2)
THEN 5231 CALL dgetrs(
'N',n,ione,ac,n,ipiv,f,n,ierr)
5233 WRITE(iout, *)
' FATAL ERROR in GETRS: ierror=',ierr
5236 flop=flop+dble(iflop)
5241 END SUBROUTINE dagmg_lapack
5243 SUBROUTINE dagmg_mumpsseq(n,a,ja,ia,f,ijob,flop)
5249 TYPE dmumps_root_struc
5251 INTEGER mblock, nblock, nprow, npcol
5252 INTEGER myrow, mycol
5253 INTEGER root_size, tot_root_size
5254 INTEGER :: cntxt_blacs, truc
5255 INTEGER,
DIMENSION(:),
POINTER :: rg2l_row
5256 INTEGER,
DIMENSION(:),
POINTER :: rg2l_col
5257 INTEGER ,
DIMENSION(:),
POINTER :: ipiv
5258 INTEGER,
DIMENSION( 9 ) :: descriptor, descb
5259 LOGICAL yes, gridinit_done
5262 DOUBLE PRECISION,
DIMENSION(:),
POINTER :: schur_pointer
5263 INTEGER schur_mloc, schur_nloc, schur_lld, machin
5267 DOUBLE PRECISION,
DIMENSION(:),
POINTER :: qr_tau
5268 DOUBLE PRECISION qr_rcond
5273 DOUBLE PRECISION,
DIMENSION(:),
POINTER::grow, gcos, gsin
5277 INTEGER elg_max,null_max
5278 INTEGER elind,euind,nlupdate,nuupdate
5279 INTEGER,
DIMENSION(:),
POINTER::perm_row,perm_col
5280 INTEGER,
DIMENSION(:),
POINTER::elrow, eurow, ptrel, ptreu
5281 DOUBLE PRECISION,
DIMENSION(:),
POINTER :: elelg, euelg, dl
5283 END TYPE dmumps_root_struc
5315 DOUBLE PRECISION,
DIMENSION(:),
POINTER :: a
5316 INTEGER,
DIMENSION(:),
POINTER :: irn, jcn
5317 DOUBLE PRECISION,
DIMENSION(:),
POINTER :: colsca, rowsca, pad0
5323 INTEGER nz_loc, pad1
5324 INTEGER,
DIMENSION(:),
POINTER :: irn_loc, jcn_loc
5325 DOUBLE PRECISION,
DIMENSION(:),
POINTER :: a_loc, pad2
5331 INTEGER,
DIMENSION(:),
POINTER :: eltptr
5332 INTEGER,
DIMENSION(:),
POINTER :: eltvar
5333 DOUBLE PRECISION,
DIMENSION(:),
POINTER :: a_elt, pad4
5339 INTEGER,
DIMENSION(:),
POINTER :: perm_in
5350 DOUBLE PRECISION,
DIMENSION(:),
POINTER :: rhs, redrhs
5351 DOUBLE PRECISION,
DIMENSION(:),
POINTER :: rhs_sparse
5352 DOUBLE PRECISION,
DIMENSION(:),
POINTER :: sol_loc
5353 INTEGER,
DIMENSION(:),
POINTER :: irhs_sparse
5354 INTEGER,
DIMENSION(:),
POINTER :: irhs_ptr
5355 INTEGER,
DIMENSION(:),
POINTER :: isol_loc
5356 INTEGER lrhs, nrhs, nz_rhs, lsol_loc, lredrhs
5365 DOUBLE PRECISION cost_subtrees
5366 DOUBLE PRECISION cntl(15)
5367 DOUBLE PRECISION rinfo(20)
5368 DOUBLE PRECISION rinfog(20)
5374 INTEGER,
DIMENSION(:),
POINTER :: sym_perm, uns_perm
5380 INTEGER,
DIMENSION(:),
POINTER :: mapping
5385 DOUBLE PRECISION,
DIMENSION(:,:),
POINTER :: null_space
5386 INTEGER deficiency, pad6
5390 INTEGER nprow, npcol, mblock, nblock
5391 INTEGER schur_mloc, schur_nloc, schur_lld
5393 INTEGER,
DIMENSION(:),
POINTER :: listvar_schur
5394 DOUBLE PRECISION,
DIMENSION(:),
POINTER :: schur
5395 DOUBLE PRECISION,
DIMENSION(:),
POINTER :: schur_cinterface
5399 CHARACTER(LEN=16) version_number
5403 CHARACTER(LEN=256) :: ooc_tmpdir
5404 CHARACTER(LEN=64) :: ooc_prefix
5408 CHARACTER(LEN=256) write_problem
5416 INTEGER comm_nodes, myid_nodes, comm_load
5417 INTEGER myid, nprocs, nslaves
5419 INTEGER,
DIMENSION(:),
POINTER :: poids
5422 INTEGER,
DIMENSION(:),
POINTER :: bufr
5424 INTEGER maxis1, pad7
5426 INTEGER*8 keep8(150)
5428 INTEGER,
DIMENSION(:),
POINTER :: is
5431 INTEGER,
DIMENSION(:),
POINTER :: is1
5436 INTEGER,
POINTER,
DIMENSION(:)::step, ne_steps, nd_steps
5438 INTEGER,
POINTER,
DIMENSION(:)::step2node
5440 INTEGER,
POINTER,
DIMENSION(:)::frere_steps, dad_steps
5441 INTEGER,
POINTER,
DIMENSION(:)::fils, ptrar, frtptr, frtelt
5442 INTEGER,
POINTER,
DIMENSION(:)::na, procnode_steps
5445 INTEGER,
DIMENSION(:),
POINTER :: ptlust_s
5446 INTEGER(8),
DIMENSION(:),
POINTER :: ptrfac
5448 DOUBLE PRECISION,
DIMENSION(:),
POINTER :: s
5450 INTEGER,
DIMENSION(:),
POINTER :: procnode
5454 INTEGER,
DIMENSION(:),
POINTER :: intarr
5455 DOUBLE PRECISION,
DIMENSION(:),
POINTER :: dblarr
5457 INTEGER nelt_loc, leltvar, na_elt, pad8
5458 INTEGER,
DIMENSION(:),
POINTER :: eltproc
5460 INTEGER,
DIMENSION(:,:),
POINTER :: candidates
5461 INTEGER,
DIMENSION(:),
POINTER :: istep_to_iniv2
5462 INTEGER,
DIMENSION(:),
POINTER :: future_niv2
5463 INTEGER,
DIMENSION(:,:),
POINTER :: tab_pos_in_pere
5464 LOGICAL,
DIMENSION(:),
POINTER :: i_am_cand
5466 INTEGER,
DIMENSION(:),
POINTER :: mem_dist
5468 INTEGER,
DIMENSION(:),
POINTER :: posinrhscomp
5469 DOUBLE PRECISION,
DIMENSION(:),
POINTER :: rhscomp
5472 DOUBLE PRECISION,
DIMENSION(:),
POINTER :: mem_subtree
5473 INTEGER,
DIMENSION(:),
POINTER :: my_root_sbtr
5474 INTEGER,
DIMENSION(:),
POINTER :: my_first_leaf
5475 INTEGER,
DIMENSION(:),
POINTER :: my_nb_leaf
5476 INTEGER,
DIMENSION(:),
POINTER :: depth_first
5477 DOUBLE PRECISION,
DIMENSION(:),
POINTER :: cost_trav
5478 INTEGER nbsa_local, zwave
5479 INTEGER(8) :: max_surf_master
5480 INTEGER :: lwk_user, zozo
5481 DOUBLE PRECISION,
DIMENSION(:),
POINTER :: wk_user
5483 DOUBLE PRECISION,
DIMENSION(:),
POINTER ::cb_son_size
5485 INTEGER instance_number
5487 INTEGER ooc_max_nb_nodes_for_zone
5488 INTEGER,
DIMENSION(:,:),
POINTER :: ooc_inode_sequence
5489 INTEGER(8),
DIMENSION(:,:),
POINTER :: ooc_size_of_block
5490 INTEGER*8,
DIMENSION(:,:),
POINTER :: ooc_vaddr
5491 INTEGER,
DIMENSION(:),
POINTER :: ooc_total_nb_nodes
5492 INTEGER,
DIMENSION(:),
POINTER :: ooc_nb_files
5493 CHARACTER,
DIMENSION(:,:),
POINTER :: ooc_file_names
5494 INTEGER,
DIMENSION(:),
POINTER :: ooc_file_name_length
5496 INTEGER,
DIMENSION(:),
POINTER :: pivnul_list
5498 DOUBLE PRECISION dkeep(30)
5500 INTEGER,
DIMENSION(:,:),
POINTER :: sup_proc
5504 type(dmumps_root_struc) :: root
5505 END TYPE dmumps_struc
5507 INTEGER :: n,ia(n+1),ijob
5508 INTEGER,
TARGET :: ja(*)
5509 REAL(kind(0.0d0)),
TARGET :: a(*),f(n)
5510 REAL(kind(0.0d0)) :: flop
5512 INTEGER,
SAVE :: iflop
5513 TYPE(dmumps_struc),
SAVE :: mumps_par
5514 INTEGER :: ierr, i, j, k
5516 IF (ijob == -2)
THEN 5520 CALL dagmg_mumps(mumps_par)
5522 ELSE IF (ijob == 1)
THEN 5531 CALL dagmg_mumps(mumps_par)
5532 mumps_par%ICNTL(2)=-1
5533 mumps_par%ICNTL(3)=-1
5534 mumps_par%ICNTL(4)=0
5535 mumps_par%ICNTL(14)=80
5536 mumps_par%ICNTL(18)=3
5537 mumps_par%ICNTL(24)=1
5538 mumps_par%NZ_loc=ia(n+1)-1
5540 ALLOCATE( mumps_par%JCN_loc(mumps_par%NZ_loc) )
5542 do j=ia(i),ia(i+1)-1
5543 mumps_par%JCN_loc(j)=i
5546 mumps_par%IRN_loc => ja(1:mumps_par%NZ_loc)
5548 ALLOCATE( mumps_par%IRN_loc(mumps_par%NZ_loc) )
5550 do j=ia(i),ia(i+1)-1
5551 mumps_par%IRN_loc(j)=i
5554 mumps_par%JCN_loc => ja(1:mumps_par%NZ_loc)
5556 memi=memi+mumps_par%NZ_loc
5557 memax=max(memax,memr+memi*rlenilen)
5558 mumps_par%A_loc => a(1:mumps_par%NZ_loc)
5563 CALL dagmg_mumps(mumps_par)
5564 flop=mumps_par%RINFO(3)
5567 DEALLOCATE(mumps_par%JCN_loc)
5568 NULLIFY(mumps_par%IRN_loc,mumps_par%A_loc)
5570 DEALLOCATE(mumps_par%IRN_loc)
5571 NULLIFY(mumps_par%JCN_loc,mumps_par%A_loc)
5573 memi=memi-mumps_par%NZ_loc
5575 ELSE IF (ijob == 2)
THEN 5579 mumps_par%RHS => f(1:n)
5580 CALL dagmg_mumps(mumps_par)
5584 END SUBROUTINE dagmg_mumpsseq
5587 END MODULE dagmg_allroutines
5591 SUBROUTINE dagmg( n,a,ja,ia,f,x,ijob,iprint,nrest,iter,tol )
5593 USE dagmg_allroutines
5595 INTEGER :: n,ia(n+1),ja(*),ijob,iprint,nrest,iter
5596 REAL (kind(0.0d0)) :: a(*),f(n),x(n)
5597 REAL (kind(0.0d0)) :: tol
5729 INTEGER,
SAVE :: nza
5730 REAL(kind(0.0d0)),
SAVE :: cputm=0.0d0,eltm=0.0d0,flop=0.0d0
5731 LOGICAL,
SAVE :: preprocessed=.false.,solve=.false.
5732 INTEGER :: i,init,ijb,k
5733 REAL(kind(0.0d0)) :: cputmp,eltmp,memh
5734 REAL(kind(0.0d0)) :: resid
5735 INTEGER,
POINTER,
DIMENSION(:) :: iw
5736 REAL(kind(0.0d0)),
POINTER,
DIMENSION(:) :: ascal
5737 REAL(kind(0.0d0)),
POINTER,
DIMENSION(:) :: w
5738 REAL(kind(0.0d0)) :: adum(1),fdum(1)
5739 INTEGER :: listrank(1),ifirstlistrank
5743 IF (iprint <= 0)
THEN 5746 ELSE IF (iprint == 5)
THEN 5755 transint=trans.AND.(.NOT.spd)
5757 wff=wfo.AND.(irank<=0)
5759 IF (mod(ijb,10) >= 2 .AND. .NOT.preprocessed)
THEN 5760 WRITE (iout,1001) irank,ijob
5764 IF (ijb < 0 .AND. solve)
GOTO 450
5765 IF (ijb < 0)
GOTO 500
5766 IF (mod(ijb,10) >= 2)
GOTO 300
5767 IF (preprocessed)
THEN 5770 CALL dagmg_mumpsseq(nn(nlev),adum,ja,ia,fdum,-2,flop)
5771 preprocessed=.false.
5778 CALL dagmg_mestime(-1,0.0d0,0.0d0)
5783 IF (huge(n) > 1.0e10)
THEN 5784 rlenilen=dble(8)/dble(real_len)
5786 rlenilen=dble(4)/dble(real_len)
5796 WRITE(iout,900) irank
5801 ALLOCATE(
dt(1)%idiag(n+1),w(n),iw(n))
5802 CALL dagmg_partroword(n,a,ja,ia,
dt(1)%idiag,w,iw)
5807 CALL dagmg_setupl1(n,a,ja,ia,listrank,ifirstlistrank)
5811 CALL dagmg_smoothsetup
5813 memh=memr+memi*rlenilen
5815 CALL dagmg_mestime(1,cputmp,eltmp)
5818 WRITE(iout,960) irank, memax/nza, real_len &
5819 , memax*real_len/(2**20)
5820 IF(mod(ijb,10) == 1)
THEN 5821 WRITE(iout,961) irank, memh/nza, real_len &
5822 , memh*real_len/(2**20)
5828 WRITE(iout,997) irank,eltmp
5832 IF (mod(ijb,10) == 1)
RETURN 5837 CALL dagmg_mestime(-2,0.0d0,0.0d0)
5841 IF (nrst <= 0) nrst=10
5844 IF (mod(ijb,10) >= 3)
THEN 5846 WRITE(iout,901) irank
5848 CALL dagmg_applyprec(n,f,x,a,ja,ia,flop)
5849 CALL dagmg_mestime(2,cputmp,eltmp)
5858 ELSE IF (nrst > 1)
THEN 5860 CALL dagmg_gcr(n,f,x,iter,resid,a,ja,ia,init,flop)
5867 CALL dagmg_flexcg(n,f,x,iter,resid,a,ja,ia,init,flop)
5873 CALL dagmg_mestime(2,cputm,eltm)
5879 WRITE(iout,990) irank
5884 IF (wff .AND. iter.NE.0)
THEN 5886 WRITE(iout,955) i,kstat(2,i-1),kstat(2,i), &
5887 dble(kstat(2,i))/dble(kstat(2,i-1)),kstat(1,i)
5891 WRITE(iout,954) irank,flop/dble(11*n+2*nza)
5892 WRITE(iout,962) irank,(memh+mritr)/nza, real_len &
5893 , (memh+mritr)*real_len/(2**20)
5897 WRITE(iout,999) irank,eltm
5906 IF (mod(ijb,10) > 0)
RETURN 5913 CALL dagmg_mumpsseq(nn(nlev),adum,ja,ia,fdum,-2,flop)
5914 preprocessed=.false.
5921 WRITE (iout,902) irank
5927 900
FORMAT(i3,
'*ENTERING AGMG **********************************',&
5928 '***************************')
5929 901
FORMAT(i3,
'*ONE APPLICATION OF AGMG PRECONDITIONER')
5930 902
FORMAT(i3,
'*LEAVING AGMG * (MEMORY RELEASED) ***************',&
5931 '***************************')
5932 903
FORMAT(i3,
'*SYSTEM TOO SMALL: use direct solver')
5933 954
FORMAT(i3,
'*',
' Equiv. number of CG iter.:',f9.2)
5934 955
FORMAT(
'**** level',i2,
' #call=',i6,
' #cycle=',i6, &
5935 ' mean=',f7.2,
' max=',i3)
5936 960
FORMAT( i3,
'*',
' memory used (peak):',f9.2, &
5937 ' real(',i1,
') words per nnz (',f8.2,
' Mb)')
5938 961
FORMAT( i3,
'*',
' memory still allocated:',f9.2, &
5939 ' real(',i1,
') words per nnz (',f8.2,
' Mb)')
5940 962
FORMAT( i3,
'*',
' memory used for solution:',f9.2, &
5941 ' real(',i1,
') words per nnz (',f8.2,
' Mb)')
5942 990
FORMAT(i3,
'*GLOBAL STATISTICS for preconditioner application:')
5943 996
FORMAT(i3,
'*',
' Setup time (CPU): ',1pe10.2, &
5945 997
FORMAT(i3,
'*',
' Setup time (Elapsed): ',1pe10.2, &
5947 998
FORMAT(i3,
'*',
' Solution time (CPU): ',1pe10.2, &
5949 999
FORMAT(i3,
'*',
' Solution time (Elapsed): ',1pe10.2, &
5951 1001
FORMAT(i3,
'*',
' FATAL ERROR: setup not done: ijob=',i3, &
5953 1002
FORMAT(i3,
'*',
' FATAL ERROR: ijob=',i3, &
5954 ' (i.e. >= 100: work with transpose) is not allowed in the || case')
5955 END SUBROUTINE dagmg
double sig
correlated to variance of initial distribution