17 SUBROUTINE leq_cg(VNAME, VNO, VAR, A_M, B_m, cmethod, &
35 CHARACTER(LEN=*),
INTENT(IN) :: Vname
37 INTEGER,
INTENT(IN) :: VNO
42 DOUBLE PRECISION,
DIMENSION(ijkstart3:ijkend3),
INTENT(INOUT) :: Var
44 DOUBLE PRECISION,
DIMENSION(ijkstart3:ijkend3,-3:3),
INTENT(INOUT) 46 DOUBLE PRECISION,
DIMENSION(ijkstart3:ijkend3),
INTENT(INOUT) :: B_m
50 CHARACTER(LEN=*),
INTENT(IN) :: CMETHOD
52 DOUBLE PRECISION,
INTENT(IN) :: TOL
55 CHARACTER(LEN=4),
INTENT(IN) :: PC
57 INTEGER,
INTENT(IN) :: ITMAX
59 INTEGER,
INTENT(INOUT) :: IER
63 call leq_cg0( vname, vno, var, a_m, b_m, &
65 elseif(pc.eq.
'DIAG')
then 66 call leq_cg0( vname, vno, var, a_m, b_m, &
68 elseif(pc.eq.
'NONE')
then 69 call leq_cg0( vname, vno, var, a_m, b_m, &
73 'preconditioner option not found - check mfix.dat and readme' 96 SUBROUTINE leq_cg0(VNAME, VNO, VAR, A_M, B_m, cmethod, &
97 tol, itmax, matvec, msolve, ier )
117 CHARACTER(LEN=*),
INTENT(IN) :: Vname
119 INTEGER,
INTENT(IN) :: VNO
131 CHARACTER(LEN=*),
INTENT(IN) :: CMETHOD
133 DOUBLE PRECISION,
INTENT(IN) :: TOL
135 INTEGER,
INTENT(IN) :: ITMAX
137 INTEGER,
INTENT(INOUT) :: IER
147 INTEGER,
PARAMETER :: idebugl = 0
148 DOUBLE PRECISION,
PARAMETER :: ratiotol = 0.2
149 logical,
parameter :: do_unit_scaling = .true.
153 DOUBLE PRECISION,
DIMENSION(ijkstart3:ijkend3) :: &
155 DOUBLE PRECISION,
DIMENSION(0:ITMAX+1) :: &
157 DOUBLE PRECISION :: RxZ, PxQ, oam
158 DOUBLE PRECISION :: Rnorm, Rnorm0, TOLMIN
159 LOGICAL :: isconverged
160 INTEGER :: i, j, k, ijk
193 tolmin = epsilon(
one )
197 if (do_unit_scaling)
then 207 a_m(ijk,:) = a_m(ijk,:)*oam
208 b_m(ijk) = b_m(ijk)*oam
229 if (idebugl >= 1)
then 230 if(
mype.eq.0) print*,
'leq_cg, initial: ', vname,
' resid ', rnorm0
236 call matvec(vname, var, a_m, r)
241 r(ijk) = b_m(ijk) - r(ijk)
252 rnorm0 = rnorm0 + r(ijk)*r(ijk)
255 rnorm0 = dot_product(r,r)
257 rnorm0 = sqrt( rnorm0 )
262 if (idebugl >= 1)
then 263 if(
mype.eq.0) print*,
'leq_cg, initial: ', vname,
' resid ', rnorm0
274 call msolve( vname, r, a_m, zvec, cmethod)
283 rxz = rxz + r(ijk) * zvec(ijk)
287 rho(i-1) = dot_product( r, zvec )
294 if (rho(i-1) .eq.
zero)
then 323 beta(i-1) = ( rho(i-1)/rho(i-2) )
327 p(ijk) = zvec(ijk) + beta(i-1)* p(ijk)
330 p(:) = zvec(:) + beta(i-1)*p(:)
336 call matvec(vname, p, a_m, q)
343 pxq = pxq + p(ijk) * q(ijk)
346 pxq = dot_product( p, q )
354 alpha(i) = rho(i-1)/pxq
362 r(ijk) = r(ijk) - alpha(i) * q(ijk)
363 var(ijk) = var(ijk) + alpha(i) * p(ijk)
366 r(:) = r(:) - alpha(i) * q(:)
367 var(:) = var(:) + alpha(i) * p(:)
377 rnorm = rnorm + r(ijk) * r(ijk)
380 rnorm = dot_product( r, r )
382 rnorm = sqrt( rnorm )
387 if (idebugl.ge.1)
then 388 print*,
'leq_cs, initial: ', vname,
' Vnorm ', rnorm
390 print*,
'iter, Rnorm ', iter, rnorm
391 print*,
'PxQ, rho(i-1) ', pxq, rho(i-1)
392 print*,
'alpha(i), beta(i-1) ', alpha(i), beta(i-1)
396 isconverged = (rnorm <= tol*rnorm0)
398 if (isconverged)
then 411 if (idebugl >= 1)
then 412 call matvec( vname, var, a_m, r )
416 r(ijk) = r(ijk) - b_m(ijk)
427 rnorm = rnorm + r(ijk) * r(ijk)
430 rnorm = dot_product( r,r)
432 rnorm = sqrt( rnorm )
437 if(
mype.eq.0) print*,
'leq_cg: final Rnorm ', rnorm
439 if(
mype.eq.0) print*,
'leq_cg ratio : ', vname,
' ',iter, &
444 if (.not.isconverged)
then 447 if (
real(Rnorm) >= ratiotol*
real(rnorm0)) then
subroutine leq_matvec(VNAME, VAR, A_M, Avar)
double precision, parameter one
integer, dimension(dim_eqs) iter_tot
subroutine leq_msolve(VNAME, B_m, A_M, Var, CMETHOD)
subroutine leq_msolve0(VNAME, B_m, A_M, Var, CMETHOD)
double precision function dot_product_par(r1, r2)
integer, parameter unit_log
subroutine leq_msolve1(VNAME, B_m, A_M, Var, CMETHOD)
subroutine leq_cg0(VNAME, VNO, VAR, A_M, B_m, cmethod, TOL, ITMAX, MATVEC, MSOLVE, IER)
subroutine leq_cg(VNAME, VNO, VAR, A_M, B_m, cmethod, TOL, PC, ITMAX, IER)
double precision, parameter zero