@ -474,7 +474,7 @@ contains
call psb_info ( ictxt , me , np )
call psb_info ( ictxt , me , np )
if ( debug_level > 1 ) then
if ( debug_level > 1 ) then
write ( debug_unit , * ) me , ' inner_ml_aply at level ', level
write ( debug_unit , * ) me , ' Start inner_ml_aply at level ', level
end if
end if
select case ( p % precv ( level ) % parms % ml_type )
select case ( p % precv ( level ) % parms % ml_type )
@ -538,6 +538,9 @@ contains
go to 9999
go to 9999
end select
end select
if ( debug_level > 1 ) then
write ( debug_unit , * ) me , ' End inner_ml_aply at level ' , level
end if
call psb_erractionrestore ( err_act )
call psb_erractionrestore ( err_act )
return
return
@ -603,7 +606,7 @@ contains
call p % precv ( level ) % sm % apply ( cone , &
call p % precv ( level ) % sm % apply ( cone , &
& mlprec_wrk ( level ) % vx2l , czero , mlprec_wrk ( level ) % vy2l , &
& mlprec_wrk ( level ) % vx2l , czero , mlprec_wrk ( level ) % vy2l , &
& p % precv ( level ) % base_desc , trans , &
& p % precv ( level ) % base_desc , trans , &
& sweeps , work , info )
& sweeps , work , info ,init = 'Z' )
if ( info / = psb_success_ ) then
if ( info / = psb_success_ ) then
call psb_errpush ( psb_err_internal_error_ , name , &
call psb_errpush ( psb_err_internal_error_ , name , &
& a_err = 'Error during ADD smoother_apply' )
& a_err = 'Error during ADD smoother_apply' )
@ -615,7 +618,6 @@ contains
call psb_map_X2Y ( cone , mlprec_wrk ( level ) % vx2l , &
call psb_map_X2Y ( cone , mlprec_wrk ( level ) % vx2l , &
& czero , mlprec_wrk ( level + 1 ) % vx2l , &
& czero , mlprec_wrk ( level + 1 ) % vx2l , &
& p % precv ( level + 1 ) % map , info , work = work )
& p % precv ( level + 1 ) % map , info , work = work )
call mlprec_wrk ( level + 1 ) % vy2l % zero ( )
if ( info / = psb_success_ ) then
if ( info / = psb_success_ ) then
call psb_errpush ( psb_err_internal_error_ , name , &
call psb_errpush ( psb_err_internal_error_ , name , &
& a_err = 'Error during restriction' )
& a_err = 'Error during restriction' )
@ -917,7 +919,7 @@ contains
call psb_info ( ictxt , me , np )
call psb_info ( ictxt , me , np )
if ( debug_level > 1 ) then
if ( debug_level > 1 ) then
write ( debug_unit , * ) me , name , ' at level ', level
write ( debug_unit , * ) me , name , ' start at level ', level
end if
end if
if ( ( level < 1 ) . or . ( level > nlev ) ) then
if ( ( level < 1 ) . or . ( level > nlev ) ) then
@ -937,7 +939,7 @@ contains
if ( info == psb_success_ ) call p % precv ( level ) % sm % apply ( cone , &
if ( info == psb_success_ ) call p % precv ( level ) % sm % apply ( cone , &
& mlprec_wrk ( level ) % vx2l , czero , mlprec_wrk ( level ) % vy2l , &
& mlprec_wrk ( level ) % vx2l , czero , mlprec_wrk ( level ) % vy2l , &
& p % precv ( level ) % base_desc , trans , &
& p % precv ( level ) % base_desc , trans , &
& sweeps , work , info , init = ' Y ')
& sweeps , work , info , init = ' Z ')
else if ( level < nlev ) then
else if ( level < nlev ) then
@ -946,13 +948,13 @@ contains
if ( info == psb_success_ ) call p % precv ( level ) % sm % apply ( cone , &
if ( info == psb_success_ ) call p % precv ( level ) % sm % apply ( cone , &
& mlprec_wrk ( level ) % vx2l , czero , mlprec_wrk ( level ) % vy2l , &
& mlprec_wrk ( level ) % vx2l , czero , mlprec_wrk ( level ) % vy2l , &
& p % precv ( level ) % base_desc , trans , &
& p % precv ( level ) % base_desc , trans , &
& sweeps , work , info , init = ' Y ')
& sweeps , work , info , init = ' Z ')
else
else
sweeps = p % precv ( level ) % parms % sweeps_post
sweeps = p % precv ( level ) % parms % sweeps_post
if ( info == psb_success_ ) call p % precv ( level ) % sm2 % apply ( cone , &
if ( info == psb_success_ ) call p % precv ( level ) % sm2 % apply ( cone , &
& mlprec_wrk ( level ) % vx2l , czero , mlprec_wrk ( level ) % vy2l , &
& mlprec_wrk ( level ) % vx2l , czero , mlprec_wrk ( level ) % vy2l , &
& p % precv ( level ) % base_desc , trans , &
& p % precv ( level ) % base_desc , trans , &
& sweeps , work , info , init = ' Y ')
& sweeps , work , info , init = ' Z ')
end if
end if
if ( info / = psb_success_ ) then
if ( info / = psb_success_ ) then
@ -983,7 +985,7 @@ contains
call psb_map_X2Y ( cone , mlprec_wrk ( level ) % vty , &
call psb_map_X2Y ( cone , mlprec_wrk ( level ) % vty , &
& czero , mlprec_wrk ( level + 1 ) % vx2l , &
& czero , mlprec_wrk ( level + 1 ) % vx2l , &
& p % precv ( level + 1 ) % map , info , work = work )
& p % precv ( level + 1 ) % map , info , work = work )
call mlprec_wrk ( level + 1 ) % vy2l % zero ( )
if ( info / = psb_success_ ) then
if ( info / = psb_success_ ) then
call psb_errpush ( psb_err_internal_error_ , name , &
call psb_errpush ( psb_err_internal_error_ , name , &
& a_err = 'Error during restriction' )
& a_err = 'Error during restriction' )
@ -992,11 +994,11 @@ contains
! Set the preconditioner
! Set the preconditioner
if ( level < nlev ) then
if ( level < = nlev - 2 ) then
if ( p % precv ( level ) % parms % ml_type == mld_kcyclesym_ml_ ) then
if ( p % precv ( level ) % parms % ml_type == mld_kcyclesym_ml_ ) then
call mld_cinneritkcycle ( p , mlprec_wrk , level + 1 , trans , work , 'FCG' )
call mld_cinneritkcycle ( p , mlprec_wrk , level + 1 , trans , work , 'FCG' )
elseif ( p % precv ( level ) % parms % ml_type == mld_kcycle_ml_ ) then
elseif ( p % precv ( level ) % parms % ml_type == mld_kcycle_ml_ ) then
call mld_cinneritkcycle ( p , mlprec_wrk , level + 1 , trans , work , ' C GR')
call mld_cinneritkcycle ( p , mlprec_wrk , level + 1 , trans , work , ' GC R')
else
else
call psb_errpush ( psb_err_internal_error_ , name , &
call psb_errpush ( psb_err_internal_error_ , name , &
& a_err = 'Bad value for ml_type' )
& a_err = 'Bad value for ml_type' )
@ -1091,7 +1093,8 @@ contains
type ( mld_mlprec_wrk_type ) , intent ( inout ) :: mlprec_wrk ( : )
type ( mld_mlprec_wrk_type ) , intent ( inout ) :: mlprec_wrk ( : )
integer ( psb_ipk_ ) , intent ( in ) :: level
integer ( psb_ipk_ ) , intent ( in ) :: level
character , intent ( in ) :: trans , innersolv
character , intent ( in ) :: trans
character ( len = * ) , intent ( in ) :: innersolv
complex ( psb_spk_ ) , target :: work ( : )
complex ( psb_spk_ ) , target :: work ( : )
! Other variables
! Other variables
@ -1099,9 +1102,10 @@ contains
type ( psb_c_vect_type ) , dimension ( 0 : 1 ) :: d
type ( psb_c_vect_type ) , dimension ( 0 : 1 ) :: d
complex ( psb_spk_ ) :: delta_old , rhs_norm , alpha , tau , tau1 , tau2 , tau3 , tau4 , beta
complex ( psb_spk_ ) :: delta_old , rhs_norm , alpha , tau , tau1 , tau2 , tau3 , tau4 , beta
real ( psb_spk_ ) :: l2_norm , delta , rtol = 0.25
real ( psb_spk_ ) :: l2_norm , delta , rtol = 0.25 , delta0 , tnrm
complex ( psb_spk_ ) , allocatable :: temp_v ( : )
complex ( psb_spk_ ) , allocatable :: temp_v ( : )
integer ( psb_ipk_ ) :: info , nlev , i , iter , max_iter = 2 , idx
integer ( psb_ipk_ ) :: info , nlev , i , iter , max_iter = 2 , idx
character ( len = 20 ) :: name = 'innerit_k_cycle'
! Assemble rhs , w , v , v1 , x
! Assemble rhs , w , v , v1 , x
@ -1120,6 +1124,14 @@ contains
call psb_geasb ( x , &
call psb_geasb ( x , &
& p % precv ( level ) % base_desc , info , &
& p % precv ( level ) % base_desc , info , &
& scratch = . true . , mold = mlprec_wrk ( level ) % vx2l % v )
& scratch = . true . , mold = mlprec_wrk ( level ) % vx2l % v )
! Assemble d ( 0 ) and d ( 1 )
call psb_geasb ( d ( 0 ) , &
& p % precv ( level ) % base_desc , info , &
& scratch = . true . , mold = mlprec_wrk ( level ) % vy2l % v )
call psb_geasb ( d ( 1 ) , &
& p % precv ( level ) % base_desc , info , &
& scratch = . true . , mold = mlprec_wrk ( level ) % vy2l % v )
call x % zero ( )
call x % zero ( )
@ -1133,30 +1145,20 @@ contains
nc2l = p % precv ( level ) % base_desc % get_local_cols ( )
nc2l = p % precv ( level ) % base_desc % get_local_cols ( )
info = psb_err_alloc_request_
info = psb_err_alloc_request_
call psb_errpush ( info , name , i_err = ( / 2 * nc2l , izero , izero , izero , izero / ) , &
call psb_errpush ( info , name , i_err = ( / 2 * nc2l , izero , izero , izero , izero / ) , &
& a_err = ' TYPE@ (psb_spk_)')
& a_err = ' complex (psb_spk_)')
go to 9999
go to 9999
end if
end if
delta = psb_gedot ( w , w , p % precv ( level ) % base_desc , info )
delta 0 = psb_genrm2 ( w , p % precv ( level ) % base_desc , info )
! Apply the preconditioner
! Apply the preconditioner
call mlprec_wrk ( level ) % vy2l % zero ( )
call mlprec_wrk ( level ) % vy2l % set ( czero )
idx = 0
idx = 0
call inner_ml_aply ( level , p , mlprec_wrk , trans , work , info )
call inner_ml_aply ( level , p , mlprec_wrk , trans , work , info )
! Assemble d ( 0 ) and d ( 1 )
call psb_geasb ( d ( 0 ) , &
& p % precv ( level ) % base_desc , info , &
& scratch = . true . , mold = mlprec_wrk ( level ) % vy2l % v )
call psb_geasb ( d ( 1 ) , &
& p % precv ( level ) % base_desc , info , &
& scratch = . true . , mold = mlprec_wrk ( level ) % vy2l % v )
call psb_geaxpby ( cone , mlprec_wrk ( level ) % vy2l , czero , d ( idx ) , p % precv ( level ) % base_desc , info )
call psb_geaxpby ( cone , mlprec_wrk ( level ) % vy2l , czero , d ( idx ) , p % precv ( level ) % base_desc , info )
call psb_spmm ( cone , p % precv ( level ) % base_a , d ( idx ) , czero , v , p % precv ( level ) % base_desc , info )
call psb_spmm ( cone , p % precv ( level ) % base_a , d ( idx ) , czero , v , p % precv ( level ) % base_desc , info )
if ( info / = psb_success_ ) then
if ( info / = psb_success_ ) then
call psb_errpush ( psb_err_internal_error_ , name , &
call psb_errpush ( psb_err_internal_error_ , name , &
@ -1165,24 +1167,27 @@ contains
end if
end if
! FCG
! FCG
if ( innersolv == 'FCG' ) then
if ( psb_toupper( trim ( innersolv) ) == 'FCG' ) then
delta_old = psb_gedot ( d ( idx ) , w , p % precv ( level ) % base_desc , info )
delta_old = psb_gedot ( d ( idx ) , w , p % precv ( level ) % base_desc , info )
tau = psb_gedot ( d ( idx ) , v , p % precv ( level ) % base_desc , info )
tau = psb_gedot ( d ( idx ) , v , p % precv ( level ) % base_desc , info )
! C GR
! GC R
else
else if ( psb_toupper ( trim ( innersolv ) ) == 'GCR' ) then
delta_old = psb_gedot ( v , w , p % precv ( level ) % base_desc , info )
delta_old = psb_gedot ( v , w , p % precv ( level ) % base_desc , info )
tau = psb_gedot ( v , v , p % precv ( level ) % base_desc , info )
tau = psb_gedot ( v , v , p % precv ( level ) % base_desc , info )
else
call psb_errpush ( psb_err_internal_error_ , name , &
& a_err = 'Invalid inner solver' )
go to 9999
endif
endif
alpha = delta_old / tau
alpha = delta_old / tau
! Update residual w
! Update residual w
call psb_geaxpby ( - alpha , v , cone , w , p % precv ( level ) % base_desc , info )
call psb_geaxpby ( - alpha , v , cone , w , p % precv ( level ) % base_desc , info )
l2_norm = psb_ge dot( w , w , p % precv ( level ) % base_desc , info )
l2_norm = psb_ge nrm2( w , p % precv ( level ) % base_desc , info )
iter = 0
iter = 0
if ( l2_norm < = rtol * delta0 ) then
if ( l2_norm < = rtol * delta ) then
! Update solution x
! Update solution x
call psb_geaxpby ( alpha , d ( idx ) , cone , x , p % precv ( level ) % base_desc , info )
call psb_geaxpby ( alpha , d ( idx ) , cone , x , p % precv ( level ) % base_desc , info )
else
else
@ -1204,18 +1209,20 @@ contains
end if
end if
! tau1 , tau2 , tau3 , tau4
! tau1 , tau2 , tau3 , tau4
! FCG
if ( psb_toupper ( trim ( innersolv ) ) == 'FCG' ) then
if ( innersolv == 'FCG' ) then
tau1 = psb_gedot ( d ( idx ) , v , p % precv ( level ) % base_desc , info )
tau1 = psb_gedot ( d ( idx ) , v , p % precv ( level ) % base_desc , info )
tau2 = psb_gedot ( d ( idx ) , v1 , p % precv ( level ) % base_desc , info )
tau2 = psb_gedot ( d ( idx ) , v1 , p % precv ( level ) % base_desc , info )
tau3 = psb_gedot ( d ( idx ) , w , p % precv ( level ) % base_desc , info )
tau3 = psb_gedot ( d ( idx ) , w , p % precv ( level ) % base_desc , info )
tau4 = tau2 - ( tau1 * tau1 ) / tau
tau4 = tau2 - ( tau1 * tau1 ) / tau
! CGR
else if ( psb_toupper ( trim ( innersolv ) ) == 'GCR' ) then
else
tau1 = psb_gedot ( v1 , v , p % precv ( level ) % base_desc , info )
tau1 = psb_gedot ( v1 , v , p % precv ( level ) % base_desc , info )
tau2 = psb_gedot ( v1 , v1 , p % precv ( level ) % base_desc , info )
tau2 = psb_gedot ( v1 , v1 , p % precv ( level ) % base_desc , info )
tau3 = psb_gedot ( v1 , w , p % precv ( level ) % base_desc , info )
tau3 = psb_gedot ( v1 , w , p % precv ( level ) % base_desc , info )
tau4 = tau2 - ( tau1 * tau1 ) / tau
tau4 = tau2 - ( tau1 * tau1 ) / tau
else
call psb_errpush ( psb_err_internal_error_ , name , &
& a_err = 'Invalid inner solver' )
go to 9999
endif
endif
! Update solution
! Update solution
@ -1225,8 +1232,8 @@ contains
call psb_geaxpby ( alpha , d ( idx ) , cone , x , p % precv ( level ) % base_desc , info )
call psb_geaxpby ( alpha , d ( idx ) , cone , x , p % precv ( level ) % base_desc , info )
endif
endif
! Free vectors
call psb_geaxpby ( cone , x , czero , mlprec_wrk ( level ) % vy2l , p % precv ( level ) % base_desc , info )
call psb_geaxpby ( cone , x , czero , mlprec_wrk ( level ) % vy2l , p % precv ( level ) % base_desc , info )
! Free vectors
call psb_gefree ( v , p % precv ( level ) % base_desc , info )
call psb_gefree ( v , p % precv ( level ) % base_desc , info )
call psb_gefree ( v1 , p % precv ( level ) % base_desc , info )
call psb_gefree ( v1 , p % precv ( level ) % base_desc , info )
call psb_gefree ( w , p % precv ( level ) % base_desc , info )
call psb_gefree ( w , p % precv ( level ) % base_desc , info )