Changes in src/solvers/pcg.F90 [08dfb5f:b378423]
- File:
-
- 1 edited
-
src/solvers/pcg.F90 (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/solvers/pcg.F90
r08dfb5f rb378423 41 41 #endif 42 42 43 integer,save :: coarseid=0 43 44 private :: & 44 45 preconditioner, & … … 49 50 50 51 contains 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 51 245 52 246 subroutine prec1Level(DD,sol,A,rhs,A_ghost,refactor)
Note: See TracChangeset
for help on using the changeset viewer.
