Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/solvers/pcg.F90

    rb378423 r08dfb5f  
    4141#endif 
    4242 
    43   integer,save :: coarseid=0 
    4443  private :: & 
    4544       preconditioner, & 
     
    5049 
    5150contains 
    52  
    53   !-------------------------------------------- 
    54   ! Preconditioned conjugate gradient method 
    55   !-------------------------------------------- 
    56   subroutine pcg (A, b, x, Msh, tol_, maxit_, & 
    57        x0_, solinf, resvects_, CoarseMtx_) 
    58     implicit none 
    59  
    60     type(SpMtx),intent(in out) :: A ! System matrix (sparse) 
    61     float(kind=rk),dimension(:),pointer :: b ! RHS 
    62     float(kind=rk),dimension(:),pointer :: x ! Solution 
    63     ! Mesh - aux data for Ax operation 
    64     type(Mesh),                       intent(in) :: Msh 
    65  
    66     ! Optional arguments 
    67     ! Tolerance of the method 
    68     real(kind=rk),          intent(in), optional :: tol_ 
    69     ! Max number of iterations 
    70     integer,                intent(in), optional :: maxit_ 
    71     ! Initial guess 
    72     float(kind=rk), dimension(:), intent(in), optional :: x0_ 
    73     ! Solution statistics 
    74     type(ConvInf),            intent(in out), optional :: solinf 
    75     ! Fill in the 'resvect' or not 
    76     logical,                      intent(in), optional :: resvects_ 
    77     type(SpMtx),optional                         :: CoarseMtx_ ! Coarse matrix 
    78  
    79     real(kind=rk) :: tol   ! Tolerance 
    80     integer       :: maxit ! Max number of iterations 
    81     logical       :: resvects=.false. 
    82  
    83     !real(kind=rk), dimension(size(b)) :: r, p, q, m, z, b_k 
    84     real(kind=rk),dimension(:),pointer :: r, p, q, m, z, b_k 
    85     real(kind=rk) :: rho_curr, rho_prev, init_norm, res_norm 
    86     real(kind=rk) :: alpha, beta, tmp, ratio_norm 
    87     integer :: iter,nfreds 
    88     integer :: ierr 
    89     ! + test 
    90     float(kind=rk), dimension(:), pointer :: arr_copy, gv_tmp 
    91  
    92 !!$    real(kind=rk) :: r_max 
    93  
    94     write(stream,'(/a)') 'Preconditioned conjugate gradient:' 
    95  
    96     if (size(b) /= size(x)) & 
    97          call DOUG_abort('[pcg] : SEVERE : size(b) /= size(x)',-1) 
    98  
    99 !!$    if (present(x0_)) 
    100 !!$         ! use method with initial guess 
    101  
    102  
    103     nfreds=size(b) 
    104     allocate(r(nfreds)) 
    105     allocate(p(nfreds)) 
    106     allocate(q(nfreds)) 
    107     allocate(m(nfreds)) 
    108     allocate(z(nfreds)) 
    109     allocate(b_k(nfreds)) 
    110  
    111  
    112     tol = sctls%solve_tolerance 
    113     if (present(tol_)) & 
    114          tol = tol_ 
    115  
    116     maxit = sctls%solve_maxiters 
    117     if (maxit==-1) maxit=100000 
    118     if (present(maxit_)) & 
    119          maxit = maxit_ 
    120  
    121     if (present(resvects_).and.(.not.present(solinf))) & 
    122          call DOUG_abort('[pcg] : SEVERE : "resvects_" must be given along'//& 
    123          ' with "solinf".',-1) 
    124  
    125     ! Allocate convergence info structure 
    126     if (present(solinf).and.(.not.present(resvects_))) then 
    127        call ConvInf_Init(solinf) 
    128     else if (present(solinf)) then 
    129        if (present(resvects_).and.(resvects_.eqv.(.true.))) then 
    130          call ConvInf_Init(solinf, maxit) 
    131          resvects = .true. 
    132        end if 
    133     end if 
    134  
    135     ! Initialise auxiliary data structures 
    136     ! to assist with pmvm 
    137     call pmvmCommStructs_init(A, Msh) 
    138  
    139     ! + test 
    140     if (ismaster()) & 
    141          allocate(gv_tmp(Msh%ngf)) 
    142     allocate(arr_copy(Msh%nlf)) 
    143  
    144     ! Build preconditioner 
    145     !  call preconditioner(A, m, CoarseMtx_) 
    146 !!$    ! + test 
    147 !!$    arr_copy = m 
    148 !!$    call Vect_newToOldPerm(arr_copy) 
    149 !!$    gv_tmp = 0.0_rk 
    150 !!$    call Vect_Gather(arr_copy, gv_tmp, Msh) 
    151 !!$    if (ismaster()) & 
    152 !!$         call Vect_Print(gv_tmp, 'm ::') 
    153  
    154 !!$    ! + test 
    155 !!$    !b = 1.0_rk 
    156 !!$    arr_copy = b 
    157 !!$    call Vect_newToOldPerm(arr_copy) 
    158 !!$    call Vect_Print(arr_copy, 'b local (original ordering) ::') 
    159 !!$    gv_tmp = 0.0_rk 
    160 !!$    call Vect_Gather(arr_copy, gv_tmp, Msh) 
    161 !!$    if (ismaster()) & 
    162 !!$         call Vect_Print(gv_tmp, 'b global (original ordering) ::') 
    163  
    164 !!$    ! + test 
    165 !!$    arr_copy = x 
    166 !!$    call Vect_newToOldPerm(arr_copy) 
    167 !!$    call Vect_Print(arr_copy, 'x local (original ordering) ::') 
    168 !!$    gv_tmp = 0.0_rk 
    169 !!$    call Vect_Gather(arr_copy, gv_tmp, Msh) 
    170 !!$    if (ismaster()) & 
    171 !!$         call Vect_Print(gv_tmp, 'x global (original ordering) ::') 
    172  
    173     !r = b - SpMtx_pmvm(A, x, Msh) 
    174     call SpMtx_pmvm(r,A,x,Msh) 
    175     r = b - r 
    176     !call Vect_Print(r,'initial residual') 
    177  
    178     ! + test 
    179 !!$    arr_copy = r 
    180 !!$    call Vect_newToOldPerm(arr_copy) 
    181 !!$    gv_tmp = 0.0_rk 
    182 !!$    call Vect_Gather(arr_copy, gv_tmp, Msh) 
    183 !!$    if (ismaster()) & 
    184 !!$         call Vect_Print(gv_tmp, 'r ::') 
    185  
    186     init_norm = Vect_dot_product(r,r) 
    187     if (init_norm == 0.0) & 
    188          init_norm = 1.0 
    189  
    190     write(stream,'(a,i6,a,e8.2)') 'maxit = ',maxit,', tol = ',tol 
    191     write(stream,'(a,e22.15)') 'init_norm = ', dsqrt(init_norm) 
    192  
    193     iter = 1 
    194     ratio_norm = 1.0_rk 
    195     do while((ratio_norm > tol*tol).and.(iter <= maxit)) 
    196        call msolve(m,r,z) 
    197        !if (present(CoarseMtx_)) then 
    198        !  call preconditioner(z,A,r,CoarseMtx_) 
    199        !  !z=r 
    200        !else 
    201        !  call preconditioner(z,A,r) 
    202        !endif 
    203  
    204        !call Vect_Print(z,'preconditioner') 
    205  
    206        ! compute current rho 
    207        rho_curr = Vect_dot_product(r,z) 
    208        if (iter == 1) then 
    209           p = z 
    210        else 
    211           beta = rho_curr / rho_prev 
    212           p = z + beta * p 
    213        end if 
    214        !q = SpMtx_pmvm(A, p, Msh) 
    215        call SpMtx_pmvm(q,A,p,Msh) 
    216        ! compute alpha 
    217        alpha = rho_curr / Vect_dot_product(p,q) 
    218        x = x + alpha * p 
    219        r = r - alpha * q 
    220        rho_prev = rho_curr 
    221        ! check 
    222        res_norm = Vect_dot_product(r,r) 
    223        ratio_norm = dsqrt(res_norm) / dsqrt(init_norm) 
    224 !!$       ratio_norm = res_norm / init_norm 
    225        if (ismaster()) & 
    226             write(stream, '(i5,a,e22.15)') iter,': res_norm=',dsqrt(res_norm) 
    227             !write(stream, '(i5,a,e22.15,e22.15)') iter,': dsqrt(ratio_norm)=',& 
    228             !dsqrt(ratio_norm), dsqrt(res_norm) 
    229        iter = iter + 1 
    230     end do 
    231  
    232     ! Deallocate auxiliary data structures 
    233     ! helped to assist with pmvm 
    234     call pmvmCommStructs_destroy() 
    235  
    236     deallocate(b_k) 
    237     deallocate(z) 
    238     deallocate(m) 
    239     deallocate(q) 
    240     deallocate(p) 
    241     deallocate(r) 
    242     if (associated(gv_tmp)) deallocate(gv_tmp) 
    243     if (associated(arr_copy)) deallocate(arr_copy) 
    244   end subroutine pcg 
    24551 
    24652  subroutine prec1Level(DD,sol,A,rhs,A_ghost,refactor) 
Note: See TracChangeset for help on using the changeset viewer.