17 SUBROUTINE leq_gmres(VNAME, VNO, VAR, A_M, B_M, &
18 cmethod, tol, itmax, max_it, ier)
34 CHARACTER(LEN=*),
INTENT(IN) :: Vname
36 INTEGER,
INTENT(IN) :: VNO
41 DOUBLE PRECISION,
DIMENSION(DIMENSION_3),
INTENT(INOUT) :: Var
43 DOUBLE PRECISION,
DIMENSION(DIMENSION_3,-3:3),
INTENT(INOUT) :: A_m
45 DOUBLE PRECISION,
DIMENSION(DIMENSION_3),
INTENT(INOUT) :: B_m
48 CHARACTER(LEN=*),
INTENT(IN) :: CMETHOD
50 DOUBLE PRECISION,
INTENT(IN) :: TOL
52 INTEGER,
INTENT(IN) :: ITMAX
55 INTEGER,
INTENT(IN) :: MAX_IT
57 INTEGER,
INTENT(INOUT) :: IER
61 LOGICAL :: IS_BM_ZERO, ALL_IS_BM_ZERO
64 is_bm_zero = (maxval( abs(b_m(:)) ) .EQ.
zero)
67 IF (all_is_bm_zero)
THEN 94 SUBROUTINE leq_gmres0(VNAME, VNO, VAR, A_M, B_M, &
95 cmethod, tol, itmax, max_it, &
104 USE gridmap, only: istart3, iend3, jstart3, jend3, kstart3, kend3
115 CHARACTER(LEN=*),
INTENT(IN) :: Vname
117 INTEGER,
INTENT(IN) :: VNO
122 DOUBLE PRECISION,
INTENT(INOUT) :: Var(
dimension_3)
124 DOUBLE PRECISION,
INTENT(INOUT) :: A_m(
dimension_3,-3:3)
126 DOUBLE PRECISION,
INTENT(INOUT) :: B_m(
dimension_3)
129 CHARACTER(LEN=*),
INTENT(IN) :: CMETHOD
131 DOUBLE PRECISION,
INTENT(IN) :: TOL
133 INTEGER,
INTENT(IN) :: ITMAX
135 INTEGER,
INTENT(IN) :: MAX_IT
137 INTEGER,
INTENT(INOUT) :: IER
151 DOUBLE PRECISION,
dimension(:,:),
allocatable :: V
152 DOUBLE PRECISION H(itmax+1,itmax)
153 DOUBLE PRECISION CS(itmax)
154 DOUBLE PRECISION SN(itmax)
155 DOUBLE PRECISION Y(itmax)
157 DOUBLE PRECISION,
dimension(:),
allocatable :: R,TEMP,WW
159 DOUBLE PRECISION E1(itmax+2)
160 DOUBLE PRECISION SS(itmax+2)
162 DOUBLE PRECISION BNRM2, ERROR, ERROR0
163 DOUBLE PRECISION NORM_R0, NORM_R, NORM_W
164 DOUBLE PRECISION INV_NORM_R, NORM_S, NORM_Y
167 INTEGER IJK, II, JJ, KK, I, K
168 INTEGER RESTRT, M, ITER, MDIM
169 DOUBLE PRECISION DTEMP
170 DOUBLE PRECISION MINH, MAXH, CONDH, ALL_MINH, ALL_MAXH
171 DOUBLE PRECISION INV_H_IP1_I
173 LOGICAL IS_BM_ZERO, IS_ERROR, IS_CONVERGED
174 LOGICAL ALL_IS_BM_ZERO, ALL_IS_ERROR, ALL_IS_CONVERGED
176 CHARACTER(LEN=40) :: NAME
187 name =
'LEQ_GMRES0 ' // trim(vname)
210 bnrm2 = sqrt( bnrm2 )
216 is_bm_zero = bnrm2 .EQ.
zero 218 IF (all_is_bm_zero)
THEN 226 CALL matvec(vname, var, a_m, r)
232 ijk = funijk( ii,jj,kk )
233 temp(ijk) = b_m(ijk) - r(ijk)
239 CALL msolve(vname, temp, a_m, r, cmethod)
242 norm_r = sqrt( norm_r )
248 IF (jdebug.GE.1)
THEN 249 CALL write_debug( name,
' INITIAL ERROR ', error0 )
250 CALL write_debug( name,
' INITIAL RESIDUAL ', norm_r0)
260 CALL matvec( vname, var, a_m, r )
267 ijk = funijk( ii,jj,kk )
268 temp(ijk) = b_m(ijk) - r(ijk)
274 CALL msolve(vname, temp, a_m, r, cmethod)
277 norm_r = sqrt( norm_r )
278 inv_norm_r =
one / norm_r
285 ijk = funijk( ii,jj,kk )
286 v(ijk,1) = r(ijk) * inv_norm_r
291 ss(:) = norm_r * e1(:)
299 CALL matvec(vname, v(:,i), a_m, temp)
301 CALL msolve(vname, temp, a_m, ww, cmethod)
312 ijk = funijk( ii,jj,kk )
313 ww(ijk) = ww(ijk) - h(k,i)*v(ijk,k)
320 norm_w = sqrt( norm_w )
323 inv_h_ip1_i =
one / h(i+1,i)
329 ijk = funijk( ii,jj,kk )
330 v(ijk, i+1) = ww(ijk) * inv_h_ip1_i
338 dtemp = cs(k)*h(k,i) + sn(k)*h(k+1,i)
339 h(k+1,i) = -sn(k)*h(k,i) + cs(k)*h(k+1,i)
345 CALL rotmat( h(i,i), h(i+1,i), cs(i), sn(i) )
348 ss(i+1) = -sn(i)*ss(i)
350 h(i,i) = cs(i)*h(i,i) + sn(i)*h(i+1,i)
352 error = abs( ss(i+1) ) / bnrm2
354 is_converged = (error .LE. tol*error0)
356 IF (all_is_converged)
THEN 371 y(jj) = y(jj) - h(jj,ii)*yii
377 IF (jdebug.GE.1)
THEN 381 maxh = max( maxh, abs(h(ii,ii)) )
382 minh = min( minh, abs(h(ii,ii)) )
391 temp(1:mdim) = ss(1:mdim) - &
392 matmul( h(1:mdim,1:mdim ), y(1:mdim) )
393 dtemp = dot_product( temp(1:mdim), temp(1:mdim) )
394 dtemp = sqrt( dtemp )
396 norm_s = dot_product( ss(1:mdim),ss(1:mdim) )
397 norm_s = sqrt( norm_s )
399 norm_y = dot_product( y(1:mdim),y(1:mdim) )
400 norm_y = sqrt( norm_y )
402 is_error = (dtemp .GT. condh*norm_s)
404 IF (all_is_error)
THEN 406 'DTEMP, NORM_S ', dtemp, norm_s )
408 'CONDH, NORM_Y ', condh, norm_y )
410 '** STOP IN LEQ_GMRES ** ')
422 ijk = funijk( ii,jj,kk )
423 var(ijk) = var(ijk) + &
424 dot_product( v(ijk,1:i), y(1:i) )
434 is_converged = ( error .LE. tol*error0)
436 IF ( all_is_converged )
THEN 456 y(jj) = y(jj) - h(jj,ii)*yii
462 IF (jdebug.GE.1)
THEN 466 maxh = max( maxh, abs(h(ii,ii)) )
467 minh = min( minh, abs(h(ii,ii)) )
471 temp(1:mdim) = ss(1:mdim) - &
472 matmul( h(1:mdim,1:mdim ), y(1:mdim) )
474 dtemp = dot_product( temp(1:mdim), temp(1:mdim) )
475 dtemp = sqrt( dtemp )
477 norm_s = dot_product( ss(1:mdim),ss(1:mdim) )
478 norm_s = sqrt( norm_s )
480 norm_y = dot_product( y(1:mdim),y(1:mdim) )
481 norm_y = sqrt( norm_y )
483 is_error = (dtemp .GT. condh*norm_s)
485 IF (all_is_error)
THEN 487 'DTEMP, NORM_S ', dtemp, norm_s )
489 'CONDH, NORM_Y ', condh, norm_y )
491 '** STOP IN LEQ_GMRES ** ')
502 ijk = funijk( ii,jj,kk )
503 var(ijk) = var(ijk) + &
504 dot_product( v(ijk,1:m), y(1:m) )
509 CALL matvec(vname, var, a_m, r)
516 ijk = funijk( ii,jj,kk )
517 temp(ijk) = b_m(ijk) - r(ijk)
523 CALL msolve( vname, temp, a_m, r, cmethod)
525 norm_r = sqrt( norm_r )
528 error = ss(i+1) / bnrm2
530 IF (jdebug.GE.1)
THEN 531 CALL write_debug(name,
'LEQ_GMRES: I, ITER ', i, iter)
532 CALL write_debug(name,
'LEQ_GMRES: ERROR, NORM_R ', &
536 is_converged = (error .LE. tol*error0)
538 IF (all_is_converged)
THEN 545 is_error = (error .GT. tol*error0)
547 IF (all_is_error)
THEN 551 IF (jdebug.GE.1)
THEN 552 CALL matvec(vname, var, a_m, r)
559 ijk = funijk( ii,jj,kk )
560 r(ijk) = r(ijk) - b_m(ijk)
566 norm_r = sqrt( norm_r )
574 CALL write_debug(name,
'ERR RATIO ', error/error0 )
575 CALL write_debug(name,
'RESID RATIO ', norm_r/norm_r0 )
593 SUBROUTINE rotmat( A, B, C, S )
602 DOUBLE PRECISION A,B,C,S
606 DOUBLE PRECISION ONE,ZERO
607 parameter(one=1.0d0,zero=0.0d0)
611 DOUBLE PRECISION TEMP
617 ELSEIF (abs(b) .GT. abs(a))
THEN 619 s = one / sqrt( one + temp*temp )
623 c = one / sqrt( one + temp*temp )
663 DOUBLE PRECISION,
INTENT(INOUT) :: A_M(
dimension_3, -3:3)
665 CHARACTER(LEN=*),
INTENT(IN) :: VNAME
669 logical,
parameter :: do_reset = .true.
673 integer,
dimension(-3:3) :: ijktable
674 integer :: istartl, iendl, jstartl, jendl, kstartl, kendl, elstart
675 integer :: i,j,k,el, ijk,ijk2, ii,jj,kk
676 integer :: nerror, all_nerror
677 logical :: is_in_k, is_in_j, is_in_i, is_in
678 logical :: is_bc_k, is_bc_j, is_bc_i, is_bc, is_ok
702 is_in = is_in_k .and. is_in_j .and. is_in_i
706 ijktable( -2 ) = jm_of(ijk)
707 ijktable( -1 ) = im_of(ijk)
709 ijktable( 1 ) = ip_of(ijk)
710 ijktable( 2 ) = jp_of(ijk)
713 ijktable( -3 ) = km_of(ijk)
714 ijktable( 3 ) = kp_of(ijk)
725 ijk2 = ijktable( el )
732 is_bc = is_bc_k .or. is_bc_j .or. is_bc_i
734 is_ok = (a_m(ijk,el).eq.
zero)
737 if (do_reset) a_m(ijk,el) =
zero 748 if ((nerror >= 1) .and. (
mype.eq.
pe_io))
then 750 call write_debug(
'leq_check: ' // trim( vname ), &
751 'A_m is reset. nerror = ', nerror )
753 call write_debug(
'leq_check: ' // trim( vname ), &
754 'A_m is not reset. nerror = ', nerror )
integer, dimension(:), allocatable i_of
subroutine leq_matvec(VNAME, VAR, A_M, Avar)
double precision, parameter one
subroutine leq_check(vname, A_m)
subroutine leq_msolve(VNAME, B_m, A_M, Var, CMETHOD)
integer, dimension(:), allocatable k_of
integer, dimension(:), allocatable j_of
subroutine leq_gmres(VNAME, VNO, VAR, A_M, B_M, cmethod, TOL, ITMAX, MAX_IT, IER)
double precision function dot_product_par(r1, r2)
subroutine rotmat(A, B, C, S)
subroutine leq_gmres0(VNAME, VNO, VAR, A_M, B_M, CMETHOD, TOL, ITMAX, MAX_IT, MATVEC, MSOLVE, IER)
double precision, parameter zero