Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/solvers/pcg.F90

    r08dfb5f rb378423  
    4141#endif 
    4242 
     43  integer,save :: coarseid=0 
    4344  private :: & 
    4445       preconditioner, & 
     
    4950 
    5051contains 
     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 
    51245 
    52246  subroutine prec1Level(DD,sol,A,rhs,A_ghost,refactor) 
Note: See TracChangeset for help on using the changeset viewer.